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 50194ec04bSChuanhong Guo static SPINAND_OP_VARIANTS(read_cache_variants_2gq5, 51194ec04bSChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0), 52194ec04bSChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 53194ec04bSChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0), 54194ec04bSChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 55194ec04bSChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 56194ec04bSChuanhong Guo SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 57194ec04bSChuanhong Guo 58c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(write_cache_variants, 59c93c6132SChuanhong Guo SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 60c93c6132SChuanhong Guo SPINAND_PROG_LOAD(true, 0, NULL, 0)); 61c93c6132SChuanhong Guo 62c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(update_cache_variants, 63c93c6132SChuanhong Guo SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 64c93c6132SChuanhong Guo SPINAND_PROG_LOAD(false, 0, NULL, 0)); 65c93c6132SChuanhong Guo 66c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section, 67c93c6132SChuanhong Guo struct mtd_oob_region *region) 68c93c6132SChuanhong Guo { 69c93c6132SChuanhong Guo if (section > 3) 70c93c6132SChuanhong Guo return -ERANGE; 71c93c6132SChuanhong Guo 72c93c6132SChuanhong Guo region->offset = (16 * section) + 8; 73c93c6132SChuanhong Guo region->length = 8; 74c93c6132SChuanhong Guo 75c93c6132SChuanhong Guo return 0; 76c93c6132SChuanhong Guo } 77c93c6132SChuanhong Guo 78c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section, 79c93c6132SChuanhong Guo struct mtd_oob_region *region) 80c93c6132SChuanhong Guo { 81c93c6132SChuanhong Guo if (section > 3) 82c93c6132SChuanhong Guo return -ERANGE; 83c93c6132SChuanhong Guo 84c93c6132SChuanhong Guo if (section) { 85c93c6132SChuanhong Guo region->offset = 16 * section; 86c93c6132SChuanhong Guo region->length = 8; 87c93c6132SChuanhong Guo } else { 88c93c6132SChuanhong Guo /* section 0 has one byte reserved for bad block mark */ 89c93c6132SChuanhong Guo region->offset = 1; 90c93c6132SChuanhong Guo region->length = 7; 91c93c6132SChuanhong Guo } 92c93c6132SChuanhong Guo return 0; 93c93c6132SChuanhong Guo } 94c93c6132SChuanhong Guo 95cfd93d7cSJeff Kletsky static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { 96cfd93d7cSJeff Kletsky .ecc = gd5fxgq4xa_ooblayout_ecc, 97cfd93d7cSJeff Kletsky .free = gd5fxgq4xa_ooblayout_free, 98cfd93d7cSJeff Kletsky }; 99cfd93d7cSJeff Kletsky 100c93c6132SChuanhong Guo static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand, 101c93c6132SChuanhong Guo u8 status) 102c93c6132SChuanhong Guo { 103c93c6132SChuanhong Guo switch (status & STATUS_ECC_MASK) { 104c93c6132SChuanhong Guo case STATUS_ECC_NO_BITFLIPS: 105c93c6132SChuanhong Guo return 0; 106c93c6132SChuanhong Guo 107c93c6132SChuanhong Guo case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 108c93c6132SChuanhong Guo /* 1-7 bits are flipped. return the maximum. */ 109c93c6132SChuanhong Guo return 7; 110c93c6132SChuanhong Guo 111c93c6132SChuanhong Guo case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 112c93c6132SChuanhong Guo return 8; 113c93c6132SChuanhong Guo 114c93c6132SChuanhong Guo case STATUS_ECC_UNCOR_ERROR: 115c93c6132SChuanhong Guo return -EBADMSG; 116c93c6132SChuanhong Guo 117c93c6132SChuanhong Guo default: 118c93c6132SChuanhong Guo break; 119c93c6132SChuanhong Guo } 120c93c6132SChuanhong Guo 121c93c6132SChuanhong Guo return -EINVAL; 122c93c6132SChuanhong Guo } 123c93c6132SChuanhong Guo 124469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, 125c40c7a99SStefan Roese struct mtd_oob_region *region) 126c40c7a99SStefan Roese { 127c40c7a99SStefan Roese if (section) 128c40c7a99SStefan Roese return -ERANGE; 129c40c7a99SStefan Roese 130c40c7a99SStefan Roese region->offset = 64; 131c40c7a99SStefan Roese region->length = 64; 132c40c7a99SStefan Roese 133c40c7a99SStefan Roese return 0; 134c40c7a99SStefan Roese } 135c40c7a99SStefan Roese 136469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section, 137c40c7a99SStefan Roese struct mtd_oob_region *region) 138c40c7a99SStefan Roese { 139c40c7a99SStefan Roese if (section) 140c40c7a99SStefan Roese return -ERANGE; 141c40c7a99SStefan Roese 142c40c7a99SStefan Roese /* Reserve 1 bytes for the BBM. */ 143c40c7a99SStefan Roese region->offset = 1; 144c40c7a99SStefan Roese region->length = 63; 145c40c7a99SStefan Roese 146c40c7a99SStefan Roese return 0; 147c40c7a99SStefan Roese } 148c40c7a99SStefan Roese 149469b9924SReto Schneider /* Valid for Q4/Q5 and Q6 (untested) devices */ 150469b9924SReto Schneider static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = { 151469b9924SReto Schneider .ecc = gd5fxgqx_variant2_ooblayout_ecc, 152469b9924SReto Schneider .free = gd5fxgqx_variant2_ooblayout_free, 153cfd93d7cSJeff Kletsky }; 154cfd93d7cSJeff Kletsky 155302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section, 156302d8a22SHauke Mehrtens struct mtd_oob_region *oobregion) 157302d8a22SHauke Mehrtens { 158302d8a22SHauke Mehrtens if (section) 159302d8a22SHauke Mehrtens return -ERANGE; 160302d8a22SHauke Mehrtens 161302d8a22SHauke Mehrtens oobregion->offset = 128; 162302d8a22SHauke Mehrtens oobregion->length = 128; 163302d8a22SHauke Mehrtens 164302d8a22SHauke Mehrtens return 0; 165302d8a22SHauke Mehrtens } 166302d8a22SHauke Mehrtens 167302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section, 168302d8a22SHauke Mehrtens struct mtd_oob_region *oobregion) 169302d8a22SHauke Mehrtens { 170302d8a22SHauke Mehrtens if (section) 171302d8a22SHauke Mehrtens return -ERANGE; 172302d8a22SHauke Mehrtens 173302d8a22SHauke Mehrtens oobregion->offset = 1; 174302d8a22SHauke Mehrtens oobregion->length = 127; 175302d8a22SHauke Mehrtens 176302d8a22SHauke Mehrtens return 0; 177302d8a22SHauke Mehrtens } 178302d8a22SHauke Mehrtens 179302d8a22SHauke Mehrtens static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = { 180302d8a22SHauke Mehrtens .ecc = gd5fxgq4xc_ooblayout_256_ecc, 181302d8a22SHauke Mehrtens .free = gd5fxgq4xc_ooblayout_256_free, 182302d8a22SHauke Mehrtens }; 183302d8a22SHauke Mehrtens 184c40c7a99SStefan Roese static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, 185c40c7a99SStefan Roese u8 status) 186c40c7a99SStefan Roese { 187c40c7a99SStefan Roese u8 status2; 188469b9924SReto Schneider struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 189c40c7a99SStefan Roese &status2); 190c40c7a99SStefan Roese int ret; 191c40c7a99SStefan Roese 192c40c7a99SStefan Roese switch (status & STATUS_ECC_MASK) { 193c40c7a99SStefan Roese case STATUS_ECC_NO_BITFLIPS: 194c40c7a99SStefan Roese return 0; 195c40c7a99SStefan Roese 196c40c7a99SStefan Roese case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: 197c40c7a99SStefan Roese /* 198c40c7a99SStefan Roese * Read status2 register to determine a more fine grained 199c40c7a99SStefan Roese * bit error status 200c40c7a99SStefan Roese */ 201c40c7a99SStefan Roese ret = spi_mem_exec_op(spinand->spimem, &op); 202c40c7a99SStefan Roese if (ret) 203c40c7a99SStefan Roese return ret; 204c40c7a99SStefan Roese 205c40c7a99SStefan Roese /* 206c40c7a99SStefan Roese * 4 ... 7 bits are flipped (1..4 can't be detected, so 207c40c7a99SStefan Roese * report the maximum of 4 in this case 208c40c7a99SStefan Roese */ 209c40c7a99SStefan Roese /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */ 210c40c7a99SStefan Roese return ((status & STATUS_ECC_MASK) >> 2) | 211c40c7a99SStefan Roese ((status2 & STATUS_ECC_MASK) >> 4); 212c40c7a99SStefan Roese 213c40c7a99SStefan Roese case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: 214c40c7a99SStefan Roese return 8; 215c40c7a99SStefan Roese 216c40c7a99SStefan Roese case STATUS_ECC_UNCOR_ERROR: 217c40c7a99SStefan Roese return -EBADMSG; 218c40c7a99SStefan Roese 219c40c7a99SStefan Roese default: 220c40c7a99SStefan Roese break; 221c40c7a99SStefan Roese } 222c40c7a99SStefan Roese 223c40c7a99SStefan Roese return -EINVAL; 224c40c7a99SStefan Roese } 225c40c7a99SStefan Roese 226469b9924SReto Schneider static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, 227469b9924SReto Schneider u8 status) 228469b9924SReto Schneider { 229469b9924SReto Schneider u8 status2; 230469b9924SReto Schneider struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, 231469b9924SReto Schneider &status2); 232469b9924SReto Schneider int ret; 233469b9924SReto Schneider 234469b9924SReto Schneider switch (status & STATUS_ECC_MASK) { 235469b9924SReto Schneider case STATUS_ECC_NO_BITFLIPS: 236469b9924SReto Schneider return 0; 237469b9924SReto Schneider 238469b9924SReto Schneider case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS: 239469b9924SReto Schneider /* 240469b9924SReto Schneider * Read status2 register to determine a more fine grained 241469b9924SReto Schneider * bit error status 242469b9924SReto Schneider */ 243469b9924SReto Schneider ret = spi_mem_exec_op(spinand->spimem, &op); 244469b9924SReto Schneider if (ret) 245469b9924SReto Schneider return ret; 246469b9924SReto Schneider 247469b9924SReto Schneider /* 248469b9924SReto Schneider * 1 ... 4 bits are flipped (and corrected) 249469b9924SReto Schneider */ 250469b9924SReto Schneider /* bits sorted this way (1...0): ECCSE1, ECCSE0 */ 251469b9924SReto Schneider return ((status2 & STATUS_ECC_MASK) >> 4) + 1; 252469b9924SReto Schneider 253469b9924SReto Schneider case STATUS_ECC_UNCOR_ERROR: 254469b9924SReto Schneider return -EBADMSG; 255469b9924SReto Schneider 256469b9924SReto Schneider default: 257469b9924SReto Schneider break; 258469b9924SReto Schneider } 259469b9924SReto Schneider 260469b9924SReto Schneider return -EINVAL; 261469b9924SReto Schneider } 262469b9924SReto Schneider 263cfd93d7cSJeff Kletsky static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand, 264cfd93d7cSJeff Kletsky u8 status) 265cfd93d7cSJeff Kletsky { 266cfd93d7cSJeff Kletsky switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) { 267cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS: 268cfd93d7cSJeff Kletsky return 0; 269c93c6132SChuanhong Guo 270cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS: 271cfd93d7cSJeff Kletsky return 3; 272cfd93d7cSJeff Kletsky 273cfd93d7cSJeff Kletsky case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR: 274cfd93d7cSJeff Kletsky return -EBADMSG; 275cfd93d7cSJeff Kletsky 276cfd93d7cSJeff Kletsky default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */ 277cfd93d7cSJeff Kletsky return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2; 278cfd93d7cSJeff Kletsky } 279cfd93d7cSJeff Kletsky 280cfd93d7cSJeff Kletsky return -EINVAL; 281cfd93d7cSJeff Kletsky } 282c40c7a99SStefan Roese 283c93c6132SChuanhong Guo static const struct spinand_info gigadevice_spinand_table[] = { 284f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4xA", 285f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1), 286377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 287c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 288c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 289c93c6132SChuanhong Guo &write_cache_variants, 290c93c6132SChuanhong Guo &update_cache_variants), 291aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 292c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 293c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 294f1541773SChuanhong Guo SPINAND_INFO("GD5F2GQ4xA", 295f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2), 296377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 297c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 298c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 299c93c6132SChuanhong Guo &write_cache_variants, 300c93c6132SChuanhong Guo &update_cache_variants), 301aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 302c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 303c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 304f1541773SChuanhong Guo SPINAND_INFO("GD5F4GQ4xA", 305f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4), 306a126483eSFrieder Schrempf NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1), 307c93c6132SChuanhong Guo NAND_ECCREQ(8, 512), 308c93c6132SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 309c93c6132SChuanhong Guo &write_cache_variants, 310c93c6132SChuanhong Guo &update_cache_variants), 311aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 312c93c6132SChuanhong Guo SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, 313c93c6132SChuanhong Guo gd5fxgq4xa_ecc_get_status)), 314302d8a22SHauke Mehrtens SPINAND_INFO("GD5F4GQ4RC", 315302d8a22SHauke Mehrtens SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68), 316302d8a22SHauke Mehrtens NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 317302d8a22SHauke Mehrtens NAND_ECCREQ(8, 512), 318302d8a22SHauke Mehrtens SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 319302d8a22SHauke Mehrtens &write_cache_variants, 320302d8a22SHauke Mehrtens &update_cache_variants), 321302d8a22SHauke Mehrtens SPINAND_HAS_QE_BIT, 322302d8a22SHauke Mehrtens SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 323302d8a22SHauke Mehrtens gd5fxgq4ufxxg_ecc_get_status)), 324302d8a22SHauke Mehrtens SPINAND_INFO("GD5F4GQ4UC", 325302d8a22SHauke Mehrtens SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68), 326302d8a22SHauke Mehrtens NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 327302d8a22SHauke Mehrtens NAND_ECCREQ(8, 512), 328302d8a22SHauke Mehrtens SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 329302d8a22SHauke Mehrtens &write_cache_variants, 330302d8a22SHauke Mehrtens &update_cache_variants), 331302d8a22SHauke Mehrtens SPINAND_HAS_QE_BIT, 332302d8a22SHauke Mehrtens SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops, 333302d8a22SHauke Mehrtens gd5fxgq4ufxxg_ecc_get_status)), 334f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4UExxG", 335f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1), 336377e517bSBoris Brezillon NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 337c40c7a99SStefan Roese NAND_ECCREQ(8, 512), 338c40c7a99SStefan Roese SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 339c40c7a99SStefan Roese &write_cache_variants, 340c40c7a99SStefan Roese &update_cache_variants), 341aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 342469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 343c40c7a99SStefan Roese gd5fxgq4uexxg_ecc_get_status)), 344573eec22SChuanhong Guo SPINAND_INFO("GD5F1GQ4RExxG", 345573eec22SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1), 346573eec22SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 347573eec22SChuanhong Guo NAND_ECCREQ(8, 512), 348573eec22SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 349573eec22SChuanhong Guo &write_cache_variants, 350573eec22SChuanhong Guo &update_cache_variants), 351573eec22SChuanhong Guo SPINAND_HAS_QE_BIT, 352573eec22SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 353573eec22SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 354573eec22SChuanhong Guo SPINAND_INFO("GD5F2GQ4UExxG", 355573eec22SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2), 356573eec22SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 357573eec22SChuanhong Guo NAND_ECCREQ(8, 512), 358573eec22SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 359573eec22SChuanhong Guo &write_cache_variants, 360573eec22SChuanhong Guo &update_cache_variants), 361573eec22SChuanhong Guo SPINAND_HAS_QE_BIT, 362573eec22SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 363573eec22SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 364573eec22SChuanhong Guo SPINAND_INFO("GD5F2GQ4RExxG", 365573eec22SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2), 366573eec22SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 367573eec22SChuanhong Guo NAND_ECCREQ(8, 512), 368573eec22SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 369573eec22SChuanhong Guo &write_cache_variants, 370573eec22SChuanhong Guo &update_cache_variants), 371573eec22SChuanhong Guo SPINAND_HAS_QE_BIT, 372573eec22SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 373573eec22SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 374f1541773SChuanhong Guo SPINAND_INFO("GD5F1GQ4UFxxG", 375f1541773SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), 376cfd93d7cSJeff Kletsky NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 377cfd93d7cSJeff Kletsky NAND_ECCREQ(8, 512), 378cfd93d7cSJeff Kletsky SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, 379cfd93d7cSJeff Kletsky &write_cache_variants, 380cfd93d7cSJeff Kletsky &update_cache_variants), 381aea7687eSHauke Mehrtens SPINAND_HAS_QE_BIT, 382469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 383cfd93d7cSJeff Kletsky gd5fxgq4ufxxg_ecc_get_status)), 384469b9924SReto Schneider SPINAND_INFO("GD5F1GQ5UExxG", 385469b9924SReto Schneider SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), 386469b9924SReto Schneider NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 387469b9924SReto Schneider NAND_ECCREQ(4, 512), 388a4f9dd55SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 389469b9924SReto Schneider &write_cache_variants, 390469b9924SReto Schneider &update_cache_variants), 391469b9924SReto Schneider SPINAND_HAS_QE_BIT, 392469b9924SReto Schneider SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 393469b9924SReto Schneider gd5fxgq5xexxg_ecc_get_status)), 394620a9888SChuanhong Guo SPINAND_INFO("GD5F1GQ5RExxG", 395620a9888SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41), 396620a9888SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 397620a9888SChuanhong Guo NAND_ECCREQ(4, 512), 398620a9888SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 399620a9888SChuanhong Guo &write_cache_variants, 400620a9888SChuanhong Guo &update_cache_variants), 401620a9888SChuanhong Guo SPINAND_HAS_QE_BIT, 402620a9888SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 403620a9888SChuanhong Guo gd5fxgq5xexxg_ecc_get_status)), 404194ec04bSChuanhong Guo SPINAND_INFO("GD5F2GQ5UExxG", 405194ec04bSChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52), 406194ec04bSChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 407194ec04bSChuanhong Guo NAND_ECCREQ(4, 512), 408194ec04bSChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 409194ec04bSChuanhong Guo &write_cache_variants, 410194ec04bSChuanhong Guo &update_cache_variants), 411194ec04bSChuanhong Guo SPINAND_HAS_QE_BIT, 412194ec04bSChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 413194ec04bSChuanhong Guo gd5fxgq5xexxg_ecc_get_status)), 414194ec04bSChuanhong Guo SPINAND_INFO("GD5F2GQ5RExxG", 415194ec04bSChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42), 416194ec04bSChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 417194ec04bSChuanhong Guo NAND_ECCREQ(4, 512), 418194ec04bSChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 419194ec04bSChuanhong Guo &write_cache_variants, 420194ec04bSChuanhong Guo &update_cache_variants), 421194ec04bSChuanhong Guo SPINAND_HAS_QE_BIT, 422194ec04bSChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 423194ec04bSChuanhong Guo gd5fxgq5xexxg_ecc_get_status)), 424194ec04bSChuanhong Guo SPINAND_INFO("GD5F4GQ6UExxG", 425194ec04bSChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55), 426194ec04bSChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), 427194ec04bSChuanhong Guo NAND_ECCREQ(4, 512), 428194ec04bSChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 429194ec04bSChuanhong Guo &write_cache_variants, 430194ec04bSChuanhong Guo &update_cache_variants), 431194ec04bSChuanhong Guo SPINAND_HAS_QE_BIT, 432194ec04bSChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 433194ec04bSChuanhong Guo gd5fxgq5xexxg_ecc_get_status)), 434194ec04bSChuanhong Guo SPINAND_INFO("GD5F4GQ6RExxG", 435194ec04bSChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45), 436194ec04bSChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), 437194ec04bSChuanhong Guo NAND_ECCREQ(4, 512), 438194ec04bSChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 439194ec04bSChuanhong Guo &write_cache_variants, 440194ec04bSChuanhong Guo &update_cache_variants), 441194ec04bSChuanhong Guo SPINAND_HAS_QE_BIT, 442194ec04bSChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 443194ec04bSChuanhong Guo gd5fxgq5xexxg_ecc_get_status)), 44454647cd0SChuanhong Guo SPINAND_INFO("GD5F1GM7UExxG", 44554647cd0SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91), 44654647cd0SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 44754647cd0SChuanhong Guo NAND_ECCREQ(8, 512), 44854647cd0SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 44954647cd0SChuanhong Guo &write_cache_variants, 45054647cd0SChuanhong Guo &update_cache_variants), 45154647cd0SChuanhong Guo SPINAND_HAS_QE_BIT, 45254647cd0SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 45354647cd0SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 45454647cd0SChuanhong Guo SPINAND_INFO("GD5F1GM7RExxG", 45554647cd0SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81), 45654647cd0SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 45754647cd0SChuanhong Guo NAND_ECCREQ(8, 512), 45854647cd0SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 45954647cd0SChuanhong Guo &write_cache_variants, 46054647cd0SChuanhong Guo &update_cache_variants), 46154647cd0SChuanhong Guo SPINAND_HAS_QE_BIT, 46254647cd0SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 46354647cd0SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 46454647cd0SChuanhong Guo SPINAND_INFO("GD5F2GM7UExxG", 46554647cd0SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), 46654647cd0SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 46754647cd0SChuanhong Guo NAND_ECCREQ(8, 512), 46854647cd0SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 46954647cd0SChuanhong Guo &write_cache_variants, 47054647cd0SChuanhong Guo &update_cache_variants), 47154647cd0SChuanhong Guo SPINAND_HAS_QE_BIT, 47254647cd0SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 47354647cd0SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 47454647cd0SChuanhong Guo SPINAND_INFO("GD5F2GM7RExxG", 47554647cd0SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82), 47654647cd0SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 47754647cd0SChuanhong Guo NAND_ECCREQ(8, 512), 47854647cd0SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 47954647cd0SChuanhong Guo &write_cache_variants, 48054647cd0SChuanhong Guo &update_cache_variants), 48154647cd0SChuanhong Guo SPINAND_HAS_QE_BIT, 48254647cd0SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 48354647cd0SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 48454647cd0SChuanhong Guo SPINAND_INFO("GD5F4GM8UExxG", 48554647cd0SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95), 48654647cd0SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), 48754647cd0SChuanhong Guo NAND_ECCREQ(8, 512), 48854647cd0SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 48954647cd0SChuanhong Guo &write_cache_variants, 49054647cd0SChuanhong Guo &update_cache_variants), 49154647cd0SChuanhong Guo SPINAND_HAS_QE_BIT, 49254647cd0SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 49354647cd0SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 49454647cd0SChuanhong Guo SPINAND_INFO("GD5F4GM8RExxG", 49554647cd0SChuanhong Guo SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85), 49654647cd0SChuanhong Guo NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), 49754647cd0SChuanhong Guo NAND_ECCREQ(8, 512), 49854647cd0SChuanhong Guo SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, 49954647cd0SChuanhong Guo &write_cache_variants, 50054647cd0SChuanhong Guo &update_cache_variants), 50154647cd0SChuanhong Guo SPINAND_HAS_QE_BIT, 50254647cd0SChuanhong Guo SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 50354647cd0SChuanhong Guo gd5fxgq4uexxg_ecc_get_status)), 504*ef1560b6SMd Sadre Alam SPINAND_INFO("GD5F2GQ5xExxH", 505*ef1560b6SMd Sadre Alam SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22), 506*ef1560b6SMd Sadre Alam NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 507*ef1560b6SMd Sadre Alam NAND_ECCREQ(4, 512), 508*ef1560b6SMd Sadre Alam SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, 509*ef1560b6SMd Sadre Alam &write_cache_variants, 510*ef1560b6SMd Sadre Alam &update_cache_variants), 511*ef1560b6SMd Sadre Alam SPINAND_HAS_QE_BIT, 512*ef1560b6SMd Sadre Alam SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, 513*ef1560b6SMd Sadre Alam gd5fxgq4uexxg_ecc_get_status)), 514c93c6132SChuanhong Guo }; 515c93c6132SChuanhong Guo 516c93c6132SChuanhong Guo static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { 517c93c6132SChuanhong Guo }; 518c93c6132SChuanhong Guo 519c93c6132SChuanhong Guo const struct spinand_manufacturer gigadevice_spinand_manufacturer = { 520c93c6132SChuanhong Guo .id = SPINAND_MFR_GIGADEVICE, 521c93c6132SChuanhong Guo .name = "GigaDevice", 522f1541773SChuanhong Guo .chips = gigadevice_spinand_table, 523f1541773SChuanhong Guo .nchips = ARRAY_SIZE(gigadevice_spinand_table), 524c93c6132SChuanhong Guo .ops = &gigadevice_spinand_manuf_ops, 525c93c6132SChuanhong Guo }; 526