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