All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/7] Support for SPI RX Sampling Delay Compensation
@ 2026-03-03 16:29 ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

This is an attempt to continue the efforts started in [1] to support
SPI devices that are clocked at high speeds and have a significant
delay in the RX path.

This aims to handle the known RX path delay introduced by the SPI
device itself and specified in the datasheet as maximum tCLQV value
by:

1. Applying compensation if the controller driver supports it
2. Reducing the clock frequency to a safe value if the controller
   driver's compensation capabilities are exceeded.

I'm sending this as a new RFC as quite a few things have changed
compared to [1] and a lot of time has passed. Also I'm quite unsure
if the layering for this implementation is correct and wether
it conflicts or overlaps with the PHY tuning series [2] in some
way.

This approach adds a new attribute for SPI devices to track the
RX sampling delay requirements of the device and extends the SPI
NAND drivers for Toshiba and Winbond devices to specify the values
from the datasheets (patch 1-4).

Then it adds calls to a new handler in the SPI controller drivers to
the core and provides a generic helper to calculate the delay cycles
(patch 5-6).

At last it implements the new handler for the FSL QSPI driver in
order to compensate the RX sampling delay, or as a fallback reduce
the clock rate to a value that is safe to use without violating the
RX sampling delay requirement of the device (patch 7).

This does not yet implement the fallback to reduce the clock rate
for controllers that don't have compensation capabilities or that
have not yet implemented the compensation handler. Therefore this
series doesn't cause changes in behavior for controllers other than
FSL QSPI.

Please note that some drivers such as spi-stm32-qspi.c currently
enable a RX sampling delay of one half clock cycle unconditionally
for all devices. While this works in general, as all currently known
devices are in range of sampling the data at this point, when testing
this approach with FSL QSPI it failed at low clock rates (e.g.
100 kHz). This is probably due to the sampling happening too late,
when the data line is alredy changing its state as the delay is
negligible compared to the (rather long) clock period in this case.

This series was tested on i.MX6UL with the following SPI NAND devices:

* Toshiba/Kioxia TC58CVG2S0HRAIJ (133 MHz, tCLQV max. 6 ns)
* Winbond W25M02GV (104 MHz, tCLQV max. 7 ns)
* Winbond W25N02KV (104 MHz, tCLQV max. 7 ns)

The former two chips seem to work fine even without this patchset,
probably due to the actual RX sampling delay being lower than the
maximum value specified in the datasheet. The latter chip fails
reading at 104 MHz without RX sampling delay compensation.

[1] https://lore.kernel.org/all/20231026152316.2729575-1-estl@gmx.net/
[2] https://patchwork.ozlabs.org/project/linux-mtd/cover/20260113141617.1905039-1-s-k6@ti.com/

---
Eberhard Stoll (4):
      spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
      mtd: spinand: Add support for clock to RX delay setting
      mtd: spinand: winbond: Add RX sampling delay values
      spi: spi-fsl-qspi: Add support for RX data sampling point adjustment

Frieder Schrempf (3):
      mtd: spinand: toshiba: Add RX sampling delay values
      spi: Add RX sampling point adjustment
      spi: spi-mem: Call spi_set_rx_sampling_point() for each op

 drivers/mtd/nand/spi/core.c    |  1 +
 drivers/mtd/nand/spi/toshiba.c | 48 ++++++++++++++++---------
 drivers/mtd/nand/spi/winbond.c | 42 ++++++++++++++--------
 drivers/spi/spi-fsl-qspi.c     | 80 ++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/spi-mem.c          |  2 ++
 drivers/spi/spi.c              | 73 ++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/spinand.h    |  5 +++
 include/linux/spi/spi.h        | 11 ++++++
 8 files changed, 231 insertions(+), 31 deletions(-)
---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20260303-fsl-qspi-rx-sampling-delay-9133e51ce503

Best regards,
-- 
Frieder Schrempf <frieder.schrempf@kontron.de>


^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH RFC 0/7] Support for SPI RX Sampling Delay Compensation
@ 2026-03-03 16:29 ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

This is an attempt to continue the efforts started in [1] to support
SPI devices that are clocked at high speeds and have a significant
delay in the RX path.

This aims to handle the known RX path delay introduced by the SPI
device itself and specified in the datasheet as maximum tCLQV value
by:

1. Applying compensation if the controller driver supports it
2. Reducing the clock frequency to a safe value if the controller
   driver's compensation capabilities are exceeded.

I'm sending this as a new RFC as quite a few things have changed
compared to [1] and a lot of time has passed. Also I'm quite unsure
if the layering for this implementation is correct and wether
it conflicts or overlaps with the PHY tuning series [2] in some
way.

This approach adds a new attribute for SPI devices to track the
RX sampling delay requirements of the device and extends the SPI
NAND drivers for Toshiba and Winbond devices to specify the values
from the datasheets (patch 1-4).

Then it adds calls to a new handler in the SPI controller drivers to
the core and provides a generic helper to calculate the delay cycles
(patch 5-6).

At last it implements the new handler for the FSL QSPI driver in
order to compensate the RX sampling delay, or as a fallback reduce
the clock rate to a value that is safe to use without violating the
RX sampling delay requirement of the device (patch 7).

This does not yet implement the fallback to reduce the clock rate
for controllers that don't have compensation capabilities or that
have not yet implemented the compensation handler. Therefore this
series doesn't cause changes in behavior for controllers other than
FSL QSPI.

Please note that some drivers such as spi-stm32-qspi.c currently
enable a RX sampling delay of one half clock cycle unconditionally
for all devices. While this works in general, as all currently known
devices are in range of sampling the data at this point, when testing
this approach with FSL QSPI it failed at low clock rates (e.g.
100 kHz). This is probably due to the sampling happening too late,
when the data line is alredy changing its state as the delay is
negligible compared to the (rather long) clock period in this case.

This series was tested on i.MX6UL with the following SPI NAND devices:

* Toshiba/Kioxia TC58CVG2S0HRAIJ (133 MHz, tCLQV max. 6 ns)
* Winbond W25M02GV (104 MHz, tCLQV max. 7 ns)
* Winbond W25N02KV (104 MHz, tCLQV max. 7 ns)

The former two chips seem to work fine even without this patchset,
probably due to the actual RX sampling delay being lower than the
maximum value specified in the datasheet. The latter chip fails
reading at 104 MHz without RX sampling delay compensation.

[1] https://lore.kernel.org/all/20231026152316.2729575-1-estl@gmx.net/
[2] https://patchwork.ozlabs.org/project/linux-mtd/cover/20260113141617.1905039-1-s-k6@ti.com/

---
Eberhard Stoll (4):
      spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
      mtd: spinand: Add support for clock to RX delay setting
      mtd: spinand: winbond: Add RX sampling delay values
      spi: spi-fsl-qspi: Add support for RX data sampling point adjustment

Frieder Schrempf (3):
      mtd: spinand: toshiba: Add RX sampling delay values
      spi: Add RX sampling point adjustment
      spi: spi-mem: Call spi_set_rx_sampling_point() for each op

 drivers/mtd/nand/spi/core.c    |  1 +
 drivers/mtd/nand/spi/toshiba.c | 48 ++++++++++++++++---------
 drivers/mtd/nand/spi/winbond.c | 42 ++++++++++++++--------
 drivers/spi/spi-fsl-qspi.c     | 80 ++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/spi-mem.c          |  2 ++
 drivers/spi/spi.c              | 73 ++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/spinand.h    |  5 +++
 include/linux/spi/spi.h        | 11 ++++++
 8 files changed, 231 insertions(+), 31 deletions(-)
---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20260303-fsl-qspi-rx-sampling-delay-9133e51ce503

Best regards,
-- 
Frieder Schrempf <frieder.schrempf@kontron.de>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
  2026-03-03 16:29 ` Frieder Schrempf
@ 2026-03-03 16:29   ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

Some high speed SPI devices require a delay between the controller
clock and the sampling point of the client device. This 'clock to
receive data delay' value is often referenced as tCLQV in SPI device
data sheets.

Not respecting this can lead to data being sampled too early when
the client doesn't yet reflect the correct level at the data out
pin(s).

There are two ways to handle the situation:

1. Reduce the controller clock to the amount where the sampling
   point requirement of the client is still met, meaning the
   clock period being greater than two times tCLQV.

2. If the host controller supports it, compensate by delaying the
   sampling point to meet the tCLQV requirement of the client.

Add a parameter 'rx_sampling_delay_ns' in struct spi_device to enable
setting the clock to RX data delay for each SPI device, so drivers
can check and act upon this timing requirement.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 include/linux/spi/spi.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index af7cfee7b8f60..4f8a0c28e1d46 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -181,6 +181,7 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
  * @num_tx_lanes: Number of transmit lanes wired up.
  * @rx_lane_map: Map of peripheral lanes (index) to controller lanes (value).
  * @num_rx_lanes: Number of receive lanes wired up.
+ * @rx_sampling_delay_ns: spi clk to spi rx data delay
  *
  * A @spi_device is used to interchange data between an SPI target device
  * (usually a discrete chip) and CPU memory.
@@ -235,6 +236,8 @@ struct spi_device {
 	struct spi_delay	cs_setup;
 	struct spi_delay	cs_hold;
 	struct spi_delay	cs_inactive;
+	/* Transfer characteristics */
+	u32			rx_sampling_delay_ns; /* clk to rx data delay */
 
 	u8			chip_select[SPI_DEVICE_CS_CNT_MAX];
 	u8			num_chipselect;

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
@ 2026-03-03 16:29   ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

Some high speed SPI devices require a delay between the controller
clock and the sampling point of the client device. This 'clock to
receive data delay' value is often referenced as tCLQV in SPI device
data sheets.

Not respecting this can lead to data being sampled too early when
the client doesn't yet reflect the correct level at the data out
pin(s).

There are two ways to handle the situation:

1. Reduce the controller clock to the amount where the sampling
   point requirement of the client is still met, meaning the
   clock period being greater than two times tCLQV.

2. If the host controller supports it, compensate by delaying the
   sampling point to meet the tCLQV requirement of the client.

Add a parameter 'rx_sampling_delay_ns' in struct spi_device to enable
setting the clock to RX data delay for each SPI device, so drivers
can check and act upon this timing requirement.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 include/linux/spi/spi.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index af7cfee7b8f60..4f8a0c28e1d46 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -181,6 +181,7 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
  * @num_tx_lanes: Number of transmit lanes wired up.
  * @rx_lane_map: Map of peripheral lanes (index) to controller lanes (value).
  * @num_rx_lanes: Number of receive lanes wired up.
+ * @rx_sampling_delay_ns: spi clk to spi rx data delay
  *
  * A @spi_device is used to interchange data between an SPI target device
  * (usually a discrete chip) and CPU memory.
@@ -235,6 +236,8 @@ struct spi_device {
 	struct spi_delay	cs_setup;
 	struct spi_delay	cs_hold;
 	struct spi_delay	cs_inactive;
+	/* Transfer characteristics */
+	u32			rx_sampling_delay_ns; /* clk to rx data delay */
 
 	u8			chip_select[SPI_DEVICE_CS_CNT_MAX];
 	u8			num_chipselect;

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting
  2026-03-03 16:29 ` Frieder Schrempf
@ 2026-03-03 16:29   ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

Add the configuration parameter to set the SPI clock to receive
data delay parameter for SPI NAND devices.

