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