[PATCH v2 08/17] mtd: spi-nor: Allow configuring the actual number of dummy cycles

From: Miquel Raynal

Date: Sun Oct 04 2026 - 17:34:53 EST


The SPI NOR core selects the fastest read variant advertised by the SFDP
tables. This may or may not be a wise choice but at least it is simpler
as any bus frequency will just work. There is however a downside: the
number of dummy cycles is maximized (in case the bus frequency is really
fast, this is how the chip enforces a sufficient delay). Maximizing the
number of dummy cycles means that, if the amount of cycles is
configurable in the chip, we might not take its default value. When this
happens, we need to make sure that the chip is configured accordingly.

Create a callback to configure the chip for a specific number of dummy
cycles. This callback is used:
- after deciding how to communicate with the device,
- in case of error when switching into ODTR mode, we shall negociate
another configuration,
- upon resume.

Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx>
---
drivers/mtd/spi-nor/core.c | 24 +++++++++++++++++++++++-
drivers/mtd/spi-nor/core.h | 2 ++
2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 6e22342361c3..56d8f95da0d4 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2993,6 +2993,20 @@ static int spi_nor_init_params(struct spi_nor *nor)
return 0;
}

+/**
+ * spi_nor_set_dummy() - configure chip for a given number of dummy cycles
+ * @nor: pointer to a 'struct spi_nor'
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_set_dummy(struct spi_nor *nor)
+{
+ if (!nor->params->set_dummy)
+ return 0;
+
+ return nor->params->set_dummy(nor, nor->read_dummy);
+}
+
/** spi_nor_set_octal_dtr() - enable or disable Octal DTR I/O.
* @nor: pointer to a 'struct spi_nor'
* @enable: whether to enable or disable Octal DTR
@@ -3016,7 +3030,11 @@ static int spi_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
hwcaps.mask &= ~(SNOR_HWCAPS_READ_8_8_8_DTR |
SNOR_HWCAPS_PP_8_8_8_DTR);

- return spi_nor_setup(nor, &hwcaps);
+ ret = spi_nor_setup(nor, &hwcaps);
+ if (ret)
+ return ret;
+
+ return spi_nor_set_dummy(nor);
}

ret = nor->params->set_octal_dtr(nor, enable);
@@ -3093,6 +3111,10 @@ static int spi_nor_init(struct spi_nor *nor)
struct spi_nor_flash_parameter *params = nor->params;
int err;

+ err = spi_nor_set_dummy(nor);
+ if (err)
+ return err;
+
err = spi_nor_set_octal_dtr(nor, true);
if (err) {
dev_dbg(nor->dev, "octal mode not supported\n");
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 670182b3c2ad..b64f26b69c05 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -377,6 +377,7 @@ struct spi_nor_opcodes {
* Table.
* @otp: SPI NOR OTP info.
* @set_octal_dtr: enables or disables SPI NOR octal DTR mode.
+ * @set_dummy: configure the number of read dummy cycles.
* @quad_enable: enables SPI NOR quad mode.
* @qe_mask: two bytes mask used to set/clear the QE bit
* @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
@@ -410,6 +411,7 @@ struct spi_nor_flash_parameter {
struct spi_nor_otp otp;

int (*set_octal_dtr)(struct spi_nor *nor, bool enable);
+ int (*set_dummy)(struct spi_nor *nor, u8 dummy_cycles);
int (*quad_enable)(struct spi_nor *nor);
u8 qe_mask[2];
int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable);

--
2.55.0