This parameter is often referenced as tCLQV in SPI NAND device
data sheets.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/mtd/nand/spi/core.c | 1 +
 include/linux/mtd/spinand.h | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 8aa3753aaaa1d..782a605018bc3 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1594,6 +1594,7 @@ int spinand_match_and_init(struct spinand_device *spinand,
 		spinand->user_otp = &table[i].user_otp;
 		spinand->read_retries = table[i].read_retries;
 		spinand->set_read_retry = table[i].set_read_retry;
+		spinand->spimem->spi->rx_sampling_delay_ns = table[i].rx_sampling_delay_ns;
 
 		/* I/O variants selection with single-spi SDR commands */
 
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6a024cf1c53ac..b76aaf0747962 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -568,6 +568,7 @@ enum spinand_bus_interface {
  * @model: model name
  * @devid: device ID
  * @flags: OR-ing of the SPINAND_XXX flags
+ * @rx_sampling_delay_ns: clock to rx data delay timing (tCLQV)
  * @memorg: memory organization
  * @eccreq: ECC requirements
  * @eccinfo: on-die ECC info
@@ -592,6 +593,7 @@ struct spinand_info {
 	const char *model;
 	struct spinand_devid devid;
 	u32 flags;
+	u32 rx_sampling_delay_ns;
 	struct nand_memory_organization memorg;
 	struct nand_ecc_props eccreq;
 	struct spinand_ecc_info eccinfo;
@@ -643,6 +645,9 @@ struct spinand_info {
 #define SPINAND_CONFIGURE_CHIP(__configure_chip)			\
 	.configure_chip = __configure_chip
 
+#define SPINAND_RX_SAMPLING_DELAY(__delay)				\
+	.rx_sampling_delay_ns = __delay
+
 #define SPINAND_CONT_READ(__set_cont_read)				\
 	.set_cont_read = __set_cont_read
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting
@ 2026-03-03 16:29   ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

Add the configuration parameter to set the SPI clock to receive
data delay parameter for SPI NAND devices.

This parameter is often referenced as tCLQV in SPI NAND device
data sheets.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/mtd/nand/spi/core.c | 1 +
 include/linux/mtd/spinand.h | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 8aa3753aaaa1d..782a605018bc3 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1594,6 +1594,7 @@ int spinand_match_and_init(struct spinand_device *spinand,
 		spinand->user_otp = &table[i].user_otp;
 		spinand->read_retries = table[i].read_retries;
 		spinand->set_read_retry = table[i].set_read_retry;
+		spinand->spimem->spi->rx_sampling_delay_ns = table[i].rx_sampling_delay_ns;
 
 		/* I/O variants selection with single-spi SDR commands */
 
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6a024cf1c53ac..b76aaf0747962 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -568,6 +568,7 @@ enum spinand_bus_interface {
  * @model: model name
  * @devid: device ID
  * @flags: OR-ing of the SPINAND_XXX flags
+ * @rx_sampling_delay_ns: clock to rx data delay timing (tCLQV)
  * @memorg: memory organization
  * @eccreq: ECC requirements
  * @eccinfo: on-die ECC info
@@ -592,6 +593,7 @@ struct spinand_info {
 	const char *model;
 	struct spinand_devid devid;
 	u32 flags;
+	u32 rx_sampling_delay_ns;
 	struct nand_memory_organization memorg;
 	struct nand_ecc_props eccreq;
 	struct spinand_ecc_info eccinfo;
@@ -643,6 +645,9 @@ struct spinand_info {
 #define SPINAND_CONFIGURE_CHIP(__configure_chip)			\
 	.configure_chip = __configure_chip
 
+#define SPINAND_RX_SAMPLING_DELAY(__delay)				\
+	.rx_sampling_delay_ns = __delay
+
 #define SPINAND_CONT_READ(__set_cont_read)				\
 	.set_cont_read = __set_cont_read
 

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 3/7] mtd: spinand: winbond: Add RX sampling delay values
  2026-03-03 16:29 ` Frieder Schrempf
@ 2026-03-03 16:29   ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

Add tCLQV (Clock Low to Output Valid) parameter from datasheets
for Winbond SPI NAND chips. This allows to let the drivers
properly handle high sampling delays at high clock speeds.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/mtd/nand/spi/winbond.c | 42 ++++++++++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 6dfd0dcc8ee7a..ec223e6d695a7 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -458,7 +458,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1G-bit densities */
 	SPINAND_INFO("W25N01GV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
@@ -468,7 +469,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N01GW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -477,7 +479,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	SPINAND_INFO("W25N01JW", /* high-speed 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -487,7 +490,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&w25n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	SPINAND_INFO("W25N01KV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
 		     NAND_MEMORG(1, 2048, 96, 64, 1024, 20, 1, 1, 1),
@@ -496,7 +500,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W35N01JW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdc, 0x21),
 		     NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 1, 1),
@@ -507,7 +512,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
 		     SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	SPINAND_INFO("W35N02JW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x22),
 		     NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 2, 1),
@@ -518,7 +524,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
 		     SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	SPINAND_INFO("W35N04JW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x23),
 		     NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 4, 1),
@@ -529,7 +536,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
 		     SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 2G-bit densities */
 	SPINAND_INFO("W25M02GV", /* 2x1G-bit 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
@@ -541,7 +549,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w25_ops),
 		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
-		     SPINAND_SELECT_TARGET(w25m02gv_select_target)),
+		     SPINAND_SELECT_TARGET(w25m02gv_select_target),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N02JW", /* high-speed 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
@@ -551,7 +560,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N02KV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -560,7 +570,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N02KW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22),
 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -569,7 +580,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 4G-bit densities */
 	SPINAND_INFO("W25N04KV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
@@ -579,7 +591,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N04KW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x23),
 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 1, 1, 1),
@@ -588,7 +601,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 };
 
 static int winbond_spinand_init(struct spinand_device *spinand)

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 3/7] mtd: spinand: winbond: Add RX sampling delay values
@ 2026-03-03 16:29   ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

Add tCLQV (Clock Low to Output Valid) parameter from datasheets
for Winbond SPI NAND chips. This allows to let the drivers
properly handle high sampling delays at high clock speeds.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/mtd/nand/spi/winbond.c | 42 ++++++++++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 6dfd0dcc8ee7a..ec223e6d695a7 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -458,7 +458,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1G-bit densities */
 	SPINAND_INFO("W25N01GV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
@@ -468,7 +469,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N01GW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -477,7 +479,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	SPINAND_INFO("W25N01JW", /* high-speed 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -487,7 +490,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&w25n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	SPINAND_INFO("W25N01KV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
 		     NAND_MEMORG(1, 2048, 96, 64, 1024, 20, 1, 1, 1),
@@ -496,7 +500,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W35N01JW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdc, 0x21),
 		     NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 1, 1),
@@ -507,7 +512,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
 		     SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	SPINAND_INFO("W35N02JW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x22),
 		     NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 2, 1),
@@ -518,7 +524,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
 		     SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	SPINAND_INFO("W35N04JW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x23),
 		     NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 4, 1),
@@ -529,7 +536,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
 		     SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 2G-bit densities */
 	SPINAND_INFO("W25M02GV", /* 2x1G-bit 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
@@ -541,7 +549,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     0,
 		     SPINAND_INFO_VENDOR_OPS(&winbond_w25_ops),
 		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
-		     SPINAND_SELECT_TARGET(w25m02gv_select_target)),
+		     SPINAND_SELECT_TARGET(w25m02gv_select_target),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N02JW", /* high-speed 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
@@ -551,7 +560,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
-		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)),
+		     SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N02KV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -560,7 +570,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N02KW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22),
 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -569,7 +580,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 4G-bit densities */
 	SPINAND_INFO("W25N04KV", /* 3.3V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
@@ -579,7 +591,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(7)),
 	SPINAND_INFO("W25N04KW", /* 1.8V */
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x23),
 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 1, 1, 1),
@@ -588,7 +601,8 @@ static const struct spinand_info winbond_spinand_table[] = {
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 };
 
 static int winbond_spinand_init(struct spinand_device *spinand)

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
  2026-03-03 16:29 ` Frieder Schrempf
@ 2026-03-03 16:29   ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Add tCLQV (Clock Low to Output Valid) parameter from datasheets
for Toshiba/Kioxia SPI NAND chips. This allows to let the drivers
properly handle high sampling delays at high clock speeds.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/mtd/nand/spi/toshiba.c | 48 +++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
index ef649162ee680..7679f3acbae07 100644
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
@@ -118,7 +118,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 2Gb (1st generation) */
 	SPINAND_INFO("TC58CVG1S3HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
@@ -129,7 +130,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 3.3V 4Gb (1st generation) */
 	SPINAND_INFO("TC58CVG2S0HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
@@ -140,7 +142,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 1.8V 1Gb (1st generation) */
 	SPINAND_INFO("TC58CYG0S3HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
@@ -151,7 +154,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 1.8V 2Gb (1st generation) */
 	SPINAND_INFO("TC58CYG1S3HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
@@ -162,7 +166,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 1.8V 4Gb (1st generation) */
 	SPINAND_INFO("TC58CYG2S0HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
@@ -173,7 +178,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 
 	/*
 	 * 2nd generation serial nand has HOLD_D which is equivalent to
@@ -189,7 +195,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 2Gb (2nd generation) */
 	SPINAND_INFO("TC58CVG1S3HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
@@ -200,7 +207,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 4Gb (2nd generation) */
 	SPINAND_INFO("TC58CVG2S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
@@ -211,7 +219,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 8Gb (2nd generation) */
 	SPINAND_INFO("TH58CVG3S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
@@ -222,7 +231,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 1Gb (2nd generation) */
 	SPINAND_INFO("TC58CYG0S3HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
@@ -233,7 +243,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 2Gb (2nd generation) */
 	SPINAND_INFO("TC58CYG1S3HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
@@ -244,7 +255,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 4Gb (2nd generation) */
 	SPINAND_INFO("TC58CYG2S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
@@ -255,7 +267,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 8Gb (2nd generation) */
 	SPINAND_INFO("TH58CYG3S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
@@ -266,7 +279,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 1Gb (1st generation) */
 	SPINAND_INFO("TC58NYG0S3HBAI4",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA1),
@@ -277,7 +291,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
 	/* 1.8V 4Gb (1st generation) */
 	SPINAND_INFO("TH58NYG2S3HBAI4",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
@@ -288,7 +302,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
 	/* 1.8V 8Gb (1st generation) */
 	SPINAND_INFO("TH58NYG3S0HBAI6",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
@@ -299,7 +313,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
 };
 
 static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
@ 2026-03-03 16:29   ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Add tCLQV (Clock Low to Output Valid) parameter from datasheets
for Toshiba/Kioxia SPI NAND chips. This allows to let the drivers
properly handle high sampling delays at high clock speeds.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/mtd/nand/spi/toshiba.c | 48 +++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
index ef649162ee680..7679f3acbae07 100644
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
@@ -118,7 +118,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 2Gb (1st generation) */
 	SPINAND_INFO("TC58CVG1S3HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
@@ -129,7 +130,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 3.3V 4Gb (1st generation) */
 	SPINAND_INFO("TC58CVG2S0HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
@@ -140,7 +142,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 1.8V 1Gb (1st generation) */
 	SPINAND_INFO("TC58CYG0S3HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
@@ -151,7 +154,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 1.8V 2Gb (1st generation) */
 	SPINAND_INFO("TC58CYG1S3HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
@@ -162,7 +166,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 	/* 1.8V 4Gb (1st generation) */
 	SPINAND_INFO("TC58CYG2S0HRAIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
@@ -173,7 +178,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(8)),
 
 	/*
 	 * 2nd generation serial nand has HOLD_D which is equivalent to
@@ -189,7 +195,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 2Gb (2nd generation) */
 	SPINAND_INFO("TC58CVG1S3HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
@@ -200,7 +207,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 4Gb (2nd generation) */
 	SPINAND_INFO("TC58CVG2S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
@@ -211,7 +219,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 3.3V 8Gb (2nd generation) */
 	SPINAND_INFO("TH58CVG3S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
@@ -222,7 +231,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 1Gb (2nd generation) */
 	SPINAND_INFO("TC58CYG0S3HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
@@ -233,7 +243,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 2Gb (2nd generation) */
 	SPINAND_INFO("TC58CYG1S3HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
@@ -244,7 +255,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 4Gb (2nd generation) */
 	SPINAND_INFO("TC58CYG2S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
@@ -255,7 +267,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 8Gb (2nd generation) */
 	SPINAND_INFO("TH58CYG3S0HRAIJ",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
@@ -266,7 +279,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
+		     SPINAND_RX_SAMPLING_DELAY(6)),
 	/* 1.8V 1Gb (1st generation) */
 	SPINAND_INFO("TC58NYG0S3HBAI4",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA1),
@@ -277,7 +291,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_variants),
 		     0,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
 	/* 1.8V 4Gb (1st generation) */
 	SPINAND_INFO("TH58NYG2S3HBAI4",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
@@ -288,7 +302,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
 	/* 1.8V 8Gb (1st generation) */
 	SPINAND_INFO("TH58NYG3S0HBAI6",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
@@ -299,7 +313,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
 					      &update_cache_x4_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
-				     tx58cxgxsxraix_ecc_get_status)),
+				     tx58cxgxsxraix_ecc_get_status),
 };
 
 static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 5/7] spi: Add RX sampling point adjustment
  2026-03-03 16:29 ` Frieder Schrempf
@ 2026-03-03 16:29   ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Some SPI devices such as SPI NAND chips specify a clock-to-RX-sampling
delay constraint, which means that for the data read from the device
at a certain clock rate, we need to make sure that the point at
which the data is sampled is correct.

The default is to assume that the data can be sampled one half clock
cycle after the triggering clock edge. For high clock rates, this
can be too early.

To check this we introduce a new core function spi_set_rx_sampling_point()
and a handler set_rx_sampling_point() in the SPI controller.

Controllers implementing set_rx_sampling_point() can calculate the
sampling point delay using the helper spi_calc_rx_sampling_point()
and store the value to set the appropriate registers during transfer.

In case the controller capabilities are not sufficient to compensate
the RX delay, spi_set_rx_sampling_point() returns a reduced clock
rate value that is safe to use.

This commit does not introduce generic logic for controllers that
don't implement set_rx_sampling_point() in order to reduce the clock
rate if the RX sampling delay requirement can not be met.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/spi/spi.c       | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/spi/spi.h |  8 ++++++
 2 files changed, 81 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 61f7bde8c7fbb..b039007ed430f 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3988,6 +3988,77 @@ static int spi_set_cs_timing(struct spi_device *spi)
 	return status;
 }
 
+/**
+ * spi_calc_rx_sampling_point - calculate RX sampling delay cycles
+ * @spi: the device that requires specific a RX sampling delay
+ * @freq: pointer to the clock frequency setpoint for the calculation. This gets
+ *        altered to a reduced value if required.
+ * @max_delay_cycles: the upper limit of supported delay cycles
+ * @delay_cycles_per_clock_cycle: the ratio between delay cycles and
+ *				  master clock cycles
+ *
+ * This function takes in the rx_sampling_delay_ns value from the SPI device
+ * and the given clock frequency setpoint and calculates the required sampling
+ * delay cycles to meet the device's spec. It uses the given controller
+ * constraints and if those are exceeded, it adjusts the clock frequency
+ * setpoint to a lower value that is safe to be used.
+ *
+ * Return: calculated number of delay cycles
+ */
+unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
+					u16 max_delay_cycles,
+					u16 delay_cycles_per_clock_cycle)
+{
+	unsigned long long temp;
+	u16 delay_cycles;
+
+	/* if sampling delay is zero, we assume the default sampling point can be used */
+	if (!spi->rx_sampling_delay_ns)
+		return 0;
+
+	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
+	do_div(temp, 1000000000UL);
+	delay_cycles = temp;
+
+	if (delay_cycles > max_delay_cycles) {
+		/*
+		 * Reduce the clock to the point where the sampling delay requirement
+		 * can be met.
+		 */
+		delay_cycles = max_delay_cycles;
+		temp = (1000000000UL * delay_cycles);
+		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
+		*freq = temp;
+	}
+
+	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
+
+	return delay_cycles;
+}
+EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point);
+
+/**
+ * spi_set_rx_sampling_point - set the RX sampling delay in the controller driver
+ * @spi: the device that requires specific a RX sampling delay
+ * @freq: the clock frequency setpoint for the RX sampling delay calculation
+ *
+ * This function calls the set_rx_sampling_point() handle in the controller
+ * driver it is available. This makes sure that the controller uses the proper
+ * RX sampling point adjustment. This function should be called whenever
+ * the devices rx_sampling_delay_ns or the currently used clock frequency
+ * changes.
+ *
+ * Return: adjusted clock frequency
+ */
+unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
+{
+	if (spi->controller->set_rx_sampling_point)
+		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
+
+	return freq;
+}
+EXPORT_SYMBOL_GPL(spi_set_rx_sampling_point);
+
 /**
  * spi_setup - setup SPI mode and clock rate
  * @spi: the device whose settings are being modified
@@ -4090,6 +4161,8 @@ int spi_setup(struct spi_device *spi)
 		}
 	}
 
+	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);
+
 	status = spi_set_cs_timing(spi);
 	if (status) {
 		mutex_unlock(&spi->controller->io_mutex);
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 4f8a0c28e1d46..f5be4f54d1424 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -685,6 +685,9 @@ struct spi_controller {
 	 */
 	int (*set_cs_timing)(struct spi_device *spi);
 
+	/* set RX sampling point */
+	unsigned int (*set_rx_sampling_point)(struct spi_device *spi, unsigned int freq);
+
 	/*
 	 * Bidirectional bulk transfers
 	 *
@@ -1337,6 +1340,11 @@ extern int spi_setup(struct spi_device *spi);
 extern int spi_async(struct spi_device *spi, struct spi_message *message);
 extern int spi_target_abort(struct spi_device *spi);
 
+unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
+					       u16 max_delay_cycles,
+					       u16 delay_cycles_per_clock_cycle);
+unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq);
+
 static inline size_t
 spi_max_message_size(struct spi_device *spi)
 {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 5/7] spi: Add RX sampling point adjustment
@ 2026-03-03 16:29   ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Some SPI devices such as SPI NAND chips specify a clock-to-RX-sampling
delay constraint, which means that for the data read from the device
at a certain clock rate, we need to make sure that the point at
which the data is sampled is correct.

The default is to assume that the data can be sampled one half clock
cycle after the triggering clock edge. For high clock rates, this
can be too early.

To check this we introduce a new core function spi_set_rx_sampling_point()
and a handler set_rx_sampling_point() in the SPI controller.

Controllers implementing set_rx_sampling_point() can calculate the
sampling point delay using the helper spi_calc_rx_sampling_point()
and store the value to set the appropriate registers during transfer.

In case the controller capabilities are not sufficient to compensate
the RX delay, spi_set_rx_sampling_point() returns a reduced clock
rate value that is safe to use.

This commit does not introduce generic logic for controllers that
don't implement set_rx_sampling_point() in order to reduce the clock
rate if the RX sampling delay requirement can not be met.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/spi/spi.c       | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/spi/spi.h |  8 ++++++
 2 files changed, 81 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 61f7bde8c7fbb..b039007ed430f 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3988,6 +3988,77 @@ static int spi_set_cs_timing(struct spi_device *spi)
 	return status;
 }
 
+/**
+ * spi_calc_rx_sampling_point - calculate RX sampling delay cycles
+ * @spi: the device that requires specific a RX sampling delay
+ * @freq: pointer to the clock frequency setpoint for the calculation. This gets
+ *        altered to a reduced value if required.
+ * @max_delay_cycles: the upper limit of supported delay cycles
+ * @delay_cycles_per_clock_cycle: the ratio between delay cycles and
+ *				  master clock cycles
+ *
+ * This function takes in the rx_sampling_delay_ns value from the SPI device
+ * and the given clock frequency setpoint and calculates the required sampling
+ * delay cycles to meet the device's spec. It uses the given controller
+ * constraints and if those are exceeded, it adjusts the clock frequency
+ * setpoint to a lower value that is safe to be used.
+ *
+ * Return: calculated number of delay cycles
+ */
+unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
+					u16 max_delay_cycles,
+					u16 delay_cycles_per_clock_cycle)
+{
+	unsigned long long temp;
+	u16 delay_cycles;
+
+	/* if sampling delay is zero, we assume the default sampling point can be used */
+	if (!spi->rx_sampling_delay_ns)
+		return 0;
+
+	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
+	do_div(temp, 1000000000UL);
+	delay_cycles = temp;
+
+	if (delay_cycles > max_delay_cycles) {
+		/*
+		 * Reduce the clock to the point where the sampling delay requirement
+		 * can be met.
+		 */
+		delay_cycles = max_delay_cycles;
+		temp = (1000000000UL * delay_cycles);
+		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
+		*freq = temp;
+	}
+
+	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
+
+	return delay_cycles;
+}
+EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point);
+
+/**
+ * spi_set_rx_sampling_point - set the RX sampling delay in the controller driver
+ * @spi: the device that requires specific a RX sampling delay
+ * @freq: the clock frequency setpoint for the RX sampling delay calculation
+ *
+ * This function calls the set_rx_sampling_point() handle in the controller
+ * driver it is available. This makes sure that the controller uses the proper
+ * RX sampling point adjustment. This function should be called whenever
+ * the devices rx_sampling_delay_ns or the currently used clock frequency
+ * changes.
+ *
+ * Return: adjusted clock frequency
+ */
+unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
+{
+	if (spi->controller->set_rx_sampling_point)
+		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
+
+	return freq;
+}
+EXPORT_SYMBOL_GPL(spi_set_rx_sampling_point);
+
 /**
  * spi_setup - setup SPI mode and clock rate
  * @spi: the device whose settings are being modified
@@ -4090,6 +4161,8 @@ int spi_setup(struct spi_device *spi)
 		}
 	}
 
+	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);
+
 	status = spi_set_cs_timing(spi);
 	if (status) {
 		mutex_unlock(&spi->controller->io_mutex);
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 4f8a0c28e1d46..f5be4f54d1424 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -685,6 +685,9 @@ struct spi_controller {
 	 */
 	int (*set_cs_timing)(struct spi_device *spi);
 
+	/* set RX sampling point */
+	unsigned int (*set_rx_sampling_point)(struct spi_device *spi, unsigned int freq);
+
 	/*
 	 * Bidirectional bulk transfers
 	 *
@@ -1337,6 +1340,11 @@ extern int spi_setup(struct spi_device *spi);
 extern int spi_async(struct spi_device *spi, struct spi_message *message);
 extern int spi_target_abort(struct spi_device *spi);
 
+unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
+					       u16 max_delay_cycles,
+					       u16 delay_cycles_per_clock_cycle);
+unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq);
+
 static inline size_t
 spi_max_message_size(struct spi_device *spi)
 {

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-03 16:29 ` Frieder Schrempf
@ 2026-03-03 16:29   ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Frieder Schrempf <frieder.schrempf@kontron.de>

With clock rates changing on a per-op basis, we need to make sure
that we meet the RX sampling point delay constraint of the underlying
SPI chip.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/spi/spi-mem.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index a09371a075d2e..6b8bee7d6f5e3 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -589,6 +589,8 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
 {
 	if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
 		op->max_freq = mem->spi->max_speed_hz;
+
+	op->max_freq = spi_set_rx_sampling_point(mem->spi, op->max_freq);
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-03 16:29   ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Frieder Schrempf <frieder.schrempf@kontron.de>

With clock rates changing on a per-op basis, we need to make sure
that we meet the RX sampling point delay constraint of the underlying
SPI chip.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/spi/spi-mem.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index a09371a075d2e..6b8bee7d6f5e3 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -589,6 +589,8 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
 {
 	if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
 		op->max_freq = mem->spi->max_speed_hz;
+
+	op->max_freq = spi_set_rx_sampling_point(mem->spi, op->max_freq);
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
 

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 7/7] spi: spi-fsl-qspi: Add support for RX data sampling point adjustment
  2026-03-03 16:29 ` Frieder Schrempf
@ 2026-03-03 16:29   ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

This QSPI controller supports shifting the RX data sampling point to
compensate line or SPI device response delays. This enables fast SPI
data transfers even for devices which have a significant delay in the
RX data stream.

Implement the set_rx_sampling_point() handler to:

1. check if the sampling point needs to be adjusted
2. prepare a value for the SDRSMP bits in the SMPR register and save it
3. reduce the clock rate if sampling point adjustment is not enough

During operation the SDRSMP bits in the SMPR register get updated
with the calculated value.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/spi/spi-fsl-qspi.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
index a223b4bc6e637..7021db144f84b 100644
--- a/drivers/spi/spi-fsl-qspi.c
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -88,6 +88,7 @@
 
 #define QUADSPI_SMPR			0x108
 #define QUADSPI_SMPR_DDRSMP_MASK	GENMASK(18, 16)
+#define QUADSPI_SMPR_SDRSMP(x)		((x) << 5)
 #define QUADSPI_SMPR_FSDLY_MASK		BIT(6)
 #define QUADSPI_SMPR_FSPHS_MASK		BIT(5)
 #define QUADSPI_SMPR_HSENA_MASK		BIT(0)
@@ -290,6 +291,16 @@ struct fsl_qspi {
 	struct device *dev;
 	int selected;
 	u32 memmap_phy;
+	u32 smpr;
+};
+
+#define RX_SAMPLING_MAX_DELAY_CYCLES			3
+#define RX_SAMPLING_DELAY_CYCLES_PER_CLOCK_CYCLE	2
+
+struct fsl_qspi_chip_data {
+	u8 sdrsmp;
+	u32 rx_sampling_delay_ns;
+	unsigned int rate;
 };
 
 static bool needs_swap_endian(struct fsl_qspi *q)
@@ -545,6 +556,27 @@ static void fsl_qspi_invalidate(struct fsl_qspi *q)
 	qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
 }
 
+static void fsl_qspi_update_rx_sampling_delay(struct fsl_qspi *q, u32 sdrsmp)
+{
+	void __iomem *base = q->iobase;
+	u32 mcr, smpr = QUADSPI_SMPR_SDRSMP(sdrsmp);
+
+	/* skip if requested value matches cached value */
+	if (q->smpr == smpr)
+		return;
+
+	/* Disable the module */
+	mcr = qspi_readl(q, base + QUADSPI_MCR);
+	qspi_writel(q, mcr | QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
+
+	qspi_writel(q, smpr, base + QUADSPI_SMPR);
+
+	/* Enable the module */
+	qspi_writel(q, mcr & ~QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
+
+	q->smpr = smpr;
+}
+
 static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi,
 				const struct spi_mem_op *op)
 {
@@ -668,6 +700,7 @@ static int fsl_qspi_readl_poll_tout(struct fsl_qspi *q, void __iomem *base,
 static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 {
 	struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->controller);
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(mem->spi);
 	void __iomem *base = q->iobase;
 	u32 addr_offset = 0;
 	int err = 0;
@@ -679,6 +712,8 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 	fsl_qspi_readl_poll_tout(q, base + QUADSPI_SR, (QUADSPI_SR_IP_ACC_MASK |
 				 QUADSPI_SR_AHB_ACC_MASK), 10, 1000);
 
+	fsl_qspi_update_rx_sampling_delay(q, chip->sdrsmp);
+
 	fsl_qspi_select_mem(q, mem->spi, op);
 
 	if (needs_amba_base_offset(q))
@@ -871,6 +906,28 @@ static const struct spi_controller_mem_caps fsl_qspi_mem_caps = {
 	.per_op_freq = true,
 };
 
+static int fsl_qspi_setup_device(struct spi_device *spi)
+{
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
+
+	if (!chip) {
+		chip = kzalloc_obj(*chip, GFP_KERNEL);
+		if (!chip)
+			return -ENOMEM;
+		spi_set_ctldata(spi, chip);
+	}
+
+	return 0;
+}
+
+static void fsl_qspi_cleanup_device(struct spi_device *spi)
+{
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
+
+	kfree(chip);
+	spi_set_ctldata(spi, NULL);
+}
+
 static void fsl_qspi_disable(void *data)
 {
 	struct fsl_qspi *q = data;
@@ -891,6 +948,25 @@ static void fsl_qspi_cleanup(void *data)
 	mutex_destroy(&q->lock);
 }
 
+static unsigned int fsl_qspi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
+{
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
+
+	/* skip calculation if input clock rate and sampling delay did not change */
+	if (spi->rx_sampling_delay_ns == chip->rx_sampling_delay_ns &&
+	    freq == chip->rate)
+		return freq;
+
+	chip->rate = freq;
+	chip->rx_sampling_delay_ns = spi->rx_sampling_delay_ns;
+
+	chip->sdrsmp = spi_calc_rx_sampling_point(spi, &freq,
+						  RX_SAMPLING_MAX_DELAY_CYCLES,
+						  RX_SAMPLING_DELAY_CYCLES_PER_CLOCK_CYCLE);
+
+	return freq;
+}
+
 static int fsl_qspi_probe(struct platform_device *pdev)
 {
 	struct spi_controller *ctlr;
@@ -915,6 +991,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, q);
 
+	ctlr->setup = fsl_qspi_setup_device;
+	ctlr->cleanup = fsl_qspi_cleanup_device;
+	ctlr->set_rx_sampling_point = fsl_qspi_set_rx_sampling_point;
+
 	/* find the resources */
 	q->iobase = devm_platform_ioremap_resource_byname(pdev, "QuadSPI");
 	if (IS_ERR(q->iobase))

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH RFC 7/7] spi: spi-fsl-qspi: Add support for RX data sampling point adjustment
@ 2026-03-03 16:29   ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-03 16:29 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

From: Eberhard Stoll <eberhard.stoll@kontron.de>

This QSPI controller supports shifting the RX data sampling point to
compensate line or SPI device response delays. This enables fast SPI
data transfers even for devices which have a significant delay in the
RX data stream.

Implement the set_rx_sampling_point() handler to:

1. check if the sampling point needs to be adjusted
2. prepare a value for the SDRSMP bits in the SMPR register and save it
3. reduce the clock rate if sampling point adjustment is not enough

During operation the SDRSMP bits in the SMPR register get updated
with the calculated value.

Signed-off-by: Eberhard Stoll <eberhard.stoll@kontron.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/spi/spi-fsl-qspi.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
index a223b4bc6e637..7021db144f84b 100644
--- a/drivers/spi/spi-fsl-qspi.c
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -88,6 +88,7 @@
 
 #define QUADSPI_SMPR			0x108
 #define QUADSPI_SMPR_DDRSMP_MASK	GENMASK(18, 16)
+#define QUADSPI_SMPR_SDRSMP(x)		((x) << 5)
 #define QUADSPI_SMPR_FSDLY_MASK		BIT(6)
 #define QUADSPI_SMPR_FSPHS_MASK		BIT(5)
 #define QUADSPI_SMPR_HSENA_MASK		BIT(0)
@@ -290,6 +291,16 @@ struct fsl_qspi {
 	struct device *dev;
 	int selected;
 	u32 memmap_phy;
+	u32 smpr;
+};
+
+#define RX_SAMPLING_MAX_DELAY_CYCLES			3
+#define RX_SAMPLING_DELAY_CYCLES_PER_CLOCK_CYCLE	2
+
+struct fsl_qspi_chip_data {
+	u8 sdrsmp;
+	u32 rx_sampling_delay_ns;
+	unsigned int rate;
 };
 
 static bool needs_swap_endian(struct fsl_qspi *q)
@@ -545,6 +556,27 @@ static void fsl_qspi_invalidate(struct fsl_qspi *q)
 	qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
 }
 
+static void fsl_qspi_update_rx_sampling_delay(struct fsl_qspi *q, u32 sdrsmp)
+{
+	void __iomem *base = q->iobase;
+	u32 mcr, smpr = QUADSPI_SMPR_SDRSMP(sdrsmp);
+
+	/* skip if requested value matches cached value */
+	if (q->smpr == smpr)
+		return;
+
+	/* Disable the module */
+	mcr = qspi_readl(q, base + QUADSPI_MCR);
+	qspi_writel(q, mcr | QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
+
+	qspi_writel(q, smpr, base + QUADSPI_SMPR);
+
+	/* Enable the module */
+	qspi_writel(q, mcr & ~QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
+
+	q->smpr = smpr;
+}
+
 static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi,
 				const struct spi_mem_op *op)
 {
@@ -668,6 +700,7 @@ static int fsl_qspi_readl_poll_tout(struct fsl_qspi *q, void __iomem *base,
 static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 {
 	struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->controller);
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(mem->spi);
 	void __iomem *base = q->iobase;
 	u32 addr_offset = 0;
 	int err = 0;
@@ -679,6 +712,8 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 	fsl_qspi_readl_poll_tout(q, base + QUADSPI_SR, (QUADSPI_SR_IP_ACC_MASK |
 				 QUADSPI_SR_AHB_ACC_MASK), 10, 1000);
 
+	fsl_qspi_update_rx_sampling_delay(q, chip->sdrsmp);
+
 	fsl_qspi_select_mem(q, mem->spi, op);
 
 	if (needs_amba_base_offset(q))
@@ -871,6 +906,28 @@ static const struct spi_controller_mem_caps fsl_qspi_mem_caps = {
 	.per_op_freq = true,
 };
 
+static int fsl_qspi_setup_device(struct spi_device *spi)
+{
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
+
+	if (!chip) {
+		chip = kzalloc_obj(*chip, GFP_KERNEL);
+		if (!chip)
+			return -ENOMEM;
+		spi_set_ctldata(spi, chip);
+	}
+
+	return 0;
+}
+
+static void fsl_qspi_cleanup_device(struct spi_device *spi)
+{
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
+
+	kfree(chip);
+	spi_set_ctldata(spi, NULL);
+}
+
 static void fsl_qspi_disable(void *data)
 {
 	struct fsl_qspi *q = data;
@@ -891,6 +948,25 @@ static void fsl_qspi_cleanup(void *data)
 	mutex_destroy(&q->lock);
 }
 
+static unsigned int fsl_qspi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
+{
+	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
+
+	/* skip calculation if input clock rate and sampling delay did not change */
+	if (spi->rx_sampling_delay_ns == chip->rx_sampling_delay_ns &&
+	    freq == chip->rate)
+		return freq;
+
+	chip->rate = freq;
+	chip->rx_sampling_delay_ns = spi->rx_sampling_delay_ns;
+
+	chip->sdrsmp = spi_calc_rx_sampling_point(spi, &freq,
+						  RX_SAMPLING_MAX_DELAY_CYCLES,
+						  RX_SAMPLING_DELAY_CYCLES_PER_CLOCK_CYCLE);
+
+	return freq;
+}
+
 static int fsl_qspi_probe(struct platform_device *pdev)
 {
 	struct spi_controller *ctlr;
@@ -915,6 +991,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, q);
 
+	ctlr->setup = fsl_qspi_setup_device;
+	ctlr->cleanup = fsl_qspi_cleanup_device;
+	ctlr->set_rx_sampling_point = fsl_qspi_set_rx_sampling_point;
+
 	/* find the resources */
 	q->iobase = devm_platform_ioremap_resource_byname(pdev, "QuadSPI");
 	if (IS_ERR(q->iobase))

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-03 21:01     ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

Subject: Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point()
 for each op

> +	op->max_freq = spi_set_rx_sampling_point(mem->spi, op->max_freq);

Does spi_set_rx_sampling_point() return an error code? If so, you need to
check for it. If it can fail, silently ignoring the return value may cause
timing violations. Suggest adding error handling or documenting why failure
is acceptable here.

Also, the blank line before this statement is unnecessary. Remove it to keep
the function compact.

---

AI bot review and may be useless.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-03 21:01     ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

Subject: Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point()
 for each op

> +	op->max_freq = spi_set_rx_sampling_point(mem->spi, op->max_freq);

Does spi_set_rx_sampling_point() return an error code? If so, you need to
check for it. If it can fail, silently ignoring the return value may cause
timing violations. Suggest adding error handling or documenting why failure
is acceptable here.

Also, the blank line before this statement is unnecessary. Remove it to keep
the function compact.

---

AI bot review and may be useless.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 7/7] spi: spi-fsl-qspi: Add support for RX data sampling point adjustment
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-03 21:01     ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

> +#define QUADSPI_SMPR_SDRSMP(x)		((x) << 5)

Macro argument 'x' should be parenthesized: ((x) << 5) is fine, but
consider ((x) << 5) for consistency with kernel style.

> +struct fsl_qspi_chip_data {
> +	u8 sdrsmp;
> +	u32 rx_sampling_delay_ns;
> +	unsigned int rate;
> +};

Consider documenting struct members with kernel-doc comments explaining
the purpose of each field.

> +static void fsl_qspi_update_rx_sampling_delay(struct fsl_qspi *q, u32 sdrsmp)
> +{
> +	void __iomem *base = q->iobase;
> +	u32 mcr, smpr = QUADSPI_SMPR_SDRSMP(sdrsmp);
> +
> +	/* skip if requested value matches cached value */
> +	if (q->smpr == smpr)
> +		return;
> +
> +	/* Disable the module */
> +	mcr = qspi_readl(q, base + QUADSPI_MCR);
> +	qspi_writel(q, mcr | QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
> +
> +	qspi_writel(q, smpr, base + QUADSPI_SMPR);
> +
> +	/* Enable the module */
> +	qspi_writel(q, mcr & ~QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
> +
> +	q->smpr = smpr;
> +}

Missing synchronization: if fsl_qspi_exec_op() calls this concurrently
from multiple threads, q->smpr cache may become inconsistent. Consider
protecting with q->lock (already used elsewhere in driver).

> +	struct fsl_qspi_chip_data *chip = spi_get_ctldata(mem->spi);
> +	void __iomem *base = q->iobase;
> +	u32 addr_offset = 0;
> +	int err = 0;
> @@ -679,6 +712,8 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
> 	fsl_qspi_readl_poll_tout(q, base + QUADSPI_SR, (QUADSPI_SR_IP_ACC_MASK |
> 				 QUADSPI_SR_AHB_ACC_MASK), 10, 1000);
> 
> +	fsl_qspi_update_rx_sampling_delay(q, chip->sdrsmp);

Potential NULL dereference: if fsl_qspi_setup_device() was never called
or failed silently, 'chip' is NULL. Add NULL check or ensure setup is
always called before exec_op.

> +static int fsl_qspi_setup_device(struct spi_device *spi)
> +{
> +	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
> +
> +	if (!chip) {
> +		chip = kzalloc_obj(*chip, GFP_KERNEL);

kzalloc_obj() is non-standard. Use kzalloc(sizeof(*chip), GFP_KERNEL)
or verify kzalloc_obj() is defined in kernel headers.

> +		if (!chip)
> +			return -ENOMEM;
> +		spi_set_ctldata(spi, chip);
> +	}
> +
> +	return 0;
> +}

setup_device() allows re-entry without freeing old chip. If called

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 7/7] spi: spi-fsl-qspi: Add support for RX data sampling point adjustment
@ 2026-03-03 21:01     ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

> +#define QUADSPI_SMPR_SDRSMP(x)		((x) << 5)

Macro argument 'x' should be parenthesized: ((x) << 5) is fine, but
consider ((x) << 5) for consistency with kernel style.

> +struct fsl_qspi_chip_data {
> +	u8 sdrsmp;
> +	u32 rx_sampling_delay_ns;
> +	unsigned int rate;
> +};

Consider documenting struct members with kernel-doc comments explaining
the purpose of each field.

> +static void fsl_qspi_update_rx_sampling_delay(struct fsl_qspi *q, u32 sdrsmp)
> +{
> +	void __iomem *base = q->iobase;
> +	u32 mcr, smpr = QUADSPI_SMPR_SDRSMP(sdrsmp);
> +
> +	/* skip if requested value matches cached value */
> +	if (q->smpr == smpr)
> +		return;
> +
> +	/* Disable the module */
> +	mcr = qspi_readl(q, base + QUADSPI_MCR);
> +	qspi_writel(q, mcr | QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
> +
> +	qspi_writel(q, smpr, base + QUADSPI_SMPR);
> +
> +	/* Enable the module */
> +	qspi_writel(q, mcr & ~QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR);
> +
> +	q->smpr = smpr;
> +}

Missing synchronization: if fsl_qspi_exec_op() calls this concurrently
from multiple threads, q->smpr cache may become inconsistent. Consider
protecting with q->lock (already used elsewhere in driver).

> +	struct fsl_qspi_chip_data *chip = spi_get_ctldata(mem->spi);
> +	void __iomem *base = q->iobase;
> +	u32 addr_offset = 0;
> +	int err = 0;
> @@ -679,6 +712,8 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
> 	fsl_qspi_readl_poll_tout(q, base + QUADSPI_SR, (QUADSPI_SR_IP_ACC_MASK |
> 				 QUADSPI_SR_AHB_ACC_MASK), 10, 1000);
> 
> +	fsl_qspi_update_rx_sampling_delay(q, chip->sdrsmp);

Potential NULL dereference: if fsl_qspi_setup_device() was never called
or failed silently, 'chip' is NULL. Add NULL check or ensure setup is
always called before exec_op.

> +static int fsl_qspi_setup_device(struct spi_device *spi)
> +{
> +	struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi);
> +
> +	if (!chip) {
> +		chip = kzalloc_obj(*chip, GFP_KERNEL);

kzalloc_obj() is non-standard. Use kzalloc(sizeof(*chip), GFP_KERNEL)
or verify kzalloc_obj() is defined in kernel headers.

> +		if (!chip)
> +			return -ENOMEM;
> +		spi_set_ctldata(spi, chip);
> +	}
> +
> +	return 0;
> +}

setup_device() allows re-entry without freeing old chip. If called

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-03 21:01     ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

> +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
> +					u16 max_delay_cycles,
> +					u16 delay_cycles_per_clock_cycle)
> +{
> +	unsigned long long temp;
> +	u16 delay_cycles;
> +
> +	/* if sampling delay is zero, we assume the default sampling point can be used */
> +	if (!spi->rx_sampling_delay_ns)
> +		return 0;
> +
> +	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
> +	do_div(temp, 1000000000UL);
> +	delay_cycles = temp;

Potential overflow: multiplying three u32/u16 values before assigning to
u64. Cast operands to u64 before multiplication to avoid intermediate
overflow.

> +	if (delay_cycles > max_delay_cycles) {
> +		/*
> +		 * Reduce the clock to the point where the sampling delay requirement
> +		 * can be met.
> +		 */
> +		delay_cycles = max_delay_cycles;
> +		temp = (1000000000UL * delay_cycles);
> +		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
> +		*freq = temp;

Same overflow risk in denominator multiplication. Cast to u64 first.

> +	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);

Line exceeds 80 chars. Break into two lines.

> +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
> +{
> +	if (spi->controller->set_rx_sampling_point)
> +		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
> +
> +	return freq;
> +}

Bug: function receives 'freq' parameter but ignores it and passes
'spi->max_speed_hz' to the handler instead. Should pass 'freq' or remove
the parameter.

> +	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);

This call happens after spi_set_cs_timing() check but before the mutex is
unlocked. Verify this is the intended placement and that no locking issues
exist with controller callbacks.

AI bot review and may be useless.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
@ 2026-03-03 21:01     ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

> +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
> +					u16 max_delay_cycles,
> +					u16 delay_cycles_per_clock_cycle)
> +{
> +	unsigned long long temp;
> +	u16 delay_cycles;
> +
> +	/* if sampling delay is zero, we assume the default sampling point can be used */
> +	if (!spi->rx_sampling_delay_ns)
> +		return 0;
> +
> +	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
> +	do_div(temp, 1000000000UL);
> +	delay_cycles = temp;

Potential overflow: multiplying three u32/u16 values before assigning to
u64. Cast operands to u64 before multiplication to avoid intermediate
overflow.

> +	if (delay_cycles > max_delay_cycles) {
> +		/*
> +		 * Reduce the clock to the point where the sampling delay requirement
> +		 * can be met.
> +		 */
> +		delay_cycles = max_delay_cycles;
> +		temp = (1000000000UL * delay_cycles);
> +		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
> +		*freq = temp;

Same overflow risk in denominator multiplication. Cast to u64 first.

> +	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);

Line exceeds 80 chars. Break into two lines.

> +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
> +{
> +	if (spi->controller->set_rx_sampling_point)
> +		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
> +
> +	return freq;
> +}

Bug: function receives 'freq' parameter but ignores it and passes
'spi->max_speed_hz' to the handler instead. Should pass 'freq' or remove
the parameter.

> +	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);

This call happens after spi_set_cs_timing() check but before the mutex is
unlocked. Verify this is the intended placement and that no locking issues
exist with controller callbacks.

AI bot review and may be useless.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-03 21:01     ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

> + * @rx_sampling_delay_ns: spi clk to spi rx data delay

Comment is too terse. Expand to clarify the unit and purpose:
"clock-to-RX-data delay in nanoseconds; see tCLQV in device datasheets"

> +	/* Transfer characteristics */
> +	u32			rx_sampling_delay_ns; /* clk to rx data delay */

The inline comment duplicates the field name. Remove it or expand the
block comment above to explain when/how drivers should use this field.
Also: is u32 the right type? Consider if negative values or larger
ranges are possible, or if this should be `struct spi_delay` for
consistency with cs_setup, cs_hold, cs_inactive above.

> +	struct spi_delay	cs_inactive;
> +	/* Transfer characteristics */

The comment "Transfer characteristics" is vague. Either name it more
specifically (e.g., "RX sampling configuration") or fold it into the
existing block comment at the top of the struct.

---

AI bot review and may be useless.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
@ 2026-03-03 21:01     ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

> + * @rx_sampling_delay_ns: spi clk to spi rx data delay

Comment is too terse. Expand to clarify the unit and purpose:
"clock-to-RX-data delay in nanoseconds; see tCLQV in device datasheets"

> +	/* Transfer characteristics */
> +	u32			rx_sampling_delay_ns; /* clk to rx data delay */

The inline comment duplicates the field name. Remove it or expand the
block comment above to explain when/how drivers should use this field.
Also: is u32 the right type? Consider if negative values or larger
ranges are possible, or if this should be `struct spi_delay` for
consistency with cs_setup, cs_hold, cs_inactive above.

> +	struct spi_delay	cs_inactive;
> +	/* Transfer characteristics */

The comment "Transfer characteristics" is vague. Either name it more
specifically (e.g., "RX sampling configuration") or fold it into the
existing block comment at the top of the struct.

---

AI bot review and may be useless.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-03 21:01     ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

> +		spinand->spimem->spi->rx_sampling_delay_ns = table[i].rx_sampling_delay_ns;

Line exceeds 80 columns (currently ~85). Break into two lines or shorten
variable names.

Also, this assignment happens unconditionally for every matched device.
Should there be a null check on spinand->spimem or spinand->spimem->spi
before dereferencing? Or is this guaranteed to be initialized at this
point in the probe flow?

> + * @rx_sampling_delay_ns: clock to rx data delay timing (tCLQV)

Good. Clarifies the datasheet reference.

> +	u32 rx_sampling_delay_ns;

Consider whether this field should be initialized to 0 or a sensible
default in the macro. Currently, devices that don't use the
SPINAND_RX_SAMPLING_DELAY() macro will have an uninitialized value
(likely 0 from kzalloc, but worth documenting).

> +#define SPINAND_RX_SAMPLING_DELAY(__delay)				\
> +	.rx_sampling_delay_ns = __delay

Macro looks fine. Consistent with existing SPINAND_* patterns.

---

AI bot review and may be useless.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting
@ 2026-03-03 21:01     ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

> +		spinand->spimem->spi->rx_sampling_delay_ns = table[i].rx_sampling_delay_ns;

Line exceeds 80 columns (currently ~85). Break into two lines or shorten
variable names.

Also, this assignment happens unconditionally for every matched device.
Should there be a null check on spinand->spimem or spinand->spimem->spi
before dereferencing? Or is this guaranteed to be initialized at this
point in the probe flow?

> + * @rx_sampling_delay_ns: clock to rx data delay timing (tCLQV)

Good. Clarifies the datasheet reference.

> +	u32 rx_sampling_delay_ns;

Consider whether this field should be initialized to 0 or a sensible
default in the macro. Currently, devices that don't use the
SPINAND_RX_SAMPLING_DELAY() macro will have an uninitialized value
(likely 0 from kzalloc, but worth documenting).

> +#define SPINAND_RX_SAMPLING_DELAY(__delay)				\
> +	.rx_sampling_delay_ns = __delay

Macro looks fine. Consistent with existing SPINAND_* patterns.

---

AI bot review and may be useless.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-03 21:01     ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
> +		     SPINAND_RX_SAMPLING_DELAY(6)),

Inconsistent indentation: use tabs to align with opening paren on
previous line. Should be two tabs + spaces to match column position.

> +		     SPINAND_RX_SAMPLING_DELAY(8)),

Same indentation issue across all added SPINAND_RX_SAMPLING_DELAY()
lines. Verify alignment matches the struct initializer style used
elsewhere in the file.

> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
> +		     SPINAND_RX_SAMPLING_DELAY(6)),

Line 195: trailing comma after SPINAND_RX_SAMPLING_DELAY(6) is correct
for struct init, but confirm this macro expands to a valid struct
member or initializer list entry.

No resource leaks or locking issues detected in error paths. Patch is
primarily data-driven table updates with no dynamic allocation or
synchronization primitives.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
@ 2026-03-03 21:01     ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
> +		     SPINAND_RX_SAMPLING_DELAY(6)),

Inconsistent indentation: use tabs to align with opening paren on
previous line. Should be two tabs + spaces to match column position.

> +		     SPINAND_RX_SAMPLING_DELAY(8)),

Same indentation issue across all added SPINAND_RX_SAMPLING_DELAY()
lines. Verify alignment matches the struct initializer style used
elsewhere in the file.

> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
> +		     SPINAND_RX_SAMPLING_DELAY(6)),

Line 195: trailing comma after SPINAND_RX_SAMPLING_DELAY(6) is correct
for struct init, but confirm this macro expands to a valid struct
member or initializer list entry.

No resource leaks or locking issues detected in error paths. Patch is
primarily data-driven table updates with no dynamic allocation or
synchronization primitives.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 3/7] mtd: spinand: winbond: Add RX sampling delay values
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-03 21:01     ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

The patch looks straightforward—adding RX sampling delay parameters to
Winbond SPI NAND device entries. A few observations:

> -		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
> +		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
> +		     SPINAND_RX_SAMPLING_DELAY(6)),

Trailing comma removal on the SPINAND_ECCINFO line is correct for the
macro continuation. Consistent across all hunks.

> +		     SPINAND_RX_SAMPLING_DELAY(6)),

The delay values (6, 7, 8) appear to come from datasheets per the commit
message. No obvious logic errors, but consider adding a brief inline
comment explaining the tCLQV mapping if the values are not self-evident
to future maintainers. For example:

  /* tCLQV from datasheet */
  SPINAND_RX_SAMPLING_DELAY(6)),

This is minor—the commit message already documents the intent. The patch
is mechanically sound: consistent formatting, no resource leaks, no
locking issues. All entries follow the same pattern.

One style note: ensure the macro SPINAND_RX_SAMPLING_DELAY is defined
elsewhere in the patchset (likely in an earlier patch in the series).
If not already reviewed, verify its signature matches the usage here.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 3/7] mtd: spinand: winbond: Add RX sampling delay values
@ 2026-03-03 21:01     ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-03 21:01 UTC (permalink / raw)
  To: Mark Brown, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Han Xu
  Cc: Frank Li, Eberhard Stoll, Frieder Schrempf, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

From: Frank Li (AI-BOT) <frank.li@nxp.com>

AI bot review and may be useless.

The patch looks straightforward—adding RX sampling delay parameters to
Winbond SPI NAND device entries. A few observations:

> -		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
> +		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
> +		     SPINAND_RX_SAMPLING_DELAY(6)),

Trailing comma removal on the SPINAND_ECCINFO line is correct for the
macro continuation. Consistent across all hunks.

> +		     SPINAND_RX_SAMPLING_DELAY(6)),

The delay values (6, 7, 8) appear to come from datasheets per the commit
message. No obvious logic errors, but consider adding a brief inline
comment explaining the tCLQV mapping if the values are not self-evident
to future maintainers. For example:

  /* tCLQV from datasheet */
  SPINAND_RX_SAMPLING_DELAY(6)),

This is minor—the commit message already documents the intent. The patch
is mechanically sound: consistent formatting, no resource leaks, no
locking issues. All entries follow the same pattern.

One style note: ensure the macro SPINAND_RX_SAMPLING_DELAY is defined
elsewhere in the patchset (likely in an earlier patch in the series).
If not already reviewed, verify its signature matches the usage here.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
  2026-03-03 21:01     ` Frank Li
@ 2026-03-05 22:14       ` Mark Brown
  -1 siblings, 0 replies; 65+ messages in thread
From: Mark Brown @ 2026-03-05 22:14 UTC (permalink / raw)
  To: Frank Li
  Cc: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

[-- Attachment #1: Type: text/plain, Size: 1090 bytes --]

On Tue, Mar 03, 2026 at 04:01:14PM -0500, Frank Li wrote:
> From: Frank Li (AI-BOT) <frank.li@nxp.com>

Please add a human step before sending these reviews.

> > + * @rx_sampling_delay_ns: spi clk to spi rx data delay

> Comment is too terse. Expand to clarify the unit and purpose:
> "clock-to-RX-data delay in nanoseconds; see tCLQV in device datasheets"

I'm not sure restating the unit in the comment as well as the name is
super useful...

> > +	/* Transfer characteristics */
> > +	u32			rx_sampling_delay_ns; /* clk to rx data delay */

> The inline comment duplicates the field name. Remove it or expand the
> block comment above to explain when/how drivers should use this field.
> Also: is u32 the right type? Consider if negative values or larger
> ranges are possible, or if this should be `struct spi_delay` for
> consistency with cs_setup, cs_hold, cs_inactive above.

...especially given the contradictory feedback here, and the comment
about a negative delay is obviously not appropriate.  I'm not convinced
anyone needs an explanation of what to do with the field either.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
@ 2026-03-05 22:14       ` Mark Brown
  0 siblings, 0 replies; 65+ messages in thread
From: Mark Brown @ 2026-03-05 22:14 UTC (permalink / raw)
  To: Frank Li
  Cc: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx


[-- Attachment #1.1: Type: text/plain, Size: 1090 bytes --]

On Tue, Mar 03, 2026 at 04:01:14PM -0500, Frank Li wrote:
> From: Frank Li (AI-BOT) <frank.li@nxp.com>

Please add a human step before sending these reviews.

> > + * @rx_sampling_delay_ns: spi clk to spi rx data delay

> Comment is too terse. Expand to clarify the unit and purpose:
> "clock-to-RX-data delay in nanoseconds; see tCLQV in device datasheets"

I'm not sure restating the unit in the comment as well as the name is
super useful...

> > +	/* Transfer characteristics */
> > +	u32			rx_sampling_delay_ns; /* clk to rx data delay */

> The inline comment duplicates the field name. Remove it or expand the
> block comment above to explain when/how drivers should use this field.
> Also: is u32 the right type? Consider if negative values or larger
> ranges are possible, or if this should be `struct spi_delay` for
> consistency with cs_setup, cs_hold, cs_inactive above.

...especially given the contradictory feedback here, and the comment
about a negative delay is obviously not appropriate.  I'm not convinced
anyone needs an explanation of what to do with the field either.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 144 bytes --]

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [EXT] Re: [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
  2026-03-05 22:14       ` Mark Brown
@ 2026-03-05 22:34         ` Frank Li
  -1 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-05 22:34 UTC (permalink / raw)
  To: Mark Brown
  Cc: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org,
	imx@lists.linux.dev

> 
> On Tue, Mar 03, 2026 at 04:01:14PM -0500, Frank Li wrote:
> > From: Frank Li (AI-BOT) <frank.li@nxp.com>
> 
> Please add a human step before sending these reviews.
> 
> > > + * @rx_sampling_delay_ns: spi clk to spi rx data delay
> 
> > Comment is too terse. Expand to clarify the unit and purpose:
> > "clock-to-RX-data delay in nanoseconds; see tCLQV in device datasheets"
> 
> I'm not sure restating the unit in the comment as well as the name is
> super useful...
> 
> > > +	/* Transfer characteristics */
> > > +	u32			rx_sampling_delay_ns; /* clk to rx data delay
> */
> 
> > The inline comment duplicates the field name. Remove it or expand the
> > block comment above to explain when/how drivers should use this field.
> > Also: is u32 the right type? Consider if negative values or larger
> > ranges are possible, or if this should be `struct spi_delay` for
> > consistency with cs_setup, cs_hold, cs_inactive above.
> 
> ...especially given the contradictory feedback here, and the comment
> about a negative delay is obviously not appropriate.  I'm not convinced
> anyone needs an explanation of what to do with the field either.

Sorry, I have not careful review AI bot generated result before sent
Out. Please discard it

Frank

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [EXT] Re: [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay
@ 2026-03-05 22:34         ` Frank Li
  0 siblings, 0 replies; 65+ messages in thread
From: Frank Li @ 2026-03-05 22:34 UTC (permalink / raw)
  To: Mark Brown
  Cc: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org,
	imx@lists.linux.dev

> 
> On Tue, Mar 03, 2026 at 04:01:14PM -0500, Frank Li wrote:
> > From: Frank Li (AI-BOT) <frank.li@nxp.com>
> 
> Please add a human step before sending these reviews.
> 
> > > + * @rx_sampling_delay_ns: spi clk to spi rx data delay
> 
> > Comment is too terse. Expand to clarify the unit and purpose:
> > "clock-to-RX-data delay in nanoseconds; see tCLQV in device datasheets"
> 
> I'm not sure restating the unit in the comment as well as the name is
> super useful...
> 
> > > +	/* Transfer characteristics */
> > > +	u32			rx_sampling_delay_ns; /* clk to rx data delay
> */
> 
> > The inline comment duplicates the field name. Remove it or expand the
> > block comment above to explain when/how drivers should use this field.
> > Also: is u32 the right type? Consider if negative values or larger
> > ranges are possible, or if this should be `struct spi_delay` for
> > consistency with cs_setup, cs_hold, cs_inactive above.
> 
> ...especially given the contradictory feedback here, and the comment
> about a negative delay is obviously not appropriate.  I'm not convinced
> anyone needs an explanation of what to do with the field either.

Sorry, I have not careful review AI bot generated result before sent
Out. Please discard it

Frank

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
  2026-03-03 16:29   ` Frieder Schrempf
  (?)
  (?)
@ 2026-03-06  9:05   ` kernel test robot
  -1 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2026-03-06  9:05 UTC (permalink / raw)
  To: Frieder Schrempf; +Cc: oe-kbuild-all

Hi Frieder,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build warnings:

[auto build test WARNING on 11439c4635edd669ae435eec308f4ab8a0804808]

url:    https://github.com/intel-lab-lkp/linux/commits/Frieder-Schrempf/spi-Add-rx_sampling_delay_ns-parameter-for-clock-to-RX-delay/20260304-004536
base:   11439c4635edd669ae435eec308f4ab8a0804808
patch link:    https://lore.kernel.org/r/20260303-fsl-qspi-rx-sampling-delay-v1-5-9326bbc492d6%40kontron.de
patch subject: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
config: sparc-randconfig-001-20260306 (https://download.01.org/0day-ci/archive/20260306/202603061603.IJQi8bQr-lkp@intel.com/config)
compiler: sparc-linux-gcc (GCC) 12.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260306/202603061603.IJQi8bQr-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603061603.IJQi8bQr-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:620,
                    from include/asm-generic/bug.h:31,
                    from arch/sparc/include/asm/bug.h:25,
                    from include/linux/bug.h:5,
                    from include/linux/slab.h:15,
                    from include/linux/resource_ext.h:11,
                    from include/linux/acpi.h:14,
                    from drivers/spi/spi.c:7:
   drivers/spi/spi.c: In function 'spi_calc_rx_sampling_point':
>> drivers/spi/spi.c:4034:40: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type 'unsigned int' [-Wformat=]
    4034 |         dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
         |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:231:29: note: in definition of macro '__dynamic_func_call_cls'
     231 |                 func(&id, ##__VA_ARGS__);                       \
         |                             ^~~~~~~~~~~
   include/linux/dynamic_debug.h:261:9: note: in expansion of macro '_dynamic_func_call_cls'
     261 |         _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:284:9: note: in expansion of macro '_dynamic_func_call'
     284 |         _dynamic_func_call(fmt, __dynamic_dev_dbg,              \
         |         ^~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:165:9: note: in expansion of macro 'dynamic_dev_dbg'
     165 |         dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~
   include/linux/dev_printk.h:165:30: note: in expansion of macro 'dev_fmt'
     165 |         dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                              ^~~~~~~
   drivers/spi/spi.c:4034:9: note: in expansion of macro 'dev_dbg'
    4034 |         dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
         |         ^~~~~~~
   drivers/spi/spi.c:4034:94: note: format string is defined here
    4034 |         dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
         |                                                                                            ~~^
         |                                                                                              |
         |                                                                                              long unsigned int
         |                                                                                            %u


vim +4034 drivers/spi/spi.c

  3990	
  3991	/**
  3992	 * spi_calc_rx_sampling_point - calculate RX sampling delay cycles
  3993	 * @spi: the device that requires specific a RX sampling delay
  3994	 * @freq: pointer to the clock frequency setpoint for the calculation. This gets
  3995	 *        altered to a reduced value if required.
  3996	 * @max_delay_cycles: the upper limit of supported delay cycles
  3997	 * @delay_cycles_per_clock_cycle: the ratio between delay cycles and
  3998	 *				  master clock cycles
  3999	 *
  4000	 * This function takes in the rx_sampling_delay_ns value from the SPI device
  4001	 * and the given clock frequency setpoint and calculates the required sampling
  4002	 * delay cycles to meet the device's spec. It uses the given controller
  4003	 * constraints and if those are exceeded, it adjusts the clock frequency
  4004	 * setpoint to a lower value that is safe to be used.
  4005	 *
  4006	 * Return: calculated number of delay cycles
  4007	 */
  4008	unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
  4009						u16 max_delay_cycles,
  4010						u16 delay_cycles_per_clock_cycle)
  4011	{
  4012		unsigned long long temp;
  4013		u16 delay_cycles;
  4014	
  4015		/* if sampling delay is zero, we assume the default sampling point can be used */
  4016		if (!spi->rx_sampling_delay_ns)
  4017			return 0;
  4018	
  4019		temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
  4020		do_div(temp, 1000000000UL);
  4021		delay_cycles = temp;
  4022	
  4023		if (delay_cycles > max_delay_cycles) {
  4024			/*
  4025			 * Reduce the clock to the point where the sampling delay requirement
  4026			 * can be met.
  4027			 */
  4028			delay_cycles = max_delay_cycles;
  4029			temp = (1000000000UL * delay_cycles);
  4030			do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
  4031			*freq = temp;
  4032		}
  4033	
> 4034		dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
  4035	
  4036		return delay_cycles;
  4037	}
  4038	EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point);
  4039	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
  2026-03-03 16:29   ` Frieder Schrempf
  (?)
  (?)
@ 2026-03-06  9:37   ` kernel test robot
  -1 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2026-03-06  9:37 UTC (permalink / raw)
  To: Frieder Schrempf; +Cc: oe-kbuild-all

Hi Frieder,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on 11439c4635edd669ae435eec308f4ab8a0804808]

url:    https://github.com/intel-lab-lkp/linux/commits/Frieder-Schrempf/spi-Add-rx_sampling_delay_ns-parameter-for-clock-to-RX-delay/20260304-004536
base:   11439c4635edd669ae435eec308f4ab8a0804808
patch link:    https://lore.kernel.org/r/20260303-fsl-qspi-rx-sampling-delay-v1-4-9326bbc492d6%40kontron.de
patch subject: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
config: sparc64-randconfig-001-20260306 (https://download.01.org/0day-ci/archive/20260306/202603061757.Ig1cxEXk-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 14.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260306/202603061757.Ig1cxEXk-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603061757.Ig1cxEXk-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

>> drivers/mtd/nand/spi/toshiba.c:328:3: error: unterminated argument list invoking macro "SPINAND_INFO"
     328 | };
         |   ^
>> drivers/mtd/nand/spi/toshiba.c:285:9: error: 'SPINAND_INFO' undeclared here (not in a function)
     285 |         SPINAND_INFO("TC58NYG0S3HBAI4",
         |         ^~~~~~~~~~~~
>> drivers/mtd/nand/spi/toshiba.c:329: error: expected '}' at end of input
   drivers/mtd/nand/spi/toshiba.c:110:60: note: to match this '{'
     110 | static const struct spinand_info toshiba_spinand_table[] = {
         |                                                            ^
>> drivers/mtd/nand/spi/toshiba.c:110:34: warning: 'toshiba_spinand_table' defined but not used [-Wunused-const-variable=]
     110 | static const struct spinand_info toshiba_spinand_table[] = {
         |                                  ^~~~~~~~~~~~~~~~~~~~~


vim +/SPINAND_INFO +328 drivers/mtd/nand/spi/toshiba.c

10949af1681d5bb Schrempf Frieder 2018-11-08  109  
10949af1681d5bb Schrempf Frieder 2018-11-08  110  static const struct spinand_info toshiba_spinand_table[] = {
798fcdd010006e8 Yoshio Furuyama  2020-03-24  111  	/* 3.3V 1Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  112  	SPINAND_INFO("TC58CVG0S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  113  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
377e517b5fa5359 Boris Brezillon  2018-11-04  114  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  115  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  116  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  117  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  118  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  119  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  120  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  121  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  122  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  123  	/* 3.3V 2Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  124  	SPINAND_INFO("TC58CVG1S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  125  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
377e517b5fa5359 Boris Brezillon  2018-11-04  126  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  127  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  128  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  129  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  130  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  131  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  132  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  133  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  134  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  135  	/* 3.3V 4Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  136  	SPINAND_INFO("TC58CVG2S0HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  137  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
377e517b5fa5359 Boris Brezillon  2018-11-04  138  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
9ee0f956cfbb87b Robert Marko     2020-01-03  139  		     NAND_ECCREQ(8, 512),
9ee0f956cfbb87b Robert Marko     2020-01-03  140  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
9ee0f956cfbb87b Robert Marko     2020-01-03  141  					      &write_cache_variants,
9ee0f956cfbb87b Robert Marko     2020-01-03  142  					      &update_cache_variants),
9ee0f956cfbb87b Robert Marko     2020-01-03  143  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  144  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  145  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  146  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  147  	/* 1.8V 1Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  148  	SPINAND_INFO("TC58CYG0S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  149  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
377e517b5fa5359 Boris Brezillon  2018-11-04  150  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  151  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  152  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  153  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  154  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  155  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  156  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  157  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  158  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  159  	/* 1.8V 2Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  160  	SPINAND_INFO("TC58CYG1S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  161  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
377e517b5fa5359 Boris Brezillon  2018-11-04  162  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  163  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  164  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  165  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  166  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  167  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  168  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  169  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  170  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  171  	/* 1.8V 4Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  172  	SPINAND_INFO("TC58CYG2S0HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  173  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
377e517b5fa5359 Boris Brezillon  2018-11-04  174  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
10949af1681d5bb Schrempf Frieder 2018-11-08  175  		     NAND_ECCREQ(8, 512),
10949af1681d5bb Schrempf Frieder 2018-11-08  176  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
10949af1681d5bb Schrempf Frieder 2018-11-08  177  					      &write_cache_variants,
10949af1681d5bb Schrempf Frieder 2018-11-08  178  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  179  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  180  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  181  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  182  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  183  
798fcdd010006e8 Yoshio Furuyama  2020-03-24  184  	/*
798fcdd010006e8 Yoshio Furuyama  2020-03-24  185  	 * 2nd generation serial nand has HOLD_D which is equivalent to
798fcdd010006e8 Yoshio Furuyama  2020-03-24  186  	 * QE_BIT.
798fcdd010006e8 Yoshio Furuyama  2020-03-24  187  	 */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  188  	/* 3.3V 1Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  189  	SPINAND_INFO("TC58CVG0S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  190  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  191  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  192  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  193  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  194  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  195  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  196  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  197  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  198  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  199  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  200  	/* 3.3V 2Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  201  	SPINAND_INFO("TC58CVG1S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  202  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  203  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  204  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  205  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  206  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  207  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  208  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  209  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  210  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  211  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  212  	/* 3.3V 4Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  213  	SPINAND_INFO("TC58CVG2S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  214  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  215  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  216  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  217  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  218  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  219  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  220  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  221  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  222  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  223  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  224  	/* 3.3V 8Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  225  	SPINAND_INFO("TH58CVG3S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  226  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  227  		     NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  228  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  229  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  230  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  231  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  232  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  233  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  234  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  235  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  236  	/* 1.8V 1Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  237  	SPINAND_INFO("TC58CYG0S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  238  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  239  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  240  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  241  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  242  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  243  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  244  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  245  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  246  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  247  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  248  	/* 1.8V 2Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  249  	SPINAND_INFO("TC58CYG1S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  250  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  251  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  252  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  253  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  254  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  255  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  256  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  257  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  258  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  259  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  260  	/* 1.8V 4Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  261  	SPINAND_INFO("TC58CYG2S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  262  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  263  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  264  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  265  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  266  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  267  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  268  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  269  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  270  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  271  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  272  	/* 1.8V 8Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  273  	SPINAND_INFO("TH58CYG3S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  274  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  275  		     NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  276  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  277  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  278  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  279  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  280  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  281  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  282  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  283  		     SPINAND_RX_SAMPLING_DELAY(6)),
dabd64be75ae38b Sridharan S N    2023-06-23  284  	/* 1.8V 1Gb (1st generation) */
dabd64be75ae38b Sridharan S N    2023-06-23 @285  	SPINAND_INFO("TC58NYG0S3HBAI4",
dabd64be75ae38b Sridharan S N    2023-06-23  286  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA1),
dabd64be75ae38b Sridharan S N    2023-06-23  287  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
dabd64be75ae38b Sridharan S N    2023-06-23  288  		     NAND_ECCREQ(8, 512),
dabd64be75ae38b Sridharan S N    2023-06-23  289  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  290  					      &write_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  291  					      &update_cache_variants),
dabd64be75ae38b Sridharan S N    2023-06-23  292  		     0,
dabd64be75ae38b Sridharan S N    2023-06-23  293  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  294  				     tx58cxgxsxraix_ecc_get_status),
dabd64be75ae38b Sridharan S N    2023-06-23  295  	/* 1.8V 4Gb (1st generation) */
dabd64be75ae38b Sridharan S N    2023-06-23  296  	SPINAND_INFO("TH58NYG2S3HBAI4",
dabd64be75ae38b Sridharan S N    2023-06-23  297  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
dabd64be75ae38b Sridharan S N    2023-06-23  298  		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 2, 1),
dabd64be75ae38b Sridharan S N    2023-06-23  299  		     NAND_ECCREQ(8, 512),
dabd64be75ae38b Sridharan S N    2023-06-23  300  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  301  					      &write_cache_x4_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  302  					      &update_cache_x4_variants),
dabd64be75ae38b Sridharan S N    2023-06-23  303  		     SPINAND_HAS_QE_BIT,
dabd64be75ae38b Sridharan S N    2023-06-23  304  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  305  				     tx58cxgxsxraix_ecc_get_status),
dabd64be75ae38b Sridharan S N    2023-06-23  306  	/* 1.8V 8Gb (1st generation) */
dabd64be75ae38b Sridharan S N    2023-06-23  307  	SPINAND_INFO("TH58NYG3S0HBAI6",
dabd64be75ae38b Sridharan S N    2023-06-23  308  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
dabd64be75ae38b Sridharan S N    2023-06-23  309  		     NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
dabd64be75ae38b Sridharan S N    2023-06-23  310  		     NAND_ECCREQ(8, 512),
dabd64be75ae38b Sridharan S N    2023-06-23  311  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  312  					      &write_cache_x4_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  313  					      &update_cache_x4_variants),
dabd64be75ae38b Sridharan S N    2023-06-23  314  		     SPINAND_HAS_QE_BIT,
dabd64be75ae38b Sridharan S N    2023-06-23  315  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  316  				     tx58cxgxsxraix_ecc_get_status),
10949af1681d5bb Schrempf Frieder 2018-11-08  317  };
10949af1681d5bb Schrempf Frieder 2018-11-08  318  
10949af1681d5bb Schrempf Frieder 2018-11-08  319  static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
10949af1681d5bb Schrempf Frieder 2018-11-08  320  };
10949af1681d5bb Schrempf Frieder 2018-11-08  321  
10949af1681d5bb Schrempf Frieder 2018-11-08  322  const struct spinand_manufacturer toshiba_spinand_manufacturer = {
10949af1681d5bb Schrempf Frieder 2018-11-08  323  	.id = SPINAND_MFR_TOSHIBA,
10949af1681d5bb Schrempf Frieder 2018-11-08  324  	.name = "Toshiba",
f1541773af49ecd Chuanhong Guo    2020-02-08  325  	.chips = toshiba_spinand_table,
f1541773af49ecd Chuanhong Guo    2020-02-08  326  	.nchips = ARRAY_SIZE(toshiba_spinand_table),
10949af1681d5bb Schrempf Frieder 2018-11-08  327  	.ops = &toshiba_spinand_manuf_ops,
10949af1681d5bb Schrempf Frieder 2018-11-08 @328  };

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
  2026-03-03 16:29   ` Frieder Schrempf
                     ` (2 preceding siblings ...)
  (?)
@ 2026-03-06 11:02   ` kernel test robot
  -1 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2026-03-06 11:02 UTC (permalink / raw)
  To: Frieder Schrempf; +Cc: llvm, oe-kbuild-all

Hi Frieder,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on 11439c4635edd669ae435eec308f4ab8a0804808]

url:    https://github.com/intel-lab-lkp/linux/commits/Frieder-Schrempf/spi-Add-rx_sampling_delay_ns-parameter-for-clock-to-RX-delay/20260304-004536
base:   11439c4635edd669ae435eec308f4ab8a0804808
patch link:    https://lore.kernel.org/r/20260303-fsl-qspi-rx-sampling-delay-v1-4-9326bbc492d6%40kontron.de
patch subject: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
config: um-randconfig-001-20260306 (https://download.01.org/0day-ci/archive/20260306/202603061813.ClFYVtLL-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project c32caeec8158d634bb71ab8911a6031248b9fc47)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260306/202603061813.ClFYVtLL-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603061813.ClFYVtLL-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/mtd/nand/spi/toshiba.c:11:
   In file included from include/linux/mtd/spinand.h:16:
   In file included from include/linux/spi/spi.h:17:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:1209:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
    1209 |         return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
         |                                                   ~~~~~~~~~~ ^
>> drivers/mtd/nand/spi/toshiba.c:285:2: error: unterminated function-like macro invocation
     285 |         SPINAND_INFO("TC58NYG0S3HBAI4",
         |         ^
   include/linux/mtd/spinand.h:676:9: note: macro 'SPINAND_INFO' defined here
     676 | #define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants,  \
         |         ^
>> drivers/mtd/nand/spi/toshiba.c:328:3: error: expected expression
     328 | };
         |   ^
>> drivers/mtd/nand/spi/toshiba.c:328:3: error: expected '}'
   drivers/mtd/nand/spi/toshiba.c:110:60: note: to match this '{'
     110 | static const struct spinand_info toshiba_spinand_table[] = {
         |                                                            ^
>> drivers/mtd/nand/spi/toshiba.c:283:38: error: expected ';' after top level declarator
     283 |                      SPINAND_RX_SAMPLING_DELAY(6)),
         |                                                    ^
         |                                                    ;
   1 warning and 4 errors generated.


vim +285 drivers/mtd/nand/spi/toshiba.c

10949af1681d5bb Schrempf Frieder 2018-11-08  109  
10949af1681d5bb Schrempf Frieder 2018-11-08  110  static const struct spinand_info toshiba_spinand_table[] = {
798fcdd010006e8 Yoshio Furuyama  2020-03-24  111  	/* 3.3V 1Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  112  	SPINAND_INFO("TC58CVG0S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  113  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
377e517b5fa5359 Boris Brezillon  2018-11-04  114  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  115  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  116  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  117  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  118  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  119  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  120  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  121  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  122  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  123  	/* 3.3V 2Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  124  	SPINAND_INFO("TC58CVG1S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  125  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
377e517b5fa5359 Boris Brezillon  2018-11-04  126  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  127  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  128  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  129  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  130  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  131  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  132  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  133  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  134  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  135  	/* 3.3V 4Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  136  	SPINAND_INFO("TC58CVG2S0HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  137  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
377e517b5fa5359 Boris Brezillon  2018-11-04  138  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
9ee0f956cfbb87b Robert Marko     2020-01-03  139  		     NAND_ECCREQ(8, 512),
9ee0f956cfbb87b Robert Marko     2020-01-03  140  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
9ee0f956cfbb87b Robert Marko     2020-01-03  141  					      &write_cache_variants,
9ee0f956cfbb87b Robert Marko     2020-01-03  142  					      &update_cache_variants),
9ee0f956cfbb87b Robert Marko     2020-01-03  143  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  144  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  145  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  146  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  147  	/* 1.8V 1Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  148  	SPINAND_INFO("TC58CYG0S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  149  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
377e517b5fa5359 Boris Brezillon  2018-11-04  150  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  151  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  152  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  153  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  154  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  155  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  156  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  157  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  158  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  159  	/* 1.8V 2Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  160  	SPINAND_INFO("TC58CYG1S3HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  161  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
377e517b5fa5359 Boris Brezillon  2018-11-04  162  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
db214513f62fd13 Yoshio Furuyama  2019-01-16  163  		     NAND_ECCREQ(8, 512),
db214513f62fd13 Yoshio Furuyama  2019-01-16  164  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  165  					      &write_cache_variants,
db214513f62fd13 Yoshio Furuyama  2019-01-16  166  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  167  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  168  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  169  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  170  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  171  	/* 1.8V 4Gb (1st generation) */
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  172  	SPINAND_INFO("TC58CYG2S0HRAIG",
f1541773af49ecd Chuanhong Guo    2020-02-08  173  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
377e517b5fa5359 Boris Brezillon  2018-11-04  174  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
10949af1681d5bb Schrempf Frieder 2018-11-08  175  		     NAND_ECCREQ(8, 512),
10949af1681d5bb Schrempf Frieder 2018-11-08  176  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
10949af1681d5bb Schrempf Frieder 2018-11-08  177  					      &write_cache_variants,
10949af1681d5bb Schrempf Frieder 2018-11-08  178  					      &update_cache_variants),
db214513f62fd13 Yoshio Furuyama  2019-01-16  179  		     0,
6b49e58d6d9dab0 Yoshio Furuyama  2020-03-24  180  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  181  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  182  		     SPINAND_RX_SAMPLING_DELAY(8)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  183  
798fcdd010006e8 Yoshio Furuyama  2020-03-24  184  	/*
798fcdd010006e8 Yoshio Furuyama  2020-03-24  185  	 * 2nd generation serial nand has HOLD_D which is equivalent to
798fcdd010006e8 Yoshio Furuyama  2020-03-24  186  	 * QE_BIT.
798fcdd010006e8 Yoshio Furuyama  2020-03-24  187  	 */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  188  	/* 3.3V 1Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  189  	SPINAND_INFO("TC58CVG0S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  190  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  191  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  192  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  193  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  194  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  195  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  196  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  197  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  198  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  199  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  200  	/* 3.3V 2Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  201  	SPINAND_INFO("TC58CVG1S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  202  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  203  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  204  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  205  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  206  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  207  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  208  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  209  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  210  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  211  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  212  	/* 3.3V 4Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  213  	SPINAND_INFO("TC58CVG2S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  214  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  215  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  216  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  217  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  218  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  219  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  220  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  221  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  222  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  223  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  224  	/* 3.3V 8Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  225  	SPINAND_INFO("TH58CVG3S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  226  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  227  		     NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  228  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  229  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  230  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  231  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  232  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  233  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  234  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  235  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  236  	/* 1.8V 1Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  237  	SPINAND_INFO("TC58CYG0S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  238  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  239  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  240  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  241  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  242  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  243  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  244  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  245  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  246  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  247  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  248  	/* 1.8V 2Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  249  	SPINAND_INFO("TC58CYG1S3HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  250  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  251  		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  252  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  253  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  254  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  255  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  256  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  257  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  258  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  259  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  260  	/* 1.8V 4Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  261  	SPINAND_INFO("TC58CYG2S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  262  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  263  		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  264  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  265  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  266  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  267  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  268  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  269  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  270  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03  271  		     SPINAND_RX_SAMPLING_DELAY(6)),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  272  	/* 1.8V 8Gb (2nd generation) */
798fcdd010006e8 Yoshio Furuyama  2020-03-24  273  	SPINAND_INFO("TH58CYG3S0HRAIJ",
798fcdd010006e8 Yoshio Furuyama  2020-03-24  274  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  275  		     NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  276  		     NAND_ECCREQ(8, 512),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  277  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  278  					      &write_cache_x4_variants,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  279  					      &update_cache_x4_variants),
798fcdd010006e8 Yoshio Furuyama  2020-03-24  280  		     SPINAND_HAS_QE_BIT,
798fcdd010006e8 Yoshio Furuyama  2020-03-24  281  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  282  				     tx58cxgxsxraix_ecc_get_status),
b1a60738d0766b4 Frieder Schrempf 2026-03-03 @283  		     SPINAND_RX_SAMPLING_DELAY(6)),
dabd64be75ae38b Sridharan S N    2023-06-23  284  	/* 1.8V 1Gb (1st generation) */
dabd64be75ae38b Sridharan S N    2023-06-23 @285  	SPINAND_INFO("TC58NYG0S3HBAI4",
dabd64be75ae38b Sridharan S N    2023-06-23  286  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA1),
dabd64be75ae38b Sridharan S N    2023-06-23  287  		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
dabd64be75ae38b Sridharan S N    2023-06-23  288  		     NAND_ECCREQ(8, 512),
dabd64be75ae38b Sridharan S N    2023-06-23  289  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  290  					      &write_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  291  					      &update_cache_variants),
dabd64be75ae38b Sridharan S N    2023-06-23  292  		     0,
dabd64be75ae38b Sridharan S N    2023-06-23  293  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  294  				     tx58cxgxsxraix_ecc_get_status),
dabd64be75ae38b Sridharan S N    2023-06-23  295  	/* 1.8V 4Gb (1st generation) */
dabd64be75ae38b Sridharan S N    2023-06-23  296  	SPINAND_INFO("TH58NYG2S3HBAI4",
dabd64be75ae38b Sridharan S N    2023-06-23  297  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
dabd64be75ae38b Sridharan S N    2023-06-23  298  		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 2, 1),
dabd64be75ae38b Sridharan S N    2023-06-23  299  		     NAND_ECCREQ(8, 512),
dabd64be75ae38b Sridharan S N    2023-06-23  300  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  301  					      &write_cache_x4_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  302  					      &update_cache_x4_variants),
dabd64be75ae38b Sridharan S N    2023-06-23  303  		     SPINAND_HAS_QE_BIT,
dabd64be75ae38b Sridharan S N    2023-06-23  304  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  305  				     tx58cxgxsxraix_ecc_get_status),
dabd64be75ae38b Sridharan S N    2023-06-23  306  	/* 1.8V 8Gb (1st generation) */
dabd64be75ae38b Sridharan S N    2023-06-23  307  	SPINAND_INFO("TH58NYG3S0HBAI6",
dabd64be75ae38b Sridharan S N    2023-06-23  308  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
dabd64be75ae38b Sridharan S N    2023-06-23  309  		     NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
dabd64be75ae38b Sridharan S N    2023-06-23  310  		     NAND_ECCREQ(8, 512),
dabd64be75ae38b Sridharan S N    2023-06-23  311  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  312  					      &write_cache_x4_variants,
dabd64be75ae38b Sridharan S N    2023-06-23  313  					      &update_cache_x4_variants),
dabd64be75ae38b Sridharan S N    2023-06-23  314  		     SPINAND_HAS_QE_BIT,
dabd64be75ae38b Sridharan S N    2023-06-23  315  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
b1a60738d0766b4 Frieder Schrempf 2026-03-03  316  				     tx58cxgxsxraix_ecc_get_status),
10949af1681d5bb Schrempf Frieder 2018-11-08  317  };
10949af1681d5bb Schrempf Frieder 2018-11-08  318  
10949af1681d5bb Schrempf Frieder 2018-11-08  319  static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
10949af1681d5bb Schrempf Frieder 2018-11-08  320  };
10949af1681d5bb Schrempf Frieder 2018-11-08  321  
10949af1681d5bb Schrempf Frieder 2018-11-08  322  const struct spinand_manufacturer toshiba_spinand_manufacturer = {
10949af1681d5bb Schrempf Frieder 2018-11-08  323  	.id = SPINAND_MFR_TOSHIBA,
10949af1681d5bb Schrempf Frieder 2018-11-08  324  	.name = "Toshiba",
f1541773af49ecd Chuanhong Guo    2020-02-08  325  	.chips = toshiba_spinand_table,
f1541773af49ecd Chuanhong Guo    2020-02-08  326  	.nchips = ARRAY_SIZE(toshiba_spinand_table),
10949af1681d5bb Schrempf Frieder 2018-11-08  327  	.ops = &toshiba_spinand_manuf_ops,
10949af1681d5bb Schrempf Frieder 2018-11-08 @328  };

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-09 15:09     ` Miquel Raynal
  -1 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:09 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

Hi Frieder,

First, thanks for the series! I believe it will conflict with the SPI
tuning series as you mentioned, but we should be able to make them live
side by side.

On 03/03/2026 at 17:29:27 +01, Frieder Schrempf <frieder@fris.de> wrote:

> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>
> With clock rates changing on a per-op basis, we need to make sure
> that we meet the RX sampling point delay constraint of the underlying
> SPI chip.
>
> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
> ---
>  drivers/spi/spi-mem.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
> index a09371a075d2e..6b8bee7d6f5e3 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -589,6 +589,8 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
>  {
>  	if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
>  		op->max_freq = mem->spi->max_speed_hz;
> +
> +	op->max_freq = spi_set_rx_sampling_point(mem->spi,
> op->max_freq);

How can this work with the above 2 lines? Maybe there will be the need
to use a "min of the max" frequencies?

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-09 15:09     ` Miquel Raynal
  0 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:09 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx

Hi Frieder,

First, thanks for the series! I believe it will conflict with the SPI
tuning series as you mentioned, but we should be able to make them live
side by side.

On 03/03/2026 at 17:29:27 +01, Frieder Schrempf <frieder@fris.de> wrote:

> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>
> With clock rates changing on a per-op basis, we need to make sure
> that we meet the RX sampling point delay constraint of the underlying
> SPI chip.
>
> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
> ---
>  drivers/spi/spi-mem.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
> index a09371a075d2e..6b8bee7d6f5e3 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -589,6 +589,8 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
>  {
>  	if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
>  		op->max_freq = mem->spi->max_speed_hz;
> +
> +	op->max_freq = spi_set_rx_sampling_point(mem->spi,
> op->max_freq);

How can this work with the above 2 lines? Maybe there will be the need
to use a "min of the max" frequencies?

Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-09 15:11     ` Miquel Raynal
  -1 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:11 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx


> +#define SPINAND_RX_SAMPLING_DELAY(__delay)				\
> +	.rx_sampling_delay_ns = __delay

For this macro I would be in favour of suffixing it with the unit,
ie: _NS.

Miquèl

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting
@ 2026-03-09 15:11     ` Miquel Raynal
  0 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:11 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx


> +#define SPINAND_RX_SAMPLING_DELAY(__delay)				\
> +	.rx_sampling_delay_ns = __delay

For this macro I would be in favour of suffixing it with the unit,
ie: _NS.

Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-09 15:12     ` Miquel Raynal
  -1 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:12 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx


> @@ -277,7 +291,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>  					      &update_cache_variants),
>  		     0,
>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
>  	/* 1.8V 4Gb (1st generation) */
>  	SPINAND_INFO("TH58NYG2S3HBAI4",
>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
> @@ -288,7 +302,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>  					      &update_cache_x4_variants),
>  		     SPINAND_HAS_QE_BIT,
>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
>  	/* 1.8V 8Gb (1st generation) */
>  	SPINAND_INFO("TH58NYG3S0HBAI6",
>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
> @@ -299,7 +313,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>  					      &update_cache_x4_variants),
>  		     SPINAND_HAS_QE_BIT,
>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
>  };

Are these 3 changes legitimate?

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
@ 2026-03-09 15:12     ` Miquel Raynal
  0 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:12 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx


> @@ -277,7 +291,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>  					      &update_cache_variants),
>  		     0,
>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
>  	/* 1.8V 4Gb (1st generation) */
>  	SPINAND_INFO("TH58NYG2S3HBAI4",
>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
> @@ -288,7 +302,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>  					      &update_cache_x4_variants),
>  		     SPINAND_HAS_QE_BIT,
>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
>  	/* 1.8V 8Gb (1st generation) */
>  	SPINAND_INFO("TH58NYG3S0HBAI6",
>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
> @@ -299,7 +313,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>  					      &update_cache_x4_variants),
>  		     SPINAND_HAS_QE_BIT,
>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
> -				     tx58cxgxsxraix_ecc_get_status)),
> +				     tx58cxgxsxraix_ecc_get_status),
>  };

Are these 3 changes legitimate?

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
  2026-03-03 16:29   ` Frieder Schrempf
@ 2026-03-09 15:25     ` Miquel Raynal
  -1 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:25 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx,
	Santhosh Kumar K

Hello,

+ Santhosh

On 03/03/2026 at 17:29:26 +01, Frieder Schrempf <frieder@fris.de> wrote:

> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>
> Some SPI devices such as SPI NAND chips specify a clock-to-RX-sampling
> delay constraint, which means that for the data read from the device
> at a certain clock rate, we need to make sure that the point at
> which the data is sampled is correct.
>
> The default is to assume that the data can be sampled one half clock
> cycle after the triggering clock edge. For high clock rates, this
> can be too early.
>
> To check this we introduce a new core function spi_set_rx_sampling_point()
> and a handler set_rx_sampling_point() in the SPI controller.
>
> Controllers implementing set_rx_sampling_point() can calculate the
> sampling point delay using the helper spi_calc_rx_sampling_point()
> and store the value to set the appropriate registers during transfer.
>
> In case the controller capabilities are not sufficient to compensate
> the RX delay, spi_set_rx_sampling_point() returns a reduced clock
> rate value that is safe to use.
>
> This commit does not introduce generic logic for controllers that
> don't implement set_rx_sampling_point() in order to reduce the clock
> rate if the RX sampling delay requirement can not be met.
>
> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
> ---
>  drivers/spi/spi.c       | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/spi/spi.h |  8 ++++++
>  2 files changed, 81 insertions(+)
>
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 61f7bde8c7fbb..b039007ed430f 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -3988,6 +3988,77 @@ static int spi_set_cs_timing(struct spi_device *spi)
>  	return status;
>  }
>  
> +/**
> + * spi_calc_rx_sampling_point - calculate RX sampling delay cycles
> + * @spi: the device that requires specific a RX sampling delay
> + * @freq: pointer to the clock frequency setpoint for the calculation. This gets
> + *        altered to a reduced value if required.
> + * @max_delay_cycles: the upper limit of supported delay cycles
> + * @delay_cycles_per_clock_cycle: the ratio between delay cycles and
> + *				  master clock cycles
> + *
> + * This function takes in the rx_sampling_delay_ns value from the SPI device
> + * and the given clock frequency setpoint and calculates the required sampling
> + * delay cycles to meet the device's spec. It uses the given controller
> + * constraints and if those are exceeded, it adjusts the clock frequency
> + * setpoint to a lower value that is safe to be used.
> + *
> + * Return: calculated number of delay cycles
> + */
> +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
> +					u16 max_delay_cycles,
> +					u16 delay_cycles_per_clock_cycle)
> +{
> +	unsigned long long temp;
> +	u16 delay_cycles;
> +
> +	/* if sampling delay is zero, we assume the default sampling point can be used */
> +	if (!spi->rx_sampling_delay_ns)
> +		return 0;
> +
> +	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
> +	do_div(temp, 1000000000UL);
> +	delay_cycles = temp;
> +
> +	if (delay_cycles > max_delay_cycles) {
> +		/*
> +		 * Reduce the clock to the point where the sampling delay requirement
> +		 * can be met.
> +		 */
> +		delay_cycles = max_delay_cycles;
> +		temp = (1000000000UL * delay_cycles);
> +		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
> +		*freq = temp;

This is silently modifying the spi_device structure, I don't like this much.

> +	}
> +
> +	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
> +
> +	return delay_cycles;
> +}
> +EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point);
> +
> +/**
> + * spi_set_rx_sampling_point - set the RX sampling delay in the controller driver
> + * @spi: the device that requires specific a RX sampling delay
> + * @freq: the clock frequency setpoint for the RX sampling delay calculation
> + *
> + * This function calls the set_rx_sampling_point() handle in the controller
> + * driver it is available. This makes sure that the controller uses the proper
> + * RX sampling point adjustment. This function should be called whenever
> + * the devices rx_sampling_delay_ns or the currently used clock frequency
> + * changes.
> + *
> + * Return: adjusted clock frequency
> + */
> +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
> +{
> +	if (spi->controller->set_rx_sampling_point)
> +		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
> +
> +	return freq;
> +}
> +EXPORT_SYMBOL_GPL(spi_set_rx_sampling_point);
> +
>  /**
>   * spi_setup - setup SPI mode and clock rate
>   * @spi: the device whose settings are being modified
> @@ -4090,6 +4161,8 @@ int spi_setup(struct spi_device *spi)
>  		}
>  	}
>  
> +	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);

I believe we need a clearer yet stronger logic around the setting of
max_speed_hz.

The "maximum speed" parameter is reaching its limit. This is clearly
what needs to be discussed with Santhosh. The SPI tuning series is
playing with this value as well.

Cheers,
Miquèl

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
@ 2026-03-09 15:25     ` Miquel Raynal
  0 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-09 15:25 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Frieder Schrempf, Tudor Ambarus, Pratyush Yadav,
	Michael Walle, linux-spi, linux-kernel, linux-mtd, imx,
	Santhosh Kumar K

Hello,

+ Santhosh

On 03/03/2026 at 17:29:26 +01, Frieder Schrempf <frieder@fris.de> wrote:

> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>
> Some SPI devices such as SPI NAND chips specify a clock-to-RX-sampling
> delay constraint, which means that for the data read from the device
> at a certain clock rate, we need to make sure that the point at
> which the data is sampled is correct.
>
> The default is to assume that the data can be sampled one half clock
> cycle after the triggering clock edge. For high clock rates, this
> can be too early.
>
> To check this we introduce a new core function spi_set_rx_sampling_point()
> and a handler set_rx_sampling_point() in the SPI controller.
>
> Controllers implementing set_rx_sampling_point() can calculate the
> sampling point delay using the helper spi_calc_rx_sampling_point()
> and store the value to set the appropriate registers during transfer.
>
> In case the controller capabilities are not sufficient to compensate
> the RX delay, spi_set_rx_sampling_point() returns a reduced clock
> rate value that is safe to use.
>
> This commit does not introduce generic logic for controllers that
> don't implement set_rx_sampling_point() in order to reduce the clock
> rate if the RX sampling delay requirement can not be met.
>
> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
> ---
>  drivers/spi/spi.c       | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/spi/spi.h |  8 ++++++
>  2 files changed, 81 insertions(+)
>
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 61f7bde8c7fbb..b039007ed430f 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -3988,6 +3988,77 @@ static int spi_set_cs_timing(struct spi_device *spi)
>  	return status;
>  }
>  
> +/**
> + * spi_calc_rx_sampling_point - calculate RX sampling delay cycles
> + * @spi: the device that requires specific a RX sampling delay
> + * @freq: pointer to the clock frequency setpoint for the calculation. This gets
> + *        altered to a reduced value if required.
> + * @max_delay_cycles: the upper limit of supported delay cycles
> + * @delay_cycles_per_clock_cycle: the ratio between delay cycles and
> + *				  master clock cycles
> + *
> + * This function takes in the rx_sampling_delay_ns value from the SPI device
> + * and the given clock frequency setpoint and calculates the required sampling
> + * delay cycles to meet the device's spec. It uses the given controller
> + * constraints and if those are exceeded, it adjusts the clock frequency
> + * setpoint to a lower value that is safe to be used.
> + *
> + * Return: calculated number of delay cycles
> + */
> +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
> +					u16 max_delay_cycles,
> +					u16 delay_cycles_per_clock_cycle)
> +{
> +	unsigned long long temp;
> +	u16 delay_cycles;
> +
> +	/* if sampling delay is zero, we assume the default sampling point can be used */
> +	if (!spi->rx_sampling_delay_ns)
> +		return 0;
> +
> +	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
> +	do_div(temp, 1000000000UL);
> +	delay_cycles = temp;
> +
> +	if (delay_cycles > max_delay_cycles) {
> +		/*
> +		 * Reduce the clock to the point where the sampling delay requirement
> +		 * can be met.
> +		 */
> +		delay_cycles = max_delay_cycles;
> +		temp = (1000000000UL * delay_cycles);
> +		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
> +		*freq = temp;

This is silently modifying the spi_device structure, I don't like this much.

> +	}
> +
> +	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
> +
> +	return delay_cycles;
> +}
> +EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point);
> +
> +/**
> + * spi_set_rx_sampling_point - set the RX sampling delay in the controller driver
> + * @spi: the device that requires specific a RX sampling delay
> + * @freq: the clock frequency setpoint for the RX sampling delay calculation
> + *
> + * This function calls the set_rx_sampling_point() handle in the controller
> + * driver it is available. This makes sure that the controller uses the proper
> + * RX sampling point adjustment. This function should be called whenever
> + * the devices rx_sampling_delay_ns or the currently used clock frequency
> + * changes.
> + *
> + * Return: adjusted clock frequency
> + */
> +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
> +{
> +	if (spi->controller->set_rx_sampling_point)
> +		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
> +
> +	return freq;
> +}
> +EXPORT_SYMBOL_GPL(spi_set_rx_sampling_point);
> +
>  /**
>   * spi_setup - setup SPI mode and clock rate
>   * @spi: the device whose settings are being modified
> @@ -4090,6 +4161,8 @@ int spi_setup(struct spi_device *spi)
>  		}
>  	}
>  
> +	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);

I believe we need a clearer yet stronger logic around the setting of
max_speed_hz.

The "maximum speed" parameter is reaching its limit. This is clearly
what needs to be discussed with Santhosh. The SPI tuning series is
playing with this value as well.

Cheers,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-09 15:09     ` Miquel Raynal
@ 2026-03-10 14:16       ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-10 14:16 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Tudor Ambarus, Pratyush Yadav, Michael Walle,
	linux-spi, linux-kernel, linux-mtd, imx

Hi Miquèl,

On 09.03.26 16:09, Miquel Raynal wrote:
> Hi Frieder,
> 
> First, thanks for the series! I believe it will conflict with the SPI
> tuning series as you mentioned, but we should be able to make them live
> side by side.

Ok, good! Thanks for your feedback!

> 
> On 03/03/2026 at 17:29:27 +01, Frieder Schrempf <frieder@fris.de> wrote:
> 
>> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>>
>> With clock rates changing on a per-op basis, we need to make sure
>> that we meet the RX sampling point delay constraint of the underlying
>> SPI chip.
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
>> ---
>>  drivers/spi/spi-mem.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
>> index a09371a075d2e..6b8bee7d6f5e3 100644
>> --- a/drivers/spi/spi-mem.c
>> +++ b/drivers/spi/spi-mem.c
>> @@ -589,6 +589,8 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
>>  {
>>  	if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
>>  		op->max_freq = mem->spi->max_speed_hz;
>> +
>> +	op->max_freq = spi_set_rx_sampling_point(mem->spi,
>> op->max_freq);
> 
> How can this work with the above 2 lines? Maybe there will be the need
> to use a "min of the max" frequencies?

The sampling point delay is coupled to the clock frequency. So if the
clock changes per-op, we also need to change the sampling delay per-op.

In general, if we want to avoid switching the parameters back and forth
in cases of alternating ops with different max frequencies, we should
maybe do some "min of the max" calculation and use the resulting
frequency for all ops.

Is that what you mean?

We could even set a threshold to decide between using a common "min of
the max" frequency or do the switching per-op.

One other possibility would be to somehow cache the per-op frequencies
and calculated sampling delay values so they can be reused when
switching without much overhead.

There is one more issue that is not yet covered by this series: Before
spinand_id_detect() we don't know yet what RX sampling delay value the
chip requires, but we already use read-status and read-id operations at
maximum chip clock.

For example on Winbond W25N04KV this leads to detection failures. So we
should maybe introduce some kind of reduced clock setpoint for the
initial detection, that is safe to be used without RX sampling delay
compensation.

Thanks
Frieder

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-10 14:16       ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-10 14:16 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Tudor Ambarus, Pratyush Yadav, Michael Walle,
	linux-spi, linux-kernel, linux-mtd, imx

Hi Miquèl,

On 09.03.26 16:09, Miquel Raynal wrote:
> Hi Frieder,
> 
> First, thanks for the series! I believe it will conflict with the SPI
> tuning series as you mentioned, but we should be able to make them live
> side by side.

Ok, good! Thanks for your feedback!

> 
> On 03/03/2026 at 17:29:27 +01, Frieder Schrempf <frieder@fris.de> wrote:
> 
>> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>>
>> With clock rates changing on a per-op basis, we need to make sure
>> that we meet the RX sampling point delay constraint of the underlying
>> SPI chip.
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
>> ---
>>  drivers/spi/spi-mem.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
>> index a09371a075d2e..6b8bee7d6f5e3 100644
>> --- a/drivers/spi/spi-mem.c
>> +++ b/drivers/spi/spi-mem.c
>> @@ -589,6 +589,8 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
>>  {
>>  	if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
>>  		op->max_freq = mem->spi->max_speed_hz;
>> +
>> +	op->max_freq = spi_set_rx_sampling_point(mem->spi,
>> op->max_freq);
> 
> How can this work with the above 2 lines? Maybe there will be the need
> to use a "min of the max" frequencies?

The sampling point delay is coupled to the clock frequency. So if the
clock changes per-op, we also need to change the sampling delay per-op.

In general, if we want to avoid switching the parameters back and forth
in cases of alternating ops with different max frequencies, we should
maybe do some "min of the max" calculation and use the resulting
frequency for all ops.

Is that what you mean?

We could even set a threshold to decide between using a common "min of
the max" frequency or do the switching per-op.

One other possibility would be to somehow cache the per-op frequencies
and calculated sampling delay values so they can be reused when
switching without much overhead.

There is one more issue that is not yet covered by this series: Before
spinand_id_detect() we don't know yet what RX sampling delay value the
chip requires, but we already use read-status and read-id operations at
maximum chip clock.

For example on Winbond W25N04KV this leads to detection failures. So we
should maybe introduce some kind of reduced clock setpoint for the
initial detection, that is safe to be used without RX sampling delay
compensation.

Thanks
Frieder

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
  2026-03-09 15:12     ` Miquel Raynal
@ 2026-03-10 14:17       ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-10 14:17 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Tudor Ambarus, Pratyush Yadav, Michael Walle,
	linux-spi, linux-kernel, linux-mtd, imx

On 09.03.26 16:12, Miquel Raynal wrote:
> 
>> @@ -277,7 +291,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>>  					      &update_cache_variants),
>>  		     0,
>>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
>> -				     tx58cxgxsxraix_ecc_get_status)),
>> +				     tx58cxgxsxraix_ecc_get_status),
>>  	/* 1.8V 4Gb (1st generation) */
>>  	SPINAND_INFO("TH58NYG2S3HBAI4",
>>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
>> @@ -288,7 +302,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>>  					      &update_cache_x4_variants),
>>  		     SPINAND_HAS_QE_BIT,
>>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
>> -				     tx58cxgxsxraix_ecc_get_status)),
>> +				     tx58cxgxsxraix_ecc_get_status),
>>  	/* 1.8V 8Gb (1st generation) */
>>  	SPINAND_INFO("TH58NYG3S0HBAI6",
>>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
>> @@ -299,7 +313,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>>  					      &update_cache_x4_variants),
>>  		     SPINAND_HAS_QE_BIT,
>>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
>> -				     tx58cxgxsxraix_ecc_get_status)),
>> +				     tx58cxgxsxraix_ecc_get_status),
>>  };
> 
> Are these 3 changes legitimate?

No, they are not. This is a last-minute fixup gone wrong.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values
@ 2026-03-10 14:17       ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-10 14:17 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Tudor Ambarus, Pratyush Yadav, Michael Walle,
	linux-spi, linux-kernel, linux-mtd, imx

On 09.03.26 16:12, Miquel Raynal wrote:
> 
>> @@ -277,7 +291,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>>  					      &update_cache_variants),
>>  		     0,
>>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
>> -				     tx58cxgxsxraix_ecc_get_status)),
>> +				     tx58cxgxsxraix_ecc_get_status),
>>  	/* 1.8V 4Gb (1st generation) */
>>  	SPINAND_INFO("TH58NYG2S3HBAI4",
>>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC),
>> @@ -288,7 +302,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>>  					      &update_cache_x4_variants),
>>  		     SPINAND_HAS_QE_BIT,
>>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
>> -				     tx58cxgxsxraix_ecc_get_status)),
>> +				     tx58cxgxsxraix_ecc_get_status),
>>  	/* 1.8V 8Gb (1st generation) */
>>  	SPINAND_INFO("TH58NYG3S0HBAI6",
>>  		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3),
>> @@ -299,7 +313,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
>>  					      &update_cache_x4_variants),
>>  		     SPINAND_HAS_QE_BIT,
>>  		     SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
>> -				     tx58cxgxsxraix_ecc_get_status)),
>> +				     tx58cxgxsxraix_ecc_get_status),
>>  };
> 
> Are these 3 changes legitimate?

