[PATCH RFC] mtd: spinand: winbond: enable continuous read for W25N04LW

Dominique Martinet dominique.martinet at atmark-techno.com
Fri Aug 14 01:15:58 PDT 2026


This enables continuous read for W25N04LW:
- The ops are basically the same as cont_read_cache_dual_quad_dtr_variants
without the speed limit (this chip has no HFREQ flag that would change
the required delays) and without DTR ops (not supported)
- w25n0xjw_set_cont_read() can be reused

Unfortunately on my system (i.MX 8ULP LPSPI) the first time continuous
read is used spinand_read_from_cache_op() falls into this if and
disables continuous read, so this didn't go any further:
     /*
      * Dirmap accesses are allowed to toggle the CS.
      * Toggling the CS during a continuous read is forbidden.
      */
     if (nbytes && req->continuous) {
             /*
              * Spi controller with broken support of continuous
              * reading was detected. Disable future use of
              * continuous reading and return -EAGAIN to retry
              * reading within regular mode.
              */
             spinand->cont_read_possible = false;
             return -EAGAIN;
     }

I'm leaving this patch for anyone who could have hardware for this (or
eventually myself after I have time to check the SPI driver...)

Fun fact:
nanddump -C is about 9% faster than nanddump on large data (tried 10MB)
even if continuous read is not supported.

Signed-off-by: Dominique Martinet <dominique.martinet at atmark-techno.com>
---
 drivers/mtd/nand/spi/winbond.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 171f4c264220..ad735f73945b 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -203,6 +203,13 @@ static SPINAND_OP_VARIANTS(cont_read_cache_dual_quad_dtr_variants,
 		/* 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));
 
+static SPINAND_OP_VARIANTS(cont_read_cache_variants,
+		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),
+		WINBOND_CONT_READ_FROM_CACHE_FAST_1S_1S_1S_OP(4, 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),
@@ -780,11 +787,13 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb2, 0x23),
 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
 		     NAND_ECCREQ(8, 512),
-		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-					      &write_cache_variants,
-					      &update_cache_variants),
+		     SPINAND_INFO_OP_VARIANTS_WITH_CONT(&read_cache_variants,
+							&write_cache_variants,
+							&update_cache_variants,
+							&cont_read_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status),
+		     SPINAND_CONT_READ(w25n0xjw_set_cont_read)),
 	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),

---
base-commit: 0f1b5abff55b580facccc16324ede60b048bd23c
change-id: 20260814-w25n04lw-contread-03485e60c88e
prerequisite-change-id: 20260812-w25n04lw-3e9146d8340f:v3
prerequisite-patch-id: 3fbc1f74bfc7bbcd5dd7ecf62a7e5b0352cacbb2

Best regards,
--  
Dominique Martinet <dominique.martinet at atmark-techno.com>





More information about the linux-mtd mailing list