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
xt26g0xa_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)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
xt26g0xa_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)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
xt26g01b_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)60 static int xt26g01b_ooblayout_ecc(struct mtd_info *mtd, int section,
61 struct mtd_oob_region *region)
62 {
63 return -ERANGE;
64 }
65
xt26g01b_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)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
xt26g02b_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)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
xt26g02b_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)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
xt26g01c_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)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
xt26g01c_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)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 */
xt26g0xa_ecc_get_status(struct spinand_device * spinand,u8 status)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 */
xt26g02b_ecc_get_status(struct spinand_device * spinand,u8 status)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 */
xt26g01c_ecc_get_status(struct spinand_device * spinand,u8 status)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
xt26g11c_ecc_get_status(struct spinand_device * spinand,u8 status)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 SPINAND_INFO("XT26G12DWSIGA",
394 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
395 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
396 NAND_ECCREQ(8, 512),
397 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
398 &write_cache_variants,
399 &update_cache_variants),
400 SPINAND_HAS_QE_BIT,
401 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)),
402 SPINAND_INFO("XT26Q12DWSIGA",
403 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
404 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
405 NAND_ECCREQ(8, 512),
406 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
407 &write_cache_variants,
408 &update_cache_variants),
409 SPINAND_HAS_QE_BIT,
410 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)),
411 SPINAND_INFO("XT26G11DWSIGA",
412 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
413 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
414 NAND_ECCREQ(8, 512),
415 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
416 &write_cache_variants,
417 &update_cache_variants),
418 SPINAND_HAS_QE_BIT,
419 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)),
420 SPINAND_INFO("XT26Q14DWSIGA",
421 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x56),
422 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
423 NAND_ECCREQ(8, 512),
424 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
425 &write_cache_variants,
426 &update_cache_variants),
427 SPINAND_HAS_QE_BIT,
428 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)),
429 SPINAND_INFO("XT26G08DWSIGA",
430 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
431 NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
432 NAND_ECCREQ(8, 512),
433 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
434 &write_cache_variants,
435 &update_cache_variants),
436 SPINAND_HAS_QE_BIT,
437 SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)),
438 };
439
440 static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
441 };
442
443 const struct spinand_manufacturer xtx_spinand_manufacturer = {
444 .id = SPINAND_MFR_XTX,
445 .name = "xtx",
446 .chips = xtx_spinand_table,
447 .nchips = ARRAY_SIZE(xtx_spinand_table),
448 .ops = &xtx_spinand_manuf_ops,
449 };
450