No, they are not. This is a last-minute fixup gone wrong.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
  2026-03-09 15:25     ` Miquel Raynal
@ 2026-03-10 14:19       ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-10 14:19 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Tudor Ambarus, Pratyush Yadav, Michael Walle,
	linux-spi, linux-kernel, linux-mtd, imx, Santhosh Kumar K

On 09.03.26 16:25, Miquel Raynal wrote:
> Hello,
> 
> + Santhosh
> 
> On 03/03/2026 at 17:29:26 +01, Frieder Schrempf <frieder@fris.de> wrote:
> 
>> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>>
>> Some SPI devices such as SPI NAND chips specify a clock-to-RX-sampling
>> delay constraint, which means that for the data read from the device
>> at a certain clock rate, we need to make sure that the point at
>> which the data is sampled is correct.
>>
>> The default is to assume that the data can be sampled one half clock
>> cycle after the triggering clock edge. For high clock rates, this
>> can be too early.
>>
>> To check this we introduce a new core function spi_set_rx_sampling_point()
>> and a handler set_rx_sampling_point() in the SPI controller.
>>
>> Controllers implementing set_rx_sampling_point() can calculate the
>> sampling point delay using the helper spi_calc_rx_sampling_point()
>> and store the value to set the appropriate registers during transfer.
>>
>> In case the controller capabilities are not sufficient to compensate
>> the RX delay, spi_set_rx_sampling_point() returns a reduced clock
>> rate value that is safe to use.
>>
>> This commit does not introduce generic logic for controllers that
>> don't implement set_rx_sampling_point() in order to reduce the clock
>> rate if the RX sampling delay requirement can not be met.
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
>> ---
>>  drivers/spi/spi.c       | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/spi/spi.h |  8 ++++++
>>  2 files changed, 81 insertions(+)
>>
>> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
>> index 61f7bde8c7fbb..b039007ed430f 100644
>> --- a/drivers/spi/spi.c
>> +++ b/drivers/spi/spi.c
>> @@ -3988,6 +3988,77 @@ static int spi_set_cs_timing(struct spi_device *spi)
>>  	return status;
>>  }
>>  
>> +/**
>> + * spi_calc_rx_sampling_point - calculate RX sampling delay cycles
>> + * @spi: the device that requires specific a RX sampling delay
>> + * @freq: pointer to the clock frequency setpoint for the calculation. This gets
>> + *        altered to a reduced value if required.
>> + * @max_delay_cycles: the upper limit of supported delay cycles
>> + * @delay_cycles_per_clock_cycle: the ratio between delay cycles and
>> + *				  master clock cycles
>> + *
>> + * This function takes in the rx_sampling_delay_ns value from the SPI device
>> + * and the given clock frequency setpoint and calculates the required sampling
>> + * delay cycles to meet the device's spec. It uses the given controller
>> + * constraints and if those are exceeded, it adjusts the clock frequency
>> + * setpoint to a lower value that is safe to be used.
>> + *
>> + * Return: calculated number of delay cycles
>> + */
>> +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
>> +					u16 max_delay_cycles,
>> +					u16 delay_cycles_per_clock_cycle)
>> +{
>> +	unsigned long long temp;
>> +	u16 delay_cycles;
>> +
>> +	/* if sampling delay is zero, we assume the default sampling point can be used */
>> +	if (!spi->rx_sampling_delay_ns)
>> +		return 0;
>> +
>> +	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
>> +	do_div(temp, 1000000000UL);
>> +	delay_cycles = temp;
>> +
>> +	if (delay_cycles > max_delay_cycles) {
>> +		/*
>> +		 * Reduce the clock to the point where the sampling delay requirement
>> +		 * can be met.
>> +		 */
>> +		delay_cycles = max_delay_cycles;
>> +		temp = (1000000000UL * delay_cycles);
>> +		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
>> +		*freq = temp;
> 
> This is silently modifying the spi_device structure, I don't like this much.

Right, I agree. I think we will likely need some struct type to hold the
frequency and sampling delay values anyway. So maybe this function could
then return a value of such type.

> 
>> +	}
>> +
>> +	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
>> +
>> +	return delay_cycles;
>> +}
>> +EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point);
>> +
>> +/**
>> + * spi_set_rx_sampling_point - set the RX sampling delay in the controller driver
>> + * @spi: the device that requires specific a RX sampling delay
>> + * @freq: the clock frequency setpoint for the RX sampling delay calculation
>> + *
>> + * This function calls the set_rx_sampling_point() handle in the controller
>> + * driver it is available. This makes sure that the controller uses the proper
>> + * RX sampling point adjustment. This function should be called whenever
>> + * the devices rx_sampling_delay_ns or the currently used clock frequency
>> + * changes.
>> + *
>> + * Return: adjusted clock frequency
>> + */
>> +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
>> +{
>> +	if (spi->controller->set_rx_sampling_point)
>> +		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
>> +
>> +	return freq;
>> +}
>> +EXPORT_SYMBOL_GPL(spi_set_rx_sampling_point);
>> +
>>  /**
>>   * spi_setup - setup SPI mode and clock rate
>>   * @spi: the device whose settings are being modified
>> @@ -4090,6 +4161,8 @@ int spi_setup(struct spi_device *spi)
>>  		}
>>  	}
>>  
>> +	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);
> 
> I believe we need a clearer yet stronger logic around the setting of
> max_speed_hz.
> 
> The "maximum speed" parameter is reaching its limit. This is clearly
> what needs to be discussed with Santhosh. The SPI tuning series is
> playing with this value as well.

I agree. I'm still missing parts of the bigger picture here, so I'm
currently not really sure how this might look like. But I'm open to any
discussions and suggestions.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 5/7] spi: Add RX sampling point adjustment
@ 2026-03-10 14:19       ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-10 14:19 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Mark Brown, Richard Weinberger, Vignesh Raghavendra, Han Xu,
	Eberhard Stoll, Tudor Ambarus, Pratyush Yadav, Michael Walle,
	linux-spi, linux-kernel, linux-mtd, imx, Santhosh Kumar K

On 09.03.26 16:25, Miquel Raynal wrote:
> Hello,
> 
> + Santhosh
> 
> On 03/03/2026 at 17:29:26 +01, Frieder Schrempf <frieder@fris.de> wrote:
> 
>> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>>
>> Some SPI devices such as SPI NAND chips specify a clock-to-RX-sampling
>> delay constraint, which means that for the data read from the device
>> at a certain clock rate, we need to make sure that the point at
>> which the data is sampled is correct.
>>
>> The default is to assume that the data can be sampled one half clock
>> cycle after the triggering clock edge. For high clock rates, this
>> can be too early.
>>
>> To check this we introduce a new core function spi_set_rx_sampling_point()
>> and a handler set_rx_sampling_point() in the SPI controller.
>>
>> Controllers implementing set_rx_sampling_point() can calculate the
>> sampling point delay using the helper spi_calc_rx_sampling_point()
>> and store the value to set the appropriate registers during transfer.
>>
>> In case the controller capabilities are not sufficient to compensate
>> the RX delay, spi_set_rx_sampling_point() returns a reduced clock
>> rate value that is safe to use.
>>
>> This commit does not introduce generic logic for controllers that
>> don't implement set_rx_sampling_point() in order to reduce the clock
>> rate if the RX sampling delay requirement can not be met.
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
>> ---
>>  drivers/spi/spi.c       | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/spi/spi.h |  8 ++++++
>>  2 files changed, 81 insertions(+)
>>
>> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
>> index 61f7bde8c7fbb..b039007ed430f 100644
>> --- a/drivers/spi/spi.c
>> +++ b/drivers/spi/spi.c
>> @@ -3988,6 +3988,77 @@ static int spi_set_cs_timing(struct spi_device *spi)
>>  	return status;
>>  }
>>  
>> +/**
>> + * spi_calc_rx_sampling_point - calculate RX sampling delay cycles
>> + * @spi: the device that requires specific a RX sampling delay
>> + * @freq: pointer to the clock frequency setpoint for the calculation. This gets
>> + *        altered to a reduced value if required.
>> + * @max_delay_cycles: the upper limit of supported delay cycles
>> + * @delay_cycles_per_clock_cycle: the ratio between delay cycles and
>> + *				  master clock cycles
>> + *
>> + * This function takes in the rx_sampling_delay_ns value from the SPI device
>> + * and the given clock frequency setpoint and calculates the required sampling
>> + * delay cycles to meet the device's spec. It uses the given controller
>> + * constraints and if those are exceeded, it adjusts the clock frequency
>> + * setpoint to a lower value that is safe to be used.
>> + *
>> + * Return: calculated number of delay cycles
>> + */
>> +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned int *freq,
>> +					u16 max_delay_cycles,
>> +					u16 delay_cycles_per_clock_cycle)
>> +{
>> +	unsigned long long temp;
>> +	u16 delay_cycles;
>> +
>> +	/* if sampling delay is zero, we assume the default sampling point can be used */
>> +	if (!spi->rx_sampling_delay_ns)
>> +		return 0;
>> +
>> +	temp = *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns;
>> +	do_div(temp, 1000000000UL);
>> +	delay_cycles = temp;
>> +
>> +	if (delay_cycles > max_delay_cycles) {
>> +		/*
>> +		 * Reduce the clock to the point where the sampling delay requirement
>> +		 * can be met.
>> +		 */
>> +		delay_cycles = max_delay_cycles;
>> +		temp = (1000000000UL * delay_cycles);
>> +		do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle);
>> +		*freq = temp;
> 
> This is silently modifying the spi_device structure, I don't like this much.

Right, I agree. I think we will likely need some struct type to hold the
frequency and sampling delay values anyway. So maybe this function could
then return a value of such type.

> 
>> +	}
>> +
>> +	dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cycle(s) at %lu KHz", delay_cycles, *freq / 1000);
>> +
>> +	return delay_cycles;
>> +}
>> +EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point);
>> +
>> +/**
>> + * spi_set_rx_sampling_point - set the RX sampling delay in the controller driver
>> + * @spi: the device that requires specific a RX sampling delay
>> + * @freq: the clock frequency setpoint for the RX sampling delay calculation
>> + *
>> + * This function calls the set_rx_sampling_point() handle in the controller
>> + * driver it is available. This makes sure that the controller uses the proper
>> + * RX sampling point adjustment. This function should be called whenever
>> + * the devices rx_sampling_delay_ns or the currently used clock frequency
>> + * changes.
>> + *
>> + * Return: adjusted clock frequency
>> + */
>> +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned int freq)
>> +{
>> +	if (spi->controller->set_rx_sampling_point)
>> +		return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz);
>> +
>> +	return freq;
>> +}
>> +EXPORT_SYMBOL_GPL(spi_set_rx_sampling_point);
>> +
>>  /**
>>   * spi_setup - setup SPI mode and clock rate
>>   * @spi: the device whose settings are being modified
>> @@ -4090,6 +4161,8 @@ int spi_setup(struct spi_device *spi)
>>  		}
>>  	}
>>  
>> +	spi->max_speed_hz = spi_set_rx_sampling_point(spi, spi->max_speed_hz);
> 
> I believe we need a clearer yet stronger logic around the setting of
> max_speed_hz.
> 
> The "maximum speed" parameter is reaching its limit. This is clearly
> what needs to be discussed with Santhosh. The SPI tuning series is
> playing with this value as well.

I agree. I'm still missing parts of the bigger picture here, so I'm
currently not really sure how this might look like. But I'm open to any
discussions and suggestions.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-10 14:16       ` Frieder Schrempf
@ 2026-03-31  9:23         ` Miquel Raynal
  -1 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-31  9:23 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

Hi Frieder,

> The sampling point delay is coupled to the clock frequency. So if the
> clock changes per-op, we also need to change the sampling delay per-op.
>
> In general, if we want to avoid switching the parameters back and forth
> in cases of alternating ops with different max frequencies, we should
> maybe do some "min of the max" calculation and use the resulting
> frequency for all ops.
>
> Is that what you mean?

Not exactly, I am not afraid by the time it would take to switch, I am
afraid by the likelihood that both the PHY tuning series and your series
might want to force a different maximum frequency. For instance with TI
designs, when entering PHY mode, the frequency is 166MHz, period. You
cannot lower it because by design, you bypass the SPI divisors.

> We could even set a threshold to decide between using a common "min of
> the max" frequency or do the switching per-op.
>
> One other possibility would be to somehow cache the per-op frequencies
> and calculated sampling delay values so they can be reused when
> switching without much overhead.
>
> There is one more issue that is not yet covered by this series: Before
> spinand_id_detect() we don't know yet what RX sampling delay value the
> chip requires, but we already use read-status and read-id operations at
> maximum chip clock.

Not exactly "maximum chip clock" as in Santhosh's work, but indeed we
run these at the frequency given in the DT as bein the maximum
frequency. If that's not correct, you must lower it in the DT. That is
why I am in favour of having two maximum frequencies: the standard one,
that just works, which is the one for non optimized settings (the one we
actually use today) and another one, when tuning the bus timings.

> For example on Winbond W25N04KV this leads to detection failures. So we
> should maybe introduce some kind of reduced clock setpoint for the
> initial detection, that is safe to be used without RX sampling delay
> compensation.

That should be the DT max frequency, no?

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-31  9:23         ` Miquel Raynal
  0 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-31  9:23 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx

