|
4 | 4 | * Felix Matouschek <[email protected]>
|
5 | 5 | */
|
6 | 6 |
|
| 7 | +#include <linux/bitfield.h> |
7 | 8 | #include <linux/device.h>
|
8 | 9 | #include <linux/kernel.h>
|
9 | 10 | #include <linux/mtd/spinand.h>
|
|
15 | 16 | #define XT26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
|
16 | 17 | #define XT26G0XA_STATUS_ECC_UNCOR_ERROR (2 << 4)
|
17 | 18 |
|
| 19 | +#define XT26XXXD_STATUS_ECC3_ECC2_MASK GENMASK(7, 6) |
| 20 | +#define XT26XXXD_STATUS_ECC_NO_DETECTED (0) |
| 21 | +#define XT26XXXD_STATUS_ECC_1_7_CORRECTED (1) |
| 22 | +#define XT26XXXD_STATUS_ECC_8_CORRECTED (3) |
| 23 | +#define XT26XXXD_STATUS_ECC_UNCOR_ERROR (2) |
| 24 | + |
18 | 25 | static SPINAND_OP_VARIANTS(read_cache_variants,
|
19 | 26 | SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
|
20 | 27 | SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
@@ -84,6 +91,53 @@ static int xt26g0xa_ecc_get_status(struct spinand_device *spinand,
|
84 | 91 | return status >> 2;
|
85 | 92 | }
|
86 | 93 |
|
| 94 | +static int xt26xxxd_ooblayout_ecc(struct mtd_info *mtd, int section, |
| 95 | + struct mtd_oob_region *region) |
| 96 | +{ |
| 97 | + if (section) |
| 98 | + return -ERANGE; |
| 99 | + |
| 100 | + region->offset = mtd->oobsize / 2; |
| 101 | + region->length = mtd->oobsize / 2; |
| 102 | + |
| 103 | + return 0; |
| 104 | +} |
| 105 | + |
| 106 | +static int xt26xxxd_ooblayout_free(struct mtd_info *mtd, int section, |
| 107 | + struct mtd_oob_region *region) |
| 108 | +{ |
| 109 | + if (section) |
| 110 | + return -ERANGE; |
| 111 | + |
| 112 | + region->offset = 2; |
| 113 | + region->length = mtd->oobsize / 2 - 2; |
| 114 | + |
| 115 | + return 0; |
| 116 | +} |
| 117 | + |
| 118 | +static const struct mtd_ooblayout_ops xt26xxxd_ooblayout = { |
| 119 | + .ecc = xt26xxxd_ooblayout_ecc, |
| 120 | + .free = xt26xxxd_ooblayout_free, |
| 121 | +}; |
| 122 | + |
| 123 | +static int xt26xxxd_ecc_get_status(struct spinand_device *spinand, |
| 124 | + u8 status) |
| 125 | +{ |
| 126 | + switch (FIELD_GET(STATUS_ECC_MASK, status)) { |
| 127 | + case XT26XXXD_STATUS_ECC_NO_DETECTED: |
| 128 | + return 0; |
| 129 | + case XT26XXXD_STATUS_ECC_UNCOR_ERROR: |
| 130 | + return -EBADMSG; |
| 131 | + case XT26XXXD_STATUS_ECC_1_7_CORRECTED: |
| 132 | + return 4 + FIELD_GET(XT26XXXD_STATUS_ECC3_ECC2_MASK, status); |
| 133 | + case XT26XXXD_STATUS_ECC_8_CORRECTED: |
| 134 | + return 8; |
| 135 | + default: |
| 136 | + break; |
| 137 | + } |
| 138 | + |
| 139 | + return -EINVAL; |
| 140 | +} |
87 | 141 | static const struct spinand_info xtx_spinand_table[] = {
|
88 | 142 | SPINAND_INFO("XT26G01A",
|
89 | 143 | SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1),
|
@@ -115,6 +169,86 @@ static const struct spinand_info xtx_spinand_table[] = {
|
115 | 169 | SPINAND_HAS_QE_BIT,
|
116 | 170 | SPINAND_ECCINFO(&xt26g0xa_ooblayout,
|
117 | 171 | xt26g0xa_ecc_get_status)),
|
| 172 | + SPINAND_INFO("XT26G01D", |
| 173 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x31), |
| 174 | + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
| 175 | + NAND_ECCREQ(8, 512), |
| 176 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 177 | + &write_cache_variants, |
| 178 | + &update_cache_variants), |
| 179 | + 0, |
| 180 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 181 | + xt26xxxd_ecc_get_status)), |
| 182 | + SPINAND_INFO("XT26G11D", |
| 183 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x34), |
| 184 | + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
| 185 | + NAND_ECCREQ(8, 512), |
| 186 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 187 | + &write_cache_variants, |
| 188 | + &update_cache_variants), |
| 189 | + 0, |
| 190 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 191 | + xt26xxxd_ecc_get_status)), |
| 192 | + SPINAND_INFO("XT26Q01D", |
| 193 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51), |
| 194 | + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
| 195 | + NAND_ECCREQ(8, 512), |
| 196 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 197 | + &write_cache_variants, |
| 198 | + &update_cache_variants), |
| 199 | + 0, |
| 200 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 201 | + xt26xxxd_ecc_get_status)), |
| 202 | + SPINAND_INFO("XT26G02D", |
| 203 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x32), |
| 204 | + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), |
| 205 | + NAND_ECCREQ(8, 512), |
| 206 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 207 | + &write_cache_variants, |
| 208 | + &update_cache_variants), |
| 209 | + 0, |
| 210 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 211 | + xt26xxxd_ecc_get_status)), |
| 212 | + SPINAND_INFO("XT26G12D", |
| 213 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x35), |
| 214 | + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), |
| 215 | + NAND_ECCREQ(8, 512), |
| 216 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 217 | + &write_cache_variants, |
| 218 | + &update_cache_variants), |
| 219 | + 0, |
| 220 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 221 | + xt26xxxd_ecc_get_status)), |
| 222 | + SPINAND_INFO("XT26Q02D", |
| 223 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x52), |
| 224 | + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), |
| 225 | + NAND_ECCREQ(8, 512), |
| 226 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 227 | + &write_cache_variants, |
| 228 | + &update_cache_variants), |
| 229 | + 0, |
| 230 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 231 | + xt26xxxd_ecc_get_status)), |
| 232 | + SPINAND_INFO("XT26G04D", |
| 233 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x33), |
| 234 | + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), |
| 235 | + NAND_ECCREQ(8, 512), |
| 236 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 237 | + &write_cache_variants, |
| 238 | + &update_cache_variants), |
| 239 | + 0, |
| 240 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 241 | + xt26xxxd_ecc_get_status)), |
| 242 | + SPINAND_INFO("XT26Q04D", |
| 243 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x53), |
| 244 | + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), |
| 245 | + NAND_ECCREQ(8, 512), |
| 246 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 247 | + &write_cache_variants, |
| 248 | + &update_cache_variants), |
| 249 | + 0, |
| 250 | + SPINAND_ECCINFO(&xt26xxxd_ooblayout, |
| 251 | + xt26xxxd_ecc_get_status)), |
118 | 252 | };
|
119 | 253 |
|
120 | 254 | static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
|
|
0 commit comments