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