Hi Frieder,

> The sampling point delay is coupled to the clock frequency. So if the
> clock changes per-op, we also need to change the sampling delay per-op.
>
> In general, if we want to avoid switching the parameters back and forth
> in cases of alternating ops with different max frequencies, we should
> maybe do some "min of the max" calculation and use the resulting
> frequency for all ops.
>
> Is that what you mean?

Not exactly, I am not afraid by the time it would take to switch, I am
afraid by the likelihood that both the PHY tuning series and your series
might want to force a different maximum frequency. For instance with TI
designs, when entering PHY mode, the frequency is 166MHz, period. You
cannot lower it because by design, you bypass the SPI divisors.

> We could even set a threshold to decide between using a common "min of
> the max" frequency or do the switching per-op.
>
> One other possibility would be to somehow cache the per-op frequencies
> and calculated sampling delay values so they can be reused when
> switching without much overhead.
>
> There is one more issue that is not yet covered by this series: Before
> spinand_id_detect() we don't know yet what RX sampling delay value the
> chip requires, but we already use read-status and read-id operations at
> maximum chip clock.

Not exactly "maximum chip clock" as in Santhosh's work, but indeed we
run these at the frequency given in the DT as bein the maximum
frequency. If that's not correct, you must lower it in the DT. That is
why I am in favour of having two maximum frequencies: the standard one,
that just works, which is the one for non optimized settings (the one we
actually use today) and another one, when tuning the bus timings.

