Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mtd: spinand: add support for Dosilicon DS35Q1GA/DS35M1GA

Add support for Dosilicon DS35Q1GA (3.3V) and DS35M1GA (1.8V) SPI NAND.

These are 1Gbit (128MB) devices with:
- 2048 byte pages + 64 byte OOB
- 64 pages per block, 1024 blocks
- On-die 4-bit ECC per 512 byte sector

The 64-byte OOB area is divided into 4 segments of 16 bytes, with each
segment containing 8 bytes of user data (M2+M1) and 8 bytes of ECC
parity (R1). This provides 30 bytes of usable OOB space after reserving
2 bytes for the bad block marker.

Tested on Genexis Platinum 4410 (EcoNet EN751221) by writing known
patterns to OOB and verifying ECC parity placement in R1 regions.

Datasheet:
https://www.dosilicon.com/resources/SPI%20NAND/DS35X1GAXXX_rev08.pdf

Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

authored by

Ahmed Naseef and committed by
Miquel Raynal
a75a1dec 8f0b4cce

+95 -2
+2 -2
drivers/mtd/nand/spi/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 spinand-objs := core.o otp.o 3 - spinand-objs += alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o 4 - spinand-objs += micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o 3 + spinand-objs += alliancememory.o ato.o dosilicon.o esmt.o fmsh.o foresee.o gigadevice.o 4 + spinand-objs += macronix.o micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o 5 5 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
+1
drivers/mtd/nand/spi/core.c
··· 1227 1227 static const struct spinand_manufacturer *spinand_manufacturers[] = { 1228 1228 &alliancememory_spinand_manufacturer, 1229 1229 &ato_spinand_manufacturer, 1230 + &dosilicon_spinand_manufacturer, 1230 1231 &esmt_8c_spinand_manufacturer, 1231 1232 &esmt_c8_spinand_manufacturer, 1232 1233 &fmsh_spinand_manufacturer,
+91
drivers/mtd/nand/spi/dosilicon.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Author: Ahmed Naseef <naseefkm@gmail.com> 4 + */ 5 + 6 + #include <linux/device.h> 7 + #include <linux/kernel.h> 8 + #include <linux/mtd/spinand.h> 9 + 10 + #define SPINAND_MFR_DOSILICON 0xE5 11 + 12 + static SPINAND_OP_VARIANTS(read_cache_variants, 13 + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0), 14 + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0), 15 + SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0), 16 + SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0)); 17 + 18 + static SPINAND_OP_VARIANTS(write_cache_variants, 19 + SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0), 20 + SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0)); 21 + 22 + static SPINAND_OP_VARIANTS(update_cache_variants, 23 + SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0), 24 + SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0)); 25 + 26 + static int ds35xx_ooblayout_ecc(struct mtd_info *mtd, int section, 27 + struct mtd_oob_region *region) 28 + { 29 + if (section > 3) 30 + return -ERANGE; 31 + 32 + region->offset = 8 + (section * 16); 33 + region->length = 8; 34 + 35 + return 0; 36 + } 37 + 38 + static int ds35xx_ooblayout_free(struct mtd_info *mtd, int section, 39 + struct mtd_oob_region *region) 40 + { 41 + if (section > 3) 42 + return -ERANGE; 43 + 44 + if (section == 0) { 45 + /* reserve 2 bytes for the BBM */ 46 + region->offset = 2; 47 + region->length = 6; 48 + } else { 49 + region->offset = section * 16; 50 + region->length = 8; 51 + } 52 + 53 + return 0; 54 + } 55 + 56 + static const struct mtd_ooblayout_ops ds35xx_ooblayout = { 57 + .ecc = ds35xx_ooblayout_ecc, 58 + .free = ds35xx_ooblayout_free, 59 + }; 60 + 61 + static const struct spinand_info dosilicon_spinand_table[] = { 62 + SPINAND_INFO("DS35Q1GA", 63 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71), 64 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 65 + NAND_ECCREQ(4, 512), 66 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 67 + &write_cache_variants, 68 + &update_cache_variants), 69 + SPINAND_HAS_QE_BIT, 70 + SPINAND_ECCINFO(&ds35xx_ooblayout, NULL)), 71 + SPINAND_INFO("DS35M1GA", 72 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x21), 73 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 74 + NAND_ECCREQ(4, 512), 75 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 76 + &write_cache_variants, 77 + &update_cache_variants), 78 + SPINAND_HAS_QE_BIT, 79 + SPINAND_ECCINFO(&ds35xx_ooblayout, NULL)), 80 + }; 81 + 82 + static const struct spinand_manufacturer_ops dosilicon_spinand_manuf_ops = { 83 + }; 84 + 85 + const struct spinand_manufacturer dosilicon_spinand_manufacturer = { 86 + .id = SPINAND_MFR_DOSILICON, 87 + .name = "Dosilicon", 88 + .chips = dosilicon_spinand_table, 89 + .nchips = ARRAY_SIZE(dosilicon_spinand_table), 90 + .ops = &dosilicon_spinand_manuf_ops, 91 + };
+1
include/linux/mtd/spinand.h
··· 354 354 /* SPI NAND manufacturers */ 355 355 extern const struct spinand_manufacturer alliancememory_spinand_manufacturer; 356 356 extern const struct spinand_manufacturer ato_spinand_manufacturer; 357 + extern const struct spinand_manufacturer dosilicon_spinand_manufacturer; 357 358 extern const struct spinand_manufacturer esmt_8c_spinand_manufacturer; 358 359 extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; 359 360 extern const struct spinand_manufacturer fmsh_spinand_manufacturer;