blob: df4f9f9f0283275227bd1aa5d977cd9b8a04bf54 [file] [log] [blame]
developerdd919e82024-02-04 10:43:20 +08001Index: linux-5.4.260/drivers/mtd/nand/spi/gigadevice.c
2===================================================================
3--- linux-5.4.260.orig/drivers/mtd/nand/spi/gigadevice.c
4+++ linux-5.4.260/drivers/mtd/nand/spi/gigadevice.c
5@@ -13,7 +13,10 @@
6 #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
7 #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
8
9-#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0
10+#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4)
11+#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4)
12+
13+#define GD5FXGQXXEXXG_REG_STATUS2 0xf0
14
15 #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
16 #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
17@@ -36,6 +39,22 @@ static SPINAND_OP_VARIANTS(read_cache_va
18 SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
19 SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
20
21+static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
22+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
23+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
24+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
25+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
26+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
27+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
28+
29+static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
30+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
31+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
32+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
33+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
34+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
35+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
36+
37 static SPINAND_OP_VARIANTS(write_cache_variants,
38 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
39 SPINAND_PROG_LOAD(true, 0, NULL, 0));
40@@ -102,7 +121,7 @@ static int gd5fxgq4xa_ecc_get_status(str
41 return -EINVAL;
42 }
43
44-static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
45+static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
46 struct mtd_oob_region *region)
47 {
48 if (section)
49@@ -114,7 +133,7 @@ static int gd5fxgq4_variant2_ooblayout_e
50 return 0;
51 }
52
53-static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
54+static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
55 struct mtd_oob_region *region)
56 {
57 if (section)
58@@ -127,16 +146,46 @@ static int gd5fxgq4_variant2_ooblayout_f
59 return 0;
60 }
61
62-static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = {
63- .ecc = gd5fxgq4_variant2_ooblayout_ecc,
64- .free = gd5fxgq4_variant2_ooblayout_free,
65+/* Valid for Q4/Q5 and Q6 (untested) devices */
66+static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
67+ .ecc = gd5fxgqx_variant2_ooblayout_ecc,
68+ .free = gd5fxgqx_variant2_ooblayout_free,
69+};
70+
71+static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
72+ struct mtd_oob_region *oobregion)
73+{
74+ if (section)
75+ return -ERANGE;
76+
77+ oobregion->offset = 128;
78+ oobregion->length = 128;
79+
80+ return 0;
81+}
82+
83+static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
84+ struct mtd_oob_region *oobregion)
85+{
86+ if (section)
87+ return -ERANGE;
88+
89+ oobregion->offset = 1;
90+ oobregion->length = 127;
91+
92+ return 0;
93+}
94+
95+static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
96+ .ecc = gd5fxgq4xc_ooblayout_256_ecc,
97+ .free = gd5fxgq4xc_ooblayout_256_free,
98 };
99
100 static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
101 u8 status)
102 {
103 u8 status2;
104- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4UEXXG_REG_STATUS2,
105+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
106 &status2);
107 int ret;
108
109@@ -174,6 +223,43 @@ static int gd5fxgq4uexxg_ecc_get_status(
110 return -EINVAL;
111 }
112
113+static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
114+ u8 status)
115+{
116+ u8 status2;
117+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
118+ &status2);
119+ int ret;
120+
121+ switch (status & STATUS_ECC_MASK) {
122+ case STATUS_ECC_NO_BITFLIPS:
123+ return 0;
124+
125+ case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
126+ /*
127+ * Read status2 register to determine a more fine grained
128+ * bit error status
129+ */
130+ ret = spi_mem_exec_op(spinand->spimem, &op);
131+ if (ret)
132+ return ret;
133+
134+ /*
135+ * 1 ... 4 bits are flipped (and corrected)
136+ */
137+ /* bits sorted this way (1...0): ECCSE1, ECCSE0 */
138+ return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
139+
140+ case STATUS_ECC_UNCOR_ERROR:
141+ return -EBADMSG;
142+
143+ default:
144+ break;
145+ }
146+
147+ return -EINVAL;
148+}
149+
150 static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
151 u8 status)
152 {
153@@ -195,7 +281,8 @@ static int gd5fxgq4ufxxg_ecc_get_status(
154 }
155
156 static const struct spinand_info gigadevice_spinand_table[] = {
157- SPINAND_INFO("GD5F1GQ4xA", 0xF1,
158+ SPINAND_INFO("GD5F1GQ4xA",
159+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
160 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
161 NAND_ECCREQ(8, 512),
162 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
163@@ -204,7 +291,8 @@ static const struct spinand_info gigadev
164 SPINAND_HAS_QE_BIT,
165 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
166 gd5fxgq4xa_ecc_get_status)),
167- SPINAND_INFO("GD5F2GQ4xA", 0xF2,
168+ SPINAND_INFO("GD5F2GQ4xA",
169+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
170 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
171 NAND_ECCREQ(8, 512),
172 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
173@@ -213,7 +301,8 @@ static const struct spinand_info gigadev
174 SPINAND_HAS_QE_BIT,
175 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
176 gd5fxgq4xa_ecc_get_status)),
177- SPINAND_INFO("GD5F4GQ4xA", 0xF4,
178+ SPINAND_INFO("GD5F4GQ4xA",
179+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
180 NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
181 NAND_ECCREQ(8, 512),
182 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
183@@ -222,59 +311,205 @@ static const struct spinand_info gigadev
184 SPINAND_HAS_QE_BIT,
185 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
186 gd5fxgq4xa_ecc_get_status)),
187- SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
188+ SPINAND_INFO("GD5F4GQ4RC",
189+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
190+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
191+ NAND_ECCREQ(8, 512),
192+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
193+ &write_cache_variants,
194+ &update_cache_variants),
195+ SPINAND_HAS_QE_BIT,
196+ SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
197+ gd5fxgq4ufxxg_ecc_get_status)),
198+ SPINAND_INFO("GD5F4GQ4UC",
199+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
200+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
201+ NAND_ECCREQ(8, 512),
202+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
203+ &write_cache_variants,
204+ &update_cache_variants),
205+ SPINAND_HAS_QE_BIT,
206+ SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
207+ gd5fxgq4ufxxg_ecc_get_status)),
208+ SPINAND_INFO("GD5F1GQ4UExxG",
209+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
210+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
211+ NAND_ECCREQ(8, 512),
212+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
213+ &write_cache_variants,
214+ &update_cache_variants),
215+ SPINAND_HAS_QE_BIT,
216+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
217+ gd5fxgq4uexxg_ecc_get_status)),
218+ SPINAND_INFO("GD5F1GQ4RExxG",
219+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
220 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
221 NAND_ECCREQ(8, 512),
222 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
223 &write_cache_variants,
224 &update_cache_variants),
225 SPINAND_HAS_QE_BIT,
226- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
227+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
228+ gd5fxgq4uexxg_ecc_get_status)),
229+ SPINAND_INFO("GD5F2GQ4UExxG",
230+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
231+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
232+ NAND_ECCREQ(8, 512),
233+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
234+ &write_cache_variants,
235+ &update_cache_variants),
236+ SPINAND_HAS_QE_BIT,
237+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
238 gd5fxgq4uexxg_ecc_get_status)),
239- SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148,
240+ SPINAND_INFO("GD5F2GQ4RExxG",
241+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
242+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
243+ NAND_ECCREQ(8, 512),
244+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
245+ &write_cache_variants,
246+ &update_cache_variants),
247+ SPINAND_HAS_QE_BIT,
248+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
249+ gd5fxgq4uexxg_ecc_get_status)),
250+ SPINAND_INFO("GD5F1GQ4UFxxG",
251+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
252 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
253 NAND_ECCREQ(8, 512),
254 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
255 &write_cache_variants,
256 &update_cache_variants),
257 SPINAND_HAS_QE_BIT,
258- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
259+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
260 gd5fxgq4ufxxg_ecc_get_status)),
261+ SPINAND_INFO("GD5F1GQ5UExxG",
262+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
263+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
264+ NAND_ECCREQ(4, 512),
265+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
266+ &write_cache_variants,
267+ &update_cache_variants),
268+ SPINAND_HAS_QE_BIT,
269+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
270+ gd5fxgq5xexxg_ecc_get_status)),
271+ SPINAND_INFO("GD5F1GQ5RExxG",
272+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
273+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
274+ NAND_ECCREQ(4, 512),
275+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
276+ &write_cache_variants,
277+ &update_cache_variants),
278+ SPINAND_HAS_QE_BIT,
279+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
280+ gd5fxgq5xexxg_ecc_get_status)),
281+ SPINAND_INFO("GD5F2GQ5UExxG",
282+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
283+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
284+ NAND_ECCREQ(4, 512),
285+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
286+ &write_cache_variants,
287+ &update_cache_variants),
288+ SPINAND_HAS_QE_BIT,
289+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
290+ gd5fxgq5xexxg_ecc_get_status)),
291+ SPINAND_INFO("GD5F2GQ5RExxG",
292+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
293+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
294+ NAND_ECCREQ(4, 512),
295+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
296+ &write_cache_variants,
297+ &update_cache_variants),
298+ SPINAND_HAS_QE_BIT,
299+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
300+ gd5fxgq5xexxg_ecc_get_status)),
301+ SPINAND_INFO("GD5F4GQ6UExxG",
302+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
303+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
304+ NAND_ECCREQ(4, 512),
305+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
306+ &write_cache_variants,
307+ &update_cache_variants),
308+ SPINAND_HAS_QE_BIT,
309+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
310+ gd5fxgq5xexxg_ecc_get_status)),
311+ SPINAND_INFO("GD5F4GQ6RExxG",
312+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
313+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
314+ NAND_ECCREQ(4, 512),
315+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
316+ &write_cache_variants,
317+ &update_cache_variants),
318+ SPINAND_HAS_QE_BIT,
319+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
320+ gd5fxgq5xexxg_ecc_get_status)),
321+ SPINAND_INFO("GD5F1GM7UExxG",
322+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
323+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
324+ NAND_ECCREQ(8, 512),
325+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
326+ &write_cache_variants,
327+ &update_cache_variants),
328+ SPINAND_HAS_QE_BIT,
329+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
330+ gd5fxgq4uexxg_ecc_get_status)),
331+ SPINAND_INFO("GD5F1GM7RExxG",
332+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
333+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
334+ NAND_ECCREQ(8, 512),
335+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
336+ &write_cache_variants,
337+ &update_cache_variants),
338+ SPINAND_HAS_QE_BIT,
339+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
340+ gd5fxgq4uexxg_ecc_get_status)),
341+ SPINAND_INFO("GD5F2GM7UExxG",
342+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
343+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
344+ NAND_ECCREQ(8, 512),
345+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
346+ &write_cache_variants,
347+ &update_cache_variants),
348+ SPINAND_HAS_QE_BIT,
349+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
350+ gd5fxgq4uexxg_ecc_get_status)),
351+ SPINAND_INFO("GD5F2GM7RExxG",
352+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
353+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
354+ NAND_ECCREQ(8, 512),
355+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
356+ &write_cache_variants,
357+ &update_cache_variants),
358+ SPINAND_HAS_QE_BIT,
359+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
360+ gd5fxgq4uexxg_ecc_get_status)),
361+ SPINAND_INFO("GD5F4GM8UExxG",
362+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
363+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
364+ NAND_ECCREQ(8, 512),
365+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
366+ &write_cache_variants,
367+ &update_cache_variants),
368+ SPINAND_HAS_QE_BIT,
369+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
370+ gd5fxgq4uexxg_ecc_get_status)),
371+ SPINAND_INFO("GD5F4GM8RExxG",
372+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
373+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
374+ NAND_ECCREQ(8, 512),
375+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
376+ &write_cache_variants,
377+ &update_cache_variants),
378+ SPINAND_HAS_QE_BIT,
379+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
380+ gd5fxgq4uexxg_ecc_get_status)),
381 };
382
383-static int gigadevice_spinand_detect(struct spinand_device *spinand)
384-{
385- u8 *id = spinand->id.data;
386- u16 did;
387- int ret;
388-
389- /*
390- * Earlier GDF5-series devices (A,E) return [0][MID][DID]
391- * Later (F) devices return [MID][DID1][DID2]
392- */
393-
394- if (id[0] == SPINAND_MFR_GIGADEVICE)
395- did = (id[1] << 8) + id[2];
396- else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE)
397- did = id[2];
398- else
399- return 0;
400-
401- ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
402- ARRAY_SIZE(gigadevice_spinand_table),
403- did);
404- if (ret)
405- return ret;
406-
407- return 1;
408-}
409-
410 static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
411- .detect = gigadevice_spinand_detect,
412 };
413
414 const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
415 .id = SPINAND_MFR_GIGADEVICE,
416 .name = "GigaDevice",
417+ .chips = gigadevice_spinand_table,
418+ .nchips = ARRAY_SIZE(gigadevice_spinand_table),
419 .ops = &gigadevice_spinand_manuf_ops,
420 };
421Index: linux-5.4.260/drivers/mtd/nand/spi/macronix.c
422===================================================================
423--- linux-5.4.260.orig/drivers/mtd/nand/spi/macronix.c
424+++ linux-5.4.260/drivers/mtd/nand/spi/macronix.c
425@@ -99,7 +99,8 @@ static int mx35lf1ge4ab_ecc_get_status(s
426 }
427
428 static const struct spinand_info macronix_spinand_table[] = {
429- SPINAND_INFO("MX35LF1GE4AB", 0x12,
430+ SPINAND_INFO("MX35LF1GE4AB",
431+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
432 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
433 NAND_ECCREQ(4, 512),
434 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
435@@ -108,7 +109,8 @@ static const struct spinand_info macroni
436 SPINAND_HAS_QE_BIT,
437 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
438 mx35lf1ge4ab_ecc_get_status)),
439- SPINAND_INFO("MX35LF2GE4AB", 0x22,
440+ SPINAND_INFO("MX35LF2GE4AB",
441+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
442 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
443 NAND_ECCREQ(4, 512),
444 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
445@@ -116,51 +118,194 @@ static const struct spinand_info macroni
446 &update_cache_variants),
447 SPINAND_HAS_QE_BIT,
448 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
449- SPINAND_INFO("MX35LF2GE4AD", 0x26,
450+ SPINAND_INFO("MX35LF2GE4AD",
451+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26),
452 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
453 NAND_ECCREQ(8, 512),
454 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
455 &write_cache_variants,
456 &update_cache_variants),
457 SPINAND_HAS_QE_BIT,
458+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
459+ mx35lf1ge4ab_ecc_get_status)),
460+ SPINAND_INFO("MX35LF4GE4AD",
461+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
462+ NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1),
463+ NAND_ECCREQ(8, 512),
464+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
465+ &write_cache_variants,
466+ &update_cache_variants),
467+ SPINAND_HAS_QE_BIT,
468+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
469+ mx35lf1ge4ab_ecc_get_status)),
470+ SPINAND_INFO("MX35LF1G24AD",
471+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
472+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
473+ NAND_ECCREQ(8, 512),
474+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
475+ &write_cache_variants,
476+ &update_cache_variants),
477+ SPINAND_HAS_QE_BIT,
478 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
479- SPINAND_INFO("MX35LF4GE4AD", 0x37,
480- NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
481+ SPINAND_INFO("MX35LF2G24AD",
482+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
483+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
484 NAND_ECCREQ(8, 512),
485 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
486 &write_cache_variants,
487 &update_cache_variants),
488 SPINAND_HAS_QE_BIT,
489 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
490-};
491-
492-static int macronix_spinand_detect(struct spinand_device *spinand)
493-{
494- u8 *id = spinand->id.data;
495- int ret;
496-
497- /*
498- * Macronix SPI NAND read ID needs a dummy byte, so the first byte in
499- * raw_id is garbage.
500- */
501- if (id[1] != SPINAND_MFR_MACRONIX)
502- return 0;
503+ SPINAND_INFO("MX35LF4G24AD",
504+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
505+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
506+ NAND_ECCREQ(8, 512),
507+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
508+ &write_cache_variants,
509+ &update_cache_variants),
510+ SPINAND_HAS_QE_BIT,
511+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
512+ SPINAND_INFO("MX31LF1GE4BC",
513+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
514+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
515+ NAND_ECCREQ(8, 512),
516+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
517+ &write_cache_variants,
518+ &update_cache_variants),
519+ SPINAND_HAS_QE_BIT,
520+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
521+ mx35lf1ge4ab_ecc_get_status)),
522+ SPINAND_INFO("MX31UF1GE4BC",
523+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
524+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
525+ NAND_ECCREQ(8, 512),
526+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
527+ &write_cache_variants,
528+ &update_cache_variants),
529+ SPINAND_HAS_QE_BIT,
530+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
531+ mx35lf1ge4ab_ecc_get_status)),
532
533- ret = spinand_match_and_init(spinand, macronix_spinand_table,
534- ARRAY_SIZE(macronix_spinand_table),
535- id[2]);
536- if (ret)
537- return ret;
538+ SPINAND_INFO("MX35LF2G14AC",
539+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20),
540+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
541+ NAND_ECCREQ(4, 512),
542+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
543+ &write_cache_variants,
544+ &update_cache_variants),
545+ SPINAND_HAS_QE_BIT,
546+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
547+ mx35lf1ge4ab_ecc_get_status)),
548+ SPINAND_INFO("MX35UF4G24AD",
549+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5),
550+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
551+ NAND_ECCREQ(8, 512),
552+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
553+ &write_cache_variants,
554+ &update_cache_variants),
555+ SPINAND_HAS_QE_BIT,
556+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
557+ mx35lf1ge4ab_ecc_get_status)),
558+ SPINAND_INFO("MX35UF4GE4AD",
559+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7),
560+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
561+ NAND_ECCREQ(8, 512),
562+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
563+ &write_cache_variants,
564+ &update_cache_variants),
565+ SPINAND_HAS_QE_BIT,
566+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
567+ mx35lf1ge4ab_ecc_get_status)),
568+ SPINAND_INFO("MX35UF2G14AC",
569+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
570+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
571+ NAND_ECCREQ(4, 512),
572+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
573+ &write_cache_variants,
574+ &update_cache_variants),
575+ SPINAND_HAS_QE_BIT,
576+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
577+ mx35lf1ge4ab_ecc_get_status)),
578+ SPINAND_INFO("MX35UF2G24AD",
579+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4),
580+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
581+ NAND_ECCREQ(8, 512),
582+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
583+ &write_cache_variants,
584+ &update_cache_variants),
585+ SPINAND_HAS_QE_BIT,
586+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
587+ mx35lf1ge4ab_ecc_get_status)),
588+ SPINAND_INFO("MX35UF2GE4AD",
589+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6),
590+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
591+ NAND_ECCREQ(8, 512),
592+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
593+ &write_cache_variants,
594+ &update_cache_variants),
595+ SPINAND_HAS_QE_BIT,
596+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
597+ mx35lf1ge4ab_ecc_get_status)),
598+ SPINAND_INFO("MX35UF2GE4AC",
599+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2),
600+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
601+ NAND_ECCREQ(4, 512),
602+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
603+ &write_cache_variants,
604+ &update_cache_variants),
605+ SPINAND_HAS_QE_BIT,
606+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
607+ mx35lf1ge4ab_ecc_get_status)),
608+ SPINAND_INFO("MX35UF1G14AC",
609+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90),
610+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
611+ NAND_ECCREQ(4, 512),
612+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
613+ &write_cache_variants,
614+ &update_cache_variants),
615+ SPINAND_HAS_QE_BIT,
616+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
617+ mx35lf1ge4ab_ecc_get_status)),
618+ SPINAND_INFO("MX35UF1G24AD",
619+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94),
620+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
621+ NAND_ECCREQ(8, 512),
622+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
623+ &write_cache_variants,
624+ &update_cache_variants),
625+ SPINAND_HAS_QE_BIT,
626+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
627+ mx35lf1ge4ab_ecc_get_status)),
628+ SPINAND_INFO("MX35UF1GE4AD",
629+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96),
630+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
631+ NAND_ECCREQ(8, 512),
632+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
633+ &write_cache_variants,
634+ &update_cache_variants),
635+ SPINAND_HAS_QE_BIT,
636+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
637+ mx35lf1ge4ab_ecc_get_status)),
638+ SPINAND_INFO("MX35UF1GE4AC",
639+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
640+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
641+ NAND_ECCREQ(4, 512),
642+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
643+ &write_cache_variants,
644+ &update_cache_variants),
645+ SPINAND_HAS_QE_BIT,
646+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
647+ mx35lf1ge4ab_ecc_get_status)),
648
649- return 1;
650-}
651+};
652
653 static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
654- .detect = macronix_spinand_detect,
655 };
656
657 const struct spinand_manufacturer macronix_spinand_manufacturer = {
658 .id = SPINAND_MFR_MACRONIX,
659 .name = "Macronix",
660+ .chips = macronix_spinand_table,
661+ .nchips = ARRAY_SIZE(macronix_spinand_table),
662 .ops = &macronix_spinand_manuf_ops,
663 };
664Index: linux-5.4.260/drivers/mtd/nand/spi/micron.c
665===================================================================
666--- linux-5.4.260.orig/drivers/mtd/nand/spi/micron.c
667+++ linux-5.4.260/drivers/mtd/nand/spi/micron.c
668@@ -12,13 +12,23 @@
669
670 #define SPINAND_MFR_MICRON 0x2c
671
672-#define MICRON_STATUS_ECC_MASK GENMASK(6, 4)
673+#define MICRON_STATUS_ECC_MASK GENMASK(7, 4)
674 #define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4)
675 #define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
676 #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
677 #define MICRON_STATUS_ECC_7TO8_BITFLIPS (5 << 4)
678
679-static SPINAND_OP_VARIANTS(read_cache_variants,
680+#define MICRON_CFG_CR BIT(0)
681+
682+/*
683+ * As per datasheet, die selection is done by the 6th bit of Die
684+ * Select Register (Address 0xD0).
685+ */
686+#define MICRON_DIE_SELECT_REG 0xD0
687+
688+#define MICRON_SELECT_DIE(x) ((x) << 6)
689+
690+static SPINAND_OP_VARIANTS(quadio_read_cache_variants,
691 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
692 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
693 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
694@@ -26,46 +36,114 @@ static SPINAND_OP_VARIANTS(read_cache_va
695 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
696 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
697
698-static SPINAND_OP_VARIANTS(write_cache_variants,
699+static SPINAND_OP_VARIANTS(x4_write_cache_variants,
700 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
701 SPINAND_PROG_LOAD(true, 0, NULL, 0));
702
703-static SPINAND_OP_VARIANTS(update_cache_variants,
704+static SPINAND_OP_VARIANTS(x4_update_cache_variants,
705 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
706 SPINAND_PROG_LOAD(false, 0, NULL, 0));
707
708-static int mt29f2g01abagd_ooblayout_ecc(struct mtd_info *mtd, int section,
709- struct mtd_oob_region *region)
710+/* Micron MT29F2G01AAAED Device */
711+static SPINAND_OP_VARIANTS(x4_read_cache_variants,
712+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
713+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
714+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
715+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
716+
717+static SPINAND_OP_VARIANTS(x1_write_cache_variants,
718+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
719+
720+static SPINAND_OP_VARIANTS(x1_update_cache_variants,
721+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
722+
723+static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section,
724+ struct mtd_oob_region *region)
725 {
726 if (section)
727 return -ERANGE;
728
729- region->offset = 64;
730- region->length = 64;
731+ region->offset = mtd->oobsize / 2;
732+ region->length = mtd->oobsize / 2;
733
734 return 0;
735 }
736
737-static int mt29f2g01abagd_ooblayout_free(struct mtd_info *mtd, int section,
738- struct mtd_oob_region *region)
739+static int micron_8_ooblayout_free(struct mtd_info *mtd, int section,
740+ struct mtd_oob_region *region)
741 {
742 if (section)
743 return -ERANGE;
744
745 /* Reserve 2 bytes for the BBM. */
746 region->offset = 2;
747- region->length = 62;
748+ region->length = (mtd->oobsize / 2) - 2;
749+
750+ return 0;
751+}
752+
753+static const struct mtd_ooblayout_ops micron_8_ooblayout = {
754+ .ecc = micron_8_ooblayout_ecc,
755+ .free = micron_8_ooblayout_free,
756+};
757+
758+static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section,
759+ struct mtd_oob_region *region)
760+{
761+ struct spinand_device *spinand = mtd_to_spinand(mtd);
762+
763+ if (section >= spinand->base.memorg.pagesize /
764+ mtd->ecc_step_size)
765+ return -ERANGE;
766+
767+ region->offset = (section * 16) + 8;
768+ region->length = 8;
769+
770+ return 0;
771+}
772+
773+static int micron_4_ooblayout_free(struct mtd_info *mtd, int section,
774+ struct mtd_oob_region *region)
775+{
776+ struct spinand_device *spinand = mtd_to_spinand(mtd);
777+
778+ if (section >= spinand->base.memorg.pagesize /
779+ mtd->ecc_step_size)
780+ return -ERANGE;
781+
782+ if (section) {
783+ region->offset = 16 * section;
784+ region->length = 8;
785+ } else {
786+ /* section 0 has two bytes reserved for the BBM */
787+ region->offset = 2;
788+ region->length = 6;
789+ }
790
791 return 0;
792 }
793
794-static const struct mtd_ooblayout_ops mt29f2g01abagd_ooblayout = {
795- .ecc = mt29f2g01abagd_ooblayout_ecc,
796- .free = mt29f2g01abagd_ooblayout_free,
797+static const struct mtd_ooblayout_ops micron_4_ooblayout = {
798+ .ecc = micron_4_ooblayout_ecc,
799+ .free = micron_4_ooblayout_free,
800 };
801
802-static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand,
803- u8 status)
804+static int micron_select_target(struct spinand_device *spinand,
805+ unsigned int target)
806+{
807+ struct spi_mem_op op = SPINAND_SET_FEATURE_OP(MICRON_DIE_SELECT_REG,
808+ spinand->scratchbuf);
809+
810+ if (target > 1)
811+ return -EINVAL;
812+
813+ *spinand->scratchbuf = MICRON_SELECT_DIE(target);
814+
815+ return spi_mem_exec_op(spinand->spimem, &op);
816+}
817+
818+static int micron_8_ecc_get_status(struct spinand_device *spinand,
819+ u8 status)
820 {
821 switch (status & MICRON_STATUS_ECC_MASK) {
822 case STATUS_ECC_NO_BITFLIPS:
823@@ -91,43 +169,141 @@ static int mt29f2g01abagd_ecc_get_status
824 }
825
826 static const struct spinand_info micron_spinand_table[] = {
827- SPINAND_INFO("MT29F2G01ABAGD", 0x24,
828+ /* M79A 2Gb 3.3V */
829+ SPINAND_INFO("MT29F2G01ABAGD",
830+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
831 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
832 NAND_ECCREQ(8, 512),
833- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
834- &write_cache_variants,
835- &update_cache_variants),
836+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
837+ &x4_write_cache_variants,
838+ &x4_update_cache_variants),
839+ 0,
840+ SPINAND_ECCINFO(&micron_8_ooblayout,
841+ micron_8_ecc_get_status)),
842+ /* M79A 2Gb 1.8V */
843+ SPINAND_INFO("MT29F2G01ABBGD",
844+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
845+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
846+ NAND_ECCREQ(8, 512),
847+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
848+ &x4_write_cache_variants,
849+ &x4_update_cache_variants),
850+ 0,
851+ SPINAND_ECCINFO(&micron_8_ooblayout,
852+ micron_8_ecc_get_status)),
853+ /* M78A 1Gb 3.3V */
854+ SPINAND_INFO("MT29F1G01ABAFD",
855+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
856+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
857+ NAND_ECCREQ(8, 512),
858+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
859+ &x4_write_cache_variants,
860+ &x4_update_cache_variants),
861+ 0,
862+ SPINAND_ECCINFO(&micron_8_ooblayout,
863+ micron_8_ecc_get_status)),
864+ /* M78A 1Gb 1.8V */
865+ SPINAND_INFO("MT29F1G01ABAFD",
866+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
867+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
868+ NAND_ECCREQ(8, 512),
869+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
870+ &x4_write_cache_variants,
871+ &x4_update_cache_variants),
872+ 0,
873+ SPINAND_ECCINFO(&micron_8_ooblayout,
874+ micron_8_ecc_get_status)),
875+ /* M79A 4Gb 3.3V */
876+ SPINAND_INFO("MT29F4G01ADAGD",
877+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
878+ NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2),
879+ NAND_ECCREQ(8, 512),
880+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
881+ &x4_write_cache_variants,
882+ &x4_update_cache_variants),
883+ 0,
884+ SPINAND_ECCINFO(&micron_8_ooblayout,
885+ micron_8_ecc_get_status),
886+ SPINAND_SELECT_TARGET(micron_select_target)),
887+ /* M70A 4Gb 3.3V */
888+ SPINAND_INFO("MT29F4G01ABAFD",
889+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
890+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
891+ NAND_ECCREQ(8, 512),
892+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
893+ &x4_write_cache_variants,
894+ &x4_update_cache_variants),
895+ SPINAND_HAS_CR_FEAT_BIT,
896+ SPINAND_ECCINFO(&micron_8_ooblayout,
897+ micron_8_ecc_get_status)),
898+ /* M70A 4Gb 1.8V */
899+ SPINAND_INFO("MT29F4G01ABBFD",
900+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
901+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
902+ NAND_ECCREQ(8, 512),
903+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
904+ &x4_write_cache_variants,
905+ &x4_update_cache_variants),
906+ SPINAND_HAS_CR_FEAT_BIT,
907+ SPINAND_ECCINFO(&micron_8_ooblayout,
908+ micron_8_ecc_get_status)),
909+ /* M70A 8Gb 3.3V */
910+ SPINAND_INFO("MT29F8G01ADAFD",
911+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
912+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
913+ NAND_ECCREQ(8, 512),
914+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
915+ &x4_write_cache_variants,
916+ &x4_update_cache_variants),
917+ SPINAND_HAS_CR_FEAT_BIT,
918+ SPINAND_ECCINFO(&micron_8_ooblayout,
919+ micron_8_ecc_get_status),
920+ SPINAND_SELECT_TARGET(micron_select_target)),
921+ /* M70A 8Gb 1.8V */
922+ SPINAND_INFO("MT29F8G01ADBFD",
923+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
924+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
925+ NAND_ECCREQ(8, 512),
926+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
927+ &x4_write_cache_variants,
928+ &x4_update_cache_variants),
929+ SPINAND_HAS_CR_FEAT_BIT,
930+ SPINAND_ECCINFO(&micron_8_ooblayout,
931+ micron_8_ecc_get_status),
932+ SPINAND_SELECT_TARGET(micron_select_target)),
933+ /* M69A 2Gb 3.3V */
934+ SPINAND_INFO("MT29F2G01AAAED",
935+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9F),
936+ NAND_MEMORG(1, 2048, 64, 64, 2048, 80, 2, 1, 1),
937+ NAND_ECCREQ(4, 512),
938+ SPINAND_INFO_OP_VARIANTS(&x4_read_cache_variants,
939+ &x1_write_cache_variants,
940+ &x1_update_cache_variants),
941 0,
942- SPINAND_ECCINFO(&mt29f2g01abagd_ooblayout,
943- mt29f2g01abagd_ecc_get_status)),
944+ SPINAND_ECCINFO(&micron_4_ooblayout, NULL)),
945 };
946
947-static int micron_spinand_detect(struct spinand_device *spinand)
948+static int micron_spinand_init(struct spinand_device *spinand)
949 {
950- u8 *id = spinand->id.data;
951- int ret;
952-
953 /*
954- * Micron SPI NAND read ID need a dummy byte,
955- * so the first byte in raw_id is dummy.
956+ * M70A device series enable Continuous Read feature at Power-up,
957+ * which is not supported. Disable this bit to avoid any possible
958+ * failure.
959 */
960- if (id[1] != SPINAND_MFR_MICRON)
961- return 0;
962-
963- ret = spinand_match_and_init(spinand, micron_spinand_table,
964- ARRAY_SIZE(micron_spinand_table), id[2]);
965- if (ret)
966- return ret;
967+ if (spinand->flags & SPINAND_HAS_CR_FEAT_BIT)
968+ return spinand_upd_cfg(spinand, MICRON_CFG_CR, 0);
969
970- return 1;
971+ return 0;
972 }
973
974 static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
975- .detect = micron_spinand_detect,
976+ .init = micron_spinand_init,
977 };
978
979 const struct spinand_manufacturer micron_spinand_manufacturer = {
980 .id = SPINAND_MFR_MICRON,
981 .name = "Micron",
982+ .chips = micron_spinand_table,
983+ .nchips = ARRAY_SIZE(micron_spinand_table),
984 .ops = &micron_spinand_manuf_ops,
985 };
986Index: linux-5.4.260/drivers/mtd/nand/spi/paragon.c
987===================================================================
988--- linux-5.4.260.orig/drivers/mtd/nand/spi/paragon.c
989+++ linux-5.4.260/drivers/mtd/nand/spi/paragon.c
990@@ -97,7 +97,8 @@ static const struct mtd_ooblayout_ops pn
991
992
993 static const struct spinand_info paragon_spinand_table[] = {
994- SPINAND_INFO("PN26G01A", 0xe1,
995+ SPINAND_INFO("PN26G01A",
996+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe1),
997 NAND_MEMORG(1, 2048, 128, 64, 1024, 21, 1, 1, 1),
998 NAND_ECCREQ(8, 512),
999 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1000@@ -106,7 +107,8 @@ static const struct spinand_info paragon
1001 0,
1002 SPINAND_ECCINFO(&pn26g0xa_ooblayout,
1003 pn26g0xa_ecc_get_status)),
1004- SPINAND_INFO("PN26G02A", 0xe2,
1005+ SPINAND_INFO("PN26G02A",
1006+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe2),
1007 NAND_MEMORG(1, 2048, 128, 64, 2048, 41, 1, 1, 1),
1008 NAND_ECCREQ(8, 512),
1009 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1010@@ -117,31 +119,13 @@ static const struct spinand_info paragon
1011 pn26g0xa_ecc_get_status)),
1012 };
1013
1014-static int paragon_spinand_detect(struct spinand_device *spinand)
1015-{
1016- u8 *id = spinand->id.data;
1017- int ret;
1018-
1019- /* Read ID returns [0][MID][DID] */
1020-
1021- if (id[1] != SPINAND_MFR_PARAGON)
1022- return 0;
1023-
1024- ret = spinand_match_and_init(spinand, paragon_spinand_table,
1025- ARRAY_SIZE(paragon_spinand_table),
1026- id[2]);
1027- if (ret)
1028- return ret;
1029-
1030- return 1;
1031-}
1032-
1033 static const struct spinand_manufacturer_ops paragon_spinand_manuf_ops = {
1034- .detect = paragon_spinand_detect,
1035 };
1036
1037 const struct spinand_manufacturer paragon_spinand_manufacturer = {
1038 .id = SPINAND_MFR_PARAGON,
1039 .name = "Paragon",
1040+ .chips = paragon_spinand_table,
1041+ .nchips = ARRAY_SIZE(paragon_spinand_table),
1042 .ops = &paragon_spinand_manuf_ops,
1043 };
1044Index: linux-5.4.260/drivers/mtd/nand/spi/toshiba.c
1045===================================================================
1046--- linux-5.4.260.orig/drivers/mtd/nand/spi/toshiba.c
1047+++ linux-5.4.260/drivers/mtd/nand/spi/toshiba.c
1048@@ -10,6 +10,7 @@
1049 #include <linux/kernel.h>
1050 #include <linux/mtd/spinand.h>
1051
1052+/* Kioxia is new name of Toshiba memory. */
1053 #define SPINAND_MFR_TOSHIBA 0x98
1054 #define TOSH_STATUS_ECC_HAS_BITFLIPS_T (3 << 4)
1055
1056@@ -19,14 +20,26 @@ static SPINAND_OP_VARIANTS(read_cache_va
1057 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
1058 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
1059
1060+static SPINAND_OP_VARIANTS(write_cache_x4_variants,
1061+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
1062+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
1063+
1064+static SPINAND_OP_VARIANTS(update_cache_x4_variants,
1065+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
1066+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
1067+
1068+/*
1069+ * Backward compatibility for 1st generation Serial NAND devices
1070+ * which don't support Quad Program Load operation.
1071+ */
1072 static SPINAND_OP_VARIANTS(write_cache_variants,
1073 SPINAND_PROG_LOAD(true, 0, NULL, 0));
1074
1075 static SPINAND_OP_VARIANTS(update_cache_variants,
1076 SPINAND_PROG_LOAD(false, 0, NULL, 0));
1077
1078-static int tc58cxgxsx_ooblayout_ecc(struct mtd_info *mtd, int section,
1079- struct mtd_oob_region *region)
1080+static int tx58cxgxsxraix_ooblayout_ecc(struct mtd_info *mtd, int section,
1081+ struct mtd_oob_region *region)
1082 {
1083 if (section > 0)
1084 return -ERANGE;
1085@@ -37,8 +50,8 @@ static int tc58cxgxsx_ooblayout_ecc(stru
1086 return 0;
1087 }
1088
1089-static int tc58cxgxsx_ooblayout_free(struct mtd_info *mtd, int section,
1090- struct mtd_oob_region *region)
1091+static int tx58cxgxsxraix_ooblayout_free(struct mtd_info *mtd, int section,
1092+ struct mtd_oob_region *region)
1093 {
1094 if (section > 0)
1095 return -ERANGE;
1096@@ -50,13 +63,13 @@ static int tc58cxgxsx_ooblayout_free(str
1097 return 0;
1098 }
1099
1100-static const struct mtd_ooblayout_ops tc58cxgxsx_ooblayout = {
1101- .ecc = tc58cxgxsx_ooblayout_ecc,
1102- .free = tc58cxgxsx_ooblayout_free,
1103+static const struct mtd_ooblayout_ops tx58cxgxsxraix_ooblayout = {
1104+ .ecc = tx58cxgxsxraix_ooblayout_ecc,
1105+ .free = tx58cxgxsxraix_ooblayout_free,
1106 };
1107
1108-static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand,
1109- u8 status)
1110+static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
1111+ u8 status)
1112 {
1113 struct nand_device *nand = spinand_to_nand(spinand);
1114 u8 mbf = 0;
1115@@ -94,95 +107,174 @@ static int tc58cxgxsx_ecc_get_status(str
1116 }
1117
1118 static const struct spinand_info toshiba_spinand_table[] = {
1119- /* 3.3V 1Gb */
1120- SPINAND_INFO("TC58CVG0S3", 0xC2,
1121+ /* 3.3V 1Gb (1st generation) */
1122+ SPINAND_INFO("TC58CVG0S3HRAIG",
1123+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
1124 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
1125 NAND_ECCREQ(8, 512),
1126 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1127 &write_cache_variants,
1128 &update_cache_variants),
1129 0,
1130- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
1131- tc58cxgxsx_ecc_get_status)),
1132- /* 3.3V 2Gb */
1133- SPINAND_INFO("TC58CVG1S3", 0xCB,
1134+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1135+ tx58cxgxsxraix_ecc_get_status)),
1136+ /* 3.3V 2Gb (1st generation) */
1137+ SPINAND_INFO("TC58CVG1S3HRAIG",
1138+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
1139 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
1140 NAND_ECCREQ(8, 512),
1141 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1142 &write_cache_variants,
1143 &update_cache_variants),
1144 0,
1145- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
1146- tc58cxgxsx_ecc_get_status)),
1147- /* 3.3V 4Gb */
1148- SPINAND_INFO("TC58CVG2S0", 0xCD,
1149+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1150+ tx58cxgxsxraix_ecc_get_status)),
1151+ /* 3.3V 4Gb (1st generation) */
1152+ SPINAND_INFO("TC58CVG2S0HRAIG",
1153+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
1154 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
1155 NAND_ECCREQ(8, 512),
1156 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1157 &write_cache_variants,
1158 &update_cache_variants),
1159 0,
1160- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
1161- tc58cxgxsx_ecc_get_status)),
1162- /* 1.8V 1Gb */
1163- SPINAND_INFO("TC58CYG0S3", 0xB2,
1164+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1165+ tx58cxgxsxraix_ecc_get_status)),
1166+ /* 1.8V 1Gb (1st generation) */
1167+ SPINAND_INFO("TC58CYG0S3HRAIG",
1168+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
1169 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
1170 NAND_ECCREQ(8, 512),
1171 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1172 &write_cache_variants,
1173 &update_cache_variants),
1174 0,
1175- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
1176- tc58cxgxsx_ecc_get_status)),
1177- /* 1.8V 2Gb */
1178- SPINAND_INFO("TC58CYG1S3", 0xBB,
1179+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1180+ tx58cxgxsxraix_ecc_get_status)),
1181+ /* 1.8V 2Gb (1st generation) */
1182+ SPINAND_INFO("TC58CYG1S3HRAIG",
1183+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
1184 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
1185 NAND_ECCREQ(8, 512),
1186 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1187 &write_cache_variants,
1188 &update_cache_variants),
1189 0,
1190- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
1191- tc58cxgxsx_ecc_get_status)),
1192- /* 1.8V 4Gb */
1193- SPINAND_INFO("TC58CYG2S0", 0xBD,
1194+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1195+ tx58cxgxsxraix_ecc_get_status)),
1196+ /* 1.8V 4Gb (1st generation) */
1197+ SPINAND_INFO("TC58CYG2S0HRAIG",
1198+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
1199 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
1200 NAND_ECCREQ(8, 512),
1201 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1202 &write_cache_variants,
1203 &update_cache_variants),
1204 0,
1205- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
1206- tc58cxgxsx_ecc_get_status)),
1207-};
1208-
1209-static int toshiba_spinand_detect(struct spinand_device *spinand)
1210-{
1211- u8 *id = spinand->id.data;
1212- int ret;
1213+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1214+ tx58cxgxsxraix_ecc_get_status)),
1215
1216 /*
1217- * Toshiba SPI NAND read ID needs a dummy byte,
1218- * so the first byte in id is garbage.
1219+ * 2nd generation serial nand has HOLD_D which is equivalent to
1220+ * QE_BIT.
1221 */
1222- if (id[1] != SPINAND_MFR_TOSHIBA)
1223- return 0;
1224-
1225- ret = spinand_match_and_init(spinand, toshiba_spinand_table,
1226- ARRAY_SIZE(toshiba_spinand_table),
1227- id[2]);
1228- if (ret)
1229- return ret;
1230-
1231- return 1;
1232-}
1233+ /* 3.3V 1Gb (2nd generation) */
1234+ SPINAND_INFO("TC58CVG0S3HRAIJ",
1235+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2),
1236+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
1237+ NAND_ECCREQ(8, 512),
1238+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1239+ &write_cache_x4_variants,
1240+ &update_cache_x4_variants),
1241+ SPINAND_HAS_QE_BIT,
1242+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1243+ tx58cxgxsxraix_ecc_get_status)),
1244+ /* 3.3V 2Gb (2nd generation) */
1245+ SPINAND_INFO("TC58CVG1S3HRAIJ",
1246+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
1247+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
1248+ NAND_ECCREQ(8, 512),
1249+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1250+ &write_cache_x4_variants,
1251+ &update_cache_x4_variants),
1252+ SPINAND_HAS_QE_BIT,
1253+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1254+ tx58cxgxsxraix_ecc_get_status)),
1255+ /* 3.3V 4Gb (2nd generation) */
1256+ SPINAND_INFO("TC58CVG2S0HRAIJ",
1257+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
1258+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
1259+ NAND_ECCREQ(8, 512),
1260+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1261+ &write_cache_x4_variants,
1262+ &update_cache_x4_variants),
1263+ SPINAND_HAS_QE_BIT,
1264+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1265+ tx58cxgxsxraix_ecc_get_status)),
1266+ /* 3.3V 8Gb (2nd generation) */
1267+ SPINAND_INFO("TH58CVG3S0HRAIJ",
1268+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
1269+ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
1270+ NAND_ECCREQ(8, 512),
1271+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1272+ &write_cache_x4_variants,
1273+ &update_cache_x4_variants),
1274+ SPINAND_HAS_QE_BIT,
1275+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1276+ tx58cxgxsxraix_ecc_get_status)),
1277+ /* 1.8V 1Gb (2nd generation) */
1278+ SPINAND_INFO("TC58CYG0S3HRAIJ",
1279+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
1280+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
1281+ NAND_ECCREQ(8, 512),
1282+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1283+ &write_cache_x4_variants,
1284+ &update_cache_x4_variants),
1285+ SPINAND_HAS_QE_BIT,
1286+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1287+ tx58cxgxsxraix_ecc_get_status)),
1288+ /* 1.8V 2Gb (2nd generation) */
1289+ SPINAND_INFO("TC58CYG1S3HRAIJ",
1290+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
1291+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
1292+ NAND_ECCREQ(8, 512),
1293+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1294+ &write_cache_x4_variants,
1295+ &update_cache_x4_variants),
1296+ SPINAND_HAS_QE_BIT,
1297+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1298+ tx58cxgxsxraix_ecc_get_status)),
1299+ /* 1.8V 4Gb (2nd generation) */
1300+ SPINAND_INFO("TC58CYG2S0HRAIJ",
1301+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
1302+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
1303+ NAND_ECCREQ(8, 512),
1304+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1305+ &write_cache_x4_variants,
1306+ &update_cache_x4_variants),
1307+ SPINAND_HAS_QE_BIT,
1308+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1309+ tx58cxgxsxraix_ecc_get_status)),
1310+ /* 1.8V 8Gb (2nd generation) */
1311+ SPINAND_INFO("TH58CYG3S0HRAIJ",
1312+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
1313+ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
1314+ NAND_ECCREQ(8, 512),
1315+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1316+ &write_cache_x4_variants,
1317+ &update_cache_x4_variants),
1318+ SPINAND_HAS_QE_BIT,
1319+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1320+ tx58cxgxsxraix_ecc_get_status)),
1321+};
1322
1323 static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
1324- .detect = toshiba_spinand_detect,
1325 };
1326
1327 const struct spinand_manufacturer toshiba_spinand_manufacturer = {
1328 .id = SPINAND_MFR_TOSHIBA,
1329 .name = "Toshiba",
1330+ .chips = toshiba_spinand_table,
1331+ .nchips = ARRAY_SIZE(toshiba_spinand_table),
1332 .ops = &toshiba_spinand_manuf_ops,
1333 };