> For example on Winbond W25N04KV this leads to detection failures. So we
> should maybe introduce some kind of reduced clock setpoint for the
> initial detection, that is safe to be used without RX sampling delay
> compensation.

That should be the DT max frequency, no?

Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-31  9:23         ` Miquel Raynal
@ 2026-03-31  9:58           ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-31  9:58 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K

Hi Miquèl,

On 31.03.26 11:23, Miquel Raynal wrote:
> Hi Frieder,
> 
>> The sampling point delay is coupled to the clock frequency. So if the
>> clock changes per-op, we also need to change the sampling delay per-op.
>>
>> In general, if we want to avoid switching the parameters back and forth
>> in cases of alternating ops with different max frequencies, we should
>> maybe do some "min of the max" calculation and use the resulting
>> frequency for all ops.
>>
>> Is that what you mean?
> 
> Not exactly, I am not afraid by the time it would take to switch, I am
> afraid by the likelihood that both the PHY tuning series and your series
> might want to force a different maximum frequency. For instance with TI
> designs, when entering PHY mode, the frequency is 166MHz, period. You
> cannot lower it because by design, you bypass the SPI divisors.

Ah, ok. I didn't know the PHY mode bypasses the usual clock setup.

> 
>> We could even set a threshold to decide between using a common "min of
>> the max" frequency or do the switching per-op.
>>
>> One other possibility would be to somehow cache the per-op frequencies
>> and calculated sampling delay values so they can be reused when
>> switching without much overhead.
>>
>> There is one more issue that is not yet covered by this series: Before
>> spinand_id_detect() we don't know yet what RX sampling delay value the
>> chip requires, but we already use read-status and read-id operations at
>> maximum chip clock.
> 
> Not exactly "maximum chip clock" as in Santhosh's work, but indeed we
> run these at the frequency given in the DT as bein the maximum
> frequency. If that's not correct, you must lower it in the DT. That is
> why I am in favour of having two maximum frequencies: the standard one,
> that just works, which is the one for non optimized settings (the one we
> actually use today) and another one, when tuning the bus timings.
> 
>> For example on Winbond W25N04KV this leads to detection failures. So we
>> should maybe introduce some kind of reduced clock setpoint for the
>> initial detection, that is safe to be used without RX sampling delay
>> compensation.
> 
> That should be the DT max frequency, no?

Hm, I've seen it the other way round. In my perspective the DT max
frequency describes the maximum clock frequency supported by the chip as
given in the datasheet (assuming there are no other limitations
introduced by board design, etc.).

The RX sampling delay is a timing parameter specified in the datasheet
and it is relevant in order to interface the chip at maximum frequency
within spec.

Your approach would mean, that we need to manually calculate the maximum
supported clock frequency without RX sampling delay compensation and use
this value in the DT. Then let the driver increase the clock if RX
sampling delay compensation is available.

This would have the advantage, that even before initial detection we
would use the correct clock by default. But it has the downside that the
clock value in DT won't match the datasheet value.

In my approach we assume the driver is able to use the maximum clock
from the DT (same as in datasheet) by using RX sampling delay
compensation and only if it turns out the compensation is not possible
we will lower the clock dynamically.

What if we do the following?

1. Add a parameter in the SPI NAND chip driver that contains the maximum
supported clock frequency as given in the datasheet as this is clearly
the best place to keep this device-specific parameter.

2. Allow to leave spi-max-frequency in DT unset for SPI NANDs in case
there are no board-specific limitations and therefore the maximum
frequency supported by the combination of chip and controller can be used.

3. By default limit the clock frequency for the READ_ID op to a safe
value that works for all chips and controllers, even if RX sampling
delay compensations is not available.

4. In PHY mode, check against the DT max frequency (board limitations)
and chip max frequency before switching to this mode.

I hope this makes at least a bit of sense. I'm really not yet familiar
with all the different use-cases and limitations.

Best regards
Frieder

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-31  9:58           ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-31  9:58 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K

Hi Miquèl,

On 31.03.26 11:23, Miquel Raynal wrote:
> Hi Frieder,
> 
>> The sampling point delay is coupled to the clock frequency. So if the
>> clock changes per-op, we also need to change the sampling delay per-op.
>>
>> In general, if we want to avoid switching the parameters back and forth
>> in cases of alternating ops with different max frequencies, we should
>> maybe do some "min of the max" calculation and use the resulting
>> frequency for all ops.
>>
>> Is that what you mean?
> 
> Not exactly, I am not afraid by the time it would take to switch, I am
> afraid by the likelihood that both the PHY tuning series and your series
> might want to force a different maximum frequency. For instance with TI
> designs, when entering PHY mode, the frequency is 166MHz, period. You
> cannot lower it because by design, you bypass the SPI divisors.

Ah, ok. I didn't know the PHY mode bypasses the usual clock setup.

> 
>> We could even set a threshold to decide between using a common "min of
>> the max" frequency or do the switching per-op.
>>
>> One other possibility would be to somehow cache the per-op frequencies
>> and calculated sampling delay values so they can be reused when
>> switching without much overhead.
>>
>> There is one more issue that is not yet covered by this series: Before
>> spinand_id_detect() we don't know yet what RX sampling delay value the
>> chip requires, but we already use read-status and read-id operations at
>> maximum chip clock.
> 
> Not exactly "maximum chip clock" as in Santhosh's work, but indeed we
> run these at the frequency given in the DT as bein the maximum
> frequency. If that's not correct, you must lower it in the DT. That is
> why I am in favour of having two maximum frequencies: the standard one,
> that just works, which is the one for non optimized settings (the one we
> actually use today) and another one, when tuning the bus timings.
> 
>> For example on Winbond W25N04KV this leads to detection failures. So we
>> should maybe introduce some kind of reduced clock setpoint for the
>> initial detection, that is safe to be used without RX sampling delay
>> compensation.
> 
> That should be the DT max frequency, no?

Hm, I've seen it the other way round. In my perspective the DT max
frequency describes the maximum clock frequency supported by the chip as
given in the datasheet (assuming there are no other limitations
introduced by board design, etc.).

The RX sampling delay is a timing parameter specified in the datasheet
and it is relevant in order to interface the chip at maximum frequency
within spec.

Your approach would mean, that we need to manually calculate the maximum
supported clock frequency without RX sampling delay compensation and use
this value in the DT. Then let the driver increase the clock if RX
sampling delay compensation is available.

This would have the advantage, that even before initial detection we
would use the correct clock by default. But it has the downside that the
clock value in DT won't match the datasheet value.

In my approach we assume the driver is able to use the maximum clock
from the DT (same as in datasheet) by using RX sampling delay
compensation and only if it turns out the compensation is not possible
we will lower the clock dynamically.

What if we do the following?

1. Add a parameter in the SPI NAND chip driver that contains the maximum
supported clock frequency as given in the datasheet as this is clearly
the best place to keep this device-specific parameter.

2. Allow to leave spi-max-frequency in DT unset for SPI NANDs in case
there are no board-specific limitations and therefore the maximum
frequency supported by the combination of chip and controller can be used.

3. By default limit the clock frequency for the READ_ID op to a safe
value that works for all chips and controllers, even if RX sampling
delay compensations is not available.

4. In PHY mode, check against the DT max frequency (board limitations)
and chip max frequency before switching to this mode.

I hope this makes at least a bit of sense. I'm really not yet familiar
with all the different use-cases and limitations.

Best regards
Frieder

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-31  9:58           ` Frieder Schrempf
@ 2026-03-31 15:26             ` Miquel Raynal
  -1 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-31 15:26 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K

Hello,

>>> For example on Winbond W25N04KV this leads to detection failures. So we
>>> should maybe introduce some kind of reduced clock setpoint for the
>>> initial detection, that is safe to be used without RX sampling delay
>>> compensation.
>> 
>> That should be the DT max frequency, no?
>
> Hm, I've seen it the other way round. In my perspective the DT max
> frequency describes the maximum clock frequency supported by the chip as
> given in the datasheet (assuming there are no other limitations
> introduced by board design, etc.).

I believe that what is in the datasheet should instead be statically
described in the SPI NAND vendor file.

The max SPI frequency DT property is here to tell at which speed to use
the device, and this depends mostly on the routing.

> The RX sampling delay is a timing parameter specified in the datasheet
> and it is relevant in order to interface the chip at maximum frequency
> within spec.

If it's not design dependent, then we should handle it "statically".

> Your approach would mean, that we need to manually calculate the maximum
> supported clock frequency without RX sampling delay compensation and use
> this value in the DT. Then let the driver increase the clock if RX
> sampling delay compensation is available.
>
> This would have the advantage, that even before initial detection we
> would use the correct clock by default. But it has the downside that the
> clock value in DT won't match the datasheet value.

It never does. Winbond chips can run at 166MHz. I know no design capable
of that natively (ie. without finer tuning, like what Santhosh
proposes).

> In my approach we assume the driver is able to use the maximum clock
> from the DT (same as in datasheet) by using RX sampling delay
> compensation and only if it turns out the compensation is not possible
> we will lower the clock dynamically.
>
> What if we do the following?
>
> 1. Add a parameter in the SPI NAND chip driver that contains the maximum
> supported clock frequency as given in the datasheet as this is clearly
> the best place to keep this device-specific parameter.

I've so far avoided doing it, but yes, this is something we can do. It
is going to be simple enough to implement as all the infrastructure is
already there. You can provide variants with speed limitations (look
into winbond.c). I was writing "0" in the fields which didn't need a
limitation that is something else than the maximum speed the chip can
sustain, as anyway the DT property *will* tell us what is this speed, if
we are ever able to reach it.

> 2. Allow to leave spi-max-frequency in DT unset for SPI NANDs in case
> there are no board-specific limitations and therefore the maximum
> frequency supported by the combination of chip and controller can be
> used.

In many cases, the limitations are board specific. Anyway, this is
already the case, you may just not put any value in this property.

> 3. By default limit the clock frequency for the READ_ID op to a safe
> value that works for all chips and controllers, even if RX sampling
> delay compensations is not available.

I am sorry this is not going to work out. There is no such harmonized
speed, differences can be an order (or two) of magnitude different, we
do not want to pay the penalty of a very slow identification on all
designs. We currently do the read several times with different
parameters. What if we were trying one more time by cutting the speed by
2 (completely random proposal)?

> 4. In PHY mode, check against the DT max frequency (board limitations)
> and chip max frequency before switching to this mode.

There is not such thing :-) the max frequency in DT currently would be
set to the platform limitation. We need somehow another parameter
indicating what is the maximum speed if we can fine tune the timings.

> I hope this makes at least a bit of sense. I'm really not yet familiar
> with all the different use-cases and limitations.

If I get back to your own issue. Is there any chance we could avoid
tweaking the DT for handling it? Would there be a configuration of your
controller that would allow reading the ID of all the chips with enough
delays? Currently, the spi core doesn't care much about other parameters
than the frequency, but there is perhaps room for improvement.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-31 15:26             ` Miquel Raynal
  0 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-03-31 15:26 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K

