xref: /OK3568_Linux_fs/u-boot/drivers/mtd/nand/spi/gigadevice.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2018 Stefan Roese <sr@denx.de>
4  *
5  * Derived from drivers/mtd/nand/spi/micron.c
6  *   Copyright (c) 2016-2017 Micron Technology, Inc.
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_GIGADEVICE			0xC8
16 
17 #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS	(1 << 4)
18 #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS	(3 << 4)
19 
20 #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS	(1 << 4)
21 #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS	(3 << 4)
22 
23 #define GD5FXGQXXEXXG_REG_STATUS2		0xf0
24 
25 #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK		(7 << 4)
26 #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS	(0 << 4)
27 #define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS	(1 << 4)
28 #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR	(7 << 4)
29 
30 static SPINAND_OP_VARIANTS(read_cache_variants,
31 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
32 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
33 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
34 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
35 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
36 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
37 
38 static SPINAND_OP_VARIANTS(read_cache_variants_f,
39 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
40 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
41 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
42 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
43 		SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
44 		SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
45 
46 static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
47 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
48 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
49 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
50 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
51 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
52 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
53 
54 static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
55 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
56 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
57 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
58 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
59 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
60 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
61 
62 static SPINAND_OP_VARIANTS(write_cache_variants,
63 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
64 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
65 
66 static SPINAND_OP_VARIANTS(update_cache_variants,
67 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
68 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
69 
gd5fxgq4xa_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)70 static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
71 				  struct mtd_oob_region *region)
72 {
73 	if (section > 3)
74 		return -ERANGE;
75 
76 	region->offset = (16 * section) + 8;
77 	region->length = 8;
78 
79 	return 0;
80 }
81 
gd5fxgq4xa_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)82 static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
83 				   struct mtd_oob_region *region)
84 {
85 	if (section > 3)
86 		return -ERANGE;
87 
88 	if (section) {
89 		region->offset = 16 * section;
90 		region->length = 8;
91 	} else {
92 		/* section 0 has one byte reserved for bad block mark */
93 		region->offset = 1;
94 		region->length = 7;
95 	}
96 	return 0;
97 }
98 
99 static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
100 	.ecc = gd5fxgq4xa_ooblayout_ecc,
101 	.rfree = gd5fxgq4xa_ooblayout_free,
102 };
103 
gd5fxgq4xa_ecc_get_status(struct spinand_device * spinand,u8 status)104 static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
105 					 u8 status)
106 {
107 	switch (status & STATUS_ECC_MASK) {
108 	case STATUS_ECC_NO_BITFLIPS:
109 		return 0;
110 
111 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
112 		/* 1-7 bits are flipped. return the maximum. */
113 		return 7;
114 
115 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
116 		return 8;
117 
118 	case STATUS_ECC_UNCOR_ERROR:
119 		return -EBADMSG;
120 
121 	default:
122 		break;
123 	}
124 
125 	return -EINVAL;
126 }
127 
gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)128 static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
129 				       struct mtd_oob_region *region)
130 {
131 	if (section)
132 		return -ERANGE;
133 
134 	region->offset = 64;
135 	region->length = 64;
136 
137 	return 0;
138 }
139 
gd5fxgqx_variant2_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)140 static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
141 					struct mtd_oob_region *region)
142 {
143 	if (section)
144 		return -ERANGE;
145 
146 	/* Reserve 1 bytes for the BBM. */
147 	region->offset = 1;
148 	region->length = 63;
149 
150 	return 0;
151 }
152 
153 /* Valid for Q4/Q5 and Q6 (untested) devices */
154 static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
155 	.ecc = gd5fxgqx_variant2_ooblayout_ecc,
156 	.rfree = gd5fxgqx_variant2_ooblayout_free,
157 };
158 
gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * oobregion)159 static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
160 					struct mtd_oob_region *oobregion)
161 {
162 	if (section)
163 		return -ERANGE;
164 
165 	oobregion->offset = 128;
166 	oobregion->length = 128;
167 
168 	return 0;
169 }
170 
gd5fxgq4xc_ooblayout_256_free(struct mtd_info * mtd,int section,struct mtd_oob_region * oobregion)171 static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
172 					 struct mtd_oob_region *oobregion)
173 {
174 	if (section)
175 		return -ERANGE;
176 
177 	oobregion->offset = 1;
178 	oobregion->length = 127;
179 
180 	return 0;
181 }
182 
183 static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
184 	.ecc = gd5fxgq4xc_ooblayout_256_ecc,
185 	.rfree = gd5fxgq4xc_ooblayout_256_free,
186 };
187 
gd5fxgqx_variant3_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)188 static int gd5fxgqx_variant3_ooblayout_ecc(struct mtd_info *mtd, int section,
189 				       struct mtd_oob_region *region)
190 {
191 	return -ERANGE;
192 }
193 
gd5fxgqx_variant3_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)194 static int gd5fxgqx_variant3_ooblayout_free(struct mtd_info *mtd, int section,
195 					struct mtd_oob_region *region)
196 {
197 	if (section)
198 		return -ERANGE;
199 
200 	/* Reserve 1 bytes for the BBM. */
201 	region->offset = 1;
202 	region->length = 63;
203 
204 	return 0;
205 }
206 
207 static const struct mtd_ooblayout_ops gd5fxgqx_variant3_ooblayout = {
208 	.ecc = gd5fxgqx_variant3_ooblayout_ecc,
209 	.rfree = gd5fxgqx_variant3_ooblayout_free,
210 };
211 
gd5fxgq4uexxg_ecc_get_status(struct spinand_device * spinand,u8 status)212 static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
213 					u8 status)
214 {
215 	u8 status2;
216 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
217 						      &status2);
218 	int ret;
219 
220 	switch (status & STATUS_ECC_MASK) {
221 	case STATUS_ECC_NO_BITFLIPS:
222 		return 0;
223 
224 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
225 		/*
226 		 * Read status2 register to determine a more fine grained
227 		 * bit error status
228 		 */
229 		ret = spi_mem_exec_op(spinand->slave, &op);
230 		if (ret)
231 			return ret;
232 
233 		/*
234 		 * 4 ... 7 bits are flipped (1..4 can't be detected, so
235 		 * report the maximum of 4 in this case
236 		 */
237 		/* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
238 		return ((status & STATUS_ECC_MASK) >> 2) |
239 			((status2 & STATUS_ECC_MASK) >> 4);
240 
241 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
242 		return 8;
243 
244 	case STATUS_ECC_UNCOR_ERROR:
245 		return -EBADMSG;
246 
247 	default:
248 		break;
249 	}
250 
251 	return -EINVAL;
252 }
253 
gd5fxgq5xexxg_ecc_get_status(struct spinand_device * spinand,u8 status)254 static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
255 					u8 status)
256 {
257 	u8 status2;
258 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
259 						      &status2);
260 	int ret;
261 
262 	switch (status & STATUS_ECC_MASK) {
263 	case STATUS_ECC_NO_BITFLIPS:
264 		return 0;
265 
266 	case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
267 		/*
268 		 * Read status2 register to determine a more fine grained
269 		 * bit error status
270 		 */
271 		ret = spi_mem_exec_op(spinand->slave, &op);
272 		if (ret)
273 			return ret;
274 
275 		/*
276 		 * 1 ... 4 bits are flipped (and corrected)
277 		 */
278 		/* bits sorted this way (1...0): ECCSE1, ECCSE0 */
279 		return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
280 
281 	case STATUS_ECC_UNCOR_ERROR:
282 		return -EBADMSG;
283 
284 	default:
285 		break;
286 	}
287 
288 	return -EINVAL;
289 }
290 
gd5fxgq4ufxxg_ecc_get_status(struct spinand_device * spinand,u8 status)291 static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
292 					u8 status)
293 {
294 	switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
295 	case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
296 		return 0;
297 
298 	case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
299 		return 3;
300 
301 	case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
302 		return -EBADMSG;
303 
304 	default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
305 		return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
306 	}
307 
308 	return -EINVAL;
309 }
310 
311 static const struct spinand_info gigadevice_spinand_table[] = {
312 	SPINAND_INFO("GD5F1GQ4xA",
313 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
314 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
315 		     NAND_ECCREQ(8, 512),
316 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
317 					      &write_cache_variants,
318 					      &update_cache_variants),
319 		     SPINAND_HAS_QE_BIT,
320 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
321 				     gd5fxgq4xa_ecc_get_status)),
322 	SPINAND_INFO("GD5F2GQ4xA",
323 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
324 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
325 		     NAND_ECCREQ(8, 512),
326 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
327 					      &write_cache_variants,
328 					      &update_cache_variants),
329 		     SPINAND_HAS_QE_BIT,
330 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
331 				     gd5fxgq4xa_ecc_get_status)),
332 	SPINAND_INFO("GD5F4GQ4xA",
333 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
334 		     NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
335 		     NAND_ECCREQ(8, 512),
336 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
337 					      &write_cache_variants,
338 					      &update_cache_variants),
339 		     SPINAND_HAS_QE_BIT,
340 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
341 				     gd5fxgq4xa_ecc_get_status)),
342 	SPINAND_INFO("GD5F4GQ4RC",
343 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
344 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
345 		     NAND_ECCREQ(8, 512),
346 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
347 					      &write_cache_variants,
348 					      &update_cache_variants),
349 		     SPINAND_HAS_QE_BIT,
350 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
351 				     gd5fxgq4ufxxg_ecc_get_status)),
352 	SPINAND_INFO("GD5F4GQ4UC",
353 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
354 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
355 		     NAND_ECCREQ(8, 512),
356 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
357 					      &write_cache_variants,
358 					      &update_cache_variants),
359 		     SPINAND_HAS_QE_BIT,
360 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
361 				     gd5fxgq4ufxxg_ecc_get_status)),
362 	SPINAND_INFO("GD5F1GQ4UExxG",
363 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
364 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
365 		     NAND_ECCREQ(8, 512),
366 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
367 					      &write_cache_variants,
368 					      &update_cache_variants),
369 		     SPINAND_HAS_QE_BIT,
370 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
371 				     gd5fxgq4uexxg_ecc_get_status)),
372 	SPINAND_INFO("GD5F1GQ4RExxG",
373 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
374 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
375 		     NAND_ECCREQ(8, 512),
376 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
377 					      &write_cache_variants,
378 					      &update_cache_variants),
379 		     SPINAND_HAS_QE_BIT,
380 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
381 				     gd5fxgq4uexxg_ecc_get_status)),
382 	SPINAND_INFO("GD5F2GQ4UExxG",
383 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
384 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
385 		     NAND_ECCREQ(8, 512),
386 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
387 					      &write_cache_variants,
388 					      &update_cache_variants),
389 		     SPINAND_HAS_QE_BIT,
390 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
391 				     gd5fxgq4uexxg_ecc_get_status)),
392 	SPINAND_INFO("GD5F2GQ4RExxG",
393 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
394 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
395 		     NAND_ECCREQ(8, 512),
396 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
397 					      &write_cache_variants,
398 					      &update_cache_variants),
399 		     SPINAND_HAS_QE_BIT,
400 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
401 				     gd5fxgq4uexxg_ecc_get_status)),
402 	SPINAND_INFO("GD5F1GQ4UFxxG",
403 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
404 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
405 		     NAND_ECCREQ(8, 512),
406 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
407 					      &write_cache_variants,
408 					      &update_cache_variants),
409 		     SPINAND_HAS_QE_BIT,
410 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
411 				     gd5fxgq4ufxxg_ecc_get_status)),
412 	SPINAND_INFO("GD5F1GQ5UExxG",
413 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
414 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
415 		     NAND_ECCREQ(4, 512),
416 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
417 					      &write_cache_variants,
418 					      &update_cache_variants),
419 		     SPINAND_HAS_QE_BIT,
420 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
421 				     gd5fxgq5xexxg_ecc_get_status)),
422 	SPINAND_INFO("GD5F1GQ5RExxG",
423 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
424 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
425 		     NAND_ECCREQ(4, 512),
426 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
427 					      &write_cache_variants,
428 					      &update_cache_variants),
429 		     SPINAND_HAS_QE_BIT,
430 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
431 				     gd5fxgq5xexxg_ecc_get_status)),
432 	SPINAND_INFO("GD5F2GQ5UExxG",
433 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
434 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
435 		     NAND_ECCREQ(4, 512),
436 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
437 					      &write_cache_variants,
438 					      &update_cache_variants),
439 		     SPINAND_HAS_QE_BIT,
440 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
441 				     gd5fxgq5xexxg_ecc_get_status)),
442 	SPINAND_INFO("GD5F2GQ5RExxG",
443 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
444 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
445 		     NAND_ECCREQ(4, 512),
446 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
447 					      &write_cache_variants,
448 					      &update_cache_variants),
449 		     SPINAND_HAS_QE_BIT,
450 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
451 				     gd5fxgq5xexxg_ecc_get_status)),
452 	SPINAND_INFO("GD5F4GQ6UExxG",
453 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
454 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 2, 1),
455 		     NAND_ECCREQ(4, 512),
456 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
457 					      &write_cache_variants,
458 					      &update_cache_variants),
459 		     SPINAND_HAS_QE_BIT,
460 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
461 				     gd5fxgq5xexxg_ecc_get_status)),
462 	SPINAND_INFO("GD5F4GQ6RExxG",
463 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
464 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 2, 1),
465 		     NAND_ECCREQ(4, 512),
466 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
467 					      &write_cache_variants,
468 					      &update_cache_variants),
469 		     SPINAND_HAS_QE_BIT,
470 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
471 				     gd5fxgq5xexxg_ecc_get_status)),
472 	SPINAND_INFO("GD5F1GM7UExxG",
473 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
474 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
475 		     NAND_ECCREQ(8, 512),
476 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
477 					      &write_cache_variants,
478 					      &update_cache_variants),
479 		     SPINAND_HAS_QE_BIT,
480 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
481 				     gd5fxgq4uexxg_ecc_get_status)),
482 	SPINAND_INFO("GD5F1GM7RExxG",
483 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
484 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
485 		     NAND_ECCREQ(8, 512),
486 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
487 					      &write_cache_variants,
488 					      &update_cache_variants),
489 		     SPINAND_HAS_QE_BIT,
490 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
491 				     gd5fxgq4uexxg_ecc_get_status)),
492 	SPINAND_INFO("GD5F2GM7UExxG",
493 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
494 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
495 		     NAND_ECCREQ(8, 512),
496 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
497 					      &write_cache_variants,
498 					      &update_cache_variants),
499 		     SPINAND_HAS_QE_BIT,
500 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
501 				     gd5fxgq4uexxg_ecc_get_status)),
502 	SPINAND_INFO("GD5F2GM7RExxG",
503 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
504 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
505 		     NAND_ECCREQ(8, 512),
506 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
507 					      &write_cache_variants,
508 					      &update_cache_variants),
509 		     SPINAND_HAS_QE_BIT,
510 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
511 				     gd5fxgq4uexxg_ecc_get_status)),
512 	SPINAND_INFO("GD5F4GM8UExxG",
513 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
514 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
515 		     NAND_ECCREQ(8, 512),
516 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
517 					      &write_cache_variants,
518 					      &update_cache_variants),
519 		     SPINAND_HAS_QE_BIT,
520 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
521 				     gd5fxgq4uexxg_ecc_get_status)),
522 	SPINAND_INFO("GD5F4GM8RExxG",
523 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
524 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
525 		     NAND_ECCREQ(8, 512),
526 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
527 					      &write_cache_variants,
528 					      &update_cache_variants),
529 		     SPINAND_HAS_QE_BIT,
530 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
531 				     gd5fxgq4uexxg_ecc_get_status)),
532 	SPINAND_INFO("GD5F1GQ4UExxH",
533 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd9),
534 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
535 		     NAND_ECCREQ(8, 512),
536 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
537 					      &write_cache_variants,
538 					      &update_cache_variants),
539 		     SPINAND_HAS_QE_BIT,
540 		     SPINAND_ECCINFO(&gd5fxgqx_variant3_ooblayout,
541 				     gd5fxgq4xa_ecc_get_status)),
542 };
543 
gigadevice_spinand_set_ds(struct spinand_device * spinand,u8 ds_io)544 static int gigadevice_spinand_set_ds(struct spinand_device *spinand, u8 ds_io)
545 {
546 	struct spi_mem_op op = SPINAND_SET_FEATURE_OP(0xD0,
547 						      spinand->scratchbuf);
548 
549 	*spinand->scratchbuf = (ds_io & 0x3) << 5;
550 	return spi_mem_exec_op(spinand->slave, &op);
551 }
552 
gigadevice_spinand_init(struct spinand_device * spinand)553 static int gigadevice_spinand_init(struct spinand_device *spinand)
554 {
555 	/* GD5F1GQ5UExxG */
556 	if (spinand->id.data[1] == 0x51)
557 		gigadevice_spinand_set_ds(spinand, 3);
558 
559 	return 0;
560 }
561 
562 static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
563 	.init = gigadevice_spinand_init,
564 };
565 
566 const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
567 	.id = SPINAND_MFR_GIGADEVICE,
568 	.name = "GigaDevice",
569 	.chips = gigadevice_spinand_table,
570 	.nchips = ARRAY_SIZE(gigadevice_spinand_table),
571 	.ops = &gigadevice_spinand_manuf_ops,
572 };
573