Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Author:
0004  *  Chuanhong Guo <gch981213@gmail.com>
0005  */
0006 
0007 #include <linux/device.h>
0008 #include <linux/kernel.h>
0009 #include <linux/mtd/spinand.h>
0010 
0011 #define SPINAND_MFR_GIGADEVICE          0xC8
0012 
0013 #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS  (1 << 4)
0014 #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS    (3 << 4)
0015 
0016 #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS  (1 << 4)
0017 #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS    (3 << 4)
0018 
0019 #define GD5FXGQXXEXXG_REG_STATUS2       0xf0
0020 
0021 #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK      (7 << 4)
0022 #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS   (0 << 4)
0023 #define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS  (1 << 4)
0024 #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR   (7 << 4)
0025 
0026 static SPINAND_OP_VARIANTS(read_cache_variants,
0027         SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
0028         SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
0029         SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
0030         SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
0031         SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
0032         SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
0033 
0034 static SPINAND_OP_VARIANTS(read_cache_variants_f,
0035         SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
0036         SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
0037         SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
0038         SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
0039         SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
0040         SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
0041 
0042 static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
0043         SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
0044         SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
0045         SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
0046         SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
0047         SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
0048         SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
0049 
0050 static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
0051         SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
0052         SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
0053         SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
0054         SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
0055         SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
0056         SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
0057 
0058 static SPINAND_OP_VARIANTS(write_cache_variants,
0059         SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
0060         SPINAND_PROG_LOAD(true, 0, NULL, 0));
0061 
0062 static SPINAND_OP_VARIANTS(update_cache_variants,
0063         SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
0064         SPINAND_PROG_LOAD(false, 0, NULL, 0));
0065 
0066 static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
0067                   struct mtd_oob_region *region)
0068 {
0069     if (section > 3)
0070         return -ERANGE;
0071 
0072     region->offset = (16 * section) + 8;
0073     region->length = 8;
0074 
0075     return 0;
0076 }
0077 
0078 static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
0079                    struct mtd_oob_region *region)
0080 {
0081     if (section > 3)
0082         return -ERANGE;
0083 
0084     if (section) {
0085         region->offset = 16 * section;
0086         region->length = 8;
0087     } else {
0088         /* section 0 has one byte reserved for bad block mark */
0089         region->offset = 1;
0090         region->length = 7;
0091     }
0092     return 0;
0093 }
0094 
0095 static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
0096     .ecc = gd5fxgq4xa_ooblayout_ecc,
0097     .free = gd5fxgq4xa_ooblayout_free,
0098 };
0099 
0100 static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
0101                      u8 status)
0102 {
0103     switch (status & STATUS_ECC_MASK) {
0104     case STATUS_ECC_NO_BITFLIPS:
0105         return 0;
0106 
0107     case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
0108         /* 1-7 bits are flipped. return the maximum. */
0109         return 7;
0110 
0111     case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
0112         return 8;
0113 
0114     case STATUS_ECC_UNCOR_ERROR:
0115         return -EBADMSG;
0116 
0117     default:
0118         break;
0119     }
0120 
0121     return -EINVAL;
0122 }
0123 
0124 static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
0125                        struct mtd_oob_region *region)
0126 {
0127     if (section)
0128         return -ERANGE;
0129 
0130     region->offset = 64;
0131     region->length = 64;
0132 
0133     return 0;
0134 }
0135 
0136 static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
0137                     struct mtd_oob_region *region)
0138 {
0139     if (section)
0140         return -ERANGE;
0141 
0142     /* Reserve 1 bytes for the BBM. */
0143     region->offset = 1;
0144     region->length = 63;
0145 
0146     return 0;
0147 }
0148 
0149 /* Valid for Q4/Q5 and Q6 (untested) devices */
0150 static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
0151     .ecc = gd5fxgqx_variant2_ooblayout_ecc,
0152     .free = gd5fxgqx_variant2_ooblayout_free,
0153 };
0154 
0155 static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
0156                     struct mtd_oob_region *oobregion)
0157 {
0158     if (section)
0159         return -ERANGE;
0160 
0161     oobregion->offset = 128;
0162     oobregion->length = 128;
0163 
0164     return 0;
0165 }
0166 
0167 static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
0168                      struct mtd_oob_region *oobregion)
0169 {
0170     if (section)
0171         return -ERANGE;
0172 
0173     oobregion->offset = 1;
0174     oobregion->length = 127;
0175 
0176     return 0;
0177 }
0178 
0179 static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
0180     .ecc = gd5fxgq4xc_ooblayout_256_ecc,
0181     .free = gd5fxgq4xc_ooblayout_256_free,
0182 };
0183 
0184 static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
0185                     u8 status)
0186 {
0187     u8 status2;
0188     struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
0189                               &status2);
0190     int ret;
0191 
0192     switch (status & STATUS_ECC_MASK) {
0193     case STATUS_ECC_NO_BITFLIPS:
0194         return 0;
0195 
0196     case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
0197         /*
0198          * Read status2 register to determine a more fine grained
0199          * bit error status
0200          */
0201         ret = spi_mem_exec_op(spinand->spimem, &op);
0202         if (ret)
0203             return ret;
0204 
0205         /*
0206          * 4 ... 7 bits are flipped (1..4 can't be detected, so
0207          * report the maximum of 4 in this case
0208          */
0209         /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
0210         return ((status & STATUS_ECC_MASK) >> 2) |
0211             ((status2 & STATUS_ECC_MASK) >> 4);
0212 
0213     case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
0214         return 8;
0215 
0216     case STATUS_ECC_UNCOR_ERROR:
0217         return -EBADMSG;
0218 
0219     default:
0220         break;
0221     }
0222 
0223     return -EINVAL;
0224 }
0225 
0226 static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
0227                     u8 status)
0228 {
0229     u8 status2;
0230     struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
0231                               &status2);
0232     int ret;
0233 
0234     switch (status & STATUS_ECC_MASK) {
0235     case STATUS_ECC_NO_BITFLIPS:
0236         return 0;
0237 
0238     case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
0239         /*
0240          * Read status2 register to determine a more fine grained
0241          * bit error status
0242          */
0243         ret = spi_mem_exec_op(spinand->spimem, &op);
0244         if (ret)
0245             return ret;
0246 
0247         /*
0248          * 1 ... 4 bits are flipped (and corrected)
0249          */
0250         /* bits sorted this way (1...0): ECCSE1, ECCSE0 */
0251         return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
0252 
0253     case STATUS_ECC_UNCOR_ERROR:
0254         return -EBADMSG;
0255 
0256     default:
0257         break;
0258     }
0259 
0260     return -EINVAL;
0261 }
0262 
0263 static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
0264                     u8 status)
0265 {
0266     switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
0267     case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
0268         return 0;
0269 
0270     case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
0271         return 3;
0272 
0273     case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
0274         return -EBADMSG;
0275 
0276     default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
0277         return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
0278     }
0279 
0280     return -EINVAL;
0281 }
0282 
0283 static const struct spinand_info gigadevice_spinand_table[] = {
0284     SPINAND_INFO("GD5F1GQ4xA",
0285              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
0286              NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
0287              NAND_ECCREQ(8, 512),
0288              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0289                           &write_cache_variants,
0290                           &update_cache_variants),
0291              SPINAND_HAS_QE_BIT,
0292              SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
0293                      gd5fxgq4xa_ecc_get_status)),
0294     SPINAND_INFO("GD5F2GQ4xA",
0295              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
0296              NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
0297              NAND_ECCREQ(8, 512),
0298              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0299                           &write_cache_variants,
0300                           &update_cache_variants),
0301              SPINAND_HAS_QE_BIT,
0302              SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
0303                      gd5fxgq4xa_ecc_get_status)),
0304     SPINAND_INFO("GD5F4GQ4xA",
0305              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
0306              NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
0307              NAND_ECCREQ(8, 512),
0308              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0309                           &write_cache_variants,
0310                           &update_cache_variants),
0311              SPINAND_HAS_QE_BIT,
0312              SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
0313                      gd5fxgq4xa_ecc_get_status)),
0314     SPINAND_INFO("GD5F4GQ4RC",
0315              SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
0316              NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
0317              NAND_ECCREQ(8, 512),
0318              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
0319                           &write_cache_variants,
0320                           &update_cache_variants),
0321              SPINAND_HAS_QE_BIT,
0322              SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
0323                      gd5fxgq4ufxxg_ecc_get_status)),
0324     SPINAND_INFO("GD5F4GQ4UC",
0325              SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
0326              NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
0327              NAND_ECCREQ(8, 512),
0328              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
0329                           &write_cache_variants,
0330                           &update_cache_variants),
0331              SPINAND_HAS_QE_BIT,
0332              SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
0333                      gd5fxgq4ufxxg_ecc_get_status)),
0334     SPINAND_INFO("GD5F1GQ4UExxG",
0335              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
0336              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0337              NAND_ECCREQ(8, 512),
0338              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0339                           &write_cache_variants,
0340                           &update_cache_variants),
0341              SPINAND_HAS_QE_BIT,
0342              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0343                      gd5fxgq4uexxg_ecc_get_status)),
0344     SPINAND_INFO("GD5F1GQ4RExxG",
0345              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
0346              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0347              NAND_ECCREQ(8, 512),
0348              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0349                           &write_cache_variants,
0350                           &update_cache_variants),
0351              SPINAND_HAS_QE_BIT,
0352              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0353                      gd5fxgq4uexxg_ecc_get_status)),
0354     SPINAND_INFO("GD5F2GQ4UExxG",
0355              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
0356              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
0357              NAND_ECCREQ(8, 512),
0358              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0359                           &write_cache_variants,
0360                           &update_cache_variants),
0361              SPINAND_HAS_QE_BIT,
0362              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0363                      gd5fxgq4uexxg_ecc_get_status)),
0364     SPINAND_INFO("GD5F2GQ4RExxG",
0365              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
0366              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
0367              NAND_ECCREQ(8, 512),
0368              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0369                           &write_cache_variants,
0370                           &update_cache_variants),
0371              SPINAND_HAS_QE_BIT,
0372              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0373                      gd5fxgq4uexxg_ecc_get_status)),
0374     SPINAND_INFO("GD5F1GQ4UFxxG",
0375              SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
0376              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0377              NAND_ECCREQ(8, 512),
0378              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
0379                           &write_cache_variants,
0380                           &update_cache_variants),
0381              SPINAND_HAS_QE_BIT,
0382              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0383                      gd5fxgq4ufxxg_ecc_get_status)),
0384     SPINAND_INFO("GD5F1GQ5UExxG",
0385              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
0386              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0387              NAND_ECCREQ(4, 512),
0388              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0389                           &write_cache_variants,
0390                           &update_cache_variants),
0391              SPINAND_HAS_QE_BIT,
0392              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0393                      gd5fxgq5xexxg_ecc_get_status)),
0394     SPINAND_INFO("GD5F1GQ5RExxG",
0395              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
0396              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0397              NAND_ECCREQ(4, 512),
0398              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0399                           &write_cache_variants,
0400                           &update_cache_variants),
0401              SPINAND_HAS_QE_BIT,
0402              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0403                      gd5fxgq5xexxg_ecc_get_status)),
0404     SPINAND_INFO("GD5F2GQ5UExxG",
0405              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
0406              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
0407              NAND_ECCREQ(4, 512),
0408              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
0409                           &write_cache_variants,
0410                           &update_cache_variants),
0411              SPINAND_HAS_QE_BIT,
0412              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0413                      gd5fxgq5xexxg_ecc_get_status)),
0414     SPINAND_INFO("GD5F2GQ5RExxG",
0415              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
0416              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
0417              NAND_ECCREQ(4, 512),
0418              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
0419                           &write_cache_variants,
0420                           &update_cache_variants),
0421              SPINAND_HAS_QE_BIT,
0422              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0423                      gd5fxgq5xexxg_ecc_get_status)),
0424     SPINAND_INFO("GD5F4GQ6UExxG",
0425              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
0426              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
0427              NAND_ECCREQ(4, 512),
0428              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
0429                           &write_cache_variants,
0430                           &update_cache_variants),
0431              SPINAND_HAS_QE_BIT,
0432              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0433                      gd5fxgq5xexxg_ecc_get_status)),
0434     SPINAND_INFO("GD5F4GQ6RExxG",
0435              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
0436              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
0437              NAND_ECCREQ(4, 512),
0438              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
0439                           &write_cache_variants,
0440                           &update_cache_variants),
0441              SPINAND_HAS_QE_BIT,
0442              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0443                      gd5fxgq5xexxg_ecc_get_status)),
0444     SPINAND_INFO("GD5F1GM7UExxG",
0445              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
0446              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0447              NAND_ECCREQ(8, 512),
0448              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0449                           &write_cache_variants,
0450                           &update_cache_variants),
0451              SPINAND_HAS_QE_BIT,
0452              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0453                      gd5fxgq4uexxg_ecc_get_status)),
0454     SPINAND_INFO("GD5F1GM7RExxG",
0455              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
0456              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0457              NAND_ECCREQ(8, 512),
0458              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0459                           &write_cache_variants,
0460                           &update_cache_variants),
0461              SPINAND_HAS_QE_BIT,
0462              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0463                      gd5fxgq4uexxg_ecc_get_status)),
0464     SPINAND_INFO("GD5F2GM7UExxG",
0465              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
0466              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
0467              NAND_ECCREQ(8, 512),
0468              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0469                           &write_cache_variants,
0470                           &update_cache_variants),
0471              SPINAND_HAS_QE_BIT,
0472              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0473                      gd5fxgq4uexxg_ecc_get_status)),
0474     SPINAND_INFO("GD5F2GM7RExxG",
0475              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
0476              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
0477              NAND_ECCREQ(8, 512),
0478              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0479                           &write_cache_variants,
0480                           &update_cache_variants),
0481              SPINAND_HAS_QE_BIT,
0482              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0483                      gd5fxgq4uexxg_ecc_get_status)),
0484     SPINAND_INFO("GD5F4GM8UExxG",
0485              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
0486              NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
0487              NAND_ECCREQ(8, 512),
0488              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0489                           &write_cache_variants,
0490                           &update_cache_variants),
0491              SPINAND_HAS_QE_BIT,
0492              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0493                      gd5fxgq4uexxg_ecc_get_status)),
0494     SPINAND_INFO("GD5F4GM8RExxG",
0495              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
0496              NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
0497              NAND_ECCREQ(8, 512),
0498              SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
0499                           &write_cache_variants,
0500                           &update_cache_variants),
0501              SPINAND_HAS_QE_BIT,
0502              SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
0503                      gd5fxgq4uexxg_ecc_get_status)),
0504 };
0505 
0506 static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
0507 };
0508 
0509 const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
0510     .id = SPINAND_MFR_GIGADEVICE,
0511     .name = "GigaDevice",
0512     .chips = gigadevice_spinand_table,
0513     .nchips = ARRAY_SIZE(gigadevice_spinand_table),
0514     .ops = &gigadevice_spinand_manuf_ops,
0515 };