Hello,

>>> For example on Winbond W25N04KV this leads to detection failures. So we
>>> should maybe introduce some kind of reduced clock setpoint for the
>>> initial detection, that is safe to be used without RX sampling delay
>>> compensation.
>> 
>> That should be the DT max frequency, no?
>
> Hm, I've seen it the other way round. In my perspective the DT max
> frequency describes the maximum clock frequency supported by the chip as
> given in the datasheet (assuming there are no other limitations
> introduced by board design, etc.).

I believe that what is in the datasheet should instead be statically
described in the SPI NAND vendor file.

The max SPI frequency DT property is here to tell at which speed to use
the device, and this depends mostly on the routing.

> The RX sampling delay is a timing parameter specified in the datasheet
> and it is relevant in order to interface the chip at maximum frequency
> within spec.

If it's not design dependent, then we should handle it "statically".

> Your approach would mean, that we need to manually calculate the maximum
> supported clock frequency without RX sampling delay compensation and use
> this value in the DT. Then let the driver increase the clock if RX
> sampling delay compensation is available.
>
> This would have the advantage, that even before initial detection we
> would use the correct clock by default. But it has the downside that the
> clock value in DT won't match the datasheet value.

It never does. Winbond chips can run at 166MHz. I know no design capable
of that natively (ie. without finer tuning, like what Santhosh
proposes).

