1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Author:
4*4882a593Smuzhiyun * Chuanhong Guo <gch981213@gmail.com>
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/device.h>
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/mtd/spinand.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #define SPINAND_MFR_GIGADEVICE 0xC8
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
14*4882a593Smuzhiyun #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4)
17*4882a593Smuzhiyun #define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4)
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define GD5FXGQXXEXXG_REG_STATUS2 0xf0
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
22*4882a593Smuzhiyun #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
23*4882a593Smuzhiyun #define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4)
24*4882a593Smuzhiyun #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun static SPINAND_OP_VARIANTS(read_cache_variants,
27*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
28*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
29*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
30*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
31*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
32*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun static SPINAND_OP_VARIANTS(read_cache_variants_f,
35*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
36*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
37*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
38*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
39*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
40*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
43*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
44*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
45*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
46*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
47*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
48*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
51*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
52*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
53*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
54*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
55*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
56*4882a593Smuzhiyun SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun static SPINAND_OP_VARIANTS(write_cache_variants,
59*4882a593Smuzhiyun SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
60*4882a593Smuzhiyun SPINAND_PROG_LOAD(true, 0, NULL, 0));
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun static SPINAND_OP_VARIANTS(update_cache_variants,
63*4882a593Smuzhiyun SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
64*4882a593Smuzhiyun SPINAND_PROG_LOAD(false, 0, NULL, 0));
65*4882a593Smuzhiyun
gd5fxgq4xa_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)66*4882a593Smuzhiyun static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
67*4882a593Smuzhiyun struct mtd_oob_region *region)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun if (section > 3)
70*4882a593Smuzhiyun return -ERANGE;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun region->offset = (16 * section) + 8;
73*4882a593Smuzhiyun region->length = 8;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun return 0;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
gd5fxgq4xa_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)78*4882a593Smuzhiyun static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
79*4882a593Smuzhiyun struct mtd_oob_region *region)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun if (section > 3)
82*4882a593Smuzhiyun return -ERANGE;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun if (section) {
85*4882a593Smuzhiyun region->offset = 16 * section;
86*4882a593Smuzhiyun region->length = 8;
87*4882a593Smuzhiyun } else {
88*4882a593Smuzhiyun /* section 0 has one byte reserved for bad block mark */
89*4882a593Smuzhiyun region->offset = 1;
90*4882a593Smuzhiyun region->length = 7;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun return 0;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
96*4882a593Smuzhiyun .ecc = gd5fxgq4xa_ooblayout_ecc,
97*4882a593Smuzhiyun .free = gd5fxgq4xa_ooblayout_free,
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun
gd5fxgq4xa_ecc_get_status(struct spinand_device * spinand,u8 status)100*4882a593Smuzhiyun static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
101*4882a593Smuzhiyun u8 status)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun switch (status & STATUS_ECC_MASK) {
104*4882a593Smuzhiyun case STATUS_ECC_NO_BITFLIPS:
105*4882a593Smuzhiyun return 0;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
108*4882a593Smuzhiyun /* 1-7 bits are flipped. return the maximum. */
109*4882a593Smuzhiyun return 7;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
112*4882a593Smuzhiyun return 8;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun case STATUS_ECC_UNCOR_ERROR:
115*4882a593Smuzhiyun return -EBADMSG;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun default:
118*4882a593Smuzhiyun break;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun return -EINVAL;
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)124*4882a593Smuzhiyun static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
125*4882a593Smuzhiyun struct mtd_oob_region *region)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun if (section)
128*4882a593Smuzhiyun return -ERANGE;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun region->offset = 64;
131*4882a593Smuzhiyun region->length = 64;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun return 0;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
gd5fxgqx_variant2_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)136*4882a593Smuzhiyun static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
137*4882a593Smuzhiyun struct mtd_oob_region *region)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun if (section)
140*4882a593Smuzhiyun return -ERANGE;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun /* Reserve 1 bytes for the BBM. */
143*4882a593Smuzhiyun region->offset = 1;
144*4882a593Smuzhiyun region->length = 63;
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun return 0;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* Valid for Q4/Q5 and Q6 (untested) devices */
150*4882a593Smuzhiyun static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
151*4882a593Smuzhiyun .ecc = gd5fxgqx_variant2_ooblayout_ecc,
152*4882a593Smuzhiyun .free = gd5fxgqx_variant2_ooblayout_free,
153*4882a593Smuzhiyun };
154*4882a593Smuzhiyun
gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * oobregion)155*4882a593Smuzhiyun static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
156*4882a593Smuzhiyun struct mtd_oob_region *oobregion)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun if (section)
159*4882a593Smuzhiyun return -ERANGE;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun oobregion->offset = 128;
162*4882a593Smuzhiyun oobregion->length = 128;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun return 0;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
gd5fxgq4xc_ooblayout_256_free(struct mtd_info * mtd,int section,struct mtd_oob_region * oobregion)167*4882a593Smuzhiyun static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
168*4882a593Smuzhiyun struct mtd_oob_region *oobregion)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun if (section)
171*4882a593Smuzhiyun return -ERANGE;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun oobregion->offset = 1;
174*4882a593Smuzhiyun oobregion->length = 127;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun return 0;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
180*4882a593Smuzhiyun .ecc = gd5fxgq4xc_ooblayout_256_ecc,
181*4882a593Smuzhiyun .free = gd5fxgq4xc_ooblayout_256_free,
182*4882a593Smuzhiyun };
183*4882a593Smuzhiyun
gd5fxgqx_variant3_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)184*4882a593Smuzhiyun static int gd5fxgqx_variant3_ooblayout_ecc(struct mtd_info *mtd, int section,
185*4882a593Smuzhiyun struct mtd_oob_region *region)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun return -ERANGE;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun
gd5fxgqx_variant3_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)190*4882a593Smuzhiyun static int gd5fxgqx_variant3_ooblayout_free(struct mtd_info *mtd, int section,
191*4882a593Smuzhiyun struct mtd_oob_region *region)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun if (section)
194*4882a593Smuzhiyun return -ERANGE;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /* Reserve 1 bytes for the BBM. */
197*4882a593Smuzhiyun region->offset = 1;
198*4882a593Smuzhiyun region->length = 63;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun return 0;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun static const struct mtd_ooblayout_ops gd5fxgqx_variant3_ooblayout = {
204*4882a593Smuzhiyun .ecc = gd5fxgqx_variant3_ooblayout_ecc,
205*4882a593Smuzhiyun .free = gd5fxgqx_variant3_ooblayout_free,
206*4882a593Smuzhiyun };
207*4882a593Smuzhiyun
gd5fxgq4uexxg_ecc_get_status(struct spinand_device * spinand,u8 status)208*4882a593Smuzhiyun static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
209*4882a593Smuzhiyun u8 status)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun u8 status2;
212*4882a593Smuzhiyun struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
213*4882a593Smuzhiyun &status2);
214*4882a593Smuzhiyun int ret;
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun switch (status & STATUS_ECC_MASK) {
217*4882a593Smuzhiyun case STATUS_ECC_NO_BITFLIPS:
218*4882a593Smuzhiyun return 0;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
221*4882a593Smuzhiyun /*
222*4882a593Smuzhiyun * Read status2 register to determine a more fine grained
223*4882a593Smuzhiyun * bit error status
224*4882a593Smuzhiyun */
225*4882a593Smuzhiyun ret = spi_mem_exec_op(spinand->spimem, &op);
226*4882a593Smuzhiyun if (ret)
227*4882a593Smuzhiyun return ret;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun /*
230*4882a593Smuzhiyun * 4 ... 7 bits are flipped (1..4 can't be detected, so
231*4882a593Smuzhiyun * report the maximum of 4 in this case
232*4882a593Smuzhiyun */
233*4882a593Smuzhiyun /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
234*4882a593Smuzhiyun return ((status & STATUS_ECC_MASK) >> 2) |
235*4882a593Smuzhiyun ((status2 & STATUS_ECC_MASK) >> 4);
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
238*4882a593Smuzhiyun return 8;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun case STATUS_ECC_UNCOR_ERROR:
241*4882a593Smuzhiyun return -EBADMSG;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun default:
244*4882a593Smuzhiyun break;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun return -EINVAL;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
gd5fxgq5xexxg_ecc_get_status(struct spinand_device * spinand,u8 status)250*4882a593Smuzhiyun static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
251*4882a593Smuzhiyun u8 status)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun u8 status2;
254*4882a593Smuzhiyun struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
255*4882a593Smuzhiyun &status2);
256*4882a593Smuzhiyun int ret;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun switch (status & STATUS_ECC_MASK) {
259*4882a593Smuzhiyun case STATUS_ECC_NO_BITFLIPS:
260*4882a593Smuzhiyun return 0;
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
263*4882a593Smuzhiyun /*
264*4882a593Smuzhiyun * Read status2 register to determine a more fine grained
265*4882a593Smuzhiyun * bit error status
266*4882a593Smuzhiyun */
267*4882a593Smuzhiyun ret = spi_mem_exec_op(spinand->spimem, &op);
268*4882a593Smuzhiyun if (ret)
269*4882a593Smuzhiyun return ret;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun /*
272*4882a593Smuzhiyun * 1 ... 4 bits are flipped (and corrected)
273*4882a593Smuzhiyun */
274*4882a593Smuzhiyun /* bits sorted this way (1...0): ECCSE1, ECCSE0 */
275*4882a593Smuzhiyun return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun case STATUS_ECC_UNCOR_ERROR:
278*4882a593Smuzhiyun return -EBADMSG;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun default:
281*4882a593Smuzhiyun break;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun return -EINVAL;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
gd5fxgq4ufxxg_ecc_get_status(struct spinand_device * spinand,u8 status)287*4882a593Smuzhiyun static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
288*4882a593Smuzhiyun u8 status)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
291*4882a593Smuzhiyun case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
292*4882a593Smuzhiyun return 0;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
295*4882a593Smuzhiyun return 3;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
298*4882a593Smuzhiyun return -EBADMSG;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
301*4882a593Smuzhiyun return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun return -EINVAL;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun static const struct spinand_info gigadevice_spinand_table[] = {
308*4882a593Smuzhiyun SPINAND_INFO("GD5F1GQ4xA",
309*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
310*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
311*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
312*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
313*4882a593Smuzhiyun &write_cache_variants,
314*4882a593Smuzhiyun &update_cache_variants),
315*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
316*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
317*4882a593Smuzhiyun gd5fxgq4xa_ecc_get_status)),
318*4882a593Smuzhiyun SPINAND_INFO("GD5F2GQ4xA",
319*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
320*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
321*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
322*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
323*4882a593Smuzhiyun &write_cache_variants,
324*4882a593Smuzhiyun &update_cache_variants),
325*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
326*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
327*4882a593Smuzhiyun gd5fxgq4xa_ecc_get_status)),
328*4882a593Smuzhiyun SPINAND_INFO("GD5F4GQ4xA",
329*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
330*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
331*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
332*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
333*4882a593Smuzhiyun &write_cache_variants,
334*4882a593Smuzhiyun &update_cache_variants),
335*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
336*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
337*4882a593Smuzhiyun gd5fxgq4xa_ecc_get_status)),
338*4882a593Smuzhiyun SPINAND_INFO("GD5F4GQ4RC",
339*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
340*4882a593Smuzhiyun NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
341*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
342*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
343*4882a593Smuzhiyun &write_cache_variants,
344*4882a593Smuzhiyun &update_cache_variants),
345*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
346*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
347*4882a593Smuzhiyun gd5fxgq4ufxxg_ecc_get_status)),
348*4882a593Smuzhiyun SPINAND_INFO("GD5F4GQ4UC",
349*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
350*4882a593Smuzhiyun NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
351*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
352*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
353*4882a593Smuzhiyun &write_cache_variants,
354*4882a593Smuzhiyun &update_cache_variants),
355*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
356*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
357*4882a593Smuzhiyun gd5fxgq4ufxxg_ecc_get_status)),
358*4882a593Smuzhiyun SPINAND_INFO("GD5F1GQ4UExxG",
359*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
360*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
361*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
362*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
363*4882a593Smuzhiyun &write_cache_variants,
364*4882a593Smuzhiyun &update_cache_variants),
365*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
366*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
367*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
368*4882a593Smuzhiyun SPINAND_INFO("GD5F1GQ4RExxG",
369*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
370*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
371*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
372*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
373*4882a593Smuzhiyun &write_cache_variants,
374*4882a593Smuzhiyun &update_cache_variants),
375*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
376*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
377*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
378*4882a593Smuzhiyun SPINAND_INFO("GD5F2GQ4UExxG",
379*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
380*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
381*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
382*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
383*4882a593Smuzhiyun &write_cache_variants,
384*4882a593Smuzhiyun &update_cache_variants),
385*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
386*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
387*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
388*4882a593Smuzhiyun SPINAND_INFO("GD5F2GQ4RExxG",
389*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
390*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
391*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
392*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
393*4882a593Smuzhiyun &write_cache_variants,
394*4882a593Smuzhiyun &update_cache_variants),
395*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
396*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
397*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
398*4882a593Smuzhiyun SPINAND_INFO("GD5F1GQ4UFxxG",
399*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
400*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
401*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
402*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
403*4882a593Smuzhiyun &write_cache_variants,
404*4882a593Smuzhiyun &update_cache_variants),
405*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
406*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
407*4882a593Smuzhiyun gd5fxgq4ufxxg_ecc_get_status)),
408*4882a593Smuzhiyun SPINAND_INFO("GD5F1GQ5UExxG",
409*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
410*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
411*4882a593Smuzhiyun NAND_ECCREQ(4, 512),
412*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
413*4882a593Smuzhiyun &write_cache_variants,
414*4882a593Smuzhiyun &update_cache_variants),
415*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
416*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
417*4882a593Smuzhiyun gd5fxgq5xexxg_ecc_get_status)),
418*4882a593Smuzhiyun SPINAND_INFO("GD5F1GQ5RExxG",
419*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
420*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
421*4882a593Smuzhiyun NAND_ECCREQ(4, 512),
422*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
423*4882a593Smuzhiyun &write_cache_variants,
424*4882a593Smuzhiyun &update_cache_variants),
425*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
426*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
427*4882a593Smuzhiyun gd5fxgq5xexxg_ecc_get_status)),
428*4882a593Smuzhiyun SPINAND_INFO("GD5F2GQ5UExxG",
429*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
430*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
431*4882a593Smuzhiyun NAND_ECCREQ(4, 512),
432*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
433*4882a593Smuzhiyun &write_cache_variants,
434*4882a593Smuzhiyun &update_cache_variants),
435*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
436*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
437*4882a593Smuzhiyun gd5fxgq5xexxg_ecc_get_status)),
438*4882a593Smuzhiyun SPINAND_INFO("GD5F2GQ5RExxG",
439*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
440*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
441*4882a593Smuzhiyun NAND_ECCREQ(4, 512),
442*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
443*4882a593Smuzhiyun &write_cache_variants,
444*4882a593Smuzhiyun &update_cache_variants),
445*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
446*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
447*4882a593Smuzhiyun gd5fxgq5xexxg_ecc_get_status)),
448*4882a593Smuzhiyun SPINAND_INFO("GD5F4GQ6UExxG",
449*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
450*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
451*4882a593Smuzhiyun NAND_ECCREQ(4, 512),
452*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
453*4882a593Smuzhiyun &write_cache_variants,
454*4882a593Smuzhiyun &update_cache_variants),
455*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
456*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
457*4882a593Smuzhiyun gd5fxgq5xexxg_ecc_get_status)),
458*4882a593Smuzhiyun SPINAND_INFO("GD5F4GQ6RExxG",
459*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
460*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
461*4882a593Smuzhiyun NAND_ECCREQ(4, 512),
462*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
463*4882a593Smuzhiyun &write_cache_variants,
464*4882a593Smuzhiyun &update_cache_variants),
465*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
466*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
467*4882a593Smuzhiyun gd5fxgq5xexxg_ecc_get_status)),
468*4882a593Smuzhiyun SPINAND_INFO("GD5F1GM7UExxG",
469*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
470*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
471*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
472*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
473*4882a593Smuzhiyun &write_cache_variants,
474*4882a593Smuzhiyun &update_cache_variants),
475*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
476*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
477*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
478*4882a593Smuzhiyun SPINAND_INFO("GD5F1GM7RExxG",
479*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
480*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
481*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
482*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
483*4882a593Smuzhiyun &write_cache_variants,
484*4882a593Smuzhiyun &update_cache_variants),
485*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
486*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
487*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
488*4882a593Smuzhiyun SPINAND_INFO("GD5F2GM7UExxG",
489*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
490*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
491*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
492*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
493*4882a593Smuzhiyun &write_cache_variants,
494*4882a593Smuzhiyun &update_cache_variants),
495*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
496*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
497*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
498*4882a593Smuzhiyun SPINAND_INFO("GD5F2GM7RExxG",
499*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
500*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
501*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
502*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
503*4882a593Smuzhiyun &write_cache_variants,
504*4882a593Smuzhiyun &update_cache_variants),
505*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
506*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
507*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
508*4882a593Smuzhiyun SPINAND_INFO("GD5F4GM8UExxG",
509*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
510*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
511*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
512*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
513*4882a593Smuzhiyun &write_cache_variants,
514*4882a593Smuzhiyun &update_cache_variants),
515*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
516*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
517*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
518*4882a593Smuzhiyun SPINAND_INFO("GD5F4GM8RExxG",
519*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
520*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
521*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
522*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
523*4882a593Smuzhiyun &write_cache_variants,
524*4882a593Smuzhiyun &update_cache_variants),
525*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
526*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
527*4882a593Smuzhiyun gd5fxgq4uexxg_ecc_get_status)),
528*4882a593Smuzhiyun SPINAND_INFO("GD5F1GQ4UExxH",
529*4882a593Smuzhiyun SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd9),
530*4882a593Smuzhiyun NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
531*4882a593Smuzhiyun NAND_ECCREQ(8, 512),
532*4882a593Smuzhiyun SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
533*4882a593Smuzhiyun &write_cache_variants,
534*4882a593Smuzhiyun &update_cache_variants),
535*4882a593Smuzhiyun SPINAND_HAS_QE_BIT,
536*4882a593Smuzhiyun SPINAND_ECCINFO(&gd5fxgqx_variant3_ooblayout,
537*4882a593Smuzhiyun gd5fxgq4xa_ecc_get_status)),
538*4882a593Smuzhiyun };
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
541*4882a593Smuzhiyun };
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
544*4882a593Smuzhiyun .id = SPINAND_MFR_GIGADEVICE,
545*4882a593Smuzhiyun .name = "GigaDevice",
546*4882a593Smuzhiyun .chips = gigadevice_spinand_table,
547*4882a593Smuzhiyun .nchips = ARRAY_SIZE(gigadevice_spinand_table),
548*4882a593Smuzhiyun .ops = &gigadevice_spinand_manuf_ops,
549*4882a593Smuzhiyun };
550