xref: /linux/drivers/mtd/nand/spi/gigadevice.c (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
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 
50194ec04bSChuanhong Guo static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
51194ec04bSChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
52194ec04bSChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
53194ec04bSChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
54194ec04bSChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
55194ec04bSChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
56194ec04bSChuanhong Guo 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
57194ec04bSChuanhong Guo 
58c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(write_cache_variants,
59c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
60c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
61c93c6132SChuanhong Guo 
62c93c6132SChuanhong Guo static SPINAND_OP_VARIANTS(update_cache_variants,
63c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
64c93c6132SChuanhong Guo 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
65c93c6132SChuanhong Guo 
gd5fxgq4xa_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)66c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
67c93c6132SChuanhong Guo 				  struct mtd_oob_region *region)
68c93c6132SChuanhong Guo {
69c93c6132SChuanhong Guo 	if (section > 3)
70c93c6132SChuanhong Guo 		return -ERANGE;
71c93c6132SChuanhong Guo 
72c93c6132SChuanhong Guo 	region->offset = (16 * section) + 8;
73c93c6132SChuanhong Guo 	region->length = 8;
74c93c6132SChuanhong Guo 
75c93c6132SChuanhong Guo 	return 0;
76c93c6132SChuanhong Guo }
77c93c6132SChuanhong Guo 
gd5fxgq4xa_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)78c93c6132SChuanhong Guo static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
79c93c6132SChuanhong Guo 				   struct mtd_oob_region *region)
80c93c6132SChuanhong Guo {
81c93c6132SChuanhong Guo 	if (section > 3)
82c93c6132SChuanhong Guo 		return -ERANGE;
83c93c6132SChuanhong Guo 
84c93c6132SChuanhong Guo 	if (section) {
85c93c6132SChuanhong Guo 		region->offset = 16 * section;
86c93c6132SChuanhong Guo 		region->length = 8;
87c93c6132SChuanhong Guo 	} else {
88c93c6132SChuanhong Guo 		/* section 0 has one byte reserved for bad block mark */
89c93c6132SChuanhong Guo 		region->offset = 1;
90c93c6132SChuanhong Guo 		region->length = 7;
91c93c6132SChuanhong Guo 	}
92c93c6132SChuanhong Guo 	return 0;
93c93c6132SChuanhong Guo }
94c93c6132SChuanhong Guo 
95cfd93d7cSJeff Kletsky static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
96cfd93d7cSJeff Kletsky 	.ecc = gd5fxgq4xa_ooblayout_ecc,
97cfd93d7cSJeff Kletsky 	.free = gd5fxgq4xa_ooblayout_free,
98cfd93d7cSJeff Kletsky };
99cfd93d7cSJeff Kletsky 
gd5fxgq4xa_ecc_get_status(struct spinand_device * spinand,u8 status)100c93c6132SChuanhong Guo static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
101c93c6132SChuanhong Guo 					 u8 status)
102c93c6132SChuanhong Guo {
103c93c6132SChuanhong Guo 	switch (status & STATUS_ECC_MASK) {
104c93c6132SChuanhong Guo 	case STATUS_ECC_NO_BITFLIPS:
105c93c6132SChuanhong Guo 		return 0;
106c93c6132SChuanhong Guo 
107c93c6132SChuanhong Guo 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
108c93c6132SChuanhong Guo 		/* 1-7 bits are flipped. return the maximum. */
109c93c6132SChuanhong Guo 		return 7;
110c93c6132SChuanhong Guo 
111c93c6132SChuanhong Guo 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
112c93c6132SChuanhong Guo 		return 8;
113c93c6132SChuanhong Guo 
114c93c6132SChuanhong Guo 	case STATUS_ECC_UNCOR_ERROR:
115c93c6132SChuanhong Guo 		return -EBADMSG;
116c93c6132SChuanhong Guo 
117c93c6132SChuanhong Guo 	default:
118c93c6132SChuanhong Guo 		break;
119c93c6132SChuanhong Guo 	}
120c93c6132SChuanhong Guo 
121c93c6132SChuanhong Guo 	return -EINVAL;
122c93c6132SChuanhong Guo }
123c93c6132SChuanhong Guo 
gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)124469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
125c40c7a99SStefan Roese 				       struct mtd_oob_region *region)
126c40c7a99SStefan Roese {
127c40c7a99SStefan Roese 	if (section)
128c40c7a99SStefan Roese 		return -ERANGE;
129c40c7a99SStefan Roese 
130c40c7a99SStefan Roese 	region->offset = 64;
131c40c7a99SStefan Roese 	region->length = 64;
132c40c7a99SStefan Roese 
133c40c7a99SStefan Roese 	return 0;
134c40c7a99SStefan Roese }
135c40c7a99SStefan Roese 
gd5fxgqx_variant2_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)136469b9924SReto Schneider static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
137c40c7a99SStefan Roese 					struct mtd_oob_region *region)
138c40c7a99SStefan Roese {
139c40c7a99SStefan Roese 	if (section)
140c40c7a99SStefan Roese 		return -ERANGE;
141c40c7a99SStefan Roese 
142c40c7a99SStefan Roese 	/* Reserve 1 bytes for the BBM. */
143c40c7a99SStefan Roese 	region->offset = 1;
144c40c7a99SStefan Roese 	region->length = 63;
145c40c7a99SStefan Roese 
146c40c7a99SStefan Roese 	return 0;
147c40c7a99SStefan Roese }
148c40c7a99SStefan Roese 
149469b9924SReto Schneider /* Valid for Q4/Q5 and Q6 (untested) devices */
150469b9924SReto Schneider static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
151469b9924SReto Schneider 	.ecc = gd5fxgqx_variant2_ooblayout_ecc,
152469b9924SReto Schneider 	.free = gd5fxgqx_variant2_ooblayout_free,
153cfd93d7cSJeff Kletsky };
154cfd93d7cSJeff Kletsky 
gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * oobregion)155302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
156302d8a22SHauke Mehrtens 					struct mtd_oob_region *oobregion)
157302d8a22SHauke Mehrtens {
158302d8a22SHauke Mehrtens 	if (section)
159302d8a22SHauke Mehrtens 		return -ERANGE;
160302d8a22SHauke Mehrtens 
161302d8a22SHauke Mehrtens 	oobregion->offset = 128;
162302d8a22SHauke Mehrtens 	oobregion->length = 128;
163302d8a22SHauke Mehrtens 
164302d8a22SHauke Mehrtens 	return 0;
165302d8a22SHauke Mehrtens }
166302d8a22SHauke Mehrtens 
gd5fxgq4xc_ooblayout_256_free(struct mtd_info * mtd,int section,struct mtd_oob_region * oobregion)167302d8a22SHauke Mehrtens static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
168302d8a22SHauke Mehrtens 					 struct mtd_oob_region *oobregion)
169302d8a22SHauke Mehrtens {
170302d8a22SHauke Mehrtens 	if (section)
171302d8a22SHauke Mehrtens 		return -ERANGE;
172302d8a22SHauke Mehrtens 
173302d8a22SHauke Mehrtens 	oobregion->offset = 1;
174302d8a22SHauke Mehrtens 	oobregion->length = 127;
175302d8a22SHauke Mehrtens 
176302d8a22SHauke Mehrtens 	return 0;
177302d8a22SHauke Mehrtens }
178302d8a22SHauke Mehrtens 
179302d8a22SHauke Mehrtens static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
180302d8a22SHauke Mehrtens 	.ecc = gd5fxgq4xc_ooblayout_256_ecc,
181302d8a22SHauke Mehrtens 	.free = gd5fxgq4xc_ooblayout_256_free,
182302d8a22SHauke Mehrtens };
183302d8a22SHauke Mehrtens 
gd5fxgq4uexxg_ecc_get_status(struct spinand_device * spinand,u8 status)184c40c7a99SStefan Roese static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
185c40c7a99SStefan Roese 					u8 status)
186c40c7a99SStefan Roese {
187c40c7a99SStefan Roese 	u8 status2;
188469b9924SReto Schneider 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
189*59950610SHan Xu 						      spinand->scratchbuf);
190c40c7a99SStefan Roese 	int ret;
191c40c7a99SStefan Roese 
192c40c7a99SStefan Roese 	switch (status & STATUS_ECC_MASK) {
193c40c7a99SStefan Roese 	case STATUS_ECC_NO_BITFLIPS:
194c40c7a99SStefan Roese 		return 0;
195c40c7a99SStefan Roese 
196c40c7a99SStefan Roese 	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
197c40c7a99SStefan Roese 		/*
198c40c7a99SStefan Roese 		 * Read status2 register to determine a more fine grained
199c40c7a99SStefan Roese 		 * bit error status
200c40c7a99SStefan Roese 		 */
201c40c7a99SStefan Roese 		ret = spi_mem_exec_op(spinand->spimem, &op);
202c40c7a99SStefan Roese 		if (ret)
203c40c7a99SStefan Roese 			return ret;
204c40c7a99SStefan Roese 
205c40c7a99SStefan Roese 		/*
206c40c7a99SStefan Roese 		 * 4 ... 7 bits are flipped (1..4 can't be detected, so
207c40c7a99SStefan Roese 		 * report the maximum of 4 in this case
208c40c7a99SStefan Roese 		 */
209c40c7a99SStefan Roese 		/* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
210*59950610SHan Xu 		status2 = *(spinand->scratchbuf);
211c40c7a99SStefan Roese 		return ((status & STATUS_ECC_MASK) >> 2) |
212c40c7a99SStefan Roese 			((status2 & STATUS_ECC_MASK) >> 4);
213c40c7a99SStefan Roese 
214c40c7a99SStefan Roese 	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
215c40c7a99SStefan Roese 		return 8;
216c40c7a99SStefan Roese 
217c40c7a99SStefan Roese 	case STATUS_ECC_UNCOR_ERROR:
218c40c7a99SStefan Roese 		return -EBADMSG;
219c40c7a99SStefan Roese 
220c40c7a99SStefan Roese 	default:
221c40c7a99SStefan Roese 		break;
222c40c7a99SStefan Roese 	}
223c40c7a99SStefan Roese 
224c40c7a99SStefan Roese 	return -EINVAL;
225c40c7a99SStefan Roese }
226c40c7a99SStefan Roese 
gd5fxgq5xexxg_ecc_get_status(struct spinand_device * spinand,u8 status)227469b9924SReto Schneider static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
228469b9924SReto Schneider 					u8 status)
229469b9924SReto Schneider {
230469b9924SReto Schneider 	u8 status2;
231469b9924SReto Schneider 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
232*59950610SHan Xu 						      spinand->scratchbuf);
233469b9924SReto Schneider 	int ret;
234469b9924SReto Schneider 
235469b9924SReto Schneider 	switch (status & STATUS_ECC_MASK) {
236469b9924SReto Schneider 	case STATUS_ECC_NO_BITFLIPS:
237469b9924SReto Schneider 		return 0;
238469b9924SReto Schneider 
239469b9924SReto Schneider 	case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
240469b9924SReto Schneider 		/*
241469b9924SReto Schneider 		 * Read status2 register to determine a more fine grained
242469b9924SReto Schneider 		 * bit error status
243469b9924SReto Schneider 		 */
244469b9924SReto Schneider 		ret = spi_mem_exec_op(spinand->spimem, &op);
245469b9924SReto Schneider 		if (ret)
246469b9924SReto Schneider 			return ret;
247469b9924SReto Schneider 
248469b9924SReto Schneider 		/*
249469b9924SReto Schneider 		 * 1 ... 4 bits are flipped (and corrected)
250469b9924SReto Schneider 		 */
251469b9924SReto Schneider 		/* bits sorted this way (1...0): ECCSE1, ECCSE0 */
252*59950610SHan Xu 		status2 = *(spinand->scratchbuf);
253469b9924SReto Schneider 		return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
254469b9924SReto Schneider 
255469b9924SReto Schneider 	case STATUS_ECC_UNCOR_ERROR:
256469b9924SReto Schneider 		return -EBADMSG;
257469b9924SReto Schneider 
258469b9924SReto Schneider 	default:
259469b9924SReto Schneider 		break;
260469b9924SReto Schneider 	}
261469b9924SReto Schneider 
262469b9924SReto Schneider 	return -EINVAL;
263469b9924SReto Schneider }
264469b9924SReto Schneider 
gd5fxgq4ufxxg_ecc_get_status(struct spinand_device * spinand,u8 status)265cfd93d7cSJeff Kletsky static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
266cfd93d7cSJeff Kletsky 					u8 status)
267cfd93d7cSJeff Kletsky {
268cfd93d7cSJeff Kletsky 	switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
269cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
270cfd93d7cSJeff Kletsky 		return 0;
271c93c6132SChuanhong Guo 
272cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
273cfd93d7cSJeff Kletsky 		return 3;
274cfd93d7cSJeff Kletsky 
275cfd93d7cSJeff Kletsky 	case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
276cfd93d7cSJeff Kletsky 		return -EBADMSG;
277cfd93d7cSJeff Kletsky 
278cfd93d7cSJeff Kletsky 	default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
279cfd93d7cSJeff Kletsky 		return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
280cfd93d7cSJeff Kletsky 	}
281cfd93d7cSJeff Kletsky 
282cfd93d7cSJeff Kletsky 	return -EINVAL;
283cfd93d7cSJeff Kletsky }
284c40c7a99SStefan Roese 
285c93c6132SChuanhong Guo static const struct spinand_info gigadevice_spinand_table[] = {
286f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4xA",
287f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
288377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 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("GD5F2GQ4xA",
297f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
298377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 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)),
306f1541773SChuanhong Guo 	SPINAND_INFO("GD5F4GQ4xA",
307f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
308a126483eSFrieder Schrempf 		     NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
309c93c6132SChuanhong Guo 		     NAND_ECCREQ(8, 512),
310c93c6132SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
311c93c6132SChuanhong Guo 					      &write_cache_variants,
312c93c6132SChuanhong Guo 					      &update_cache_variants),
313aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
314c93c6132SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
315c93c6132SChuanhong Guo 				     gd5fxgq4xa_ecc_get_status)),
316302d8a22SHauke Mehrtens 	SPINAND_INFO("GD5F4GQ4RC",
317302d8a22SHauke Mehrtens 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 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)),
326302d8a22SHauke Mehrtens 	SPINAND_INFO("GD5F4GQ4UC",
327302d8a22SHauke Mehrtens 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
328302d8a22SHauke Mehrtens 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
329302d8a22SHauke Mehrtens 		     NAND_ECCREQ(8, 512),
330302d8a22SHauke Mehrtens 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
331302d8a22SHauke Mehrtens 					      &write_cache_variants,
332302d8a22SHauke Mehrtens 					      &update_cache_variants),
333302d8a22SHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
334302d8a22SHauke Mehrtens 		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
335302d8a22SHauke Mehrtens 				     gd5fxgq4ufxxg_ecc_get_status)),
336f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4UExxG",
337f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
338377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
339c40c7a99SStefan Roese 		     NAND_ECCREQ(8, 512),
340c40c7a99SStefan Roese 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
341c40c7a99SStefan Roese 					      &write_cache_variants,
342c40c7a99SStefan Roese 					      &update_cache_variants),
343aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
344469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
345c40c7a99SStefan Roese 				     gd5fxgq4uexxg_ecc_get_status)),
346573eec22SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4RExxG",
347573eec22SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
348573eec22SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
349573eec22SChuanhong Guo 		     NAND_ECCREQ(8, 512),
350573eec22SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
351573eec22SChuanhong Guo 					      &write_cache_variants,
352573eec22SChuanhong Guo 					      &update_cache_variants),
353573eec22SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
354573eec22SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
355573eec22SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
356573eec22SChuanhong Guo 	SPINAND_INFO("GD5F2GQ4UExxG",
357573eec22SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
358573eec22SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
359573eec22SChuanhong Guo 		     NAND_ECCREQ(8, 512),
360573eec22SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
361573eec22SChuanhong Guo 					      &write_cache_variants,
362573eec22SChuanhong Guo 					      &update_cache_variants),
363573eec22SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
364573eec22SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
365573eec22SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
366573eec22SChuanhong Guo 	SPINAND_INFO("GD5F2GQ4RExxG",
367573eec22SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
368573eec22SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
369573eec22SChuanhong Guo 		     NAND_ECCREQ(8, 512),
370573eec22SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
371573eec22SChuanhong Guo 					      &write_cache_variants,
372573eec22SChuanhong Guo 					      &update_cache_variants),
373573eec22SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
374573eec22SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
375573eec22SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
376f1541773SChuanhong Guo 	SPINAND_INFO("GD5F1GQ4UFxxG",
377f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
378cfd93d7cSJeff Kletsky 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
379cfd93d7cSJeff Kletsky 		     NAND_ECCREQ(8, 512),
380cfd93d7cSJeff Kletsky 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
381cfd93d7cSJeff Kletsky 					      &write_cache_variants,
382cfd93d7cSJeff Kletsky 					      &update_cache_variants),
383aea7687eSHauke Mehrtens 		     SPINAND_HAS_QE_BIT,
384469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
385cfd93d7cSJeff Kletsky 				     gd5fxgq4ufxxg_ecc_get_status)),
386469b9924SReto Schneider 	SPINAND_INFO("GD5F1GQ5UExxG",
387469b9924SReto Schneider 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
388469b9924SReto Schneider 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
389469b9924SReto Schneider 		     NAND_ECCREQ(4, 512),
390a4f9dd55SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
391469b9924SReto Schneider 					      &write_cache_variants,
392469b9924SReto Schneider 					      &update_cache_variants),
393469b9924SReto Schneider 		     SPINAND_HAS_QE_BIT,
394469b9924SReto Schneider 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
395469b9924SReto Schneider 				     gd5fxgq5xexxg_ecc_get_status)),
396620a9888SChuanhong Guo 	SPINAND_INFO("GD5F1GQ5RExxG",
397620a9888SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
398620a9888SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
399620a9888SChuanhong Guo 		     NAND_ECCREQ(4, 512),
400620a9888SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
401620a9888SChuanhong Guo 					      &write_cache_variants,
402620a9888SChuanhong Guo 					      &update_cache_variants),
403620a9888SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
404620a9888SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
405620a9888SChuanhong Guo 				     gd5fxgq5xexxg_ecc_get_status)),
406194ec04bSChuanhong Guo 	SPINAND_INFO("GD5F2GQ5UExxG",
407194ec04bSChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
408194ec04bSChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
409194ec04bSChuanhong Guo 		     NAND_ECCREQ(4, 512),
410194ec04bSChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
411194ec04bSChuanhong Guo 					      &write_cache_variants,
412194ec04bSChuanhong Guo 					      &update_cache_variants),
413194ec04bSChuanhong Guo 		     SPINAND_HAS_QE_BIT,
414194ec04bSChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
415194ec04bSChuanhong Guo 				     gd5fxgq5xexxg_ecc_get_status)),
416194ec04bSChuanhong Guo 	SPINAND_INFO("GD5F2GQ5RExxG",
417194ec04bSChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
418194ec04bSChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
419194ec04bSChuanhong Guo 		     NAND_ECCREQ(4, 512),
420194ec04bSChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
421194ec04bSChuanhong Guo 					      &write_cache_variants,
422194ec04bSChuanhong Guo 					      &update_cache_variants),
423194ec04bSChuanhong Guo 		     SPINAND_HAS_QE_BIT,
424194ec04bSChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
425194ec04bSChuanhong Guo 				     gd5fxgq5xexxg_ecc_get_status)),
426194ec04bSChuanhong Guo 	SPINAND_INFO("GD5F4GQ6UExxG",
427194ec04bSChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
428194ec04bSChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
429194ec04bSChuanhong Guo 		     NAND_ECCREQ(4, 512),
430194ec04bSChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
431194ec04bSChuanhong Guo 					      &write_cache_variants,
432194ec04bSChuanhong Guo 					      &update_cache_variants),
433194ec04bSChuanhong Guo 		     SPINAND_HAS_QE_BIT,
434194ec04bSChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
435194ec04bSChuanhong Guo 				     gd5fxgq5xexxg_ecc_get_status)),
436194ec04bSChuanhong Guo 	SPINAND_INFO("GD5F4GQ6RExxG",
437194ec04bSChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
438194ec04bSChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
439194ec04bSChuanhong Guo 		     NAND_ECCREQ(4, 512),
440194ec04bSChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
441194ec04bSChuanhong Guo 					      &write_cache_variants,
442194ec04bSChuanhong Guo 					      &update_cache_variants),
443194ec04bSChuanhong Guo 		     SPINAND_HAS_QE_BIT,
444194ec04bSChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
445194ec04bSChuanhong Guo 				     gd5fxgq5xexxg_ecc_get_status)),
44654647cd0SChuanhong Guo 	SPINAND_INFO("GD5F1GM7UExxG",
44754647cd0SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
44854647cd0SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
44954647cd0SChuanhong Guo 		     NAND_ECCREQ(8, 512),
45054647cd0SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
45154647cd0SChuanhong Guo 					      &write_cache_variants,
45254647cd0SChuanhong Guo 					      &update_cache_variants),
45354647cd0SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
45454647cd0SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
45554647cd0SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
45654647cd0SChuanhong Guo 	SPINAND_INFO("GD5F1GM7RExxG",
45754647cd0SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
45854647cd0SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
45954647cd0SChuanhong Guo 		     NAND_ECCREQ(8, 512),
46054647cd0SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
46154647cd0SChuanhong Guo 					      &write_cache_variants,
46254647cd0SChuanhong Guo 					      &update_cache_variants),
46354647cd0SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
46454647cd0SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
46554647cd0SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
46654647cd0SChuanhong Guo 	SPINAND_INFO("GD5F2GM7UExxG",
46754647cd0SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
46854647cd0SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
46954647cd0SChuanhong Guo 		     NAND_ECCREQ(8, 512),
47054647cd0SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
47154647cd0SChuanhong Guo 					      &write_cache_variants,
47254647cd0SChuanhong Guo 					      &update_cache_variants),
47354647cd0SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
47454647cd0SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
47554647cd0SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
47654647cd0SChuanhong Guo 	SPINAND_INFO("GD5F2GM7RExxG",
47754647cd0SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
47854647cd0SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
47954647cd0SChuanhong Guo 		     NAND_ECCREQ(8, 512),
48054647cd0SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
48154647cd0SChuanhong Guo 					      &write_cache_variants,
48254647cd0SChuanhong Guo 					      &update_cache_variants),
48354647cd0SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
48454647cd0SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
48554647cd0SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
48654647cd0SChuanhong Guo 	SPINAND_INFO("GD5F4GM8UExxG",
48754647cd0SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
48854647cd0SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
48954647cd0SChuanhong Guo 		     NAND_ECCREQ(8, 512),
49054647cd0SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
49154647cd0SChuanhong Guo 					      &write_cache_variants,
49254647cd0SChuanhong Guo 					      &update_cache_variants),
49354647cd0SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
49454647cd0SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
49554647cd0SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
49654647cd0SChuanhong Guo 	SPINAND_INFO("GD5F4GM8RExxG",
49754647cd0SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
49854647cd0SChuanhong Guo 		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
49954647cd0SChuanhong Guo 		     NAND_ECCREQ(8, 512),
50054647cd0SChuanhong Guo 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
50154647cd0SChuanhong Guo 					      &write_cache_variants,
50254647cd0SChuanhong Guo 					      &update_cache_variants),
50354647cd0SChuanhong Guo 		     SPINAND_HAS_QE_BIT,
50454647cd0SChuanhong Guo 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
50554647cd0SChuanhong Guo 				     gd5fxgq4uexxg_ecc_get_status)),
506ef1560b6SMd Sadre Alam 	SPINAND_INFO("GD5F2GQ5xExxH",
507ef1560b6SMd Sadre Alam 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
508ef1560b6SMd Sadre Alam 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
509ef1560b6SMd Sadre Alam 		     NAND_ECCREQ(4, 512),
510ef1560b6SMd Sadre Alam 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
511ef1560b6SMd Sadre Alam 					      &write_cache_variants,
512ef1560b6SMd Sadre Alam 					      &update_cache_variants),
513ef1560b6SMd Sadre Alam 		     SPINAND_HAS_QE_BIT,
514ef1560b6SMd Sadre Alam 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
515ef1560b6SMd Sadre Alam 				     gd5fxgq4uexxg_ecc_get_status)),
516746b0f26SSridharan S N 	SPINAND_INFO("GD5F1GQ5RExxH",
517746b0f26SSridharan S N 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x21),
518746b0f26SSridharan S N 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
519746b0f26SSridharan S N 		     NAND_ECCREQ(4, 512),
520746b0f26SSridharan S N 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
521746b0f26SSridharan S N 					      &write_cache_variants,
522746b0f26SSridharan S N 					      &update_cache_variants),
523746b0f26SSridharan S N 		     SPINAND_HAS_QE_BIT,
524746b0f26SSridharan S N 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
525746b0f26SSridharan S N 				     gd5fxgq4uexxg_ecc_get_status)),
526746b0f26SSridharan S N 	SPINAND_INFO("GD5F1GQ4RExxH",
527746b0f26SSridharan S N 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xc9),
528746b0f26SSridharan S N 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
529746b0f26SSridharan S N 		     NAND_ECCREQ(4, 512),
530746b0f26SSridharan S N 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
531746b0f26SSridharan S N 					      &write_cache_variants,
532746b0f26SSridharan S N 					      &update_cache_variants),
533746b0f26SSridharan S N 		     SPINAND_HAS_QE_BIT,
534746b0f26SSridharan S N 		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
535746b0f26SSridharan S N 				     gd5fxgq4uexxg_ecc_get_status)),
536c93c6132SChuanhong Guo };
537c93c6132SChuanhong Guo 
538c93c6132SChuanhong Guo static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
539c93c6132SChuanhong Guo };
540c93c6132SChuanhong Guo 
541c93c6132SChuanhong Guo const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
542c93c6132SChuanhong Guo 	.id = SPINAND_MFR_GIGADEVICE,
543c93c6132SChuanhong Guo 	.name = "GigaDevice",
544f1541773SChuanhong Guo 	.chips = gigadevice_spinand_table,
545f1541773SChuanhong Guo 	.nchips = ARRAY_SIZE(gigadevice_spinand_table),
546c93c6132SChuanhong Guo 	.ops = &gigadevice_spinand_manuf_ops,
547c93c6132SChuanhong Guo };
548