> In my approach we assume the driver is able to use the maximum clock
> from the DT (same as in datasheet) by using RX sampling delay
> compensation and only if it turns out the compensation is not possible
> we will lower the clock dynamically.
>
> What if we do the following?
>
> 1. Add a parameter in the SPI NAND chip driver that contains the maximum
> supported clock frequency as given in the datasheet as this is clearly
> the best place to keep this device-specific parameter.

I've so far avoided doing it, but yes, this is something we can do. It
is going to be simple enough to implement as all the infrastructure is
already there. You can provide variants with speed limitations (look
into winbond.c). I was writing "0" in the fields which didn't need a
limitation that is something else than the maximum speed the chip can
sustain, as anyway the DT property *will* tell us what is this speed, if
we are ever able to reach it.

> 2. Allow to leave spi-max-frequency in DT unset for SPI NANDs in case
> there are no board-specific limitations and therefore the maximum
> frequency supported by the combination of chip and controller can be
> used.

In many cases, the limitations are board specific. Anyway, this is
already the case, you may just not put any value in this property.

> 3. By default limit the clock frequency for the READ_ID op to a safe
> value that works for all chips and controllers, even if RX sampling
> delay compensations is not available.

I am sorry this is not going to work out. There is no such harmonized
speed, differences can be an order (or two) of magnitude different, we
do not want to pay the penalty of a very slow identification on all
designs. We currently do the read several times with different
parameters. What if we were trying one more time by cutting the speed by
2 (completely random proposal)?

> 4. In PHY mode, check against the DT max frequency (board limitations)
> and chip max frequency before switching to this mode.

There is not such thing :-) the max frequency in DT currently would be
set to the platform limitation. We need somehow another parameter
indicating what is the maximum speed if we can fine tune the timings.

> I hope this makes at least a bit of sense. I'm really not yet familiar
> with all the different use-cases and limitations.

If I get back to your own issue. Is there any chance we could avoid
tweaking the DT for handling it? Would there be a configuration of your
controller that would allow reading the ID of all the chips with enough
delays? Currently, the spi core doesn't care much about other parameters
than the frequency, but there is perhaps room for improvement.

Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-31 15:26             ` Miquel Raynal
@ 2026-03-31 17:57               ` Frieder Schrempf
  -1 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-31 17:57 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K


On 31.03.26 17:26, Miquel Raynal wrote:
> Hello,
> 
>>>> For example on Winbond W25N04KV this leads to detection failures. So we
>>>> should maybe introduce some kind of reduced clock setpoint for the
>>>> initial detection, that is safe to be used without RX sampling delay
>>>> compensation.
>>>
>>> That should be the DT max frequency, no?
>>
>> Hm, I've seen it the other way round. In my perspective the DT max
>> frequency describes the maximum clock frequency supported by the chip as
>> given in the datasheet (assuming there are no other limitations
>> introduced by board design, etc.).
> 
> I believe that what is in the datasheet should instead be statically
> described in the SPI NAND vendor file.
> 
> The max SPI frequency DT property is here to tell at which speed to use
> the device, and this depends mostly on the routing.

Ok, agree.

> 
>> The RX sampling delay is a timing parameter specified in the datasheet
>> and it is relevant in order to interface the chip at maximum frequency
>> within spec.
> 
> If it's not design dependent, then we should handle it "statically".

The RX delay introduced by the chip is not design-dependent, only
chip-dependent. There might be additional delays introduced by the board
layout, but that's out of scope currently and I don't know if we even
need this.

> 
>> Your approach would mean, that we need to manually calculate the maximum
>> supported clock frequency without RX sampling delay compensation and use
>> this value in the DT. Then let the driver increase the clock if RX
>> sampling delay compensation is available.
>>
>> This would have the advantage, that even before initial detection we
>> would use the correct clock by default. But it has the downside that the
>> clock value in DT won't match the datasheet value.
> 
> It never does. Winbond chips can run at 166MHz. I know no design capable
> of that natively (ie. without finer tuning, like what Santhosh
> proposes).

Ok, right.

> 
>> In my approach we assume the driver is able to use the maximum clock
>> from the DT (same as in datasheet) by using RX sampling delay
>> compensation and only if it turns out the compensation is not possible
>> we will lower the clock dynamically.
>>
>> What if we do the following?
>>
>> 1. Add a parameter in the SPI NAND chip driver that contains the maximum
>> supported clock frequency as given in the datasheet as this is clearly
>> the best place to keep this device-specific parameter.
> 
> I've so far avoided doing it, but yes, this is something we can do. It
> is going to be simple enough to implement as all the infrastructure is
> already there. You can provide variants with speed limitations (look
> into winbond.c). I was writing "0" in the fields which didn't need a
> limitation that is something else than the maximum speed the chip can
> sustain, as anyway the DT property *will* tell us what is this speed, if
> we are ever able to reach it.

Ok.

> 
>> 2. Allow to leave spi-max-frequency in DT unset for SPI NANDs in case
>> there are no board-specific limitations and therefore the maximum
>> frequency supported by the combination of chip and controller can be
>> used.
> 
> In many cases, the limitations are board specific. Anyway, this is
> already the case, you may just not put any value in this property.

Ok.

> 
>> 3. By default limit the clock frequency for the READ_ID op to a safe
>> value that works for all chips and controllers, even if RX sampling
>> delay compensations is not available.
> 
> I am sorry this is not going to work out. There is no such harmonized
> speed, differences can be an order (or two) of magnitude different, we
> do not want to pay the penalty of a very slow identification on all
> designs. We currently do the read several times with different
> parameters. What if we were trying one more time by cutting the speed by
> 2 (completely random proposal)?

If we try with reduced clock as a fallback after the other attempts,
there would be a slight chance of one of the earlier attempts with
normal clock rate returning some invalid data that matches an existing
chip ID, no? Isn't this a bit flaky?

Let's say for a worst case scenario a chip has an RX delay of 20ns (the
highest I've seen in datasheets so far is 8ns). In that case the maximum
clock we could safely use for reading the ID would be 1/(2*20e-9) =
25MHz. Do you think it really makes much of a difference if we read the
ID (only a handful of bytes) at 25MHz or full speed (e. g. 104 MHz)? I
mean this should be fast enough either way, no? But maybe I'm misjudging
this.

> 
>> 4. In PHY mode, check against the DT max frequency (board limitations)
>> and chip max frequency before switching to this mode.
> 
> There is not such thing :-) the max frequency in DT currently would be
> set to the platform limitation. We need somehow another parameter
> indicating what is the maximum speed if we can fine tune the timings.

So we can exceed the platform limitations using fine-tuned timings? I
guess I need to read and understand that tuning RFC series.

> 
>> I hope this makes at least a bit of sense. I'm really not yet familiar
>> with all the different use-cases and limitations.
> 
> If I get back to your own issue. Is there any chance we could avoid
> tweaking the DT for handling it? Would there be a configuration of your
> controller that would allow reading the ID of all the chips with enough
> delays? Currently, the spi core doesn't care much about other parameters
> than the frequency, but there is perhaps room for improvement.

We could use RX delay compensation (one half clock cycle) in the
controller by default (as currently done by the STM32 driver). But that
would break if we use a very low clock (for whatever reason) because
then the RX sampling delay gets neglectable compared to the clock period
and sampling is triggered at the very end of the clock cycle when the
data might already be invalid. At least that's what I suspect based on
my test results.
And it would also break if the chip actually requires more than one half
clock cycle of RX sampling delay.

The RX sampling delay setting must match the used clock frequency. In
most cases there is a lot of room for tolerance before things start to
fail, but it's not endless and especially at very high clock rates we
need to take it into account.

