xref: /openbmc/linux/drivers/mtd/nand/spi/gigadevice.c (revision 7ae5c03a)
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 
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 
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 
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 
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 
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 
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 
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 
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 						      &status2);
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 		return ((status & STATUS_ECC_MASK) >> 2) |
211 			((status2 & STATUS_ECC_MASK) >> 4);
212 
213 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
214 		return 8;
215 
216 	case STATUS_ECC_UNCOR_ERROR:
217 		return -EBADMSG;
218 
219 	default:
220 		break;
221 	}
222 
223 	return -EINVAL;
224 }
225 
226 static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
227 					u8 status)
228 {
229 	u8 status2;
230 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
231 						      &status2);
232 	int ret;
233 
234 	switch (status & STATUS_ECC_MASK) {
235 	case STATUS_ECC_NO_BITFLIPS:
236 		return 0;
237 
238 	case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
239 		/*
240 		 * Read status2 register to determine a more fine grained
241 		 * bit error status
242 		 */
243 		ret = spi_mem_exec_op(spinand->spimem, &op);
244 		if (ret)
245 			return ret;
246 
247 		/*
248 		 * 1 ... 4 bits are flipped (and corrected)
249 		 */
250 		/* bits sorted this way (1...0): ECCSE1, ECCSE0 */
251 		return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
252 
253 	case STATUS_ECC_UNCOR_ERROR:
254 		return -EBADMSG;
255 
256 	default:
257 		break;
258 	}
259 
260 	return -EINVAL;
261 }
262 
263 static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
264 					u8 status)
265 {
266 	switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
267 	case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
268 		return 0;
269 
270 	case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
271 		return 3;
272 
273 	case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
274 		return -EBADMSG;
275 
276 	default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
277 		return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
278 	}
279 
280 	return -EINVAL;
281 }
282 
283 static const struct spinand_info gigadevice_spinand_table[] = {
284 	SPINAND_INFO("GD5F1GQ4xA",
285 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
286 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
287 		     NAND_ECCREQ(8, 512),
288 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
289 					      &write_cache_variants,
290 					      &update_cache_variants),
291 		     SPINAND_HAS_QE_BIT,
292 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
293 				     gd5fxgq4xa_ecc_get_status)),
294 	SPINAND_INFO("GD5F2GQ4xA",
295 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
296 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
297 		     NAND_ECCREQ(8, 512),
298 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
299 					      &write_cache_variants,
300 					      &update_cache_variants),
301 		     SPINAND_HAS_QE_BIT,
302 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
303 				     gd5fxgq4xa_ecc_get_status)),
304 	SPINAND_INFO("GD5F4GQ4xA",
305 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
306 		     NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
307 		     NAND_ECCREQ(8, 512),
308 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
309 					      &write_cache_variants,
310 					      &update_cache_variants),
311 		     SPINAND_HAS_QE_BIT,
312 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
313 				     gd5fxgq4xa_ecc_get_status)),
314 	SPINAND_INFO("GD5F4GQ4RC",
315 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
316 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
317 		     NAND_ECCREQ(8, 512),
318 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
319 					      &write_cache_variants,
320 					      &update_cache_variants),
321 		     SPINAND_HAS_QE_BIT,
322 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
323 				     gd5fxgq4ufxxg_ecc_get_status)),
324 	SPINAND_INFO("GD5F4GQ4UC",
325 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
326 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
327 		     NAND_ECCREQ(8, 512),
328 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
329 					      &write_cache_variants,
330 					      &update_cache_variants),
331 		     SPINAND_HAS_QE_BIT,
332 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
333 				     gd5fxgq4ufxxg_ecc_get_status)),
334 	SPINAND_INFO("GD5F1GQ4UExxG",
335 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
336 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
337 		     NAND_ECCREQ(8, 512),
338 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
339 					      &write_cache_variants,
340 					      &update_cache_variants),
341 		     SPINAND_HAS_QE_BIT,
342 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
343 				     gd5fxgq4uexxg_ecc_get_status)),
344 	SPINAND_INFO("GD5F1GQ4RExxG",
345 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
346 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
347 		     NAND_ECCREQ(8, 512),
348 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
349 					      &write_cache_variants,
350 					      &update_cache_variants),
351 		     SPINAND_HAS_QE_BIT,
352 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
353 				     gd5fxgq4uexxg_ecc_get_status)),
354 	SPINAND_INFO("GD5F2GQ4UExxG",
355 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
356 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
357 		     NAND_ECCREQ(8, 512),
358 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
359 					      &write_cache_variants,
360 					      &update_cache_variants),
361 		     SPINAND_HAS_QE_BIT,
362 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
363 				     gd5fxgq4uexxg_ecc_get_status)),
364 	SPINAND_INFO("GD5F2GQ4RExxG",
365 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
366 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
367 		     NAND_ECCREQ(8, 512),
368 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
369 					      &write_cache_variants,
370 					      &update_cache_variants),
371 		     SPINAND_HAS_QE_BIT,
372 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
373 				     gd5fxgq4uexxg_ecc_get_status)),
374 	SPINAND_INFO("GD5F1GQ4UFxxG",
375 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
376 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
377 		     NAND_ECCREQ(8, 512),
378 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
379 					      &write_cache_variants,
380 					      &update_cache_variants),
381 		     SPINAND_HAS_QE_BIT,
382 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
383 				     gd5fxgq4ufxxg_ecc_get_status)),
384 	SPINAND_INFO("GD5F1GQ5UExxG",
385 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
386 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
387 		     NAND_ECCREQ(4, 512),
388 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
389 					      &write_cache_variants,
390 					      &update_cache_variants),
391 		     SPINAND_HAS_QE_BIT,
392 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
393 				     gd5fxgq5xexxg_ecc_get_status)),
394 	SPINAND_INFO("GD5F1GQ5RExxG",
395 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
396 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
397 		     NAND_ECCREQ(4, 512),
398 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
399 					      &write_cache_variants,
400 					      &update_cache_variants),
401 		     SPINAND_HAS_QE_BIT,
402 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
403 				     gd5fxgq5xexxg_ecc_get_status)),
404 	SPINAND_INFO("GD5F2GQ5UExxG",
405 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
406 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
407 		     NAND_ECCREQ(4, 512),
408 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
409 					      &write_cache_variants,
410 					      &update_cache_variants),
411 		     SPINAND_HAS_QE_BIT,
412 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
413 				     gd5fxgq5xexxg_ecc_get_status)),
414 	SPINAND_INFO("GD5F2GQ5RExxG",
415 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
416 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
417 		     NAND_ECCREQ(4, 512),
418 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
419 					      &write_cache_variants,
420 					      &update_cache_variants),
421 		     SPINAND_HAS_QE_BIT,
422 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
423 				     gd5fxgq5xexxg_ecc_get_status)),
424 	SPINAND_INFO("GD5F4GQ6UExxG",
425 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
426 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
427 		     NAND_ECCREQ(4, 512),
428 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
429 					      &write_cache_variants,
430 					      &update_cache_variants),
431 		     SPINAND_HAS_QE_BIT,
432 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
433 				     gd5fxgq5xexxg_ecc_get_status)),
434 	SPINAND_INFO("GD5F4GQ6RExxG",
435 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
436 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
437 		     NAND_ECCREQ(4, 512),
438 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
439 					      &write_cache_variants,
440 					      &update_cache_variants),
441 		     SPINAND_HAS_QE_BIT,
442 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
443 				     gd5fxgq5xexxg_ecc_get_status)),
444 	SPINAND_INFO("GD5F1GM7UExxG",
445 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
446 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
447 		     NAND_ECCREQ(8, 512),
448 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
449 					      &write_cache_variants,
450 					      &update_cache_variants),
451 		     SPINAND_HAS_QE_BIT,
452 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
453 				     gd5fxgq4uexxg_ecc_get_status)),
454 	SPINAND_INFO("GD5F1GM7RExxG",
455 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
456 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
457 		     NAND_ECCREQ(8, 512),
458 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
459 					      &write_cache_variants,
460 					      &update_cache_variants),
461 		     SPINAND_HAS_QE_BIT,
462 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
463 				     gd5fxgq4uexxg_ecc_get_status)),
464 	SPINAND_INFO("GD5F2GM7UExxG",
465 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
466 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
467 		     NAND_ECCREQ(8, 512),
468 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
469 					      &write_cache_variants,
470 					      &update_cache_variants),
471 		     SPINAND_HAS_QE_BIT,
472 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
473 				     gd5fxgq4uexxg_ecc_get_status)),
474 	SPINAND_INFO("GD5F2GM7RExxG",
475 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
476 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
477 		     NAND_ECCREQ(8, 512),
478 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
479 					      &write_cache_variants,
480 					      &update_cache_variants),
481 		     SPINAND_HAS_QE_BIT,
482 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
483 				     gd5fxgq4uexxg_ecc_get_status)),
484 	SPINAND_INFO("GD5F4GM8UExxG",
485 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
486 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
487 		     NAND_ECCREQ(8, 512),
488 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
489 					      &write_cache_variants,
490 					      &update_cache_variants),
491 		     SPINAND_HAS_QE_BIT,
492 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
493 				     gd5fxgq4uexxg_ecc_get_status)),
494 	SPINAND_INFO("GD5F4GM8RExxG",
495 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
496 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
497 		     NAND_ECCREQ(8, 512),
498 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
499 					      &write_cache_variants,
500 					      &update_cache_variants),
501 		     SPINAND_HAS_QE_BIT,
502 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
503 				     gd5fxgq4uexxg_ecc_get_status)),
504 };
505 
506 static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
507 };
508 
509 const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
510 	.id = SPINAND_MFR_GIGADEVICE,
511 	.name = "GigaDevice",
512 	.chips = gigadevice_spinand_table,
513 	.nchips = ARRAY_SIZE(gigadevice_spinand_table),
514 	.ops = &gigadevice_spinand_manuf_ops,
515 };
516