xref: /linux/drivers/mtd/nand/spi/gigadevice.c (revision c441bfb5f2866de71e092c1b9d866a65978dfe1a)
1c93c6132SChuanhong Guo // SPDX-License-Identifier: GPL-2.0
2c93c6132SChuanhong Guo /*
3c93c6132SChuanhong Guo  * Author:
4c93c6132SChuanhong Guo  *	Chuanhong Guo <gch981213@gmail.com>
5c93c6132SChuanhong Guo  */
6c93c6132SChuanhong Guo 
7c93c6132SChuanhong Guo #include <linux/device.h>
8c93c6132SChuanhong Guo #include <linux/kernel.h>
9c93c6132SChuanhong Guo #include <linux/mtd/spinand.h>
10c93c6132SChuanhong Guo 
11c93c6132SChuanhong Guo #define SPINAND_MFR_GIGADEVICE			0xC8
12cfd93d7cSJeff Kletsky 
13c93c6132SChuanhong Guo #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS	(1 << 4)
14c93c6132SChuanhong Guo #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS	(3 << 4)
15c93c6132SChuanhong Guo 
16*469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS	(1 << 4)
17*469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS	(3 << 4)
18*469b9924SReto Schneider 
19*469b9924SReto Schneider #define GD5FXGQXXEXXG_REG_STATUS2		0xf0
20c40c7a99SStefan Roese 
21cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK		(7 << 4)
22cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS	(0 << 4)
23cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS	(1 << 4)
24cfd93d7cSJeff Kletsky #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR	(7 << 4)
25cfd93d7cSJeff Kletsky 
26c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(read_cache_variants,
276387ad9cSHauke Mehrtens 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
28c93c6132SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
29c93c6132SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
30c93c6132SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
31c93c6132SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
32c93c6132SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
33c93c6132SChuanhong Guo 
34cfd93d7cSJeff Kletsky static SPINAND_OP_VARIANTS(read_cache_variants_f,
356387ad9cSHauke Mehrtens 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
36cfd93d7cSJeff Kletsky 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
37cfd93d7cSJeff Kletsky 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
38cfd93d7cSJeff Kletsky 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
39cfd93d7cSJeff Kletsky 		SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
40cfd93d7cSJeff Kletsky 		SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
41cfd93d7cSJeff Kletsky 
42c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(write_cache_variants,
43c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
44c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
45c93c6132SChuanhong Guo 
46c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(update_cache_variants,
47c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
48c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
49c93c6132SChuanhong Guo 
50c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
51c93c6132SChuanhong Guo 				  struct mtd_oob_region *region)
52c93c6132SChuanhong Guo {
53c93c6132SChuanhong Guo 	if (section > 3)
54c93c6132SChuanhong Guo 		return -ERANGE;
55c93c6132SChuanhong Guo 
56c93c6132SChuanhong Guo 	region->offset = (16 * section) + 8;
57c93c6132SChuanhong Guo 	region->length = 8;
58c93c6132SChuanhong Guo 
59c93c6132SChuanhong Guo 	return 0;
60c93c6132SChuanhong Guo }
61c93c6132SChuanhong Guo 
62c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
63c93c6132SChuanhong Guo 				   struct mtd_oob_region *region)
64c93c6132SChuanhong Guo {
65c93c6132SChuanhong Guo 	if (section > 3)
66c93c6132SChuanhong Guo 		return -ERANGE;
67c93c6132SChuanhong Guo 
68c93c6132SChuanhong Guo 	if (section) {
69c93c6132SChuanhong Guo 		region->offset = 16 * section;
70c93c6132SChuanhong Guo 		region->length = 8;
71c93c6132SChuanhong Guo 	} else {
72c93c6132SChuanhong Guo 		/* section 0 has one byte reserved for bad block mark */
73c93c6132SChuanhong Guo 		region->offset = 1;
74c93c6132SChuanhong Guo 		region->length = 7;
75c93c6132SChuanhong Guo 	}
76c93c6132SChuanhong Guo 	return 0;
77c93c6132SChuanhong Guo }
78c93c6132SChuanhong Guo 
79cfd93d7cSJeff Kletsky static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
80cfd93d7cSJeff Kletsky 	.ecc = gd5fxgq4xa_ooblayout_ecc,
81cfd93d7cSJeff Kletsky 	.free = gd5fxgq4xa_ooblayout_free,
82cfd93d7cSJeff Kletsky };
83cfd93d7cSJeff Kletsky 
84c93c6132SChuanhong Guo static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
85c93c6132SChuanhong Guo 					 u8 status)
86c93c6132SChuanhong Guo {
87c93c6132SChuanhong Guo 	switch (status & STATUS_ECC_MASK) {
88c93c6132SChuanhong Guo 	case STATUS_ECC_NO_BITFLIPS:
89c93c6132SChuanhong Guo 		return 0;
90c93c6132SChuanhong Guo 
91c93c6132SChuanhong Guo 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
92c93c6132SChuanhong Guo 		/* 1-7 bits are flipped. return the maximum. */
93c93c6132SChuanhong Guo 		return 7;
94c93c6132SChuanhong Guo 
95c93c6132SChuanhong Guo 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
96c93c6132SChuanhong Guo 		return 8;
97c93c6132SChuanhong Guo 
98c93c6132SChuanhong Guo 	case STATUS_ECC_UNCOR_ERROR:
99c93c6132SChuanhong Guo 		return -EBADMSG;
100c93c6132SChuanhong Guo 
101c93c6132SChuanhong Guo 	default:
102c93c6132SChuanhong Guo 		break;
103c93c6132SChuanhong Guo 	}
104c93c6132SChuanhong Guo 
105c93c6132SChuanhong Guo 	return -EINVAL;
106c93c6132SChuanhong Guo }
107c93c6132SChuanhong Guo 
108*469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
109c40c7a99SStefan Roese 				       struct mtd_oob_region *region)
110c40c7a99SStefan Roese {
111c40c7a99SStefan Roese 	if (section)
112c40c7a99SStefan Roese 		return -ERANGE;
113c40c7a99SStefan Roese 
114c40c7a99SStefan Roese 	region->offset = 64;
115c40c7a99SStefan Roese 	region->length = 64;
116c40c7a99SStefan Roese 
117c40c7a99SStefan Roese 	return 0;
118c40c7a99SStefan Roese }
119c40c7a99SStefan Roese 
120*469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
121c40c7a99SStefan Roese 					struct mtd_oob_region *region)
122c40c7a99SStefan Roese {
123c40c7a99SStefan Roese 	if (section)
124c40c7a99SStefan Roese 		return -ERANGE;
125c40c7a99SStefan Roese 
126c40c7a99SStefan Roese 	/* Reserve 1 bytes for the BBM. */
127c40c7a99SStefan Roese 	region->offset = 1;
128c40c7a99SStefan Roese 	region->length = 63;
129c40c7a99SStefan Roese 
130c40c7a99SStefan Roese 	return 0;
131c40c7a99SStefan Roese }
132c40c7a99SStefan Roese 
133*469b9924SReto Schneider /* Valid for Q4/Q5 and Q6 (untested) devices */
134*469b9924SReto Schneider static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
135*469b9924SReto Schneider 	.ecc = gd5fxgqx_variant2_ooblayout_ecc,
136*469b9924SReto Schneider 	.free = gd5fxgqx_variant2_ooblayout_free,
137cfd93d7cSJeff Kletsky };
138cfd93d7cSJeff Kletsky 
139302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
140302d8a22SHauke Mehrtens 					struct mtd_oob_region *oobregion)
141302d8a22SHauke Mehrtens {
142302d8a22SHauke Mehrtens 	if (section)
143302d8a22SHauke Mehrtens 		return -ERANGE;
144302d8a22SHauke Mehrtens 
145302d8a22SHauke Mehrtens 	oobregion->offset = 128;
146302d8a22SHauke Mehrtens 	oobregion->length = 128;
147302d8a22SHauke Mehrtens 
148302d8a22SHauke Mehrtens 	return 0;
149302d8a22SHauke Mehrtens }
150302d8a22SHauke Mehrtens 
151302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
152302d8a22SHauke Mehrtens 					 struct mtd_oob_region *oobregion)
153302d8a22SHauke Mehrtens {
154302d8a22SHauke Mehrtens 	if (section)
155302d8a22SHauke Mehrtens 		return -ERANGE;
156302d8a22SHauke Mehrtens 
157302d8a22SHauke Mehrtens 	oobregion->offset = 1;
158302d8a22SHauke Mehrtens 	oobregion->length = 127;
159302d8a22SHauke Mehrtens 
160302d8a22SHauke Mehrtens 	return 0;
161302d8a22SHauke Mehrtens }
162302d8a22SHauke Mehrtens 
163302d8a22SHauke Mehrtens static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
164302d8a22SHauke Mehrtens 	.ecc = gd5fxgq4xc_ooblayout_256_ecc,
165302d8a22SHauke Mehrtens 	.free = gd5fxgq4xc_ooblayout_256_free,
166302d8a22SHauke Mehrtens };
167302d8a22SHauke Mehrtens 
168c40c7a99SStefan Roese static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
169c40c7a99SStefan Roese 					u8 status)
170c40c7a99SStefan Roese {
171c40c7a99SStefan Roese 	u8 status2;
172*469b9924SReto Schneider 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
173c40c7a99SStefan Roese 						      &status2);
174c40c7a99SStefan Roese 	int ret;
175c40c7a99SStefan Roese 
176c40c7a99SStefan Roese 	switch (status & STATUS_ECC_MASK) {
177c40c7a99SStefan Roese 	case STATUS_ECC_NO_BITFLIPS:
178c40c7a99SStefan Roese 		return 0;
179c40c7a99SStefan Roese 
180c40c7a99SStefan Roese 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
181c40c7a99SStefan Roese 		/*
182c40c7a99SStefan Roese 		 * Read status2 register to determine a more fine grained
183c40c7a99SStefan Roese 		 * bit error status
184c40c7a99SStefan Roese 		 */
185c40c7a99SStefan Roese 		ret = spi_mem_exec_op(spinand->spimem, &op);
186c40c7a99SStefan Roese 		if (ret)
187c40c7a99SStefan Roese 			return ret;
188c40c7a99SStefan Roese 
189c40c7a99SStefan Roese 		/*
190c40c7a99SStefan Roese 		 * 4 ... 7 bits are flipped (1..4 can't be detected, so
191c40c7a99SStefan Roese 		 * report the maximum of 4 in this case
192c40c7a99SStefan Roese 		 */
193c40c7a99SStefan Roese 		/* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
194c40c7a99SStefan Roese 		return ((status & STATUS_ECC_MASK) >> 2) |
195c40c7a99SStefan Roese 			((status2 & STATUS_ECC_MASK) >> 4);
196c40c7a99SStefan Roese 
197c40c7a99SStefan Roese 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
198c40c7a99SStefan Roese 		return 8;
199c40c7a99SStefan Roese 
200c40c7a99SStefan Roese 	case STATUS_ECC_UNCOR_ERROR:
201c40c7a99SStefan Roese 		return -EBADMSG;
202c40c7a99SStefan Roese 
203c40c7a99SStefan Roese 	default:
204c40c7a99SStefan Roese 		break;
205c40c7a99SStefan Roese 	}
206c40c7a99SStefan Roese 
207c40c7a99SStefan Roese 	return -EINVAL;
208c40c7a99SStefan Roese }
209c40c7a99SStefan Roese 
210*469b9924SReto Schneider static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
211*469b9924SReto Schneider 					u8 status)
212*469b9924SReto Schneider {
213*469b9924SReto Schneider 	u8 status2;
214*469b9924SReto Schneider 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
215*469b9924SReto Schneider 						      &status2);
216*469b9924SReto Schneider 	int ret;
217*469b9924SReto Schneider 
218*469b9924SReto Schneider 	switch (status & STATUS_ECC_MASK) {
219*469b9924SReto Schneider 	case STATUS_ECC_NO_BITFLIPS:
220*469b9924SReto Schneider 		return 0;
221*469b9924SReto Schneider 
222*469b9924SReto Schneider 	case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
223*469b9924SReto Schneider 		/*
224*469b9924SReto Schneider 		 * Read status2 register to determine a more fine grained
225*469b9924SReto Schneider 		 * bit error status
226*469b9924SReto Schneider 		 */
227*469b9924SReto Schneider 		ret = spi_mem_exec_op(spinand->spimem, &op);
228*469b9924SReto Schneider 		if (ret)
229*469b9924SReto Schneider 			return ret;
230*469b9924SReto Schneider 
231*469b9924SReto Schneider 		/*
232*469b9924SReto Schneider 		 * 1 ... 4 bits are flipped (and corrected)
233*469b9924SReto Schneider 		 */
234*469b9924SReto Schneider 		/* bits sorted this way (1...0): ECCSE1, ECCSE0 */
235*469b9924SReto Schneider 		return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
236*469b9924SReto Schneider 
237*469b9924SReto Schneider 	case STATUS_ECC_UNCOR_ERROR:
238*469b9924SReto Schneider 		return -EBADMSG;
239*469b9924SReto Schneider 
240*469b9924SReto Schneider 	default:
241*469b9924SReto Schneider 		break;
242*469b9924SReto Schneider 	}
243*469b9924SReto Schneider 
244*469b9924SReto Schneider 	return -EINVAL;
245*469b9924SReto Schneider }
246*469b9924SReto Schneider 
247cfd93d7cSJeff Kletsky static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
248cfd93d7cSJeff Kletsky 					u8 status)
249cfd93d7cSJeff Kletsky {
250cfd93d7cSJeff Kletsky 	switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
251cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
252cfd93d7cSJeff Kletsky 		return 0;
253c93c6132SChuanhong Guo 
254cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
255cfd93d7cSJeff Kletsky 		return 3;
256cfd93d7cSJeff Kletsky 
257cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
258cfd93d7cSJeff Kletsky 		return -EBADMSG;
259cfd93d7cSJeff Kletsky 
260cfd93d7cSJeff Kletsky 	default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
261cfd93d7cSJeff Kletsky 		return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
262cfd93d7cSJeff Kletsky 	}
263cfd93d7cSJeff Kletsky 
264cfd93d7cSJeff Kletsky 	return -EINVAL;
265cfd93d7cSJeff Kletsky }
266c40c7a99SStefan Roese 
267c93c6132SChuanhong Guo static const struct spinand_info gigadevice_spinand_table[] = {
268f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4xA",
269f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
270377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
271c93c6132SChuanhong Guo 		     NAND_ECCREQ(8, 512),
272c93c6132SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
273c93c6132SChuanhong Guo 					      &write_cache_variants,
274c93c6132SChuanhong Guo 					      &update_cache_variants),
275aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
276c93c6132SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
277c93c6132SChuanhong Guo 				     gd5fxgq4xa_ecc_get_status)),
278f1541773SChuanhong Guo 	SPINAND_INFO("GD5F2GQ4xA",
279f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
280377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
281c93c6132SChuanhong Guo 		     NAND_ECCREQ(8, 512),
282c93c6132SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
283c93c6132SChuanhong Guo 					      &write_cache_variants,
284c93c6132SChuanhong Guo 					      &update_cache_variants),
285aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
286c93c6132SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
287c93c6132SChuanhong Guo 				     gd5fxgq4xa_ecc_get_status)),
288f1541773SChuanhong Guo 	SPINAND_INFO("GD5F4GQ4xA",
289f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
290a126483eSFrieder Schrempf 		     NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
291c93c6132SChuanhong Guo 		     NAND_ECCREQ(8, 512),
292c93c6132SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
293c93c6132SChuanhong Guo 					      &write_cache_variants,
294c93c6132SChuanhong Guo 					      &update_cache_variants),
295aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
296c93c6132SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
297c93c6132SChuanhong Guo 				     gd5fxgq4xa_ecc_get_status)),
298302d8a22SHauke Mehrtens 	SPINAND_INFO("GD5F4GQ4RC",
299302d8a22SHauke Mehrtens 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
300302d8a22SHauke Mehrtens 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
301302d8a22SHauke Mehrtens 		     NAND_ECCREQ(8, 512),
302302d8a22SHauke Mehrtens 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
303302d8a22SHauke Mehrtens 					      &write_cache_variants,
304302d8a22SHauke Mehrtens 					      &update_cache_variants),
305302d8a22SHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
306302d8a22SHauke Mehrtens 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
307302d8a22SHauke Mehrtens 				     gd5fxgq4ufxxg_ecc_get_status)),
308302d8a22SHauke Mehrtens 	SPINAND_INFO("GD5F4GQ4UC",
309302d8a22SHauke Mehrtens 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
310302d8a22SHauke Mehrtens 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
311302d8a22SHauke Mehrtens 		     NAND_ECCREQ(8, 512),
312302d8a22SHauke Mehrtens 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
313302d8a22SHauke Mehrtens 					      &write_cache_variants,
314302d8a22SHauke Mehrtens 					      &update_cache_variants),
315302d8a22SHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
316302d8a22SHauke Mehrtens 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
317302d8a22SHauke Mehrtens 				     gd5fxgq4ufxxg_ecc_get_status)),
318f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4UExxG",
319f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
320377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
321c40c7a99SStefan Roese 		     NAND_ECCREQ(8, 512),
322c40c7a99SStefan Roese 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
323c40c7a99SStefan Roese 					      &write_cache_variants,
324c40c7a99SStefan Roese 					      &update_cache_variants),
325aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
326*469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
327c40c7a99SStefan Roese 				     gd5fxgq4uexxg_ecc_get_status)),
328f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4UFxxG",
329f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
330cfd93d7cSJeff Kletsky 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
331cfd93d7cSJeff Kletsky 		     NAND_ECCREQ(8, 512),
332cfd93d7cSJeff Kletsky 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
333cfd93d7cSJeff Kletsky 					      &write_cache_variants,
334cfd93d7cSJeff Kletsky 					      &update_cache_variants),
335aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
336*469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
337cfd93d7cSJeff Kletsky 				     gd5fxgq4ufxxg_ecc_get_status)),
338*469b9924SReto Schneider 	SPINAND_INFO("GD5F1GQ5UExxG",
339*469b9924SReto Schneider 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
340*469b9924SReto Schneider 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
341*469b9924SReto Schneider 		     NAND_ECCREQ(4, 512),
342*469b9924SReto Schneider 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
343*469b9924SReto Schneider 					      &write_cache_variants,
344*469b9924SReto Schneider 					      &update_cache_variants),
345*469b9924SReto Schneider 		     SPINAND_HAS_QE_BIT,
346*469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
347*469b9924SReto Schneider 				     gd5fxgq5xexxg_ecc_get_status)),
348c93c6132SChuanhong Guo };
349c93c6132SChuanhong Guo 
350c93c6132SChuanhong Guo static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
351c93c6132SChuanhong Guo };
352c93c6132SChuanhong Guo 
353c93c6132SChuanhong Guo const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
354c93c6132SChuanhong Guo 	.id = SPINAND_MFR_GIGADEVICE,
355c93c6132SChuanhong Guo 	.name = "GigaDevice",
356f1541773SChuanhong Guo 	.chips = gigadevice_spinand_table,
357f1541773SChuanhong Guo 	.nchips = ARRAY_SIZE(gigadevice_spinand_table),
358c93c6132SChuanhong Guo 	.ops = &gigadevice_spinand_manuf_ops,
359c93c6132SChuanhong Guo };
360