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
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.
© 2016 - 2026 Red Hat, Inc.