1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020 Rockchip Electronics Co., Ltd 4 * 5 * Authors: 6 * Dingqiang Lin <jon.lin@rock-chips.com> 7 */ 8 9 #ifndef __UBOOT__ 10 #include <linux/device.h> 11 #include <linux/kernel.h> 12 #endif 13 #include <linux/mtd/spinand.h> 14 15 #define SPINAND_MFR_XTX 0x0B 16 17 static SPINAND_OP_VARIANTS(read_cache_variants, 18 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 19 SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 20 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 21 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 22 23 static SPINAND_OP_VARIANTS(write_cache_variants, 24 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 25 SPINAND_PROG_LOAD(true, 0, NULL, 0)); 26 27 static SPINAND_OP_VARIANTS(update_cache_variants, 28 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 29 SPINAND_PROG_LOAD(false, 0, NULL, 0)); 30 31 static int xt26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section, 32 struct mtd_oob_region *region) 33 { 34 if (section) 35 return -ERANGE; 36 37 region->offset = 48; 38 region->length = 16; 39 40 return 0; 41 } 42 43 static int xt26g0xa_ooblayout_free(struct mtd_info *mtd, int section, 44 struct mtd_oob_region *region) 45 { 46 if (section) 47 return -ERANGE; 48 49 region->offset = 2; 50 region->length = mtd->oobsize - 18; 51 52 return 0; 53 } 54 55 static const struct mtd_ooblayout_ops xt26g0xa_ooblayout = { 56 .ecc = xt26g0xa_ooblayout_ecc, 57 .rfree = xt26g0xa_ooblayout_free, 58 }; 59 60 static int xt26g01b_ooblayout_ecc(struct mtd_info *mtd, int section, 61 struct mtd_oob_region *region) 62 { 63 return -ERANGE; 64 } 65 66 static int xt26g01b_ooblayout_free(struct mtd_info *mtd, int section, 67 struct mtd_oob_region *region) 68 { 69 if (section) 70 return -ERANGE; 71 72 region->offset = 2; 73 region->length = mtd->oobsize - 2; 74 75 return 0; 76 } 77 78 static const struct mtd_ooblayout_ops xt26g01b_ooblayout = { 79 .ecc = xt26g01b_ooblayout_ecc, 80 .rfree = xt26g01b_ooblayout_free, 81 }; 82 83 static int xt26g02b_ooblayout_ecc(struct mtd_info *mtd, int section, 84 struct mtd_oob_region *region) 85 { 86 if (section > 3) 87 return -ERANGE; 88 89 region->offset = (16 * section) + 8; 90 region->length = 8; 91 92 return 0; 93 } 94 95 static int xt26g02b_ooblayout_free(struct mtd_info *mtd, int section, 96 struct mtd_oob_region *region) 97 { 98 if (section > 3) 99 return -ERANGE; 100 101 region->offset = (16 * section) + 2; 102 region->length = 6; 103 104 return 0; 105 } 106 107 static const struct mtd_ooblayout_ops xt26g02b_ooblayout = { 108 .ecc = xt26g02b_ooblayout_ecc, 109 .rfree = xt26g02b_ooblayout_free, 110 }; 111 112 static int xt26g01c_ooblayout_ecc(struct mtd_info *mtd, int section, 113 struct mtd_oob_region *region) 114 { 115 if (section) 116 return -ERANGE; 117 118 region->offset = mtd->oobsize / 2; 119 region->length = mtd->oobsize / 2; 120 121 return 0; 122 } 123 124 static int xt26g01c_ooblayout_free(struct mtd_info *mtd, int section, 125 struct mtd_oob_region *region) 126 { 127 if (section) 128 return -ERANGE; 129 130 region->offset = 2; 131 region->length = mtd->oobsize / 2 - 2; 132 133 return 0; 134 } 135 136 static const struct mtd_ooblayout_ops xt26g01c_ooblayout = { 137 .ecc = xt26g01c_ooblayout_ecc, 138 .rfree = xt26g01c_ooblayout_free, 139 }; 140 141 /* 142 * ecc bits: 0xC0[2,5] 143 * [0x0000], No bit errors were detected; 144 * [0x0001, 0x0111], Bit errors were detected and corrected. Not 145 * reach Flipping Bits; 146 * [0x1000], Multiple bit errors were detected and 147 * not corrected. 148 * [0x1100], Bit error count equals the bit flip 149 * detectionthreshold 150 * else, reserved 151 */ 152 static int xt26g0xa_ecc_get_status(struct spinand_device *spinand, 153 u8 status) 154 { 155 u8 eccsr = (status & GENMASK(5, 2)) >> 2; 156 157 if (eccsr <= 7) 158 return eccsr; 159 else if (eccsr == 12) 160 return 8; 161 else 162 return -EBADMSG; 163 } 164 165 /* 166 * ecc bits: 0xC0[4,6] 167 * [0x0], No bit errors were detected; 168 * [0x001, 0x011], Bit errors were detected and corrected. Not 169 * reach Flipping Bits; 170 * [0x100], Bit error count equals the bit flip 171 * detectionthreshold 172 * [0x101, 0x110], Reserved; 173 * [0x111], Multiple bit errors were detected and 174 * not corrected. 175 */ 176 static int xt26g02b_ecc_get_status(struct spinand_device *spinand, 177 u8 status) 178 { 179 u8 eccsr = (status & GENMASK(6, 4)) >> 4; 180 181 if (eccsr <= 4) 182 return eccsr; 183 else 184 return -EBADMSG; 185 } 186 187 /* 188 * ecc bits: 0xC0[4,7] 189 * [0b0000], No bit errors were detected; 190 * [0b0001, 0b0111], 1-7 Bit errors were detected and corrected. Not 191 * reach Flipping Bits; 192 * [0b1000], 8 Bit errors were detected and corrected. Bit error count 193 * equals the bit flip detectionthreshold; 194 * [0b1111], Bit errors greater than ECC capability(8 bits) and not corrected; 195 * others, Reserved. 196 */ 197 static int xt26g01c_ecc_get_status(struct spinand_device *spinand, 198 u8 status) 199 { 200 u8 eccsr = (status & GENMASK(7, 4)) >> 4; 201 202 if (eccsr <= 8) 203 return eccsr; 204 else 205 return -EBADMSG; 206 } 207 208 static int xt26g11c_ecc_get_status(struct spinand_device *spinand, 209 u8 status) 210 { 211 struct nand_device *nand = spinand_to_nand(spinand); 212 213 switch (status & STATUS_ECC_MASK) { 214 case STATUS_ECC_NO_BITFLIPS: 215 return 0; 216 217 case STATUS_ECC_UNCOR_ERROR: 218 return -EBADMSG; 219 220 case STATUS_ECC_HAS_BITFLIPS: 221 return 1; 222 223 default: 224 return nand->eccreq.strength; 225 } 226 227 return -EINVAL; 228 } 229 230 static const struct spinand_info xtx_spinand_table[] = { 231 SPINAND_INFO("XT26G01A", 232 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1), 233 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 234 NAND_ECCREQ(8, 512), 235 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 236 &write_cache_variants, 237 &update_cache_variants), 238 SPINAND_HAS_QE_BIT, 239 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 240 xt26g0xa_ecc_get_status)), 241 SPINAND_INFO("XT26G02A", 242 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE2), 243 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 244 NAND_ECCREQ(8, 512), 245 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 246 &write_cache_variants, 247 &update_cache_variants), 248 SPINAND_HAS_QE_BIT, 249 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 250 xt26g0xa_ecc_get_status)), 251 SPINAND_INFO("XT26G04A", 252 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE3), 253 NAND_MEMORG(1, 2048, 64, 128, 2048, 1, 1, 1), 254 NAND_ECCREQ(8, 512), 255 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 256 &write_cache_variants, 257 &update_cache_variants), 258 SPINAND_HAS_QE_BIT, 259 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 260 xt26g0xa_ecc_get_status)), 261 SPINAND_INFO("XT26G01B", 262 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xF1), 263 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 264 NAND_ECCREQ(8, 512), 265 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 266 &write_cache_variants, 267 &update_cache_variants), 268 SPINAND_HAS_QE_BIT, 269 SPINAND_ECCINFO(&xt26g01b_ooblayout, 270 xt26g0xa_ecc_get_status)), 271 SPINAND_INFO("XT26G02B", 272 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xF2), 273 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 274 NAND_ECCREQ(4, 512), 275 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 276 &write_cache_variants, 277 &update_cache_variants), 278 SPINAND_HAS_QE_BIT, 279 SPINAND_ECCINFO(&xt26g02b_ooblayout, 280 xt26g02b_ecc_get_status)), 281 SPINAND_INFO("XT26G01C", 282 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11), 283 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 284 NAND_ECCREQ(8, 512), 285 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 286 &write_cache_variants, 287 &update_cache_variants), 288 SPINAND_HAS_QE_BIT, 289 SPINAND_ECCINFO(&xt26g01c_ooblayout, 290 xt26g01c_ecc_get_status)), 291 SPINAND_INFO("XT26G02C", 292 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x12), 293 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 294 NAND_ECCREQ(8, 512), 295 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 296 &write_cache_variants, 297 &update_cache_variants), 298 SPINAND_HAS_QE_BIT, 299 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 300 xt26g01c_ecc_get_status)), 301 SPINAND_INFO("XT26G04C", 302 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x13), 303 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 304 NAND_ECCREQ(8, 512), 305 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 306 &write_cache_variants, 307 &update_cache_variants), 308 SPINAND_HAS_QE_BIT, 309 SPINAND_ECCINFO(&xt26g01c_ooblayout, 310 xt26g01c_ecc_get_status)), 311 SPINAND_INFO("XT26G11C", 312 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x15), 313 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 314 NAND_ECCREQ(8, 512), 315 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 316 &write_cache_variants, 317 &update_cache_variants), 318 SPINAND_HAS_QE_BIT, 319 SPINAND_ECCINFO(&xt26g01c_ooblayout, 320 xt26g11c_ecc_get_status)), 321 SPINAND_INFO("XT26Q02DWSIGA", 322 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52), 323 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), 324 NAND_ECCREQ(8, 512), 325 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 326 &write_cache_variants, 327 &update_cache_variants), 328 SPINAND_HAS_QE_BIT, 329 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)), 330 SPINAND_INFO("XT26Q01DWSIGA", 331 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), 332 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 333 NAND_ECCREQ(8, 512), 334 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 335 &write_cache_variants, 336 &update_cache_variants), 337 SPINAND_HAS_QE_BIT, 338 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)), 339 SPINAND_INFO("XT26Q04DWSIGA", 340 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x53), 341 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 342 NAND_ECCREQ(8, 512), 343 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 344 &write_cache_variants, 345 &update_cache_variants), 346 SPINAND_HAS_QE_BIT, 347 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)), 348 SPINAND_INFO("XT26G01DWSIGA", 349 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x31), 350 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 351 NAND_ECCREQ(8, 512), 352 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 353 &write_cache_variants, 354 &update_cache_variants), 355 SPINAND_HAS_QE_BIT, 356 SPINAND_ECCINFO(&xt26g01b_ooblayout, xt26g11c_ecc_get_status)), 357 SPINAND_INFO("XT26G02DWSIGA", 358 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32), 359 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 360 NAND_ECCREQ(8, 512), 361 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 362 &write_cache_variants, 363 &update_cache_variants), 364 SPINAND_HAS_QE_BIT, 365 SPINAND_ECCINFO(&xt26g01b_ooblayout, xt26g11c_ecc_get_status)), 366 SPINAND_INFO("XT26G04DWSIGA", 367 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x33), 368 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 369 NAND_ECCREQ(8, 512), 370 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 371 &write_cache_variants, 372 &update_cache_variants), 373 SPINAND_HAS_QE_BIT, 374 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)), 375 SPINAND_INFO("XT26Q04DWSIGT-B", 376 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x53), 377 NAND_MEMORG(1, 4096, 128, 64, 2048, 1, 1, 1), 378 NAND_ECCREQ(14, 512), 379 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 380 &write_cache_variants, 381 &update_cache_variants), 382 SPINAND_HAS_QE_BIT, 383 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)), 384 SPINAND_INFO("XT26Q01DWSIGA", 385 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), 386 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 387 NAND_ECCREQ(8, 512), 388 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 389 &write_cache_variants, 390 &update_cache_variants), 391 SPINAND_HAS_QE_BIT, 392 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)), 393 }; 394 395 static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = { 396 }; 397 398 const struct spinand_manufacturer xtx_spinand_manufacturer = { 399 .id = SPINAND_MFR_XTX, 400 .name = "xtx", 401 .chips = xtx_spinand_table, 402 .nchips = ARRAY_SIZE(xtx_spinand_table), 403 .ops = &xtx_spinand_manuf_ops, 404 }; 405