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
26static 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
34static 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
42static 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
50static 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
58static SPINAND_OP_VARIANTS(write_cache_variants,
59		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
60		SPINAND_PROG_LOAD(true, 0, NULL, 0));
61
62static SPINAND_OP_VARIANTS(update_cache_variants,
63		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
64		SPINAND_PROG_LOAD(false, 0, NULL, 0));
65
66static 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
78static 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
95static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
96	.ecc = gd5fxgq4xa_ooblayout_ecc,
97	.free = gd5fxgq4xa_ooblayout_free,
98};
99
100static 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
124static 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
136static 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 */
150static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
151	.ecc = gd5fxgqx_variant2_ooblayout_ecc,
152	.free = gd5fxgqx_variant2_ooblayout_free,
153};
154
155static 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
167static 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
179static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
180	.ecc = gd5fxgq4xc_ooblayout_256_ecc,
181	.free = gd5fxgq4xc_ooblayout_256_free,
182};
183
184static 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
227static 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
265static 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
285static 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
538static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
539};
540
541const 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