xref: /linux/drivers/mtd/nand/spi/gigadevice.c (revision 573eec222bc82fb5e724586267fbbb1aed9ffd03)
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 
16469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS	(1 << 4)
17469b9924SReto Schneider #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS	(3 << 4)
18469b9924SReto Schneider 
19469b9924SReto 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 
42a4f9dd55SChuanhong Guo static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
43a4f9dd55SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
44a4f9dd55SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
45a4f9dd55SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
46a4f9dd55SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
47a4f9dd55SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
48a4f9dd55SChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
49a4f9dd55SChuanhong Guo 
50c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(write_cache_variants,
51c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
52c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
53c93c6132SChuanhong Guo 
54c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(update_cache_variants,
55c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
56c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
57c93c6132SChuanhong Guo 
58c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
59c93c6132SChuanhong Guo 				  struct mtd_oob_region *region)
60c93c6132SChuanhong Guo {
61c93c6132SChuanhong Guo 	if (section > 3)
62c93c6132SChuanhong Guo 		return -ERANGE;
63c93c6132SChuanhong Guo 
64c93c6132SChuanhong Guo 	region->offset = (16 * section) + 8;
65c93c6132SChuanhong Guo 	region->length = 8;
66c93c6132SChuanhong Guo 
67c93c6132SChuanhong Guo 	return 0;
68c93c6132SChuanhong Guo }
69c93c6132SChuanhong Guo 
70c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
71c93c6132SChuanhong Guo 				   struct mtd_oob_region *region)
72c93c6132SChuanhong Guo {
73c93c6132SChuanhong Guo 	if (section > 3)
74c93c6132SChuanhong Guo 		return -ERANGE;
75c93c6132SChuanhong Guo 
76c93c6132SChuanhong Guo 	if (section) {
77c93c6132SChuanhong Guo 		region->offset = 16 * section;
78c93c6132SChuanhong Guo 		region->length = 8;
79c93c6132SChuanhong Guo 	} else {
80c93c6132SChuanhong Guo 		/* section 0 has one byte reserved for bad block mark */
81c93c6132SChuanhong Guo 		region->offset = 1;
82c93c6132SChuanhong Guo 		region->length = 7;
83c93c6132SChuanhong Guo 	}
84c93c6132SChuanhong Guo 	return 0;
85c93c6132SChuanhong Guo }
86c93c6132SChuanhong Guo 
87cfd93d7cSJeff Kletsky static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
88cfd93d7cSJeff Kletsky 	.ecc = gd5fxgq4xa_ooblayout_ecc,
89cfd93d7cSJeff Kletsky 	.free = gd5fxgq4xa_ooblayout_free,
90cfd93d7cSJeff Kletsky };
91cfd93d7cSJeff Kletsky 
92c93c6132SChuanhong Guo static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
93c93c6132SChuanhong Guo 					 u8 status)
94c93c6132SChuanhong Guo {
95c93c6132SChuanhong Guo 	switch (status & STATUS_ECC_MASK) {
96c93c6132SChuanhong Guo 	case STATUS_ECC_NO_BITFLIPS:
97c93c6132SChuanhong Guo 		return 0;
98c93c6132SChuanhong Guo 
99c93c6132SChuanhong Guo 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
100c93c6132SChuanhong Guo 		/* 1-7 bits are flipped. return the maximum. */
101c93c6132SChuanhong Guo 		return 7;
102c93c6132SChuanhong Guo 
103c93c6132SChuanhong Guo 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
104c93c6132SChuanhong Guo 		return 8;
105c93c6132SChuanhong Guo 
106c93c6132SChuanhong Guo 	case STATUS_ECC_UNCOR_ERROR:
107c93c6132SChuanhong Guo 		return -EBADMSG;
108c93c6132SChuanhong Guo 
109c93c6132SChuanhong Guo 	default:
110c93c6132SChuanhong Guo 		break;
111c93c6132SChuanhong Guo 	}
112c93c6132SChuanhong Guo 
113c93c6132SChuanhong Guo 	return -EINVAL;
114c93c6132SChuanhong Guo }
115c93c6132SChuanhong Guo 
116469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
117c40c7a99SStefan Roese 				       struct mtd_oob_region *region)
118c40c7a99SStefan Roese {
119c40c7a99SStefan Roese 	if (section)
120c40c7a99SStefan Roese 		return -ERANGE;
121c40c7a99SStefan Roese 
122c40c7a99SStefan Roese 	region->offset = 64;
123c40c7a99SStefan Roese 	region->length = 64;
124c40c7a99SStefan Roese 
125c40c7a99SStefan Roese 	return 0;
126c40c7a99SStefan Roese }
127c40c7a99SStefan Roese 
128469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
129c40c7a99SStefan Roese 					struct mtd_oob_region *region)
130c40c7a99SStefan Roese {
131c40c7a99SStefan Roese 	if (section)
132c40c7a99SStefan Roese 		return -ERANGE;
133c40c7a99SStefan Roese 
134c40c7a99SStefan Roese 	/* Reserve 1 bytes for the BBM. */
135c40c7a99SStefan Roese 	region->offset = 1;
136c40c7a99SStefan Roese 	region->length = 63;
137c40c7a99SStefan Roese 
138c40c7a99SStefan Roese 	return 0;
139c40c7a99SStefan Roese }
140c40c7a99SStefan Roese 
141469b9924SReto Schneider /* Valid for Q4/Q5 and Q6 (untested) devices */
142469b9924SReto Schneider static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
143469b9924SReto Schneider 	.ecc = gd5fxgqx_variant2_ooblayout_ecc,
144469b9924SReto Schneider 	.free = gd5fxgqx_variant2_ooblayout_free,
145cfd93d7cSJeff Kletsky };
146cfd93d7cSJeff Kletsky 
147302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
148302d8a22SHauke Mehrtens 					struct mtd_oob_region *oobregion)
149302d8a22SHauke Mehrtens {
150302d8a22SHauke Mehrtens 	if (section)
151302d8a22SHauke Mehrtens 		return -ERANGE;
152302d8a22SHauke Mehrtens 
153302d8a22SHauke Mehrtens 	oobregion->offset = 128;
154302d8a22SHauke Mehrtens 	oobregion->length = 128;
155302d8a22SHauke Mehrtens 
156302d8a22SHauke Mehrtens 	return 0;
157302d8a22SHauke Mehrtens }
158302d8a22SHauke Mehrtens 
159302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
160302d8a22SHauke Mehrtens 					 struct mtd_oob_region *oobregion)
161302d8a22SHauke Mehrtens {
162302d8a22SHauke Mehrtens 	if (section)
163302d8a22SHauke Mehrtens 		return -ERANGE;
164302d8a22SHauke Mehrtens 
165302d8a22SHauke Mehrtens 	oobregion->offset = 1;
166302d8a22SHauke Mehrtens 	oobregion->length = 127;
167302d8a22SHauke Mehrtens 
168302d8a22SHauke Mehrtens 	return 0;
169302d8a22SHauke Mehrtens }
170302d8a22SHauke Mehrtens 
171302d8a22SHauke Mehrtens static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
172302d8a22SHauke Mehrtens 	.ecc = gd5fxgq4xc_ooblayout_256_ecc,
173302d8a22SHauke Mehrtens 	.free = gd5fxgq4xc_ooblayout_256_free,
174302d8a22SHauke Mehrtens };
175302d8a22SHauke Mehrtens 
176c40c7a99SStefan Roese static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
177c40c7a99SStefan Roese 					u8 status)
178c40c7a99SStefan Roese {
179c40c7a99SStefan Roese 	u8 status2;
180469b9924SReto Schneider 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
181c40c7a99SStefan Roese 						      &status2);
182c40c7a99SStefan Roese 	int ret;
183c40c7a99SStefan Roese 
184c40c7a99SStefan Roese 	switch (status & STATUS_ECC_MASK) {
185c40c7a99SStefan Roese 	case STATUS_ECC_NO_BITFLIPS:
186c40c7a99SStefan Roese 		return 0;
187c40c7a99SStefan Roese 
188c40c7a99SStefan Roese 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
189c40c7a99SStefan Roese 		/*
190c40c7a99SStefan Roese 		 * Read status2 register to determine a more fine grained
191c40c7a99SStefan Roese 		 * bit error status
192c40c7a99SStefan Roese 		 */
193c40c7a99SStefan Roese 		ret = spi_mem_exec_op(spinand->spimem, &op);
194c40c7a99SStefan Roese 		if (ret)
195c40c7a99SStefan Roese 			return ret;
196c40c7a99SStefan Roese 
197c40c7a99SStefan Roese 		/*
198c40c7a99SStefan Roese 		 * 4 ... 7 bits are flipped (1..4 can't be detected, so
199c40c7a99SStefan Roese 		 * report the maximum of 4 in this case
200c40c7a99SStefan Roese 		 */
201c40c7a99SStefan Roese 		/* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
202c40c7a99SStefan Roese 		return ((status & STATUS_ECC_MASK) >> 2) |
203c40c7a99SStefan Roese 			((status2 & STATUS_ECC_MASK) >> 4);
204c40c7a99SStefan Roese 
205c40c7a99SStefan Roese 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
206c40c7a99SStefan Roese 		return 8;
207c40c7a99SStefan Roese 
208c40c7a99SStefan Roese 	case STATUS_ECC_UNCOR_ERROR:
209c40c7a99SStefan Roese 		return -EBADMSG;
210c40c7a99SStefan Roese 
211c40c7a99SStefan Roese 	default:
212c40c7a99SStefan Roese 		break;
213c40c7a99SStefan Roese 	}
214c40c7a99SStefan Roese 
215c40c7a99SStefan Roese 	return -EINVAL;
216c40c7a99SStefan Roese }
217c40c7a99SStefan Roese 
218469b9924SReto Schneider static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
219469b9924SReto Schneider 					u8 status)
220469b9924SReto Schneider {
221469b9924SReto Schneider 	u8 status2;
222469b9924SReto Schneider 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
223469b9924SReto Schneider 						      &status2);
224469b9924SReto Schneider 	int ret;
225469b9924SReto Schneider 
226469b9924SReto Schneider 	switch (status & STATUS_ECC_MASK) {
227469b9924SReto Schneider 	case STATUS_ECC_NO_BITFLIPS:
228469b9924SReto Schneider 		return 0;
229469b9924SReto Schneider 
230469b9924SReto Schneider 	case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
231469b9924SReto Schneider 		/*
232469b9924SReto Schneider 		 * Read status2 register to determine a more fine grained
233469b9924SReto Schneider 		 * bit error status
234469b9924SReto Schneider 		 */
235469b9924SReto Schneider 		ret = spi_mem_exec_op(spinand->spimem, &op);
236469b9924SReto Schneider 		if (ret)
237469b9924SReto Schneider 			return ret;
238469b9924SReto Schneider 
239469b9924SReto Schneider 		/*
240469b9924SReto Schneider 		 * 1 ... 4 bits are flipped (and corrected)
241469b9924SReto Schneider 		 */
242469b9924SReto Schneider 		/* bits sorted this way (1...0): ECCSE1, ECCSE0 */
243469b9924SReto Schneider 		return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
244469b9924SReto Schneider 
245469b9924SReto Schneider 	case STATUS_ECC_UNCOR_ERROR:
246469b9924SReto Schneider 		return -EBADMSG;
247469b9924SReto Schneider 
248469b9924SReto Schneider 	default:
249469b9924SReto Schneider 		break;
250469b9924SReto Schneider 	}
251469b9924SReto Schneider 
252469b9924SReto Schneider 	return -EINVAL;
253469b9924SReto Schneider }
254469b9924SReto Schneider 
255cfd93d7cSJeff Kletsky static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
256cfd93d7cSJeff Kletsky 					u8 status)
257cfd93d7cSJeff Kletsky {
258cfd93d7cSJeff Kletsky 	switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
259cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
260cfd93d7cSJeff Kletsky 		return 0;
261c93c6132SChuanhong Guo 
262cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
263cfd93d7cSJeff Kletsky 		return 3;
264cfd93d7cSJeff Kletsky 
265cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
266cfd93d7cSJeff Kletsky 		return -EBADMSG;
267cfd93d7cSJeff Kletsky 
268cfd93d7cSJeff Kletsky 	default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
269cfd93d7cSJeff Kletsky 		return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
270cfd93d7cSJeff Kletsky 	}
271cfd93d7cSJeff Kletsky 
272cfd93d7cSJeff Kletsky 	return -EINVAL;
273cfd93d7cSJeff Kletsky }
274c40c7a99SStefan Roese 
275c93c6132SChuanhong Guo static const struct spinand_info gigadevice_spinand_table[] = {
276f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4xA",
277f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
278377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
279c93c6132SChuanhong Guo 		     NAND_ECCREQ(8, 512),
280c93c6132SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
281c93c6132SChuanhong Guo 					      &write_cache_variants,
282c93c6132SChuanhong Guo 					      &update_cache_variants),
283aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
284c93c6132SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
285c93c6132SChuanhong Guo 				     gd5fxgq4xa_ecc_get_status)),
286f1541773SChuanhong Guo 	SPINAND_INFO("GD5F2GQ4xA",
287f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
288377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
289c93c6132SChuanhong Guo 		     NAND_ECCREQ(8, 512),
290c93c6132SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
291c93c6132SChuanhong Guo 					      &write_cache_variants,
292c93c6132SChuanhong Guo 					      &update_cache_variants),
293aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
294c93c6132SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
295c93c6132SChuanhong Guo 				     gd5fxgq4xa_ecc_get_status)),
296f1541773SChuanhong Guo 	SPINAND_INFO("GD5F4GQ4xA",
297f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
298a126483eSFrieder Schrempf 		     NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
299c93c6132SChuanhong Guo 		     NAND_ECCREQ(8, 512),
300c93c6132SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
301c93c6132SChuanhong Guo 					      &write_cache_variants,
302c93c6132SChuanhong Guo 					      &update_cache_variants),
303aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
304c93c6132SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
305c93c6132SChuanhong Guo 				     gd5fxgq4xa_ecc_get_status)),
306302d8a22SHauke Mehrtens 	SPINAND_INFO("GD5F4GQ4RC",
307302d8a22SHauke Mehrtens 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
308302d8a22SHauke Mehrtens 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
309302d8a22SHauke Mehrtens 		     NAND_ECCREQ(8, 512),
310302d8a22SHauke Mehrtens 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
311302d8a22SHauke Mehrtens 					      &write_cache_variants,
312302d8a22SHauke Mehrtens 					      &update_cache_variants),
313302d8a22SHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
314302d8a22SHauke Mehrtens 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
315302d8a22SHauke Mehrtens 				     gd5fxgq4ufxxg_ecc_get_status)),
316302d8a22SHauke Mehrtens 	SPINAND_INFO("GD5F4GQ4UC",
317302d8a22SHauke Mehrtens 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
318302d8a22SHauke Mehrtens 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
319302d8a22SHauke Mehrtens 		     NAND_ECCREQ(8, 512),
320302d8a22SHauke Mehrtens 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
321302d8a22SHauke Mehrtens 					      &write_cache_variants,
322302d8a22SHauke Mehrtens 					      &update_cache_variants),
323302d8a22SHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
324302d8a22SHauke Mehrtens 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
325302d8a22SHauke Mehrtens 				     gd5fxgq4ufxxg_ecc_get_status)),
326f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4UExxG",
327f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
328377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
329c40c7a99SStefan Roese 		     NAND_ECCREQ(8, 512),
330c40c7a99SStefan Roese 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
331c40c7a99SStefan Roese 					      &write_cache_variants,
332c40c7a99SStefan Roese 					      &update_cache_variants),
333aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
334469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
335c40c7a99SStefan Roese 				     gd5fxgq4uexxg_ecc_get_status)),
336*573eec22SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4RExxG",
337*573eec22SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
338*573eec22SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
339*573eec22SChuanhong Guo 		     NAND_ECCREQ(8, 512),
340*573eec22SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
341*573eec22SChuanhong Guo 					      &write_cache_variants,
342*573eec22SChuanhong Guo 					      &update_cache_variants),
343*573eec22SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
344*573eec22SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
345*573eec22SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
346*573eec22SChuanhong Guo 	SPINAND_INFO("GD5F2GQ4UExxG",
347*573eec22SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
348*573eec22SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
349*573eec22SChuanhong Guo 		     NAND_ECCREQ(8, 512),
350*573eec22SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
351*573eec22SChuanhong Guo 					      &write_cache_variants,
352*573eec22SChuanhong Guo 					      &update_cache_variants),
353*573eec22SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
354*573eec22SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
355*573eec22SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
356*573eec22SChuanhong Guo 	SPINAND_INFO("GD5F2GQ4RExxG",
357*573eec22SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
358*573eec22SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
359*573eec22SChuanhong Guo 		     NAND_ECCREQ(8, 512),
360*573eec22SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
361*573eec22SChuanhong Guo 					      &write_cache_variants,
362*573eec22SChuanhong Guo 					      &update_cache_variants),
363*573eec22SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
364*573eec22SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
365*573eec22SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
366f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4UFxxG",
367f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
368cfd93d7cSJeff Kletsky 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
369cfd93d7cSJeff Kletsky 		     NAND_ECCREQ(8, 512),
370cfd93d7cSJeff Kletsky 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
371cfd93d7cSJeff Kletsky 					      &write_cache_variants,
372cfd93d7cSJeff Kletsky 					      &update_cache_variants),
373aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
374469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
375cfd93d7cSJeff Kletsky 				     gd5fxgq4ufxxg_ecc_get_status)),
376469b9924SReto Schneider 	SPINAND_INFO("GD5F1GQ5UExxG",
377469b9924SReto Schneider 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
378469b9924SReto Schneider 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
379469b9924SReto Schneider 		     NAND_ECCREQ(4, 512),
380a4f9dd55SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
381469b9924SReto Schneider 					      &write_cache_variants,
382469b9924SReto Schneider 					      &update_cache_variants),
383469b9924SReto Schneider 		     SPINAND_HAS_QE_BIT,
384469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
385469b9924SReto Schneider 				     gd5fxgq5xexxg_ecc_get_status)),
386c93c6132SChuanhong Guo };
387c93c6132SChuanhong Guo 
388c93c6132SChuanhong Guo static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
389c93c6132SChuanhong Guo };
390c93c6132SChuanhong Guo 
391c93c6132SChuanhong Guo const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
392c93c6132SChuanhong Guo 	.id = SPINAND_MFR_GIGADEVICE,
393c93c6132SChuanhong Guo 	.name = "GigaDevice",
394f1541773SChuanhong Guo 	.chips = gigadevice_spinand_table,
395f1541773SChuanhong Guo 	.nchips = ARRAY_SIZE(gigadevice_spinand_table),
396c93c6132SChuanhong Guo 	.ops = &gigadevice_spinand_manuf_ops,
397c93c6132SChuanhong Guo };
398