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 const struct spinand_info xtx_spinand_table[] = { 209 SPINAND_INFO("XT26G01A", 210 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1), 211 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 212 NAND_ECCREQ(8, 512), 213 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 214 &write_cache_variants, 215 &update_cache_variants), 216 SPINAND_HAS_QE_BIT, 217 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 218 xt26g0xa_ecc_get_status)), 219 SPINAND_INFO("XT26G02A", 220 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE2), 221 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 222 NAND_ECCREQ(8, 512), 223 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 224 &write_cache_variants, 225 &update_cache_variants), 226 SPINAND_HAS_QE_BIT, 227 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 228 xt26g0xa_ecc_get_status)), 229 SPINAND_INFO("XT26G04A", 230 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE3), 231 NAND_MEMORG(1, 2048, 64, 128, 2048, 1, 1, 1), 232 NAND_ECCREQ(8, 512), 233 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 234 &write_cache_variants, 235 &update_cache_variants), 236 SPINAND_HAS_QE_BIT, 237 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 238 xt26g0xa_ecc_get_status)), 239 SPINAND_INFO("XT26G01B", 240 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xF1), 241 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 242 NAND_ECCREQ(8, 512), 243 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 244 &write_cache_variants, 245 &update_cache_variants), 246 SPINAND_HAS_QE_BIT, 247 SPINAND_ECCINFO(&xt26g01b_ooblayout, 248 xt26g0xa_ecc_get_status)), 249 SPINAND_INFO("XT26G02B", 250 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xF2), 251 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 252 NAND_ECCREQ(4, 512), 253 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 254 &write_cache_variants, 255 &update_cache_variants), 256 SPINAND_HAS_QE_BIT, 257 SPINAND_ECCINFO(&xt26g02b_ooblayout, 258 xt26g02b_ecc_get_status)), 259 SPINAND_INFO("XT26G01C", 260 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11), 261 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 262 NAND_ECCREQ(8, 512), 263 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 264 &write_cache_variants, 265 &update_cache_variants), 266 SPINAND_HAS_QE_BIT, 267 SPINAND_ECCINFO(&xt26g01c_ooblayout, 268 xt26g01c_ecc_get_status)), 269 SPINAND_INFO("XT26G02C", 270 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x12), 271 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 272 NAND_ECCREQ(8, 512), 273 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 274 &write_cache_variants, 275 &update_cache_variants), 276 SPINAND_HAS_QE_BIT, 277 SPINAND_ECCINFO(&xt26g0xa_ooblayout, 278 xt26g01c_ecc_get_status)), 279 SPINAND_INFO("XT26G04C", 280 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x13), 281 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), 282 NAND_ECCREQ(8, 512), 283 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 284 &write_cache_variants, 285 &update_cache_variants), 286 SPINAND_HAS_QE_BIT, 287 SPINAND_ECCINFO(&xt26g01c_ooblayout, 288 xt26g01c_ecc_get_status)), 289 SPINAND_INFO("XT26G11C", 290 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x15), 291 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), 292 NAND_ECCREQ(8, 512), 293 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 294 &write_cache_variants, 295 &update_cache_variants), 296 SPINAND_HAS_QE_BIT, 297 SPINAND_ECCINFO(&xt26g01c_ooblayout, 298 xt26g01c_ecc_get_status)), 299 }; 300 301 static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = { 302 }; 303 304 const struct spinand_manufacturer xtx_spinand_manufacturer = { 305 .id = SPINAND_MFR_XTX, 306 .name = "xtx", 307 .chips = xtx_spinand_table, 308 .nchips = ARRAY_SIZE(xtx_spinand_table), 309 .ops = &xtx_spinand_manuf_ops, 310 }; 311