[PATCH 10/13] mtd: spinand: winbond: Add continuous read support for W25N02LV

From: Miquel Raynal

Date: Fri Oct 30 2026 - 13:48:41 EST


LV chips have DDR support, otherwise they support the same variants as
the other chips.

$ nandcontreadtest /dev/mtd0
testing 10 blocks from 0 to 9 (10 good), seed 27
success: verified 1310720 bytes read in 756.306 ms (1692.44 KiB/s)

$ flash_speed /dev/mtd0 -C
1 page read speed is 1580 KiB/s
2 page read speed is 1580 KiB/s
3 page read speed is 1615 KiB/s
4 page read speed is 1641 KiB/s
5 page read speed is 1643 KiB/s
6 page read speed is 1643 KiB/s
7 page read speed is 1657 KiB/s
8 page read speed is 1662 KiB/s
9 page read speed is 1680 KiB/s
10 page read speed is 1666 KiB/s
11 page read speed is 1692 KiB/s
12 page read speed is 1690 KiB/s
13 page read speed is 1677 KiB/s
14 page read speed is 1696 KiB/s
15 page read speed is 1690 KiB/s
16 page read speed is 1684 KiB/s
32 page read speed is 1684 KiB/s
64 page read speed is 1706 KiB/s

Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx>
---
drivers/mtd/nand/spi/winbond.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 6d7732761785..933a85bb79b0 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -226,6 +226,17 @@ static SPINAND_OP_VARIANTS(w25nxxlv_read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0),
SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0));

+static SPINAND_OP_VARIANTS(w25nxxlv_cont_read_cache_variants,
+ WINBOND_CONT_READ_FROM_CACHE_1S_4D_4D_OP(11, NULL, 0, 66 * HZ_PER_MHZ),
+ WINBOND_CONT_READ_FROM_CACHE_1S_1D_4D_OP(5, NULL, 0, 66 * HZ_PER_MHZ),
+ WINBOND_CONT_READ_FROM_CACHE_1S_4S_4S_OP(6, NULL, 0, 0),
+ WINBOND_CONT_READ_FROM_CACHE_1S_1S_4S_OP(4, NULL, 0, 0),
+ WINBOND_CONT_READ_FROM_CACHE_1S_2S_2S_OP(4, NULL, 0, 0),
+ WINBOND_CONT_READ_FROM_CACHE_1S_1S_2S_OP(4, NULL, 0, 0),
+ /* The 1S_1D_1D variant would require 4.5 dummy bytes, this is not possible */
+ WINBOND_CONT_READ_FROM_CACHE_FAST_1S_1S_1S_OP(4, NULL, 0, 0),
+ WINBOND_CONT_READ_FROM_CACHE_1S_1S_1S_OP(3, NULL, 0, 0));
+
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_1S_4S_4S_OP(0, 2, NULL, 0, 0),
SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0),
@@ -819,11 +830,13 @@ static const struct spinand_info winbond_spinand_table[] = {
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x8a, 0x22),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&w25nxxlv_read_cache_variants,
- &write_cache_variants,
- &update_cache_variants),
+ SPINAND_INFO_OP_VARIANTS_WITH_CONT(&w25nxxlv_read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants,
+ &w25nxxlv_cont_read_cache_variants),
0,
- SPINAND_ECCINFO(&w25nxxlv_lw_ooblayout, w25nxxkv_kw_lv_lw_ecc_get_status)),
+ SPINAND_ECCINFO(&w25nxxlv_lw_ooblayout, w25nxxkv_kw_lv_lw_ecc_get_status),
+ SPINAND_CONT_READ(w25n_set_cont_read)),
SPINAND_INFO("W25N02LW", /* 1.8V */
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12, 0x22),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),

--
2.56.0