1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Author: 4 * Chuanhong Guo <gch981213@gmail.com> 5 */ 6 7 #include <linux/device.h> 8 #include <linux/kernel.h> 9 #include <linux/mtd/spinand.h> 10 11 #define SPINAND_MFR_GIGADEVICE 0xC8 12 13 #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4) 14 #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4) 15 16 #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4) 17 #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4) 18 19 #define GD5FXGQXXEXXG_REG_STATUS2 0xf0 20 21 #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4) 22 #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4) 23 #define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4) 24 #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4) 25 26 static SPINAND_OP_VARIANTS(read_cache_variants, 27 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, 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(read_cache_variants_f, 35 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), 36 SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0), 37 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), 38 SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0), 39 SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0), 40 SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0)); 41 42 static SPINAND_OP_VARIANTS(read_cache_variants_1gq5, 43 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), 44 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 45 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), 46 SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 47 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 48 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 49 50 static SPINAND_OP_VARIANTS(read_cache_variants_2gq5, 51 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0), 52 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 53 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0), 54 SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 55 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 56 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 57 58 static SPINAND_OP_VARIANTS(write_cache_variants, 59 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 60 SPINAND_PROG_LOAD(true, 0, NULL, 0)); 61 62 static SPINAND_OP_VARIANTS(update_cache_variants, 63 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 64 SPINAND_PROG_LOAD(false, 0, NULL, 0)); 65 66 static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section, 67 struct mtd_oob_region *region) 68 { 69 if (section > 3) 70 return -ERANGE; 71 72 region->offset = (16 * section) + 8; 73 region->length = 8; 74 75 return 0; 76 } 77 78 static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section, 79 struct mtd_oob_region *region) 80 { 81 if (section > 3) 82 return -ERANGE; 83 84 if (section) { 85 region->offset = 16 * section; 86 region->length = 8; 87 } else { 88 /* section 0 has one byte reserved for bad block mark */ 89 region->offset = 1; 90 region->length = 7; 91 } 92 return 0; 93 } 94 95 static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { 96 .ecc = gd5fxgq4xa_ooblayout_ecc, 97 .free = gd5fxgq4xa_ooblayout_free, 98 }; 99 100 static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand, 101 u8 status) 102 { 103 switch (status & STATUS_ECC_MASK) { 104 case STATUS_ECC_NO_BITFLIPS: 105 return 0; 106 107 case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 108 /* 1-7 bits are flipped. return the maximum. */ 109 return 7; 110 111 case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 112 return 8; 113 114 case STATUS_ECC_UNCOR_ERROR: 115 return -EBADMSG; 116 117 default: 118 break; 119 } 120 121 return -EINVAL; 122 } 123 124 static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, 125 struct mtd_oob_region *region) 126 { 127 if (section) 128 return -ERANGE; 129 130 region->offset = 64; 131 region->length = 64; 132 133 return 0; 134 } 135 136 static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section, 137 struct mtd_oob_region *region) 138 { 139 if (section) 140 return -ERANGE; 141 142 /* Reserve 1 bytes for the BBM. */ 143 region->offset = 1; 144 region->length = 63; 145 146 return 0; 147 } 148 149 /* Valid for Q4/Q5 and Q6 (untested) devices */ 150 static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = { 151 .ecc = gd5fxgqx_variant2_ooblayout_ecc, 152 .free = gd5fxgqx_variant2_ooblayout_free, 153 }; 154 155 static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section, 156 struct mtd_oob_region *oobregion) 157 { 158 if (section) 159 return -ERANGE; 160 161 oobregion->offset = 128; 162 oobregion->length = 128; 163 164 return 0; 165 } 166 167 static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section, 168 struct mtd_oob_region *oobregion) 169 { 170 if (section) 171 return -ERANGE; 172 173 oobregion->offset = 1; 174 oobregion->length = 127; 175 176 return 0; 177 } 178 179 static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = { 180 .ecc = gd5fxgq4xc_ooblayout_256_ecc, 181 .free = gd5fxgq4xc_ooblayout_256_free, 182 }; 183 184 static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, 185 u8 status) 186 { 187 u8 status2; 188 struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 189 spinand->scratchbuf); 190 int ret; 191 192 switch (status & STATUS_ECC_MASK) { 193 case STATUS_ECC_NO_BITFLIPS: 194 return 0; 195 196 case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 197 /* 198 * Read status2 register to determine a more fine grained 199 * bit error status 200 */ 201 ret = spi_mem_exec_op(spinand->spimem, &op); 202 if (ret) 203 return ret; 204 205 /* 206 * 4 ... 7 bits are flipped (1..4 can't be detected, so 207 * report the maximum of 4 in this case 208 */ 209 /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */ 210 status2 = *(spinand->scratchbuf); 211 return ((status & STATUS_ECC_MASK) >> 2) | 212 ((status2 & STATUS_ECC_MASK) >> 4); 213 214 case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 215 return 8; 216 217 case STATUS_ECC_UNCOR_ERROR: 218 return -EBADMSG; 219 220 default: 221 break; 222 } 223 224 return -EINVAL; 225 } 226 227 static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, 228 u8 status) 229 { 230 u8 status2; 231 struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 232 spinand->scratchbuf); 233 int ret; 234 235 switch (status & STATUS_ECC_MASK) { 236 case STATUS_ECC_NO_BITFLIPS: 237 return 0; 238 239 case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS: 240 /* 241 * Read status2 register to determine a more fine grained 242 * bit error status 243 */ 244 ret = spi_mem_exec_op(spinand->spimem, &op); 245 if (ret) 246 return ret; 247 248 /* 249 * 1 ... 4 bits are flipped (and corrected) 250 */ 251 /* bits sorted this way (1...0): ECCSE1, ECCSE0 */ 252 status2 = *(spinand->scratchbuf); 253 return ((status2 & STATUS_ECC_MASK) >> 4) + 1; 254 255 case STATUS_ECC_UNCOR_ERROR: 256 return -EBADMSG; 257 258 default: 259 break; 260 } 261 262 return -EINVAL; 263 } 264 265 static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand, 266 u8 status) 267 { 268 switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) { 269 case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS: 270 return 0; 271 272 case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS: 273 return 3; 274 275 case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR: 276 return -EBADMSG; 277 278 default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */ 279 return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2; 280 } 281 282 return -EINVAL; 283 } 284 285 static const struct spinand_info gigadevice_spinand_table[] = { 286 SPINAND_INFO("GD5F1GQ4xA", 287 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1), 288 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 289 NAND_ECCREQ(8, 512), 290 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 291 &write_cache_variants, 292 &update_cache_variants), 293 SPINAND_HAS_QE_BIT, 294 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 295 gd5fxgq4xa_ecc_get_status)), 296 SPINAND_INFO("GD5F2GQ4xA", 297 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2), 298 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 299 NAND_ECCREQ(8, 512), 300 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 301 &write_cache_variants, 302 &update_cache_variants), 303 SPINAND_HAS_QE_BIT, 304 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 305 gd5fxgq4xa_ecc_get_status)), 306 SPINAND_INFO("GD5F4GQ4xA", 307 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4), 308 NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1), 309 NAND_ECCREQ(8, 512), 310 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 311 &write_cache_variants, 312 &update_cache_variants), 313 SPINAND_HAS_QE_BIT, 314 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 315 gd5fxgq4xa_ecc_get_status)), 316 SPINAND_INFO("GD5F4GQ4RC", 317 SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68), 318 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 319 NAND_ECCREQ(8, 512), 320 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 321 &write_cache_variants, 322 &update_cache_variants), 323 SPINAND_HAS_QE_BIT, 324 SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 325 gd5fxgq4ufxxg_ecc_get_status)), 326 SPINAND_INFO("GD5F4GQ4UC", 327 SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68), 328 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 329 NAND_ECCREQ(8, 512), 330 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 331 &write_cache_variants, 332 &update_cache_variants), 333 SPINAND_HAS_QE_BIT, 334 SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 335 gd5fxgq4ufxxg_ecc_get_status)), 336 SPINAND_INFO("GD5F1GQ4UExxG", 337 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1), 338 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 339 NAND_ECCREQ(8, 512), 340 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 341 &write_cache_variants, 342 &update_cache_variants), 343 SPINAND_HAS_QE_BIT, 344 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 345 gd5fxgq4uexxg_ecc_get_status)), 346 SPINAND_INFO("GD5F1GQ4RExxG", 347 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1), 348 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 349 NAND_ECCREQ(8, 512), 350 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 351 &write_cache_variants, 352 &update_cache_variants), 353 SPINAND_HAS_QE_BIT, 354 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 355 gd5fxgq4uexxg_ecc_get_status)), 356 SPINAND_INFO("GD5F2GQ4UExxG", 357 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2), 358 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 359 NAND_ECCREQ(8, 512), 360 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 361 &write_cache_variants, 362 &update_cache_variants), 363 SPINAND_HAS_QE_BIT, 364 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 365 gd5fxgq4uexxg_ecc_get_status)), 366 SPINAND_INFO("GD5F2GQ4RExxG", 367 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2), 368 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 369 NAND_ECCREQ(8, 512), 370 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 371 &write_cache_variants, 372 &update_cache_variants), 373 SPINAND_HAS_QE_BIT, 374 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 375 gd5fxgq4uexxg_ecc_get_status)), 376 SPINAND_INFO("GD5F1GQ4UFxxG", 377 SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), 378 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 379 NAND_ECCREQ(8, 512), 380 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 381 &write_cache_variants, 382 &update_cache_variants), 383 SPINAND_HAS_QE_BIT, 384 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 385 gd5fxgq4ufxxg_ecc_get_status)), 386 SPINAND_INFO("GD5F1GQ5UExxG", 387 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), 388 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 389 NAND_ECCREQ(4, 512), 390 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 391 &write_cache_variants, 392 &update_cache_variants), 393 SPINAND_HAS_QE_BIT, 394 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 395 gd5fxgq5xexxg_ecc_get_status)), 396 SPINAND_INFO("GD5F1GQ5RExxG", 397 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41), 398 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 399 NAND_ECCREQ(4, 512), 400 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 401 &write_cache_variants, 402 &update_cache_variants), 403 SPINAND_HAS_QE_BIT, 404 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 405 gd5fxgq5xexxg_ecc_get_status)), 406 SPINAND_INFO("GD5F2GQ5UExxG", 407 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52), 408 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 409 NAND_ECCREQ(4, 512), 410 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 411 &write_cache_variants, 412 &update_cache_variants), 413 SPINAND_HAS_QE_BIT, 414 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 415 gd5fxgq5xexxg_ecc_get_status)), 416 SPINAND_INFO("GD5F2GQ5RExxG", 417 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42), 418 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 419 NAND_ECCREQ(4, 512), 420 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 421 &write_cache_variants, 422 &update_cache_variants), 423 SPINAND_HAS_QE_BIT, 424 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 425 gd5fxgq5xexxg_ecc_get_status)), 426 SPINAND_INFO("GD5F4GQ6UExxG", 427 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55), 428 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), 429 NAND_ECCREQ(4, 512), 430 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 431 &write_cache_variants, 432 &update_cache_variants), 433 SPINAND_HAS_QE_BIT, 434 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 435 gd5fxgq5xexxg_ecc_get_status)), 436 SPINAND_INFO("GD5F4GQ6RExxG", 437 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45), 438 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), 439 NAND_ECCREQ(4, 512), 440 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 441 &write_cache_variants, 442 &update_cache_variants), 443 SPINAND_HAS_QE_BIT, 444 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 445 gd5fxgq5xexxg_ecc_get_status)), 446 SPINAND_INFO("GD5F1GM7UExxG", 447 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91), 448 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 449 NAND_ECCREQ(8, 512), 450 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 451 &write_cache_variants, 452 &update_cache_variants), 453 SPINAND_HAS_QE_BIT, 454 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 455 gd5fxgq4uexxg_ecc_get_status)), 456 SPINAND_INFO("GD5F1GM7RExxG", 457 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81), 458 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 459 NAND_ECCREQ(8, 512), 460 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 461 &write_cache_variants, 462 &update_cache_variants), 463 SPINAND_HAS_QE_BIT, 464 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 465 gd5fxgq4uexxg_ecc_get_status)), 466 SPINAND_INFO("GD5F2GM7UExxG", 467 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), 468 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 469 NAND_ECCREQ(8, 512), 470 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 471 &write_cache_variants, 472 &update_cache_variants), 473 SPINAND_HAS_QE_BIT, 474 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 475 gd5fxgq4uexxg_ecc_get_status)), 476 SPINAND_INFO("GD5F2GM7RExxG", 477 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82), 478 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 479 NAND_ECCREQ(8, 512), 480 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 481 &write_cache_variants, 482 &update_cache_variants), 483 SPINAND_HAS_QE_BIT, 484 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 485 gd5fxgq4uexxg_ecc_get_status)), 486 SPINAND_INFO("GD5F4GM8UExxG", 487 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95), 488 NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), 489 NAND_ECCREQ(8, 512), 490 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 491 &write_cache_variants, 492 &update_cache_variants), 493 SPINAND_HAS_QE_BIT, 494 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 495 gd5fxgq4uexxg_ecc_get_status)), 496 SPINAND_INFO("GD5F4GM8RExxG", 497 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85), 498 NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), 499 NAND_ECCREQ(8, 512), 500 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 501 &write_cache_variants, 502 &update_cache_variants), 503 SPINAND_HAS_QE_BIT, 504 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 505 gd5fxgq4uexxg_ecc_get_status)), 506 SPINAND_INFO("GD5F2GQ5xExxH", 507 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22), 508 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 509 NAND_ECCREQ(4, 512), 510 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 511 &write_cache_variants, 512 &update_cache_variants), 513 SPINAND_HAS_QE_BIT, 514 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 515 gd5fxgq4uexxg_ecc_get_status)), 516 SPINAND_INFO("GD5F1GQ5RExxH", 517 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x21), 518 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 519 NAND_ECCREQ(4, 512), 520 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 521 &write_cache_variants, 522 &update_cache_variants), 523 SPINAND_HAS_QE_BIT, 524 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 525 gd5fxgq4uexxg_ecc_get_status)), 526 SPINAND_INFO("GD5F1GQ4RExxH", 527 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xc9), 528 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 529 NAND_ECCREQ(4, 512), 530 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 531 &write_cache_variants, 532 &update_cache_variants), 533 SPINAND_HAS_QE_BIT, 534 SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 535 gd5fxgq4uexxg_ecc_get_status)), 536 }; 537 538 static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { 539 }; 540 541 const struct spinand_manufacturer gigadevice_spinand_manufacturer = { 542 .id = SPINAND_MFR_GIGADEVICE, 543 .name = "GigaDevice", 544 .chips = gigadevice_spinand_table, 545 .nchips = ARRAY_SIZE(gigadevice_spinand_table), 546 .ops = &gigadevice_spinand_manuf_ops, 547 }; 548