"Das U-Boot" Source Tree

mtd/spinand: sync supported devices with linux-5.15.43

This adds more supported spinand devices from the Linux kernel
implementation.

This does not include the latest kernel implementation as this would
require a substantial amount of extra work due to the missing
ECC engine abstraction layer in U-Boot.

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> (commit message)
Link: https://lore.kernel.org/all/20230110115843.391630-3-frieder@fris.de
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

authored by

Mikhail Kshevetskiy and committed by
Dario Binacchi
8acaec92 2572470c

+626 -102
+1 -1
drivers/mtd/nand/spi/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 - spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o 3 + spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o 4 4 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
+1
drivers/mtd/nand/spi/core.c
··· 825 825 &gigadevice_spinand_manufacturer, 826 826 &macronix_spinand_manufacturer, 827 827 &micron_spinand_manufacturer, 828 + &paragon_spinand_manufacturer, 828 829 &toshiba_spinand_manufacturer, 829 830 &winbond_spinand_manufacturer, 830 831 };
+197 -26
drivers/mtd/nand/spi/gigadevice.c
··· 7 7 */ 8 8 9 9 #ifndef __UBOOT__ 10 - #include <malloc.h> 11 10 #include <linux/device.h> 12 11 #include <linux/kernel.h> 13 12 #endif 14 13 #include <linux/mtd/spinand.h> 15 14 16 15 #define SPINAND_MFR_GIGADEVICE 0xC8 16 + 17 17 #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4) 18 18 #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4) 19 19 ··· 22 22 23 23 #define GD5FXGQXXEXXG_REG_STATUS2 0xf0 24 24 25 - /* Q4 devices, QUADIO: Dummy bytes valid for 1 and 2 GBit variants */ 26 - static SPINAND_OP_VARIANTS(gd5fxgq4_read_cache_variants, 25 + #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4) 26 + #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4) 27 + #define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4) 28 + #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4) 29 + 30 + static SPINAND_OP_VARIANTS(read_cache_variants, 27 31 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), 28 32 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 29 33 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), ··· 31 35 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 32 36 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 33 37 34 - /* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */ 35 - static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants, 36 - SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), 37 - SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 38 + static SPINAND_OP_VARIANTS(read_cache_variants_f, 39 + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), 40 + SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0), 38 41 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), 39 - SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 40 - SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 41 - SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 42 + SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0), 43 + SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0), 44 + SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0)); 42 45 43 46 static SPINAND_OP_VARIANTS(write_cache_variants, 44 47 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), ··· 48 51 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 49 52 SPINAND_PROG_LOAD(false, 0, NULL, 0)); 50 53 51 - static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section, 54 + static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section, 55 + struct mtd_oob_region *region) 56 + { 57 + if (section > 3) 58 + return -ERANGE; 59 + 60 + region->offset = (16 * section) + 8; 61 + region->length = 8; 62 + 63 + return 0; 64 + } 65 + 66 + static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section, 67 + struct mtd_oob_region *region) 68 + { 69 + if (section > 3) 70 + return -ERANGE; 71 + 72 + if (section) { 73 + region->offset = 16 * section; 74 + region->length = 8; 75 + } else { 76 + /* section 0 has one byte reserved for bad block mark */ 77 + region->offset = 1; 78 + region->length = 7; 79 + } 80 + return 0; 81 + } 82 + 83 + static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { 84 + .ecc = gd5fxgq4xa_ooblayout_ecc, 85 + .rfree = gd5fxgq4xa_ooblayout_free, 86 + }; 87 + 88 + static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand, 89 + u8 status) 90 + { 91 + switch (status & STATUS_ECC_MASK) { 92 + case STATUS_ECC_NO_BITFLIPS: 93 + return 0; 94 + 95 + case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 96 + /* 1-7 bits are flipped. return the maximum. */ 97 + return 7; 98 + 99 + case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 100 + return 8; 101 + 102 + case STATUS_ECC_UNCOR_ERROR: 103 + return -EBADMSG; 104 + 105 + default: 106 + break; 107 + } 108 + 109 + return -EINVAL; 110 + } 111 + 112 + static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, 52 113 struct mtd_oob_region *region) 53 114 { 54 115 if (section) ··· 60 121 return 0; 61 122 } 62 123 63 - static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section, 124 + static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section, 64 125 struct mtd_oob_region *region) 65 126 { 66 127 if (section) ··· 73 134 return 0; 74 135 } 75 136 76 - static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand, 137 + /* Valid for Q4/Q5 and Q6 (untested) devices */ 138 + static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = { 139 + .ecc = gd5fxgqx_variant2_ooblayout_ecc, 140 + .rfree = gd5fxgqx_variant2_ooblayout_free, 141 + }; 142 + 143 + static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section, 144 + struct mtd_oob_region *oobregion) 145 + { 146 + if (section) 147 + return -ERANGE; 148 + 149 + oobregion->offset = 128; 150 + oobregion->length = 128; 151 + 152 + return 0; 153 + } 154 + 155 + static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section, 156 + struct mtd_oob_region *oobregion) 157 + { 158 + if (section) 159 + return -ERANGE; 160 + 161 + oobregion->offset = 1; 162 + oobregion->length = 127; 163 + 164 + return 0; 165 + } 166 + 167 + static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = { 168 + .ecc = gd5fxgq4xc_ooblayout_256_ecc, 169 + .rfree = gd5fxgq4xc_ooblayout_256_free, 170 + }; 171 + 172 + static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, 77 173 u8 status) 78 174 { 79 175 u8 status2; ··· 152 248 return -EINVAL; 153 249 } 154 250 155 - static const struct mtd_ooblayout_ops gd5fxgqxxexxg_ooblayout = { 156 - .ecc = gd5fxgqxxexxg_ooblayout_ecc, 157 - .rfree = gd5fxgqxxexxg_ooblayout_free, 158 - }; 251 + static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand, 252 + u8 status) 253 + { 254 + switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) { 255 + case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS: 256 + return 0; 257 + 258 + case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS: 259 + return 3; 260 + 261 + case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR: 262 + return -EBADMSG; 263 + 264 + default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */ 265 + return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2; 266 + } 267 + 268 + return -EINVAL; 269 + } 159 270 160 271 static const struct spinand_info gigadevice_spinand_table[] = { 272 + SPINAND_INFO("GD5F1GQ4xA", 273 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1), 274 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 275 + NAND_ECCREQ(8, 512), 276 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 277 + &write_cache_variants, 278 + &update_cache_variants), 279 + SPINAND_HAS_QE_BIT, 280 + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 281 + gd5fxgq4xa_ecc_get_status)), 282 + SPINAND_INFO("GD5F2GQ4xA", 283 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2), 284 + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 285 + NAND_ECCREQ(8, 512), 286 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 287 + &write_cache_variants, 288 + &update_cache_variants), 289 + SPINAND_HAS_QE_BIT, 290 + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 291 + gd5fxgq4xa_ecc_get_status)), 292 + SPINAND_INFO("GD5F4GQ4xA", 293 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4), 294 + NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1), 295 + NAND_ECCREQ(8, 512), 296 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 297 + &write_cache_variants, 298 + &update_cache_variants), 299 + SPINAND_HAS_QE_BIT, 300 + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 301 + gd5fxgq4xa_ecc_get_status)), 302 + SPINAND_INFO("GD5F4GQ4RC", 303 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68), 304 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 305 + NAND_ECCREQ(8, 512), 306 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 307 + &write_cache_variants, 308 + &update_cache_variants), 309 + SPINAND_HAS_QE_BIT, 310 + SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 311 + gd5fxgq4ufxxg_ecc_get_status)), 312 + SPINAND_INFO("GD5F4GQ4UC", 313 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68), 314 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 315 + NAND_ECCREQ(8, 512), 316 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 317 + &write_cache_variants, 318 + &update_cache_variants), 319 + SPINAND_HAS_QE_BIT, 320 + SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 321 + gd5fxgq4ufxxg_ecc_get_status)), 161 322 SPINAND_INFO("GD5F1GQ4UExxG", 162 323 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1), 163 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 324 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 164 325 NAND_ECCREQ(8, 512), 165 - SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants, 326 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 166 327 &write_cache_variants, 167 328 &update_cache_variants), 168 - 0, 169 - SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout, 170 - gd5fxgq4xexxg_ecc_get_status)), 329 + SPINAND_HAS_QE_BIT, 330 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 331 + gd5fxgq4uexxg_ecc_get_status)), 332 + SPINAND_INFO("GD5F1GQ4UFxxG", 333 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), 334 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 335 + NAND_ECCREQ(8, 512), 336 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 337 + &write_cache_variants, 338 + &update_cache_variants), 339 + SPINAND_HAS_QE_BIT, 340 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 341 + gd5fxgq4ufxxg_ecc_get_status)), 171 342 SPINAND_INFO("GD5F1GQ5UExxG", 172 343 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), 173 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 344 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 174 345 NAND_ECCREQ(4, 512), 175 - SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants, 346 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 176 347 &write_cache_variants, 177 348 &update_cache_variants), 178 - 0, 179 - SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout, 349 + SPINAND_HAS_QE_BIT, 350 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 180 351 gd5fxgq5xexxg_ecc_get_status)), 181 352 }; 182 353
+135 -10
drivers/mtd/nand/spi/macronix.c
··· 6 6 */ 7 7 8 8 #ifndef __UBOOT__ 9 - #include <malloc.h> 10 9 #include <linux/device.h> 11 10 #include <linux/kernel.h> 12 11 #endif ··· 15 14 16 15 #define SPINAND_MFR_MACRONIX 0xC2 17 16 #define MACRONIX_ECCSR_MASK 0x0F 18 - 19 17 20 18 static SPINAND_OP_VARIANTS(read_cache_variants, 21 19 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), ··· 62 60 SPI_MEM_OP_DATA_IN(1, eccsr, 1)); 63 61 64 62 int ret = spi_mem_exec_op(spinand->slave, &op); 65 - 66 63 if (ret) 67 64 return ret; 68 65 ··· 107 104 static const struct spinand_info macronix_spinand_table[] = { 108 105 SPINAND_INFO("MX35LF1GE4AB", 109 106 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12), 110 - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 107 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 111 108 NAND_ECCREQ(4, 512), 112 109 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 113 110 &write_cache_variants, ··· 117 114 mx35lf1ge4ab_ecc_get_status)), 118 115 SPINAND_INFO("MX35LF2GE4AB", 119 116 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22), 120 - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), 117 + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), 121 118 NAND_ECCREQ(4, 512), 122 119 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 123 120 &write_cache_variants, 124 121 &update_cache_variants), 125 122 SPINAND_HAS_QE_BIT, 126 123 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 124 + SPINAND_INFO("MX35LF2GE4AD", 125 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26), 126 + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 127 + NAND_ECCREQ(8, 512), 128 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 129 + &write_cache_variants, 130 + &update_cache_variants), 131 + SPINAND_HAS_QE_BIT, 132 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 133 + mx35lf1ge4ab_ecc_get_status)), 134 + SPINAND_INFO("MX35LF4GE4AD", 135 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37), 136 + NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1), 137 + NAND_ECCREQ(8, 512), 138 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 139 + &write_cache_variants, 140 + &update_cache_variants), 141 + SPINAND_HAS_QE_BIT, 142 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 143 + mx35lf1ge4ab_ecc_get_status)), 144 + SPINAND_INFO("MX35LF1G24AD", 145 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14), 146 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 147 + NAND_ECCREQ(8, 512), 148 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 149 + &write_cache_variants, 150 + &update_cache_variants), 151 + SPINAND_HAS_QE_BIT, 152 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 153 + SPINAND_INFO("MX35LF2G24AD", 154 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), 155 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), 156 + NAND_ECCREQ(8, 512), 157 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 158 + &write_cache_variants, 159 + &update_cache_variants), 160 + SPINAND_HAS_QE_BIT, 161 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 162 + SPINAND_INFO("MX35LF4G24AD", 163 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35), 164 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1), 165 + NAND_ECCREQ(8, 512), 166 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 167 + &write_cache_variants, 168 + &update_cache_variants), 169 + SPINAND_HAS_QE_BIT, 170 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 171 + SPINAND_INFO("MX31LF1GE4BC", 172 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e), 173 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 174 + NAND_ECCREQ(8, 512), 175 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 176 + &write_cache_variants, 177 + &update_cache_variants), 178 + SPINAND_HAS_QE_BIT, 179 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 180 + mx35lf1ge4ab_ecc_get_status)), 181 + SPINAND_INFO("MX31UF1GE4BC", 182 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e), 183 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 184 + NAND_ECCREQ(8, 512), 185 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 186 + &write_cache_variants, 187 + &update_cache_variants), 188 + SPINAND_HAS_QE_BIT, 189 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 190 + mx35lf1ge4ab_ecc_get_status)), 191 + 192 + SPINAND_INFO("MX35LF2G14AC", 193 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20), 194 + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), 195 + NAND_ECCREQ(4, 512), 196 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 197 + &write_cache_variants, 198 + &update_cache_variants), 199 + SPINAND_HAS_QE_BIT, 200 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 201 + mx35lf1ge4ab_ecc_get_status)), 202 + SPINAND_INFO("MX35UF4G24AD", 203 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5), 204 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1), 205 + NAND_ECCREQ(8, 512), 206 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 207 + &write_cache_variants, 208 + &update_cache_variants), 209 + SPINAND_HAS_QE_BIT, 210 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 211 + mx35lf1ge4ab_ecc_get_status)), 127 212 SPINAND_INFO("MX35UF4GE4AD", 128 213 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7), 129 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 214 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 215 + NAND_ECCREQ(8, 512), 216 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 217 + &write_cache_variants, 218 + &update_cache_variants), 219 + SPINAND_HAS_QE_BIT, 220 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 221 + mx35lf1ge4ab_ecc_get_status)), 222 + SPINAND_INFO("MX35UF2G14AC", 223 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0), 224 + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), 225 + NAND_ECCREQ(4, 512), 226 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 227 + &write_cache_variants, 228 + &update_cache_variants), 229 + SPINAND_HAS_QE_BIT, 230 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 231 + mx35lf1ge4ab_ecc_get_status)), 232 + SPINAND_INFO("MX35UF2G24AD", 233 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4), 234 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), 130 235 NAND_ECCREQ(8, 512), 131 236 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 132 237 &write_cache_variants, ··· 136 241 mx35lf1ge4ab_ecc_get_status)), 137 242 SPINAND_INFO("MX35UF2GE4AD", 138 243 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6), 139 - NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), 244 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 140 245 NAND_ECCREQ(8, 512), 141 246 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 142 247 &write_cache_variants, ··· 146 251 mx35lf1ge4ab_ecc_get_status)), 147 252 SPINAND_INFO("MX35UF2GE4AC", 148 253 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2), 149 - NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 254 + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 150 255 NAND_ECCREQ(4, 512), 151 256 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 152 257 &write_cache_variants, ··· 154 259 SPINAND_HAS_QE_BIT, 155 260 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 156 261 mx35lf1ge4ab_ecc_get_status)), 262 + SPINAND_INFO("MX35UF1G14AC", 263 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90), 264 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 265 + NAND_ECCREQ(4, 512), 266 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 267 + &write_cache_variants, 268 + &update_cache_variants), 269 + SPINAND_HAS_QE_BIT, 270 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 271 + mx35lf1ge4ab_ecc_get_status)), 272 + SPINAND_INFO("MX35UF1G24AD", 273 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94), 274 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 275 + NAND_ECCREQ(8, 512), 276 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 277 + &write_cache_variants, 278 + &update_cache_variants), 279 + SPINAND_HAS_QE_BIT, 280 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 281 + mx35lf1ge4ab_ecc_get_status)), 157 282 SPINAND_INFO("MX35UF1GE4AD", 158 283 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96), 159 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 284 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 160 285 NAND_ECCREQ(8, 512), 161 286 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 162 287 &write_cache_variants, ··· 166 291 mx35lf1ge4ab_ecc_get_status)), 167 292 SPINAND_INFO("MX35UF1GE4AC", 168 293 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), 169 - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 294 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 170 295 NAND_ECCREQ(4, 512), 171 296 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 172 297 &write_cache_variants,
+103 -41
drivers/mtd/nand/spi/micron.c
··· 7 7 */ 8 8 9 9 #ifndef __UBOOT__ 10 - #include <malloc.h> 11 10 #include <linux/device.h> 12 11 #include <linux/kernel.h> 13 12 #endif 14 - #include <linux/bitops.h> 15 13 #include <linux/mtd/spinand.h> 16 14 17 15 #define SPINAND_MFR_MICRON 0x2c ··· 32 30 33 31 #define MICRON_SELECT_DIE(x) ((x) << 6) 34 32 35 - static SPINAND_OP_VARIANTS(read_cache_variants, 33 + static SPINAND_OP_VARIANTS(quadio_read_cache_variants, 36 34 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), 37 35 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 38 36 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), ··· 40 38 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 41 39 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 42 40 43 - static SPINAND_OP_VARIANTS(write_cache_variants, 41 + static SPINAND_OP_VARIANTS(x4_write_cache_variants, 44 42 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 45 43 SPINAND_PROG_LOAD(true, 0, NULL, 0)); 46 44 47 - static SPINAND_OP_VARIANTS(update_cache_variants, 45 + static SPINAND_OP_VARIANTS(x4_update_cache_variants, 48 46 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 49 47 SPINAND_PROG_LOAD(false, 0, NULL, 0)); 50 48 49 + /* Micron MT29F2G01AAAED Device */ 50 + static SPINAND_OP_VARIANTS(x4_read_cache_variants, 51 + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 52 + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 53 + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 54 + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 55 + 56 + static SPINAND_OP_VARIANTS(x1_write_cache_variants, 57 + SPINAND_PROG_LOAD(true, 0, NULL, 0)); 58 + 59 + static SPINAND_OP_VARIANTS(x1_update_cache_variants, 60 + SPINAND_PROG_LOAD(false, 0, NULL, 0)); 61 + 51 62 static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section, 52 63 struct mtd_oob_region *region) 53 64 { ··· 78 89 .rfree = micron_8_ooblayout_free, 79 90 }; 80 91 92 + static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section, 93 + struct mtd_oob_region *region) 94 + { 95 + struct spinand_device *spinand = mtd_to_spinand(mtd); 96 + 97 + if (section >= spinand->base.memorg.pagesize / 98 + mtd->ecc_step_size) 99 + return -ERANGE; 100 + 101 + region->offset = (section * 16) + 8; 102 + region->length = 8; 103 + 104 + return 0; 105 + } 106 + 107 + static int micron_4_ooblayout_free(struct mtd_info *mtd, int section, 108 + struct mtd_oob_region *region) 109 + { 110 + struct spinand_device *spinand = mtd_to_spinand(mtd); 111 + 112 + if (section >= spinand->base.memorg.pagesize / 113 + mtd->ecc_step_size) 114 + return -ERANGE; 115 + 116 + if (section) { 117 + region->offset = 16 * section; 118 + region->length = 8; 119 + } else { 120 + /* section 0 has two bytes reserved for the BBM */ 121 + region->offset = 2; 122 + region->length = 6; 123 + } 124 + 125 + return 0; 126 + } 127 + 128 + static const struct mtd_ooblayout_ops micron_4_ooblayout = { 129 + .ecc = micron_4_ooblayout_ecc, 130 + .rfree = micron_4_ooblayout_free, 131 + }; 132 + 81 133 static int micron_select_target(struct spinand_device *spinand, 82 134 unsigned int target) 83 135 { ··· 122 174 /* M79A 2Gb 3.3V */ 123 175 SPINAND_INFO("MT29F2G01ABAGD", 124 176 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), 125 - NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1), 177 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), 126 178 NAND_ECCREQ(8, 512), 127 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 128 - &write_cache_variants, 129 - &update_cache_variants), 179 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 180 + &x4_write_cache_variants, 181 + &x4_update_cache_variants), 130 182 0, 131 183 SPINAND_ECCINFO(&micron_8_ooblayout, 132 184 micron_8_ecc_get_status)), 133 185 /* M79A 2Gb 1.8V */ 134 186 SPINAND_INFO("MT29F2G01ABBGD", 135 187 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25), 136 - NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1), 188 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), 137 189 NAND_ECCREQ(8, 512), 138 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 139 - &write_cache_variants, 140 - &update_cache_variants), 190 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 191 + &x4_write_cache_variants, 192 + &x4_update_cache_variants), 141 193 0, 142 194 SPINAND_ECCINFO(&micron_8_ooblayout, 143 195 micron_8_ecc_get_status)), 144 196 /* M78A 1Gb 3.3V */ 145 197 SPINAND_INFO("MT29F1G01ABAFD", 146 198 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14), 147 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 199 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 148 200 NAND_ECCREQ(8, 512), 149 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 150 - &write_cache_variants, 151 - &update_cache_variants), 201 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 202 + &x4_write_cache_variants, 203 + &x4_update_cache_variants), 152 204 0, 153 205 SPINAND_ECCINFO(&micron_8_ooblayout, 154 206 micron_8_ecc_get_status)), 155 207 /* M78A 1Gb 1.8V */ 156 208 SPINAND_INFO("MT29F1G01ABAFD", 157 209 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15), 158 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 210 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 159 211 NAND_ECCREQ(8, 512), 160 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 161 - &write_cache_variants, 162 - &update_cache_variants), 212 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 213 + &x4_write_cache_variants, 214 + &x4_update_cache_variants), 163 215 0, 164 216 SPINAND_ECCINFO(&micron_8_ooblayout, 165 217 micron_8_ecc_get_status)), 166 218 /* M79A 4Gb 3.3V */ 167 219 SPINAND_INFO("MT29F4G01ADAGD", 168 220 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36), 169 - NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 2), 221 + NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2), 170 222 NAND_ECCREQ(8, 512), 171 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 172 - &write_cache_variants, 173 - &update_cache_variants), 223 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 224 + &x4_write_cache_variants, 225 + &x4_update_cache_variants), 174 226 0, 175 227 SPINAND_ECCINFO(&micron_8_ooblayout, 176 228 micron_8_ecc_get_status), ··· 178 230 /* M70A 4Gb 3.3V */ 179 231 SPINAND_INFO("MT29F4G01ABAFD", 180 232 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34), 181 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 233 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 182 234 NAND_ECCREQ(8, 512), 183 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 184 - &write_cache_variants, 185 - &update_cache_variants), 235 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 236 + &x4_write_cache_variants, 237 + &x4_update_cache_variants), 186 238 SPINAND_HAS_CR_FEAT_BIT, 187 239 SPINAND_ECCINFO(&micron_8_ooblayout, 188 240 micron_8_ecc_get_status)), 189 241 /* M70A 4Gb 1.8V */ 190 242 SPINAND_INFO("MT29F4G01ABBFD", 191 243 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35), 192 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 244 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 193 245 NAND_ECCREQ(8, 512), 194 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 195 - &write_cache_variants, 196 - &update_cache_variants), 246 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 247 + &x4_write_cache_variants, 248 + &x4_update_cache_variants), 197 249 SPINAND_HAS_CR_FEAT_BIT, 198 250 SPINAND_ECCINFO(&micron_8_ooblayout, 199 251 micron_8_ecc_get_status)), 200 252 /* M70A 8Gb 3.3V */ 201 253 SPINAND_INFO("MT29F8G01ADAFD", 202 254 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46), 203 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2), 255 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2), 204 256 NAND_ECCREQ(8, 512), 205 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 206 - &write_cache_variants, 207 - &update_cache_variants), 257 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 258 + &x4_write_cache_variants, 259 + &x4_update_cache_variants), 208 260 SPINAND_HAS_CR_FEAT_BIT, 209 261 SPINAND_ECCINFO(&micron_8_ooblayout, 210 262 micron_8_ecc_get_status), ··· 212 264 /* M70A 8Gb 1.8V */ 213 265 SPINAND_INFO("MT29F8G01ADBFD", 214 266 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47), 215 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2), 267 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2), 216 268 NAND_ECCREQ(8, 512), 217 - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 218 - &write_cache_variants, 219 - &update_cache_variants), 269 + SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, 270 + &x4_write_cache_variants, 271 + &x4_update_cache_variants), 220 272 SPINAND_HAS_CR_FEAT_BIT, 221 273 SPINAND_ECCINFO(&micron_8_ooblayout, 222 274 micron_8_ecc_get_status), 223 275 SPINAND_SELECT_TARGET(micron_select_target)), 276 + /* M69A 2Gb 3.3V */ 277 + SPINAND_INFO("MT29F2G01AAAED", 278 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9F), 279 + NAND_MEMORG(1, 2048, 64, 64, 2048, 80, 2, 1, 1), 280 + NAND_ECCREQ(4, 512), 281 + SPINAND_INFO_OP_VARIANTS(&x4_read_cache_variants, 282 + &x1_write_cache_variants, 283 + &x1_update_cache_variants), 284 + 0, 285 + SPINAND_ECCINFO(&micron_4_ooblayout, NULL)), 224 286 }; 225 287 226 288 static int micron_spinand_init(struct spinand_device *spinand)
+133
drivers/mtd/nand/spi/paragon.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2019 Jeff Kletsky 4 + * 5 + * Author: Jeff Kletsky <git-commits@allycomm.com> 6 + */ 7 + 8 + #ifndef __UBOOT__ 9 + #include <linux/device.h> 10 + #include <linux/kernel.h> 11 + #endif 12 + #include <linux/mtd/spinand.h> 13 + 14 + 15 + #define SPINAND_MFR_PARAGON 0xa1 16 + 17 + 18 + #define PN26G0XA_STATUS_ECC_BITMASK (3 << 4) 19 + 20 + #define PN26G0XA_STATUS_ECC_NONE_DETECTED (0 << 4) 21 + #define PN26G0XA_STATUS_ECC_1_7_CORRECTED (1 << 4) 22 + #define PN26G0XA_STATUS_ECC_ERRORED (2 << 4) 23 + #define PN26G0XA_STATUS_ECC_8_CORRECTED (3 << 4) 24 + 25 + 26 + static SPINAND_OP_VARIANTS(read_cache_variants, 27 + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), 28 + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 29 + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), 30 + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 31 + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 32 + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 33 + 34 + static SPINAND_OP_VARIANTS(write_cache_variants, 35 + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 36 + SPINAND_PROG_LOAD(true, 0, NULL, 0)); 37 + 38 + static SPINAND_OP_VARIANTS(update_cache_variants, 39 + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 40 + SPINAND_PROG_LOAD(false, 0, NULL, 0)); 41 + 42 + 43 + static int pn26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section, 44 + struct mtd_oob_region *region) 45 + { 46 + if (section > 3) 47 + return -ERANGE; 48 + 49 + region->offset = 6 + (15 * section); /* 4 BBM + 2 user bytes */ 50 + region->length = 13; 51 + 52 + return 0; 53 + } 54 + 55 + static int pn26g0xa_ooblayout_free(struct mtd_info *mtd, int section, 56 + struct mtd_oob_region *region) 57 + { 58 + if (section > 4) 59 + return -ERANGE; 60 + 61 + if (section == 4) { 62 + region->offset = 64; 63 + region->length = 64; 64 + } else { 65 + region->offset = 4 + (15 * section); 66 + region->length = 2; 67 + } 68 + 69 + return 0; 70 + } 71 + 72 + static int pn26g0xa_ecc_get_status(struct spinand_device *spinand, 73 + u8 status) 74 + { 75 + switch (status & PN26G0XA_STATUS_ECC_BITMASK) { 76 + case PN26G0XA_STATUS_ECC_NONE_DETECTED: 77 + return 0; 78 + 79 + case PN26G0XA_STATUS_ECC_1_7_CORRECTED: 80 + return 7; /* Return upper limit by convention */ 81 + 82 + case PN26G0XA_STATUS_ECC_8_CORRECTED: 83 + return 8; 84 + 85 + case PN26G0XA_STATUS_ECC_ERRORED: 86 + return -EBADMSG; 87 + 88 + default: 89 + break; 90 + } 91 + 92 + return -EINVAL; 93 + } 94 + 95 + static const struct mtd_ooblayout_ops pn26g0xa_ooblayout = { 96 + .ecc = pn26g0xa_ooblayout_ecc, 97 + .rfree = pn26g0xa_ooblayout_free, 98 + }; 99 + 100 + 101 + static const struct spinand_info paragon_spinand_table[] = { 102 + SPINAND_INFO("PN26G01A", 103 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe1), 104 + NAND_MEMORG(1, 2048, 128, 64, 1024, 21, 1, 1, 1), 105 + NAND_ECCREQ(8, 512), 106 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 107 + &write_cache_variants, 108 + &update_cache_variants), 109 + 0, 110 + SPINAND_ECCINFO(&pn26g0xa_ooblayout, 111 + pn26g0xa_ecc_get_status)), 112 + SPINAND_INFO("PN26G02A", 113 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe2), 114 + NAND_MEMORG(1, 2048, 128, 64, 2048, 41, 1, 1, 1), 115 + NAND_ECCREQ(8, 512), 116 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 117 + &write_cache_variants, 118 + &update_cache_variants), 119 + 0, 120 + SPINAND_ECCINFO(&pn26g0xa_ooblayout, 121 + pn26g0xa_ecc_get_status)), 122 + }; 123 + 124 + static const struct spinand_manufacturer_ops paragon_spinand_manuf_ops = { 125 + }; 126 + 127 + const struct spinand_manufacturer paragon_spinand_manufacturer = { 128 + .id = SPINAND_MFR_PARAGON, 129 + .name = "Paragon", 130 + .chips = paragon_spinand_table, 131 + .nchips = ARRAY_SIZE(paragon_spinand_table), 132 + .ops = &paragon_spinand_manuf_ops, 133 + };
+19 -19
drivers/mtd/nand/spi/toshiba.c
··· 7 7 */ 8 8 9 9 #ifndef __UBOOT__ 10 - #include <malloc.h> 11 10 #include <linux/device.h> 12 11 #include <linux/kernel.h> 13 12 #endif 14 13 #include <linux/bug.h> 15 14 #include <linux/mtd/spinand.h> 16 15 16 + /* Kioxia is new name of Toshiba memory. */ 17 17 #define SPINAND_MFR_TOSHIBA 0x98 18 18 #define TOSH_STATUS_ECC_HAS_BITFLIPS_T (3 << 4) 19 19 ··· 31 31 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 32 32 SPINAND_PROG_LOAD(false, 0, NULL, 0)); 33 33 34 - /** 34 + /* 35 35 * Backward compatibility for 1st generation Serial NAND devices 36 36 * which don't support Quad Program Load operation. 37 37 */ ··· 42 42 SPINAND_PROG_LOAD(false, 0, NULL, 0)); 43 43 44 44 static int tx58cxgxsxraix_ooblayout_ecc(struct mtd_info *mtd, int section, 45 - struct mtd_oob_region *region) 45 + struct mtd_oob_region *region) 46 46 { 47 47 if (section > 0) 48 48 return -ERANGE; ··· 54 54 } 55 55 56 56 static int tx58cxgxsxraix_ooblayout_free(struct mtd_info *mtd, int section, 57 - struct mtd_oob_region *region) 57 + struct mtd_oob_region *region) 58 58 { 59 59 if (section > 0) 60 60 return -ERANGE; ··· 72 72 }; 73 73 74 74 static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, 75 - u8 status) 75 + u8 status) 76 76 { 77 77 struct nand_device *nand = spinand_to_nand(spinand); 78 78 u8 mbf = 0; ··· 113 113 /* 3.3V 1Gb (1st generation) */ 114 114 SPINAND_INFO("TC58CVG0S3HRAIG", 115 115 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2), 116 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 116 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 117 117 NAND_ECCREQ(8, 512), 118 118 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 119 119 &write_cache_variants, ··· 124 124 /* 3.3V 2Gb (1st generation) */ 125 125 SPINAND_INFO("TC58CVG1S3HRAIG", 126 126 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB), 127 - NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), 127 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 128 128 NAND_ECCREQ(8, 512), 129 129 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 130 130 &write_cache_variants, ··· 135 135 /* 3.3V 4Gb (1st generation) */ 136 136 SPINAND_INFO("TC58CVG2S0HRAIG", 137 137 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD), 138 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 138 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 139 139 NAND_ECCREQ(8, 512), 140 140 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 141 141 &write_cache_variants, ··· 146 146 /* 1.8V 1Gb (1st generation) */ 147 147 SPINAND_INFO("TC58CYG0S3HRAIG", 148 148 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2), 149 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 149 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 150 150 NAND_ECCREQ(8, 512), 151 151 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 152 152 &write_cache_variants, ··· 157 157 /* 1.8V 2Gb (1st generation) */ 158 158 SPINAND_INFO("TC58CYG1S3HRAIG", 159 159 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB), 160 - NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), 160 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 161 161 NAND_ECCREQ(8, 512), 162 162 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 163 163 &write_cache_variants, ··· 168 168 /* 1.8V 4Gb (1st generation) */ 169 169 SPINAND_INFO("TC58CYG2S0HRAIG", 170 170 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD), 171 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 171 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 172 172 NAND_ECCREQ(8, 512), 173 173 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 174 174 &write_cache_variants, ··· 184 184 /* 3.3V 1Gb (2nd generation) */ 185 185 SPINAND_INFO("TC58CVG0S3HRAIJ", 186 186 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2), 187 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 187 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 188 188 NAND_ECCREQ(8, 512), 189 189 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 190 190 &write_cache_x4_variants, ··· 195 195 /* 3.3V 2Gb (2nd generation) */ 196 196 SPINAND_INFO("TC58CVG1S3HRAIJ", 197 197 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB), 198 - NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), 198 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 199 199 NAND_ECCREQ(8, 512), 200 200 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 201 201 &write_cache_x4_variants, ··· 206 206 /* 3.3V 4Gb (2nd generation) */ 207 207 SPINAND_INFO("TC58CVG2S0HRAIJ", 208 208 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED), 209 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 209 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 210 210 NAND_ECCREQ(8, 512), 211 211 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 212 212 &write_cache_x4_variants, ··· 217 217 /* 3.3V 8Gb (2nd generation) */ 218 218 SPINAND_INFO("TH58CVG3S0HRAIJ", 219 219 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), 220 - NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1), 220 + NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1), 221 221 NAND_ECCREQ(8, 512), 222 222 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 223 223 &write_cache_x4_variants, ··· 228 228 /* 1.8V 1Gb (2nd generation) */ 229 229 SPINAND_INFO("TC58CYG0S3HRAIJ", 230 230 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2), 231 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 231 + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 232 232 NAND_ECCREQ(8, 512), 233 233 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 234 234 &write_cache_x4_variants, ··· 239 239 /* 1.8V 2Gb (2nd generation) */ 240 240 SPINAND_INFO("TC58CYG1S3HRAIJ", 241 241 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB), 242 - NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), 242 + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 243 243 NAND_ECCREQ(8, 512), 244 244 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 245 245 &write_cache_x4_variants, ··· 250 250 /* 1.8V 4Gb (2nd generation) */ 251 251 SPINAND_INFO("TC58CYG2S0HRAIJ", 252 252 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD), 253 - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 253 + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 254 254 NAND_ECCREQ(8, 512), 255 255 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 256 256 &write_cache_x4_variants, ··· 261 261 /* 1.8V 8Gb (2nd generation) */ 262 262 SPINAND_INFO("TH58CYG3S0HRAIJ", 263 263 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4), 264 - NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1), 264 + NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1), 265 265 NAND_ECCREQ(8, 512), 266 266 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 267 267 &write_cache_x4_variants,
+2 -4
drivers/mtd/nand/spi/winbond.c
··· 8 8 */ 9 9 10 10 #ifndef __UBOOT__ 11 - #include <malloc.h> 12 11 #include <linux/device.h> 13 12 #include <linux/kernel.h> 14 13 #endif 15 - #include <linux/bitops.h> 16 14 #include <linux/mtd/spinand.h> 17 15 18 16 #define SPINAND_MFR_WINBOND 0xEF ··· 81 79 static const struct spinand_info winbond_spinand_table[] = { 82 80 SPINAND_INFO("W25M02GV", 83 81 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab), 84 - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 2), 82 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), 85 83 NAND_ECCREQ(1, 512), 86 84 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 87 85 &write_cache_variants, ··· 91 89 SPINAND_SELECT_TARGET(w25m02gv_select_target)), 92 90 SPINAND_INFO("W25N01GV", 93 91 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa), 94 - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 92 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 95 93 NAND_ECCREQ(1, 512), 96 94 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 97 95 &write_cache_variants,
+4 -1
include/linux/mtd/nand.h
··· 19 19 * @oobsize: OOB area size 20 20 * @pages_per_eraseblock: number of pages per eraseblock 21 21 * @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number) 22 + * @max_bad_eraseblocks_per_lun: maximum number of eraseblocks per LUN 22 23 * @planes_per_lun: number of planes per LUN 23 24 * @luns_per_target: number of LUN per target (target is a synonym for die) 24 25 * @ntargets: total number of targets exposed by the NAND device ··· 29 30 unsigned int oobsize; 30 31 unsigned int pages_per_eraseblock; 31 32 unsigned int eraseblocks_per_lun; 33 + unsigned int max_bad_eraseblocks_per_lun; 32 34 unsigned int planes_per_lun; 33 35 unsigned int luns_per_target; 34 36 unsigned int ntargets; 35 37 }; 36 38 37 - #define NAND_MEMORG(bpc, ps, os, ppe, epl, ppl, lpt, nt) \ 39 + #define NAND_MEMORG(bpc, ps, os, ppe, epl, mbb, ppl, lpt, nt) \ 38 40 { \ 39 41 .bits_per_cell = (bpc), \ 40 42 .pagesize = (ps), \ 41 43 .oobsize = (os), \ 42 44 .pages_per_eraseblock = (ppe), \ 43 45 .eraseblocks_per_lun = (epl), \ 46 + .max_bad_eraseblocks_per_lun = (mbb), \ 44 47 .planes_per_lun = (ppl), \ 45 48 .luns_per_target = (lpt), \ 46 49 .ntargets = (nt), \
+31
include/linux/mtd/spinand.h
··· 75 75 SPI_MEM_OP_DUMMY(ndummy, 1), \ 76 76 SPI_MEM_OP_DATA_IN(len, buf, 1)) 77 77 78 + #define SPINAND_PAGE_READ_FROM_CACHE_OP_3A(fast, addr, ndummy, buf, len) \ 79 + SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \ 80 + SPI_MEM_OP_ADDR(3, addr, 1), \ 81 + SPI_MEM_OP_DUMMY(ndummy, 1), \ 82 + SPI_MEM_OP_DATA_IN(len, buf, 1)) 83 + 78 84 #define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len) \ 79 85 SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \ 80 86 SPI_MEM_OP_ADDR(2, addr, 1), \ 81 87 SPI_MEM_OP_DUMMY(ndummy, 1), \ 82 88 SPI_MEM_OP_DATA_IN(len, buf, 2)) 83 89 90 + #define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(addr, ndummy, buf, len) \ 91 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \ 92 + SPI_MEM_OP_ADDR(3, addr, 1), \ 93 + SPI_MEM_OP_DUMMY(ndummy, 1), \ 94 + SPI_MEM_OP_DATA_IN(len, buf, 2)) 95 + 84 96 #define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len) \ 85 97 SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \ 86 98 SPI_MEM_OP_ADDR(2, addr, 1), \ 87 99 SPI_MEM_OP_DUMMY(ndummy, 1), \ 88 100 SPI_MEM_OP_DATA_IN(len, buf, 4)) 89 101 102 + #define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(addr, ndummy, buf, len) \ 103 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \ 104 + SPI_MEM_OP_ADDR(3, addr, 1), \ 105 + SPI_MEM_OP_DUMMY(ndummy, 1), \ 106 + SPI_MEM_OP_DATA_IN(len, buf, 4)) 107 + 90 108 #define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len) \ 91 109 SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \ 92 110 SPI_MEM_OP_ADDR(2, addr, 2), \ 93 111 SPI_MEM_OP_DUMMY(ndummy, 2), \ 94 112 SPI_MEM_OP_DATA_IN(len, buf, 2)) 95 113 114 + #define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP_3A(addr, ndummy, buf, len) \ 115 + SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \ 116 + SPI_MEM_OP_ADDR(3, addr, 2), \ 117 + SPI_MEM_OP_DUMMY(ndummy, 2), \ 118 + SPI_MEM_OP_DATA_IN(len, buf, 2)) 119 + 96 120 #define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(addr, ndummy, buf, len) \ 97 121 SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \ 98 122 SPI_MEM_OP_ADDR(2, addr, 4), \ 123 + SPI_MEM_OP_DUMMY(ndummy, 4), \ 124 + SPI_MEM_OP_DATA_IN(len, buf, 4)) 125 + 126 + #define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP_3A(addr, ndummy, buf, len) \ 127 + SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \ 128 + SPI_MEM_OP_ADDR(3, addr, 4), \ 99 129 SPI_MEM_OP_DUMMY(ndummy, 4), \ 100 130 SPI_MEM_OP_DATA_IN(len, buf, 4)) 101 131 ··· 218 248 extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; 219 249 extern const struct spinand_manufacturer macronix_spinand_manufacturer; 220 250 extern const struct spinand_manufacturer micron_spinand_manufacturer; 251 + extern const struct spinand_manufacturer paragon_spinand_manufacturer; 221 252 extern const struct spinand_manufacturer toshiba_spinand_manufacturer; 222 253 extern const struct spinand_manufacturer winbond_spinand_manufacturer; 223 254