xref: /rk3399_rockchip-uboot/drivers/mtd/nand/spi/xtx.c (revision a4719b90cc2f09e5348b830d61f32ab6d991069a)
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 };
376 
377 static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
378 };
379 
380 const struct spinand_manufacturer xtx_spinand_manufacturer = {
381 	.id = SPINAND_MFR_XTX,
382 	.name = "xtx",
383 	.chips = xtx_spinand_table,
384 	.nchips = ARRAY_SIZE(xtx_spinand_table),
385 	.ops = &xtx_spinand_manuf_ops,
386 };
387