spi25: Check quad-enable (QE) bit
When a chip has a quad-enable bit, check its status and disable
quad i/o if the bit isn't set. Note, some chips have a volatile
QE bit that we could set/reset automatically without wear. This
would require more work on the register infrastructure and chip
database, though.
Change-Id: I8a0b9b3dee14f344d4794c91d7d6fb962a8bea87
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/164
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/include/programmer.h b/include/programmer.h
index cc219be..54cbdc0 100644
--- a/include/programmer.h
+++ b/include/programmer.h
@@ -502,6 +502,10 @@
{
return flash->mst.spi->features & SPI_MASTER_NO_4BA_MODES;
}
+static inline bool spi_master_quad(const struct flashctx *const flash)
+{
+ return flash->mst.spi->features & SPI_MASTER_QUAD;
+}
/* usbdev.c */
struct libusb_device_handle;
diff --git a/spi25_prepare.c b/spi25_prepare.c
index 76ad9a7..7482c5c 100644
--- a/spi25_prepare.c
+++ b/spi25_prepare.c
@@ -77,6 +77,31 @@
return 0;
}
+static int spi_prepare_quad_io(struct flashctx *const flash)
+{
+ if (!spi_master_quad(flash))
+ return 0;
+
+ /* Check QE bit if present */
+ if (flash->chip->reg_bits.qe.reg != INVALID_REG) {
+ const struct reg_bit_info qe = flash->chip->reg_bits.qe;
+ uint8_t reg_val;
+
+ if (spi_read_register(flash, qe.reg, ®_val)) {
+ msg_cwarn("Failed read chip register!\n");
+ reg_val = 0;
+ }
+ if (!(reg_val & 1 << qe.bit_index)) {
+ msg_cinfo("Quad-enable (QE) bit is unknown or unset, disabling quad i/o.\n");
+ flash->chip->feature_bits &= ~FEATURE_ANY_QUAD;
+ } else {
+ msg_cdbg("Quad-enable (QE) bit is set.\n");
+ }
+ }
+
+ return 0;
+}
+
int spi_prepare_io(struct flashctx *const flash, const enum preparation_steps prep)
{
if (prep != PREPARE_FULL)
@@ -86,6 +111,10 @@
if (ret)
return ret;
+ ret = spi_prepare_quad_io(flash);
+ if (ret)
+ return ret;
+
return 0;
}