1c93c6132SChuanhong Guo // SPDX-License-Identifier: GPL-2.0 2c93c6132SChuanhong Guo /* 3c93c6132SChuanhong Guo * Author: 4c93c6132SChuanhong Guo * Chuanhong Guo <gch981213@gmail.com> 5c93c6132SChuanhong Guo */ 6c93c6132SChuanhong Guo 7c93c6132SChuanhong Guo #include <linux/device.h> 8c93c6132SChuanhong Guo #include <linux/kernel.h> 9c93c6132SChuanhong Guo #include <linux/mtd/spinand.h> 10c93c6132SChuanhong Guo 11c93c6132SChuanhong Guo #define SPINAND_MFR_GIGADEVICE 0xC8 12cfd93d7cSJeff Kletsky 13c93c6132SChuanhong Guo #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4) 14c93c6132SChuanhong Guo #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4) 15c93c6132SChuanhong Guo 16*469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4) 17*469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4) 18*469b9924SReto Schneider 19*469b9924SReto Schneider #define GD5FXGQXXEXXG_REG_STATUS2 0xf0 20c40c7a99SStefan Roese 21cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4) 22cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4) 23cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4) 24cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4) 25cfd93d7cSJeff Kletsky 26c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(read_cache_variants, 276387ad9cSHauke Mehrtens SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), 28c93c6132SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 29c93c6132SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), 30c93c6132SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 31c93c6132SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 32c93c6132SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 33c93c6132SChuanhong Guo 34cfd93d7cSJeff Kletsky static SPINAND_OP_VARIANTS(read_cache_variants_f, 356387ad9cSHauke Mehrtens SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), 36cfd93d7cSJeff Kletsky SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0), 37cfd93d7cSJeff Kletsky SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), 38cfd93d7cSJeff Kletsky SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0), 39cfd93d7cSJeff Kletsky SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0), 40cfd93d7cSJeff Kletsky SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0)); 41cfd93d7cSJeff Kletsky 42c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(write_cache_variants, 43c93c6132SChuanhong Guo SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 44c93c6132SChuanhong Guo SPINAND_PROG_LOAD(true, 0, NULL, 0)); 45c93c6132SChuanhong Guo 46c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(update_cache_variants, 47c93c6132SChuanhong Guo SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 48c93c6132SChuanhong Guo SPINAND_PROG_LOAD(false, 0, NULL, 0)); 49c93c6132SChuanhong Guo 50c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section, 51c93c6132SChuanhong Guo struct mtd_oob_region *region) 52c93c6132SChuanhong Guo { 53c93c6132SChuanhong Guo if (section > 3) 54c93c6132SChuanhong Guo return -ERANGE; 55c93c6132SChuanhong Guo 56c93c6132SChuanhong Guo region->offset = (16 * section) + 8; 57c93c6132SChuanhong Guo region->length = 8; 58c93c6132SChuanhong Guo 59c93c6132SChuanhong Guo return 0; 60c93c6132SChuanhong Guo } 61c93c6132SChuanhong Guo 62c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section, 63c93c6132SChuanhong Guo struct mtd_oob_region *region) 64c93c6132SChuanhong Guo { 65c93c6132SChuanhong Guo if (section > 3) 66c93c6132SChuanhong Guo return -ERANGE; 67c93c6132SChuanhong Guo 68c93c6132SChuanhong Guo if (section) { 69c93c6132SChuanhong Guo region->offset = 16 * section; 70c93c6132SChuanhong Guo region->length = 8; 71c93c6132SChuanhong Guo } else { 72c93c6132SChuanhong Guo /* section 0 has one byte reserved for bad block mark */ 73c93c6132SChuanhong Guo region->offset = 1; 74c93c6132SChuanhong Guo region->length = 7; 75c93c6132SChuanhong Guo } 76c93c6132SChuanhong Guo return 0; 77c93c6132SChuanhong Guo } 78c93c6132SChuanhong Guo 79cfd93d7cSJeff Kletsky static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { 80cfd93d7cSJeff Kletsky .ecc = gd5fxgq4xa_ooblayout_ecc, 81cfd93d7cSJeff Kletsky .free = gd5fxgq4xa_ooblayout_free, 82cfd93d7cSJeff Kletsky }; 83cfd93d7cSJeff Kletsky 84c93c6132SChuanhong Guo static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand, 85c93c6132SChuanhong Guo u8 status) 86c93c6132SChuanhong Guo { 87c93c6132SChuanhong Guo switch (status & STATUS_ECC_MASK) { 88c93c6132SChuanhong Guo case STATUS_ECC_NO_BITFLIPS: 89c93c6132SChuanhong Guo return 0; 90c93c6132SChuanhong Guo 91c93c6132SChuanhong Guo case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 92c93c6132SChuanhong Guo /* 1-7 bits are flipped. return the maximum. */ 93c93c6132SChuanhong Guo return 7; 94c93c6132SChuanhong Guo 95c93c6132SChuanhong Guo case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 96c93c6132SChuanhong Guo return 8; 97c93c6132SChuanhong Guo 98c93c6132SChuanhong Guo case STATUS_ECC_UNCOR_ERROR: 99c93c6132SChuanhong Guo return -EBADMSG; 100c93c6132SChuanhong Guo 101c93c6132SChuanhong Guo default: 102c93c6132SChuanhong Guo break; 103c93c6132SChuanhong Guo } 104c93c6132SChuanhong Guo 105c93c6132SChuanhong Guo return -EINVAL; 106c93c6132SChuanhong Guo } 107c93c6132SChuanhong Guo 108*469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, 109c40c7a99SStefan Roese struct mtd_oob_region *region) 110c40c7a99SStefan Roese { 111c40c7a99SStefan Roese if (section) 112c40c7a99SStefan Roese return -ERANGE; 113c40c7a99SStefan Roese 114c40c7a99SStefan Roese region->offset = 64; 115c40c7a99SStefan Roese region->length = 64; 116c40c7a99SStefan Roese 117c40c7a99SStefan Roese return 0; 118c40c7a99SStefan Roese } 119c40c7a99SStefan Roese 120*469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section, 121c40c7a99SStefan Roese struct mtd_oob_region *region) 122c40c7a99SStefan Roese { 123c40c7a99SStefan Roese if (section) 124c40c7a99SStefan Roese return -ERANGE; 125c40c7a99SStefan Roese 126c40c7a99SStefan Roese /* Reserve 1 bytes for the BBM. */ 127c40c7a99SStefan Roese region->offset = 1; 128c40c7a99SStefan Roese region->length = 63; 129c40c7a99SStefan Roese 130c40c7a99SStefan Roese return 0; 131c40c7a99SStefan Roese } 132c40c7a99SStefan Roese 133*469b9924SReto Schneider /* Valid for Q4/Q5 and Q6 (untested) devices */ 134*469b9924SReto Schneider static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = { 135*469b9924SReto Schneider .ecc = gd5fxgqx_variant2_ooblayout_ecc, 136*469b9924SReto Schneider .free = gd5fxgqx_variant2_ooblayout_free, 137cfd93d7cSJeff Kletsky }; 138cfd93d7cSJeff Kletsky 139302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section, 140302d8a22SHauke Mehrtens struct mtd_oob_region *oobregion) 141302d8a22SHauke Mehrtens { 142302d8a22SHauke Mehrtens if (section) 143302d8a22SHauke Mehrtens return -ERANGE; 144302d8a22SHauke Mehrtens 145302d8a22SHauke Mehrtens oobregion->offset = 128; 146302d8a22SHauke Mehrtens oobregion->length = 128; 147302d8a22SHauke Mehrtens 148302d8a22SHauke Mehrtens return 0; 149302d8a22SHauke Mehrtens } 150302d8a22SHauke Mehrtens 151302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section, 152302d8a22SHauke Mehrtens struct mtd_oob_region *oobregion) 153302d8a22SHauke Mehrtens { 154302d8a22SHauke Mehrtens if (section) 155302d8a22SHauke Mehrtens return -ERANGE; 156302d8a22SHauke Mehrtens 157302d8a22SHauke Mehrtens oobregion->offset = 1; 158302d8a22SHauke Mehrtens oobregion->length = 127; 159302d8a22SHauke Mehrtens 160302d8a22SHauke Mehrtens return 0; 161302d8a22SHauke Mehrtens } 162302d8a22SHauke Mehrtens 163302d8a22SHauke Mehrtens static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = { 164302d8a22SHauke Mehrtens .ecc = gd5fxgq4xc_ooblayout_256_ecc, 165302d8a22SHauke Mehrtens .free = gd5fxgq4xc_ooblayout_256_free, 166302d8a22SHauke Mehrtens }; 167302d8a22SHauke Mehrtens 168c40c7a99SStefan Roese static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, 169c40c7a99SStefan Roese u8 status) 170c40c7a99SStefan Roese { 171c40c7a99SStefan Roese u8 status2; 172*469b9924SReto Schneider struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 173c40c7a99SStefan Roese &status2); 174c40c7a99SStefan Roese int ret; 175c40c7a99SStefan Roese 176c40c7a99SStefan Roese switch (status & STATUS_ECC_MASK) { 177c40c7a99SStefan Roese case STATUS_ECC_NO_BITFLIPS: 178c40c7a99SStefan Roese return 0; 179c40c7a99SStefan Roese 180c40c7a99SStefan Roese case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 181c40c7a99SStefan Roese /* 182c40c7a99SStefan Roese * Read status2 register to determine a more fine grained 183c40c7a99SStefan Roese * bit error status 184c40c7a99SStefan Roese */ 185c40c7a99SStefan Roese ret = spi_mem_exec_op(spinand->spimem, &op); 186c40c7a99SStefan Roese if (ret) 187c40c7a99SStefan Roese return ret; 188c40c7a99SStefan Roese 189c40c7a99SStefan Roese /* 190c40c7a99SStefan Roese * 4 ... 7 bits are flipped (1..4 can't be detected, so 191c40c7a99SStefan Roese * report the maximum of 4 in this case 192c40c7a99SStefan Roese */ 193c40c7a99SStefan Roese /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */ 194c40c7a99SStefan Roese return ((status & STATUS_ECC_MASK) >> 2) | 195c40c7a99SStefan Roese ((status2 & STATUS_ECC_MASK) >> 4); 196c40c7a99SStefan Roese 197c40c7a99SStefan Roese case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 198c40c7a99SStefan Roese return 8; 199c40c7a99SStefan Roese 200c40c7a99SStefan Roese case STATUS_ECC_UNCOR_ERROR: 201c40c7a99SStefan Roese return -EBADMSG; 202c40c7a99SStefan Roese 203c40c7a99SStefan Roese default: 204c40c7a99SStefan Roese break; 205c40c7a99SStefan Roese } 206c40c7a99SStefan Roese 207c40c7a99SStefan Roese return -EINVAL; 208c40c7a99SStefan Roese } 209c40c7a99SStefan Roese 210*469b9924SReto Schneider static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, 211*469b9924SReto Schneider u8 status) 212*469b9924SReto Schneider { 213*469b9924SReto Schneider u8 status2; 214*469b9924SReto Schneider struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 215*469b9924SReto Schneider &status2); 216*469b9924SReto Schneider int ret; 217*469b9924SReto Schneider 218*469b9924SReto Schneider switch (status & STATUS_ECC_MASK) { 219*469b9924SReto Schneider case STATUS_ECC_NO_BITFLIPS: 220*469b9924SReto Schneider return 0; 221*469b9924SReto Schneider 222*469b9924SReto Schneider case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS: 223*469b9924SReto Schneider /* 224*469b9924SReto Schneider * Read status2 register to determine a more fine grained 225*469b9924SReto Schneider * bit error status 226*469b9924SReto Schneider */ 227*469b9924SReto Schneider ret = spi_mem_exec_op(spinand->spimem, &op); 228*469b9924SReto Schneider if (ret) 229*469b9924SReto Schneider return ret; 230*469b9924SReto Schneider 231*469b9924SReto Schneider /* 232*469b9924SReto Schneider * 1 ... 4 bits are flipped (and corrected) 233*469b9924SReto Schneider */ 234*469b9924SReto Schneider /* bits sorted this way (1...0): ECCSE1, ECCSE0 */ 235*469b9924SReto Schneider return ((status2 & STATUS_ECC_MASK) >> 4) + 1; 236*469b9924SReto Schneider 237*469b9924SReto Schneider case STATUS_ECC_UNCOR_ERROR: 238*469b9924SReto Schneider return -EBADMSG; 239*469b9924SReto Schneider 240*469b9924SReto Schneider default: 241*469b9924SReto Schneider break; 242*469b9924SReto Schneider } 243*469b9924SReto Schneider 244*469b9924SReto Schneider return -EINVAL; 245*469b9924SReto Schneider } 246*469b9924SReto Schneider 247cfd93d7cSJeff Kletsky static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand, 248cfd93d7cSJeff Kletsky u8 status) 249cfd93d7cSJeff Kletsky { 250cfd93d7cSJeff Kletsky switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) { 251cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS: 252cfd93d7cSJeff Kletsky return 0; 253c93c6132SChuanhong Guo 254cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS: 255cfd93d7cSJeff Kletsky return 3; 256cfd93d7cSJeff Kletsky 257cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR: 258cfd93d7cSJeff Kletsky return -EBADMSG; 259cfd93d7cSJeff Kletsky 260cfd93d7cSJeff Kletsky default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */ 261cfd93d7cSJeff Kletsky return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2; 262cfd93d7cSJeff Kletsky } 263cfd93d7cSJeff Kletsky 264cfd93d7cSJeff Kletsky return -EINVAL; 265cfd93d7cSJeff Kletsky } 266c40c7a99SStefan Roese 267c93c6132SChuanhong Guo static const struct spinand_info gigadevice_spinand_table[] = { 268f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4xA", 269f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1), 270377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 271c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 272c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 273c93c6132SChuanhong Guo &write_cache_variants, 274c93c6132SChuanhong Guo &update_cache_variants), 275aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 276c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 277c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 278f1541773SChuanhong Guo SPINAND_INFO("GD5F2GQ4xA", 279f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2), 280377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 281c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 282c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 283c93c6132SChuanhong Guo &write_cache_variants, 284c93c6132SChuanhong Guo &update_cache_variants), 285aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 286c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 287c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 288f1541773SChuanhong Guo SPINAND_INFO("GD5F4GQ4xA", 289f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4), 290a126483eSFrieder Schrempf NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1), 291c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 292c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 293c93c6132SChuanhong Guo &write_cache_variants, 294c93c6132SChuanhong Guo &update_cache_variants), 295aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 296c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 297c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 298302d8a22SHauke Mehrtens SPINAND_INFO("GD5F4GQ4RC", 299302d8a22SHauke Mehrtens SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68), 300302d8a22SHauke Mehrtens NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 301302d8a22SHauke Mehrtens NAND_ECCREQ(8, 512), 302302d8a22SHauke Mehrtens SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 303302d8a22SHauke Mehrtens &write_cache_variants, 304302d8a22SHauke Mehrtens &update_cache_variants), 305302d8a22SHauke Mehrtens SPINAND_HAS_QE_BIT, 306302d8a22SHauke Mehrtens SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 307302d8a22SHauke Mehrtens gd5fxgq4ufxxg_ecc_get_status)), 308302d8a22SHauke Mehrtens SPINAND_INFO("GD5F4GQ4UC", 309302d8a22SHauke Mehrtens SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68), 310302d8a22SHauke Mehrtens NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 311302d8a22SHauke Mehrtens NAND_ECCREQ(8, 512), 312302d8a22SHauke Mehrtens SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 313302d8a22SHauke Mehrtens &write_cache_variants, 314302d8a22SHauke Mehrtens &update_cache_variants), 315302d8a22SHauke Mehrtens SPINAND_HAS_QE_BIT, 316302d8a22SHauke Mehrtens SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 317302d8a22SHauke Mehrtens gd5fxgq4ufxxg_ecc_get_status)), 318f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4UExxG", 319f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1), 320377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 321c40c7a99SStefan Roese NAND_ECCREQ(8, 512), 322c40c7a99SStefan Roese SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 323c40c7a99SStefan Roese &write_cache_variants, 324c40c7a99SStefan Roese &update_cache_variants), 325aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 326*469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 327c40c7a99SStefan Roese gd5fxgq4uexxg_ecc_get_status)), 328f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4UFxxG", 329f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), 330cfd93d7cSJeff Kletsky NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 331cfd93d7cSJeff Kletsky NAND_ECCREQ(8, 512), 332cfd93d7cSJeff Kletsky SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 333cfd93d7cSJeff Kletsky &write_cache_variants, 334cfd93d7cSJeff Kletsky &update_cache_variants), 335aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 336*469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 337cfd93d7cSJeff Kletsky gd5fxgq4ufxxg_ecc_get_status)), 338*469b9924SReto Schneider SPINAND_INFO("GD5F1GQ5UExxG", 339*469b9924SReto Schneider SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), 340*469b9924SReto Schneider NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 341*469b9924SReto Schneider NAND_ECCREQ(4, 512), 342*469b9924SReto Schneider SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 343*469b9924SReto Schneider &write_cache_variants, 344*469b9924SReto Schneider &update_cache_variants), 345*469b9924SReto Schneider SPINAND_HAS_QE_BIT, 346*469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 347*469b9924SReto Schneider gd5fxgq5xexxg_ecc_get_status)), 348c93c6132SChuanhong Guo }; 349c93c6132SChuanhong Guo 350c93c6132SChuanhong Guo static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { 351c93c6132SChuanhong Guo }; 352c93c6132SChuanhong Guo 353c93c6132SChuanhong Guo const struct spinand_manufacturer gigadevice_spinand_manufacturer = { 354c93c6132SChuanhong Guo .id = SPINAND_MFR_GIGADEVICE, 355c93c6132SChuanhong Guo .name = "GigaDevice", 356f1541773SChuanhong Guo .chips = gigadevice_spinand_table, 357f1541773SChuanhong Guo .nchips = ARRAY_SIZE(gigadevice_spinand_table), 358c93c6132SChuanhong Guo .ops = &gigadevice_spinand_manuf_ops, 359c93c6132SChuanhong Guo }; 360