.. | .. |
---|
10 | 10 | #include <linux/kernel.h> |
---|
11 | 11 | #include <linux/mtd/spinand.h> |
---|
12 | 12 | |
---|
13 | | -#define SPINAND_MFR_UNIM 0xA1 |
---|
| 13 | +#define SPINAND_MFR_UNIM_ZL 0xA1 |
---|
| 14 | +#define SPINAND_MFR_UNIM 0xB0 |
---|
14 | 15 | |
---|
15 | 16 | static SPINAND_OP_VARIANTS(read_cache_variants, |
---|
16 | 17 | SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), |
---|
.. | .. |
---|
57 | 58 | .free = tx25g01_ooblayout_free, |
---|
58 | 59 | }; |
---|
59 | 60 | |
---|
| 61 | + |
---|
| 62 | +static int um19a0xisw_ooblayout_ecc(struct mtd_info *mtd, int section, |
---|
| 63 | + struct mtd_oob_region *region) |
---|
| 64 | +{ |
---|
| 65 | + return -ERANGE; |
---|
| 66 | +} |
---|
| 67 | + |
---|
| 68 | +static int um19a0xisw_ooblayout_free(struct mtd_info *mtd, int section, |
---|
| 69 | + struct mtd_oob_region *region) |
---|
| 70 | +{ |
---|
| 71 | + if (section) |
---|
| 72 | + return -ERANGE; |
---|
| 73 | + |
---|
| 74 | + region->offset = 2; |
---|
| 75 | + region->length = 62; |
---|
| 76 | + |
---|
| 77 | + return 0; |
---|
| 78 | +} |
---|
| 79 | + |
---|
| 80 | +static const struct mtd_ooblayout_ops um19a0xisw_ooblayout = { |
---|
| 81 | + .ecc = um19a0xisw_ooblayout_ecc, |
---|
| 82 | + .free = um19a0xisw_ooblayout_free, |
---|
| 83 | +}; |
---|
| 84 | + |
---|
| 85 | +static int um19a1xisw_ooblayout_ecc(struct mtd_info *mtd, int section, |
---|
| 86 | + struct mtd_oob_region *region) |
---|
| 87 | +{ |
---|
| 88 | + if (section) |
---|
| 89 | + return -ERANGE; |
---|
| 90 | + |
---|
| 91 | + region->offset = 64; |
---|
| 92 | + region->length = 64; |
---|
| 93 | + |
---|
| 94 | + return 0; |
---|
| 95 | +} |
---|
| 96 | + |
---|
| 97 | +static int um19a1xisw_ooblayout_free(struct mtd_info *mtd, int section, |
---|
| 98 | + struct mtd_oob_region *region) |
---|
| 99 | +{ |
---|
| 100 | + if (section) |
---|
| 101 | + return -ERANGE; |
---|
| 102 | + |
---|
| 103 | + region->offset = 2; |
---|
| 104 | + region->length = 62; |
---|
| 105 | + |
---|
| 106 | + return 0; |
---|
| 107 | +} |
---|
| 108 | + |
---|
| 109 | +static const struct mtd_ooblayout_ops um19a1xisw_ooblayout = { |
---|
| 110 | + .ecc = um19a1xisw_ooblayout_ecc, |
---|
| 111 | + .free = um19a1xisw_ooblayout_free, |
---|
| 112 | +}; |
---|
| 113 | + |
---|
60 | 114 | /* |
---|
61 | 115 | * ecc bits: 0xC0[4,6] |
---|
62 | 116 | * [0b000], No bit errors were detected; |
---|
.. | .. |
---|
69 | 123 | static int tx25g01_ecc_get_status(struct spinand_device *spinand, |
---|
70 | 124 | u8 status) |
---|
71 | 125 | { |
---|
72 | | - u8 eccsr = (status & GENMASK(6, 4)) >> 2; |
---|
| 126 | + struct nand_device *nand = spinand_to_nand(spinand); |
---|
| 127 | + u8 eccsr = (status & GENMASK(6, 4)) >> 4; |
---|
73 | 128 | |
---|
74 | | - if (eccsr <= 7) |
---|
| 129 | + if (eccsr < 4) |
---|
75 | 130 | return eccsr; |
---|
76 | | - else if (eccsr == 12) |
---|
77 | | - return 8; |
---|
| 131 | + else if (eccsr == 4) |
---|
| 132 | + return nanddev_get_ecc_requirements(nand)->strength; |
---|
78 | 133 | else |
---|
79 | 134 | return -EBADMSG; |
---|
80 | 135 | } |
---|
81 | 136 | |
---|
82 | | -static const struct spinand_info unim_spinand_table[] = { |
---|
| 137 | +/* |
---|
| 138 | + * ecc bits: 0xC0[4,6] |
---|
| 139 | + * [0b000], No bit errors were detected; |
---|
| 140 | + * [0b001] and [0b011], 1~6 Bit errors were detected and corrected. Not |
---|
| 141 | + * reach Flipping Bits; |
---|
| 142 | + * [0b101], Bit error count equals the bit flip |
---|
| 143 | + * detection threshold |
---|
| 144 | + * [0b010], Multiple bit errors were detected and |
---|
| 145 | + * not corrected. |
---|
| 146 | + * others, Reserved. |
---|
| 147 | + */ |
---|
| 148 | +static int um19axxisw_ecc_ecc_get_status(struct spinand_device *spinand, |
---|
| 149 | + u8 status) |
---|
| 150 | +{ |
---|
| 151 | + struct nand_device *nand = spinand_to_nand(spinand); |
---|
| 152 | + u8 eccsr = (status & GENMASK(6, 4)) >> 4; |
---|
| 153 | + |
---|
| 154 | + if (eccsr <= 1 || eccsr == 3) |
---|
| 155 | + return eccsr; |
---|
| 156 | + else if (eccsr == 5) |
---|
| 157 | + return nanddev_get_ecc_requirements(nand)->strength; |
---|
| 158 | + else |
---|
| 159 | + return -EBADMSG; |
---|
| 160 | +} |
---|
| 161 | + |
---|
| 162 | +static const struct spinand_info unim_zl_spinand_table[] = { |
---|
83 | 163 | SPINAND_INFO("TX25G01", |
---|
84 | 164 | SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xF1), |
---|
85 | 165 | NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), |
---|
.. | .. |
---|
91 | 171 | SPINAND_ECCINFO(&tx25g01_ooblayout, tx25g01_ecc_get_status)), |
---|
92 | 172 | }; |
---|
93 | 173 | |
---|
| 174 | +static const struct spinand_info unim_spinand_table[] = { |
---|
| 175 | + SPINAND_INFO("UM19A1HISW", |
---|
| 176 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), |
---|
| 177 | + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), |
---|
| 178 | + NAND_ECCREQ(8, 512), |
---|
| 179 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
---|
| 180 | + &write_cache_variants, |
---|
| 181 | + &update_cache_variants), |
---|
| 182 | + SPINAND_HAS_QE_BIT, |
---|
| 183 | + SPINAND_ECCINFO(&um19a1xisw_ooblayout, um19axxisw_ecc_ecc_get_status)), |
---|
| 184 | + SPINAND_INFO("UM19A0HCSW", |
---|
| 185 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14), |
---|
| 186 | + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), |
---|
| 187 | + NAND_ECCREQ(8, 512), |
---|
| 188 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
---|
| 189 | + &write_cache_variants, |
---|
| 190 | + &update_cache_variants), |
---|
| 191 | + SPINAND_HAS_QE_BIT, |
---|
| 192 | + SPINAND_ECCINFO(&um19a0xisw_ooblayout, um19axxisw_ecc_ecc_get_status)), |
---|
| 193 | + SPINAND_INFO("UM19A0LCSW", |
---|
| 194 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15), |
---|
| 195 | + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), |
---|
| 196 | + NAND_ECCREQ(8, 512), |
---|
| 197 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
---|
| 198 | + &write_cache_variants, |
---|
| 199 | + &update_cache_variants), |
---|
| 200 | + SPINAND_HAS_QE_BIT, |
---|
| 201 | + SPINAND_ECCINFO(&um19a0xisw_ooblayout, um19axxisw_ecc_ecc_get_status)), |
---|
| 202 | + SPINAND_INFO("UM19A1LISW", |
---|
| 203 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25), |
---|
| 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 | + SPINAND_HAS_QE_BIT, |
---|
| 210 | + SPINAND_ECCINFO(&um19a1xisw_ooblayout, um19axxisw_ecc_ecc_get_status)), |
---|
| 211 | +}; |
---|
| 212 | + |
---|
94 | 213 | static const struct spinand_manufacturer_ops unim_spinand_manuf_ops = { |
---|
95 | 214 | }; |
---|
96 | 215 | |
---|
| 216 | +const struct spinand_manufacturer unim_zl_spinand_manufacturer = { |
---|
| 217 | + .id = SPINAND_MFR_UNIM_ZL, |
---|
| 218 | + .name = "UNIM_ZL", |
---|
| 219 | + .chips = unim_zl_spinand_table, |
---|
| 220 | + .nchips = ARRAY_SIZE(unim_zl_spinand_table), |
---|
| 221 | + .ops = &unim_spinand_manuf_ops, |
---|
| 222 | +}; |
---|
| 223 | + |
---|
97 | 224 | const struct spinand_manufacturer unim_spinand_manufacturer = { |
---|
98 | 225 | .id = SPINAND_MFR_UNIM, |
---|
99 | 226 | .name = "UNIM", |
---|