So if we don't cap the speed for reading the ID by default, we somehow
need to know what value to use for the RX sampling delay or we need to
try different values. And if the controller does not support or
implement the RX sampling delay compensation, we need to cap the speed
anyway.


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-31 17:57               ` Frieder Schrempf
  0 siblings, 0 replies; 65+ messages in thread
From: Frieder Schrempf @ 2026-03-31 17:57 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K


On 31.03.26 17:26, Miquel Raynal wrote:
> Hello,
> 
>>>> For example on Winbond W25N04KV this leads to detection failures. So we
>>>> should maybe introduce some kind of reduced clock setpoint for the
>>>> initial detection, that is safe to be used without RX sampling delay
>>>> compensation.
>>>
>>> That should be the DT max frequency, no?
>>
>> Hm, I've seen it the other way round. In my perspective the DT max
>> frequency describes the maximum clock frequency supported by the chip as
>> given in the datasheet (assuming there are no other limitations
>> introduced by board design, etc.).
> 
> I believe that what is in the datasheet should instead be statically
> described in the SPI NAND vendor file.
> 
> The max SPI frequency DT property is here to tell at which speed to use
> the device, and this depends mostly on the routing.

Ok, agree.

> 
>> The RX sampling delay is a timing parameter specified in the datasheet
>> and it is relevant in order to interface the chip at maximum frequency
>> within spec.
> 
> If it's not design dependent, then we should handle it "statically".

The RX delay introduced by the chip is not design-dependent, only
chip-dependent. There might be additional delays introduced by the board
layout, but that's out of scope currently and I don't know if we even
need this.

> 
>> Your approach would mean, that we need to manually calculate the maximum
>> supported clock frequency without RX sampling delay compensation and use
>> this value in the DT. Then let the driver increase the clock if RX
>> sampling delay compensation is available.
>>
>> This would have the advantage, that even before initial detection we
>> would use the correct clock by default. But it has the downside that the
>> clock value in DT won't match the datasheet value.
> 
> It never does. Winbond chips can run at 166MHz. I know no design capable
> of that natively (ie. without finer tuning, like what Santhosh
> proposes).

Ok, right.

> 
>> In my approach we assume the driver is able to use the maximum clock
>> from the DT (same as in datasheet) by using RX sampling delay
>> compensation and only if it turns out the compensation is not possible
>> we will lower the clock dynamically.
>>
>> What if we do the following?
>>
>> 1. Add a parameter in the SPI NAND chip driver that contains the maximum
>> supported clock frequency as given in the datasheet as this is clearly
>> the best place to keep this device-specific parameter.
> 
> I've so far avoided doing it, but yes, this is something we can do. It
> is going to be simple enough to implement as all the infrastructure is
> already there. You can provide variants with speed limitations (look
> into winbond.c). I was writing "0" in the fields which didn't need a
> limitation that is something else than the maximum speed the chip can
> sustain, as anyway the DT property *will* tell us what is this speed, if
> we are ever able to reach it.

Ok.

> 
>> 2. Allow to leave spi-max-frequency in DT unset for SPI NANDs in case
>> there are no board-specific limitations and therefore the maximum
>> frequency supported by the combination of chip and controller can be
>> used.
> 
> In many cases, the limitations are board specific. Anyway, this is
> already the case, you may just not put any value in this property.

Ok.

> 
>> 3. By default limit the clock frequency for the READ_ID op to a safe
>> value that works for all chips and controllers, even if RX sampling
>> delay compensations is not available.
> 
> I am sorry this is not going to work out. There is no such harmonized
> speed, differences can be an order (or two) of magnitude different, we
> do not want to pay the penalty of a very slow identification on all
> designs. We currently do the read several times with different
> parameters. What if we were trying one more time by cutting the speed by
> 2 (completely random proposal)?

If we try with reduced clock as a fallback after the other attempts,
there would be a slight chance of one of the earlier attempts with
normal clock rate returning some invalid data that matches an existing
chip ID, no? Isn't this a bit flaky?

Let's say for a worst case scenario a chip has an RX delay of 20ns (the
highest I've seen in datasheets so far is 8ns). In that case the maximum
clock we could safely use for reading the ID would be 1/(2*20e-9) =
25MHz. Do you think it really makes much of a difference if we read the
ID (only a handful of bytes) at 25MHz or full speed (e. g. 104 MHz)? I
mean this should be fast enough either way, no? But maybe I'm misjudging
this.

> 
>> 4. In PHY mode, check against the DT max frequency (board limitations)
>> and chip max frequency before switching to this mode.
> 
> There is not such thing :-) the max frequency in DT currently would be
> set to the platform limitation. We need somehow another parameter
> indicating what is the maximum speed if we can fine tune the timings.

So we can exceed the platform limitations using fine-tuned timings? I
guess I need to read and understand that tuning RFC series.

> 
>> I hope this makes at least a bit of sense. I'm really not yet familiar
>> with all the different use-cases and limitations.
> 
> If I get back to your own issue. Is there any chance we could avoid
> tweaking the DT for handling it? Would there be a configuration of your
> controller that would allow reading the ID of all the chips with enough
> delays? Currently, the spi core doesn't care much about other parameters
> than the frequency, but there is perhaps room for improvement.

We could use RX delay compensation (one half clock cycle) in the
controller by default (as currently done by the STM32 driver). But that
would break if we use a very low clock (for whatever reason) because
then the RX sampling delay gets neglectable compared to the clock period
and sampling is triggered at the very end of the clock cycle when the
data might already be invalid. At least that's what I suspect based on
my test results.
And it would also break if the chip actually requires more than one half
clock cycle of RX sampling delay.

The RX sampling delay setting must match the used clock frequency. In
most cases there is a lot of room for tolerance before things start to
fail, but it's not endless and especially at very high clock rates we
need to take it into account.

So if we don't cap the speed for reading the ID by default, we somehow
need to know what value to use for the RX sampling delay or we need to
try different values. And if the controller does not support or
implement the RX sampling delay compensation, we need to cap the speed
anyway.


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-31 17:57               ` Frieder Schrempf
@ 2026-03-31 18:20                 ` Mark Brown
  -1 siblings, 0 replies; 65+ messages in thread
From: Mark Brown @ 2026-03-31 18:20 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Miquel Raynal, Frieder Schrempf, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K

[-- Attachment #1: Type: text/plain, Size: 868 bytes --]

On Tue, Mar 31, 2026 at 07:57:21PM +0200, Frieder Schrempf wrote:
> On 31.03.26 17:26, Miquel Raynal wrote:

> > I am sorry this is not going to work out. There is no such harmonized
> > speed, differences can be an order (or two) of magnitude different, we
> > do not want to pay the penalty of a very slow identification on all
> > designs. We currently do the read several times with different
> > parameters. What if we were trying one more time by cutting the speed by
> > 2 (completely random proposal)?

> If we try with reduced clock as a fallback after the other attempts,
> there would be a slight chance of one of the earlier attempts with
> normal clock rate returning some invalid data that matches an existing
> chip ID, no? Isn't this a bit flaky?

I'd worry about single bit errors causing confusion between related
parts from a single manufacturer...

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-03-31 18:20                 ` Mark Brown
  0 siblings, 0 replies; 65+ messages in thread
From: Mark Brown @ 2026-03-31 18:20 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Miquel Raynal, Frieder Schrempf, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K


[-- Attachment #1.1: Type: text/plain, Size: 868 bytes --]

On Tue, Mar 31, 2026 at 07:57:21PM +0200, Frieder Schrempf wrote:
> On 31.03.26 17:26, Miquel Raynal wrote:

> > I am sorry this is not going to work out. There is no such harmonized
> > speed, differences can be an order (or two) of magnitude different, we
> > do not want to pay the penalty of a very slow identification on all
> > designs. We currently do the read several times with different
> > parameters. What if we were trying one more time by cutting the speed by
> > 2 (completely random proposal)?

> If we try with reduced clock as a fallback after the other attempts,
> there would be a slight chance of one of the earlier attempts with
> normal clock rate returning some invalid data that matches an existing
> chip ID, no? Isn't this a bit flaky?

I'd worry about single bit errors causing confusion between related
parts from a single manufacturer...

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 144 bytes --]

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-03-31 17:57               ` Frieder Schrempf
@ 2026-04-01  8:32                 ` Miquel Raynal
  -1 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-04-01  8:32 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K

Hi Frieder,

> The RX delay introduced by the chip is not design-dependent, only
> chip-dependent. There might be additional delays introduced by the board
> layout, but that's out of scope currently and I don't know if we even
> need this.

We do, for very high speeds, and this is the purpose of the PHY tuning
series from Santhosh.

[...]

>>> 3. By default limit the clock frequency for the READ_ID op to a safe
>>> value that works for all chips and controllers, even if RX sampling
>>> delay compensations is not available.
>> 
>> I am sorry this is not going to work out. There is no such harmonized
>> speed, differences can be an order (or two) of magnitude different, we
>> do not want to pay the penalty of a very slow identification on all
>> designs. We currently do the read several times with different
>> parameters. What if we were trying one more time by cutting the speed by
>> 2 (completely random proposal)?
>
> If we try with reduced clock as a fallback after the other attempts,
> there would be a slight chance of one of the earlier attempts with
> normal clock rate returning some invalid data that matches an existing
> chip ID, no? Isn't this a bit flaky?

Yeah, I understand your (and Mark's) concern.

> Let's say for a worst case scenario a chip has an RX delay of 20ns (the
> highest I've seen in datasheets so far is 8ns). In that case the maximum
> clock we could safely use for reading the ID would be 1/(2*20e-9) =
> 25MHz. Do you think it really makes much of a difference if we read the
> ID (only a handful of bytes) at 25MHz or full speed (e. g. 104 MHz)? I
> mean this should be fast enough either way, no? But maybe I'm misjudging
> this.

I am honestly not a big fan of the global penalty, but I am not totally
opposed either, especially since you just said you only observed 8ns
delays at most. This is 62.5MHz, which is already above what most
designs use, so the penalty would be minimal. What about taking this
approach and see if that fixes most of our use cases?

>>> 4. In PHY mode, check against the DT max frequency (board limitations)
>>> and chip max frequency before switching to this mode.
>> 
>> There is not such thing :-) the max frequency in DT currently would be
>> set to the platform limitation. We need somehow another parameter
>> indicating what is the maximum speed if we can fine tune the timings.
>
> So we can exceed the platform limitations using fine-tuned timings? I
> guess I need to read and understand that tuning RFC series.

Well, this is still under discussion. As of today, the max speed in DT
is the maximum speed. But it is in most cases the maximum speed
*without* tuning, which means if we tune the PHY delays we can increase
the speed further. I already proposed to turn this DT property into an
array, in order to indicate what are the maximum speed*s*, without and
with tuning, if ever possible.

>>> I hope this makes at least a bit of sense. I'm really not yet familiar
>>> with all the different use-cases and limitations.
>> 
>> If I get back to your own issue. Is there any chance we could avoid
>> tweaking the DT for handling it? Would there be a configuration of your
>> controller that would allow reading the ID of all the chips with enough
>> delays? Currently, the spi core doesn't care much about other parameters
>> than the frequency, but there is perhaps room for improvement.
>
> We could use RX delay compensation (one half clock cycle) in the
> controller by default (as currently done by the STM32 driver). But that
> would break if we use a very low clock (for whatever reason) because
> then the RX sampling delay gets neglectable compared to the clock period
> and sampling is triggered at the very end of the clock cycle when the
> data might already be invalid. At least that's what I suspect based on
> my test results.
> And it would also break if the chip actually requires more than one half
> clock cycle of RX sampling delay.
>
> The RX sampling delay setting must match the used clock frequency. In
> most cases there is a lot of room for tolerance before things start to
> fail, but it's not endless and especially at very high clock rates we
> need to take it into account.
>
> So if we don't cap the speed for reading the ID by default, we somehow
> need to know what value to use for the RX sampling delay or we need to
> try different values. And if the controller does not support or
> implement the RX sampling delay compensation, we need to cap the speed
> anyway.

What about:

*SPI controller drivers*
- Enable RX delay compensation in the controller by default, disable it
if the speed is very low, ie. compensation is dangerous
*Core*
- READID at max 65MHz (with the default RX delay compensation)
*Vendor driver*
- Indicate the internal RX delay per chip (maybe we need some heuristics
depending on the speed as well?)
*SPI controller drivers*
- Hook to tune RX based on the fastest reachable speed.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-04-01  8:32                 ` Miquel Raynal
  0 siblings, 0 replies; 65+ messages in thread
From: Miquel Raynal @ 2026-04-01  8:32 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, Michael Walle, linux-spi, linux-kernel, linux-mtd,
	imx, Santhosh Kumar K

Hi Frieder,

> The RX delay introduced by the chip is not design-dependent, only
> chip-dependent. There might be additional delays introduced by the board
> layout, but that's out of scope currently and I don't know if we even
> need this.

We do, for very high speeds, and this is the purpose of the PHY tuning
series from Santhosh.

[...]

>>> 3. By default limit the clock frequency for the READ_ID op to a safe
>>> value that works for all chips and controllers, even if RX sampling
>>> delay compensations is not available.
>> 
>> I am sorry this is not going to work out. There is no such harmonized
>> speed, differences can be an order (or two) of magnitude different, we
>> do not want to pay the penalty of a very slow identification on all
>> designs. We currently do the read several times with different
>> parameters. What if we were trying one more time by cutting the speed by
>> 2 (completely random proposal)?
>
> If we try with reduced clock as a fallback after the other attempts,
> there would be a slight chance of one of the earlier attempts with
> normal clock rate returning some invalid data that matches an existing
> chip ID, no? Isn't this a bit flaky?

Yeah, I understand your (and Mark's) concern.

> Let's say for a worst case scenario a chip has an RX delay of 20ns (the
> highest I've seen in datasheets so far is 8ns). In that case the maximum
> clock we could safely use for reading the ID would be 1/(2*20e-9) =
> 25MHz. Do you think it really makes much of a difference if we read the
> ID (only a handful of bytes) at 25MHz or full speed (e. g. 104 MHz)? I
> mean this should be fast enough either way, no? But maybe I'm misjudging
> this.

I am honestly not a big fan of the global penalty, but I am not totally
opposed either, especially since you just said you only observed 8ns
delays at most. This is 62.5MHz, which is already above what most
designs use, so the penalty would be minimal. What about taking this
approach and see if that fixes most of our use cases?

>>> 4. In PHY mode, check against the DT max frequency (board limitations)
>>> and chip max frequency before switching to this mode.
>> 
>> There is not such thing :-) the max frequency in DT currently would be
>> set to the platform limitation. We need somehow another parameter
>> indicating what is the maximum speed if we can fine tune the timings.
>
> So we can exceed the platform limitations using fine-tuned timings? I
> guess I need to read and understand that tuning RFC series.

Well, this is still under discussion. As of today, the max speed in DT
is the maximum speed. But it is in most cases the maximum speed
*without* tuning, which means if we tune the PHY delays we can increase
the speed further. I already proposed to turn this DT property into an
array, in order to indicate what are the maximum speed*s*, without and
with tuning, if ever possible.

>>> I hope this makes at least a bit of sense. I'm really not yet familiar
>>> with all the different use-cases and limitations.
>> 
>> If I get back to your own issue. Is there any chance we could avoid
>> tweaking the DT for handling it? Would there be a configuration of your
>> controller that would allow reading the ID of all the chips with enough
>> delays? Currently, the spi core doesn't care much about other parameters
>> than the frequency, but there is perhaps room for improvement.
>
> We could use RX delay compensation (one half clock cycle) in the
> controller by default (as currently done by the STM32 driver). But that
> would break if we use a very low clock (for whatever reason) because
> then the RX sampling delay gets neglectable compared to the clock period
> and sampling is triggered at the very end of the clock cycle when the
> data might already be invalid. At least that's what I suspect based on
> my test results.
> And it would also break if the chip actually requires more than one half
> clock cycle of RX sampling delay.
>
> The RX sampling delay setting must match the used clock frequency. In
> most cases there is a lot of room for tolerance before things start to
> fail, but it's not endless and especially at very high clock rates we
> need to take it into account.
>
> So if we don't cap the speed for reading the ID by default, we somehow
> need to know what value to use for the RX sampling delay or we need to
> try different values. And if the controller does not support or
> implement the RX sampling delay compensation, we need to cap the speed
> anyway.

What about:

*SPI controller drivers*
- Enable RX delay compensation in the controller by default, disable it
if the speed is very low, ie. compensation is dangerous
*Core*
- READID at max 65MHz (with the default RX delay compensation)
*Vendor driver*
- Indicate the internal RX delay per chip (maybe we need some heuristics
depending on the speed as well?)
*SPI controller drivers*
- Hook to tune RX based on the fastest reachable speed.

Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
  2026-04-01  8:32                 ` Miquel Raynal
@ 2026-04-01 11:00                   ` Michael Walle
  -1 siblings, 0 replies; 65+ messages in thread
From: Michael Walle @ 2026-04-01 11:00 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, linux-spi, linux-kernel, linux-mtd, imx,
	Santhosh Kumar K

[-- Attachment #1: Type: text/plain, Size: 1159 bytes --]

On Wed Apr 1, 2026 at 10:32 AM CEST, Miquel Raynal wrote:
>> Let's say for a worst case scenario a chip has an RX delay of 20ns (the
>> highest I've seen in datasheets so far is 8ns). In that case the maximum
>> clock we could safely use for reading the ID would be 1/(2*20e-9) =
>> 25MHz. Do you think it really makes much of a difference if we read the
>> ID (only a handful of bytes) at 25MHz or full speed (e. g. 104 MHz)? I
>> mean this should be fast enough either way, no? But maybe I'm misjudging
>> this.
>
> I am honestly not a big fan of the global penalty, but I am not totally
> opposed either, especially since you just said you only observed 8ns
> delays at most. This is 62.5MHz, which is already above what most
> designs use, so the penalty would be minimal. What about taking this
> approach and see if that fixes most of our use cases?

What are the actual numbers we are talking about here? I mean, at
least for SPI NOR, we only read the ID *once*. And it takes about 56
bits (command + id length of 6). That is about 2us at 25MHz. I'd
guess the setup and the software handling takes far longer than
that.

-michael

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op
@ 2026-04-01 11:00                   ` Michael Walle
  0 siblings, 0 replies; 65+ messages in thread
From: Michael Walle @ 2026-04-01 11:00 UTC (permalink / raw)
  To: Miquel Raynal, Frieder Schrempf
  Cc: Frieder Schrempf, Mark Brown, Richard Weinberger,
	Vignesh Raghavendra, Han Xu, Eberhard Stoll, Tudor Ambarus,
	Pratyush Yadav, linux-spi, linux-kernel, linux-mtd, imx,
	Santhosh Kumar K


[-- Attachment #1.1: Type: text/plain, Size: 1159 bytes --]

On Wed Apr 1, 2026 at 10:32 AM CEST, Miquel Raynal wrote:
>> Let's say for a worst case scenario a chip has an RX delay of 20ns (the
>> highest I've seen in datasheets so far is 8ns). In that case the maximum
>> clock we could safely use for reading the ID would be 1/(2*20e-9) =
>> 25MHz. Do you think it really makes much of a difference if we read the
>> ID (only a handful of bytes) at 25MHz or full speed (e. g. 104 MHz)? I
>> mean this should be fast enough either way, no? But maybe I'm misjudging
>> this.
>
> I am honestly not a big fan of the global penalty, but I am not totally
> opposed either, especially since you just said you only observed 8ns
> delays at most. This is 62.5MHz, which is already above what most
> designs use, so the penalty would be minimal. What about taking this
> approach and see if that fixes most of our use cases?

What are the actual numbers we are talking about here? I mean, at
least for SPI NOR, we only read the ID *once*. And it takes about 56
bits (command + id length of 6). That is about 2us at 25MHz. I'd
guess the setup and the software handling takes far longer than
that.

-michael

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]

[-- Attachment #2: Type: text/plain, Size: 144 bytes --]

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2026-04-01 11:00 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-03 16:29 [PATCH RFC 0/7] Support for SPI RX Sampling Delay Compensation Frieder Schrempf
2026-03-03 16:29 ` Frieder Schrempf
2026-03-03 16:29 ` [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay Frieder Schrempf
2026-03-03 16:29   ` Frieder Schrempf
2026-03-03 21:01   ` Frank Li
2026-03-03 21:01     ` Frank Li
2026-03-05 22:14     ` Mark Brown
2026-03-05 22:14       ` Mark Brown
2026-03-05 22:34       ` [EXT] " Frank Li
2026-03-05 22:34         ` Frank Li
2026-03-03 16:29 ` [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting Frieder Schrempf
2026-03-03 16:29   ` Frieder Schrempf
2026-03-03 21:01   ` Frank Li
2026-03-03 21:01     ` Frank Li
2026-03-09 15:11   ` Miquel Raynal
2026-03-09 15:11     ` Miquel Raynal
2026-03-03 16:29 ` [PATCH RFC 3/7] mtd: spinand: winbond: Add RX sampling delay values Frieder Schrempf
2026-03-03 16:29   ` Frieder Schrempf
2026-03-03 21:01   ` Frank Li
2026-03-03 21:01     ` Frank Li
2026-03-03 16:29 ` [PATCH RFC 4/7] mtd: spinand: toshiba: " Frieder Schrempf
2026-03-03 16:29   ` Frieder Schrempf
2026-03-03 21:01   ` Frank Li
2026-03-03 21:01     ` Frank Li
2026-03-06  9:37   ` kernel test robot
2026-03-06 11:02   ` kernel test robot
2026-03-09 15:12   ` Miquel Raynal
2026-03-09 15:12     ` Miquel Raynal
2026-03-10 14:17     ` Frieder Schrempf
2026-03-10 14:17       ` Frieder Schrempf
2026-03-03 16:29 ` [PATCH RFC 5/7] spi: Add RX sampling point adjustment Frieder Schrempf
2026-03-03 16:29   ` Frieder Schrempf
2026-03-03 21:01   ` Frank Li
2026-03-03 21:01     ` Frank Li
2026-03-06  9:05   ` kernel test robot
2026-03-09 15:25   ` Miquel Raynal
2026-03-09 15:25     ` Miquel Raynal
2026-03-10 14:19     ` Frieder Schrempf
2026-03-10 14:19       ` Frieder Schrempf
2026-03-03 16:29 ` [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op Frieder Schrempf
2026-03-03 16:29   ` Frieder Schrempf
2026-03-03 21:01   ` Frank Li
2026-03-03 21:01     ` Frank Li
2026-03-09 15:09   ` Miquel Raynal
2026-03-09 15:09     ` Miquel Raynal
2026-03-10 14:16     ` Frieder Schrempf
2026-03-10 14:16       ` Frieder Schrempf
2026-03-31  9:23       ` Miquel Raynal
2026-03-31  9:23         ` Miquel Raynal
2026-03-31  9:58         ` Frieder Schrempf
2026-03-31  9:58           ` Frieder Schrempf
2026-03-31 15:26           ` Miquel Raynal
2026-03-31 15:26             ` Miquel Raynal
2026-03-31 17:57             ` Frieder Schrempf
2026-03-31 17:57               ` Frieder Schrempf
2026-03-31 18:20               ` Mark Brown
2026-03-31 18:20                 ` Mark Brown
2026-04-01  8:32               ` Miquel Raynal
2026-04-01  8:32                 ` Miquel Raynal
2026-04-01 11:00                 ` Michael Walle
2026-04-01 11:00                   ` Michael Walle
2026-03-03 16:29 ` [PATCH RFC 7/7] spi: spi-fsl-qspi: Add support for RX data sampling point adjustment Frieder Schrempf
2026-03-03 16:29   ` Frieder Schrempf
2026-03-03 21:01   ` Frank Li
2026-03-03 21:01     ` Frank Li

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.