* [PATCH v3] mtd: spinand: dosilicon: Add support for additional models
@ 2026-05-27 10:00 Qing Wu
2026-05-27 12:29 ` Miquel Raynal
0 siblings, 1 reply; 2+ messages in thread
From: Qing Wu @ 2026-05-27 10:00 UTC (permalink / raw)
To: ses1er
Cc: Miquel Raynal, Michal Simek, Vignesh Raghavendra, linux-mtd,
linux-kernel
Add support for additional Dosilicon SPI NAND chips.
Datasheets for chips included in this patch: https://www.dosilicon.com/SPI%20NAND%20Flash.html
Tested on a TP-Link TL-7DR7250 with a Dosilicon DS35Q1GB (0xE5 0xF1)
Signed-off-by: Qing Wu <ses1er@gmail.com>
---
Changes in v3:
- Changed title
- Updated 2 bytes for BBM
- Link to v2: https://lore.kernel.org/all/20260520003733.82514-1-ses1er@gmail.com/
Changes in v2:
- Fixed compilation errors.
- Link to v1: https://lore.kernel.org/all/20260217211427.9120-1-ses1er@gmail.com
---
drivers/mtd/nand/spi/dosilicon.c | 218 ++++++++++++++++++++++++++++---
1 file changed, 203 insertions(+), 15 deletions(-)
diff --git a/drivers/mtd/nand/spi/dosilicon.c b/drivers/mtd/nand/spi/dosilicon.c
index f99899866ceb..fcd967c1bcbc 100644
--- a/drivers/mtd/nand/spi/dosilicon.c
+++ b/drivers/mtd/nand/spi/dosilicon.c
@@ -9,21 +9,27 @@
#define SPINAND_MFR_DOSILICON 0xE5
+#define DOSICON_STATUS_ECC_MASK GENMASK(6, 4)
+#define DOSICON_STATUS_ECC_NO_BITFLIPS (0 << 4)
+#define DOSICON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
+#define DOSICON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
+#define DOSICON_STATUS_ECC_7TO8_BITFLIPS (5 << 4)
+
static SPINAND_OP_VARIANTS(read_cache_variants,
- SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0),
- SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0),
- 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));
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
static SPINAND_OP_VARIANTS(write_cache_variants,
- SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0),
- SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0));
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
static SPINAND_OP_VARIANTS(update_cache_variants,
- SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0),
- SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0));
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
-static int ds35xx_ooblayout_ecc(struct mtd_info *mtd, int section,
+static int ds35xxga_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section > 3)
@@ -35,7 +41,7 @@ static int ds35xx_ooblayout_ecc(struct mtd_info *mtd, int section,
return 0;
}
-static int ds35xx_ooblayout_free(struct mtd_info *mtd, int section,
+static int ds35xxga_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section > 3)
@@ -53,11 +59,67 @@ static int ds35xx_ooblayout_free(struct mtd_info *mtd, int section,
return 0;
}
-static const struct mtd_ooblayout_ops ds35xx_ooblayout = {
- .ecc = ds35xx_ooblayout_ecc,
- .free = ds35xx_ooblayout_free,
+static const struct mtd_ooblayout_ops ds35xxga_ooblayout = {
+ .ecc = ds35xxga_ooblayout_ecc,
+ .free = ds35xxga_ooblayout_free,
};
+static int ds35xxgb_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ region->offset = 64;
+ region->length = 64;
+
+ return 0;
+}
+
+static int ds35xxgb_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ /* Reserve 2 bytes for the BBM. */
+ region->offset = 2;
+ region->length = 62;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops ds35xxgb_ooblayout = {
+ .ecc = ds35xxgb_ooblayout_ecc,
+ .free = ds35xxgb_ooblayout_free,
+};
+
+static int ds35xxgb_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ switch (status & DOSICON_STATUS_ECC_MASK) {
+ case STATUS_ECC_NO_BITFLIPS:
+ return 0;
+
+ case STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ case DOSICON_STATUS_ECC_1TO3_BITFLIPS:
+ return 3;
+
+ case DOSICON_STATUS_ECC_4TO6_BITFLIPS:
+ return 6;
+
+ case DOSICON_STATUS_ECC_7TO8_BITFLIPS:
+ return 8;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
static const struct spinand_info dosilicon_spinand_table[] = {
SPINAND_INFO("DS35Q1GA",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71),
@@ -67,7 +129,16 @@ static const struct spinand_info dosilicon_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&ds35xx_ooblayout, NULL)),
+ SPINAND_ECCINFO(&ds35xxga_ooblayout, NULL)),
+ SPINAND_INFO("DS35Q2GA",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x72),
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxga_ooblayout, NULL)),
SPINAND_INFO("DS35M1GA",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x21),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -76,7 +147,124 @@ static const struct spinand_info dosilicon_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&ds35xx_ooblayout, NULL)),
+ SPINAND_ECCINFO(&ds35xxga_ooblayout, NULL)),
+ SPINAND_INFO("DS35M2GA",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxga_ooblayout, NULL)),
+ SPINAND_INFO("DS35Q2GB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xF2),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35M1GB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA1),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35Q1GB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xF1),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35Q4GM",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xF4),
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 2, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35Q12B",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xF5),
+ NAND_MEMORG(1, 2048, 128, 64, 512, 10, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35M12B",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA5),
+ NAND_MEMORG(1, 2048, 128, 64, 512, 10, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35Q1GD-IB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35M4GB-IB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x64),
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35Q4GB-IB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB4),
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35Q12C-IB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x75),
+ NAND_MEMORG(1, 2048, 128, 64, 512, 10, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35M12C-IB",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
+ NAND_MEMORG(1, 2048, 128, 64, 512, 10, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
+ SPINAND_INFO("DS35Q2GBS",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&ds35xxgb_ooblayout, ds35xxgb_ecc_get_status)),
};
static const struct spinand_manufacturer_ops dosilicon_spinand_manuf_ops = {
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH v3] mtd: spinand: dosilicon: Add support for additional models
2026-05-27 10:00 [PATCH v3] mtd: spinand: dosilicon: Add support for additional models Qing Wu
@ 2026-05-27 12:29 ` Miquel Raynal
0 siblings, 0 replies; 2+ messages in thread
From: Miquel Raynal @ 2026-05-27 12:29 UTC (permalink / raw)
To: Qing Wu; +Cc: Michal Simek, Vignesh Raghavendra, linux-mtd, linux-kernel
On 27/05/2026 at 06:00:21 -04, Qing Wu <ses1er@gmail.com> wrote:
> Add support for additional Dosilicon SPI NAND chips.
>
> Datasheets for chips included in this patch: https://www.dosilicon.com/SPI%20NAND%20Flash.html
>
> Tested on a TP-Link TL-7DR7250 with a Dosilicon DS35Q1GB (0xE5 0xF1)
>
> Signed-off-by: Qing Wu <ses1er@gmail.com>
> ---
> Changes in v3:
> - Changed title
> - Updated 2 bytes for BBM
> - Link to v2: https://lore.kernel.org/all/20260520003733.82514-1-ses1er@gmail.com/
> Changes in v2:
> - Fixed compilation errors.
> - Link to v1: https://lore.kernel.org/all/20260217211427.9120-1-ses1er@gmail.com
> ---
> drivers/mtd/nand/spi/dosilicon.c | 218 ++++++++++++++++++++++++++++---
> 1 file changed, 203 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/mtd/nand/spi/dosilicon.c b/drivers/mtd/nand/spi/dosilicon.c
> index f99899866ceb..fcd967c1bcbc 100644
> --- a/drivers/mtd/nand/spi/dosilicon.c
> +++ b/drivers/mtd/nand/spi/dosilicon.c
> @@ -9,21 +9,27 @@
>
> #define SPINAND_MFR_DOSILICON 0xE5
>
> +#define DOSICON_STATUS_ECC_MASK GENMASK(6, 4)
> +#define DOSICON_STATUS_ECC_NO_BITFLIPS (0 << 4)
> +#define DOSICON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
> +#define DOSICON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
> +#define DOSICON_STATUS_ECC_7TO8_BITFLIPS (5 << 4)
> +
> static SPINAND_OP_VARIANTS(read_cache_variants,
> - SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0),
> - SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0),
> - 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));
> + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
> + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
> + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
> + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
Spurious changes? This cannot be even compile tested.
Please don't rush your v4.
Also please run get_maintainers.pl, the Cc list is not complete.
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-05-27 12:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27 10:00 [PATCH v3] mtd: spinand: dosilicon: Add support for additional models Qing Wu
2026-05-27 12:29 ` Miquel Raynal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox