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 16469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4) 17469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4) 18469b9924SReto Schneider 19469b9924SReto 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 42a4f9dd55SChuanhong Guo static SPINAND_OP_VARIANTS(read_cache_variants_1gq5, 43a4f9dd55SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), 44a4f9dd55SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 45a4f9dd55SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), 46a4f9dd55SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 47a4f9dd55SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 48a4f9dd55SChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 49a4f9dd55SChuanhong Guo 50c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(write_cache_variants, 51c93c6132SChuanhong Guo SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 52c93c6132SChuanhong Guo SPINAND_PROG_LOAD(true, 0, NULL, 0)); 53c93c6132SChuanhong Guo 54c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(update_cache_variants, 55c93c6132SChuanhong Guo SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 56c93c6132SChuanhong Guo SPINAND_PROG_LOAD(false, 0, NULL, 0)); 57c93c6132SChuanhong Guo 58c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section, 59c93c6132SChuanhong Guo struct mtd_oob_region *region) 60c93c6132SChuanhong Guo { 61c93c6132SChuanhong Guo if (section > 3) 62c93c6132SChuanhong Guo return -ERANGE; 63c93c6132SChuanhong Guo 64c93c6132SChuanhong Guo region->offset = (16 * section) + 8; 65c93c6132SChuanhong Guo region->length = 8; 66c93c6132SChuanhong Guo 67c93c6132SChuanhong Guo return 0; 68c93c6132SChuanhong Guo } 69c93c6132SChuanhong Guo 70c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section, 71c93c6132SChuanhong Guo struct mtd_oob_region *region) 72c93c6132SChuanhong Guo { 73c93c6132SChuanhong Guo if (section > 3) 74c93c6132SChuanhong Guo return -ERANGE; 75c93c6132SChuanhong Guo 76c93c6132SChuanhong Guo if (section) { 77c93c6132SChuanhong Guo region->offset = 16 * section; 78c93c6132SChuanhong Guo region->length = 8; 79c93c6132SChuanhong Guo } else { 80c93c6132SChuanhong Guo /* section 0 has one byte reserved for bad block mark */ 81c93c6132SChuanhong Guo region->offset = 1; 82c93c6132SChuanhong Guo region->length = 7; 83c93c6132SChuanhong Guo } 84c93c6132SChuanhong Guo return 0; 85c93c6132SChuanhong Guo } 86c93c6132SChuanhong Guo 87cfd93d7cSJeff Kletsky static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { 88cfd93d7cSJeff Kletsky .ecc = gd5fxgq4xa_ooblayout_ecc, 89cfd93d7cSJeff Kletsky .free = gd5fxgq4xa_ooblayout_free, 90cfd93d7cSJeff Kletsky }; 91cfd93d7cSJeff Kletsky 92c93c6132SChuanhong Guo static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand, 93c93c6132SChuanhong Guo u8 status) 94c93c6132SChuanhong Guo { 95c93c6132SChuanhong Guo switch (status & STATUS_ECC_MASK) { 96c93c6132SChuanhong Guo case STATUS_ECC_NO_BITFLIPS: 97c93c6132SChuanhong Guo return 0; 98c93c6132SChuanhong Guo 99c93c6132SChuanhong Guo case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 100c93c6132SChuanhong Guo /* 1-7 bits are flipped. return the maximum. */ 101c93c6132SChuanhong Guo return 7; 102c93c6132SChuanhong Guo 103c93c6132SChuanhong Guo case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 104c93c6132SChuanhong Guo return 8; 105c93c6132SChuanhong Guo 106c93c6132SChuanhong Guo case STATUS_ECC_UNCOR_ERROR: 107c93c6132SChuanhong Guo return -EBADMSG; 108c93c6132SChuanhong Guo 109c93c6132SChuanhong Guo default: 110c93c6132SChuanhong Guo break; 111c93c6132SChuanhong Guo } 112c93c6132SChuanhong Guo 113c93c6132SChuanhong Guo return -EINVAL; 114c93c6132SChuanhong Guo } 115c93c6132SChuanhong Guo 116469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, 117c40c7a99SStefan Roese struct mtd_oob_region *region) 118c40c7a99SStefan Roese { 119c40c7a99SStefan Roese if (section) 120c40c7a99SStefan Roese return -ERANGE; 121c40c7a99SStefan Roese 122c40c7a99SStefan Roese region->offset = 64; 123c40c7a99SStefan Roese region->length = 64; 124c40c7a99SStefan Roese 125c40c7a99SStefan Roese return 0; 126c40c7a99SStefan Roese } 127c40c7a99SStefan Roese 128469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section, 129c40c7a99SStefan Roese struct mtd_oob_region *region) 130c40c7a99SStefan Roese { 131c40c7a99SStefan Roese if (section) 132c40c7a99SStefan Roese return -ERANGE; 133c40c7a99SStefan Roese 134c40c7a99SStefan Roese /* Reserve 1 bytes for the BBM. */ 135c40c7a99SStefan Roese region->offset = 1; 136c40c7a99SStefan Roese region->length = 63; 137c40c7a99SStefan Roese 138c40c7a99SStefan Roese return 0; 139c40c7a99SStefan Roese } 140c40c7a99SStefan Roese 141469b9924SReto Schneider /* Valid for Q4/Q5 and Q6 (untested) devices */ 142469b9924SReto Schneider static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = { 143469b9924SReto Schneider .ecc = gd5fxgqx_variant2_ooblayout_ecc, 144469b9924SReto Schneider .free = gd5fxgqx_variant2_ooblayout_free, 145cfd93d7cSJeff Kletsky }; 146cfd93d7cSJeff Kletsky 147302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section, 148302d8a22SHauke Mehrtens struct mtd_oob_region *oobregion) 149302d8a22SHauke Mehrtens { 150302d8a22SHauke Mehrtens if (section) 151302d8a22SHauke Mehrtens return -ERANGE; 152302d8a22SHauke Mehrtens 153302d8a22SHauke Mehrtens oobregion->offset = 128; 154302d8a22SHauke Mehrtens oobregion->length = 128; 155302d8a22SHauke Mehrtens 156302d8a22SHauke Mehrtens return 0; 157302d8a22SHauke Mehrtens } 158302d8a22SHauke Mehrtens 159302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section, 160302d8a22SHauke Mehrtens struct mtd_oob_region *oobregion) 161302d8a22SHauke Mehrtens { 162302d8a22SHauke Mehrtens if (section) 163302d8a22SHauke Mehrtens return -ERANGE; 164302d8a22SHauke Mehrtens 165302d8a22SHauke Mehrtens oobregion->offset = 1; 166302d8a22SHauke Mehrtens oobregion->length = 127; 167302d8a22SHauke Mehrtens 168302d8a22SHauke Mehrtens return 0; 169302d8a22SHauke Mehrtens } 170302d8a22SHauke Mehrtens 171302d8a22SHauke Mehrtens static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = { 172302d8a22SHauke Mehrtens .ecc = gd5fxgq4xc_ooblayout_256_ecc, 173302d8a22SHauke Mehrtens .free = gd5fxgq4xc_ooblayout_256_free, 174302d8a22SHauke Mehrtens }; 175302d8a22SHauke Mehrtens 176c40c7a99SStefan Roese static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, 177c40c7a99SStefan Roese u8 status) 178c40c7a99SStefan Roese { 179c40c7a99SStefan Roese u8 status2; 180469b9924SReto Schneider struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 181c40c7a99SStefan Roese &status2); 182c40c7a99SStefan Roese int ret; 183c40c7a99SStefan Roese 184c40c7a99SStefan Roese switch (status & STATUS_ECC_MASK) { 185c40c7a99SStefan Roese case STATUS_ECC_NO_BITFLIPS: 186c40c7a99SStefan Roese return 0; 187c40c7a99SStefan Roese 188c40c7a99SStefan Roese case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 189c40c7a99SStefan Roese /* 190c40c7a99SStefan Roese * Read status2 register to determine a more fine grained 191c40c7a99SStefan Roese * bit error status 192c40c7a99SStefan Roese */ 193c40c7a99SStefan Roese ret = spi_mem_exec_op(spinand->spimem, &op); 194c40c7a99SStefan Roese if (ret) 195c40c7a99SStefan Roese return ret; 196c40c7a99SStefan Roese 197c40c7a99SStefan Roese /* 198c40c7a99SStefan Roese * 4 ... 7 bits are flipped (1..4 can't be detected, so 199c40c7a99SStefan Roese * report the maximum of 4 in this case 200c40c7a99SStefan Roese */ 201c40c7a99SStefan Roese /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */ 202c40c7a99SStefan Roese return ((status & STATUS_ECC_MASK) >> 2) | 203c40c7a99SStefan Roese ((status2 & STATUS_ECC_MASK) >> 4); 204c40c7a99SStefan Roese 205c40c7a99SStefan Roese case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 206c40c7a99SStefan Roese return 8; 207c40c7a99SStefan Roese 208c40c7a99SStefan Roese case STATUS_ECC_UNCOR_ERROR: 209c40c7a99SStefan Roese return -EBADMSG; 210c40c7a99SStefan Roese 211c40c7a99SStefan Roese default: 212c40c7a99SStefan Roese break; 213c40c7a99SStefan Roese } 214c40c7a99SStefan Roese 215c40c7a99SStefan Roese return -EINVAL; 216c40c7a99SStefan Roese } 217c40c7a99SStefan Roese 218469b9924SReto Schneider static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, 219469b9924SReto Schneider u8 status) 220469b9924SReto Schneider { 221469b9924SReto Schneider u8 status2; 222469b9924SReto Schneider struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 223469b9924SReto Schneider &status2); 224469b9924SReto Schneider int ret; 225469b9924SReto Schneider 226469b9924SReto Schneider switch (status & STATUS_ECC_MASK) { 227469b9924SReto Schneider case STATUS_ECC_NO_BITFLIPS: 228469b9924SReto Schneider return 0; 229469b9924SReto Schneider 230469b9924SReto Schneider case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS: 231469b9924SReto Schneider /* 232469b9924SReto Schneider * Read status2 register to determine a more fine grained 233469b9924SReto Schneider * bit error status 234469b9924SReto Schneider */ 235469b9924SReto Schneider ret = spi_mem_exec_op(spinand->spimem, &op); 236469b9924SReto Schneider if (ret) 237469b9924SReto Schneider return ret; 238469b9924SReto Schneider 239469b9924SReto Schneider /* 240469b9924SReto Schneider * 1 ... 4 bits are flipped (and corrected) 241469b9924SReto Schneider */ 242469b9924SReto Schneider /* bits sorted this way (1...0): ECCSE1, ECCSE0 */ 243469b9924SReto Schneider return ((status2 & STATUS_ECC_MASK) >> 4) + 1; 244469b9924SReto Schneider 245469b9924SReto Schneider case STATUS_ECC_UNCOR_ERROR: 246469b9924SReto Schneider return -EBADMSG; 247469b9924SReto Schneider 248469b9924SReto Schneider default: 249469b9924SReto Schneider break; 250469b9924SReto Schneider } 251469b9924SReto Schneider 252469b9924SReto Schneider return -EINVAL; 253469b9924SReto Schneider } 254469b9924SReto Schneider 255cfd93d7cSJeff Kletsky static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand, 256cfd93d7cSJeff Kletsky u8 status) 257cfd93d7cSJeff Kletsky { 258cfd93d7cSJeff Kletsky switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) { 259cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS: 260cfd93d7cSJeff Kletsky return 0; 261c93c6132SChuanhong Guo 262cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS: 263cfd93d7cSJeff Kletsky return 3; 264cfd93d7cSJeff Kletsky 265cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR: 266cfd93d7cSJeff Kletsky return -EBADMSG; 267cfd93d7cSJeff Kletsky 268cfd93d7cSJeff Kletsky default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */ 269cfd93d7cSJeff Kletsky return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2; 270cfd93d7cSJeff Kletsky } 271cfd93d7cSJeff Kletsky 272cfd93d7cSJeff Kletsky return -EINVAL; 273cfd93d7cSJeff Kletsky } 274c40c7a99SStefan Roese 275c93c6132SChuanhong Guo static const struct spinand_info gigadevice_spinand_table[] = { 276f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4xA", 277f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1), 278377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 279c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 280c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 281c93c6132SChuanhong Guo &write_cache_variants, 282c93c6132SChuanhong Guo &update_cache_variants), 283aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 284c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 285c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 286f1541773SChuanhong Guo SPINAND_INFO("GD5F2GQ4xA", 287f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2), 288377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 289c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 290c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 291c93c6132SChuanhong Guo &write_cache_variants, 292c93c6132SChuanhong Guo &update_cache_variants), 293aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 294c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 295c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 296f1541773SChuanhong Guo SPINAND_INFO("GD5F4GQ4xA", 297f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4), 298a126483eSFrieder Schrempf NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1), 299c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 300c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 301c93c6132SChuanhong Guo &write_cache_variants, 302c93c6132SChuanhong Guo &update_cache_variants), 303aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 304c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 305c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 306302d8a22SHauke Mehrtens SPINAND_INFO("GD5F4GQ4RC", 307302d8a22SHauke Mehrtens SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68), 308302d8a22SHauke Mehrtens NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 309302d8a22SHauke Mehrtens NAND_ECCREQ(8, 512), 310302d8a22SHauke Mehrtens SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 311302d8a22SHauke Mehrtens &write_cache_variants, 312302d8a22SHauke Mehrtens &update_cache_variants), 313302d8a22SHauke Mehrtens SPINAND_HAS_QE_BIT, 314302d8a22SHauke Mehrtens SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 315302d8a22SHauke Mehrtens gd5fxgq4ufxxg_ecc_get_status)), 316302d8a22SHauke Mehrtens SPINAND_INFO("GD5F4GQ4UC", 317302d8a22SHauke Mehrtens SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68), 318302d8a22SHauke Mehrtens NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 319302d8a22SHauke Mehrtens NAND_ECCREQ(8, 512), 320302d8a22SHauke Mehrtens SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 321302d8a22SHauke Mehrtens &write_cache_variants, 322302d8a22SHauke Mehrtens &update_cache_variants), 323302d8a22SHauke Mehrtens SPINAND_HAS_QE_BIT, 324302d8a22SHauke Mehrtens SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 325302d8a22SHauke Mehrtens gd5fxgq4ufxxg_ecc_get_status)), 326f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4UExxG", 327f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1), 328377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 329c40c7a99SStefan Roese NAND_ECCREQ(8, 512), 330c40c7a99SStefan Roese SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 331c40c7a99SStefan Roese &write_cache_variants, 332c40c7a99SStefan Roese &update_cache_variants), 333aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 334469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 335c40c7a99SStefan Roese gd5fxgq4uexxg_ecc_get_status)), 336*573eec22SChuanhong Guo SPINAND_INFO("GD5F1GQ4RExxG", 337*573eec22SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1), 338*573eec22SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 339*573eec22SChuanhong Guo NAND_ECCREQ(8, 512), 340*573eec22SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 341*573eec22SChuanhong Guo &write_cache_variants, 342*573eec22SChuanhong Guo &update_cache_variants), 343*573eec22SChuanhong Guo SPINAND_HAS_QE_BIT, 344*573eec22SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 345*573eec22SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 346*573eec22SChuanhong Guo SPINAND_INFO("GD5F2GQ4UExxG", 347*573eec22SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2), 348*573eec22SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 349*573eec22SChuanhong Guo NAND_ECCREQ(8, 512), 350*573eec22SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 351*573eec22SChuanhong Guo &write_cache_variants, 352*573eec22SChuanhong Guo &update_cache_variants), 353*573eec22SChuanhong Guo SPINAND_HAS_QE_BIT, 354*573eec22SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 355*573eec22SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 356*573eec22SChuanhong Guo SPINAND_INFO("GD5F2GQ4RExxG", 357*573eec22SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2), 358*573eec22SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 359*573eec22SChuanhong Guo NAND_ECCREQ(8, 512), 360*573eec22SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 361*573eec22SChuanhong Guo &write_cache_variants, 362*573eec22SChuanhong Guo &update_cache_variants), 363*573eec22SChuanhong Guo SPINAND_HAS_QE_BIT, 364*573eec22SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 365*573eec22SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 366f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4UFxxG", 367f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), 368cfd93d7cSJeff Kletsky NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 369cfd93d7cSJeff Kletsky NAND_ECCREQ(8, 512), 370cfd93d7cSJeff Kletsky SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 371cfd93d7cSJeff Kletsky &write_cache_variants, 372cfd93d7cSJeff Kletsky &update_cache_variants), 373aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 374469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 375cfd93d7cSJeff Kletsky gd5fxgq4ufxxg_ecc_get_status)), 376469b9924SReto Schneider SPINAND_INFO("GD5F1GQ5UExxG", 377469b9924SReto Schneider SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), 378469b9924SReto Schneider NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 379469b9924SReto Schneider NAND_ECCREQ(4, 512), 380a4f9dd55SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 381469b9924SReto Schneider &write_cache_variants, 382469b9924SReto Schneider &update_cache_variants), 383469b9924SReto Schneider SPINAND_HAS_QE_BIT, 384469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 385469b9924SReto Schneider gd5fxgq5xexxg_ecc_get_status)), 386c93c6132SChuanhong Guo }; 387c93c6132SChuanhong Guo 388c93c6132SChuanhong Guo static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { 389c93c6132SChuanhong Guo }; 390c93c6132SChuanhong Guo 391c93c6132SChuanhong Guo const struct spinand_manufacturer gigadevice_spinand_manufacturer = { 392c93c6132SChuanhong Guo .id = SPINAND_MFR_GIGADEVICE, 393c93c6132SChuanhong Guo .name = "GigaDevice", 394f1541773SChuanhong Guo .chips = gigadevice_spinand_table, 395f1541773SChuanhong Guo .nchips = ARRAY_SIZE(gigadevice_spinand_table), 396c93c6132SChuanhong Guo .ops = &gigadevice_spinand_manuf_ops, 397c93c6132SChuanhong Guo }; 398