0e233bb1d2903e37836e279144bd1875bbd01910
[openwrt/openwrt.git] / package / boot / uboot-mediatek / patches / 100-22-mtd-spi-nand-backport-from-upstream-kernel.patch
1 From 8d0665327819c41fce2c8d50f19c967b22eae564 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Wed, 27 Jul 2022 16:36:13 +0800
4 Subject: [PATCH 57/71] mtd: spi-nand: backport from upstream kernel
5
6 Backport new features from upstream kernel
7
8 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
9 ---
10 drivers/mtd/nand/spi/Kconfig | 1 +
11 drivers/mtd/nand/spi/Makefile | 2 +-
12 drivers/mtd/nand/spi/core.c | 102 ++++++----
13 drivers/mtd/nand/spi/etron.c | 181 +++++++++++++++++
14 drivers/mtd/nand/spi/gigadevice.c | 322 ++++++++++++++++++++++++++----
15 drivers/mtd/nand/spi/macronix.c | 173 +++++++++++++---
16 drivers/mtd/nand/spi/micron.c | 50 ++---
17 drivers/mtd/nand/spi/toshiba.c | 66 +++---
18 drivers/mtd/nand/spi/winbond.c | 164 ++++++++++++---
19 include/linux/mtd/spinand.h | 87 +++++---
20 10 files changed, 923 insertions(+), 225 deletions(-)
21 create mode 100644 drivers/mtd/nand/spi/etron.c
22
23 --- a/drivers/mtd/nand/spi/Kconfig
24 +++ b/drivers/mtd/nand/spi/Kconfig
25 @@ -5,3 +5,4 @@ menuconfig MTD_SPI_NAND
26 select SPI_MEM
27 help
28 This is the framework for the SPI NAND device drivers.
29 +
30 --- a/drivers/mtd/nand/spi/Makefile
31 +++ b/drivers/mtd/nand/spi/Makefile
32 @@ -1,4 +1,4 @@
33 # SPDX-License-Identifier: GPL-2.0
34
35 -spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o
36 +spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o etron.o
37 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
38 --- a/drivers/mtd/nand/spi/core.c
39 +++ b/drivers/mtd/nand/spi/core.c
40 @@ -17,6 +17,7 @@
41 #include <linux/mtd/spinand.h>
42 #include <linux/of.h>
43 #include <linux/slab.h>
44 +#include <linux/string.h>
45 #include <linux/spi/spi.h>
46 #include <linux/spi/spi-mem.h>
47 #else
48 @@ -451,10 +452,11 @@ out:
49 return status & STATUS_BUSY ? -ETIMEDOUT : 0;
50 }
51
52 -static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf)
53 +static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr,
54 + u8 ndummy, u8 *buf)
55 {
56 - struct spi_mem_op op = SPINAND_READID_OP(0, spinand->scratchbuf,
57 - SPINAND_MAX_ID_LEN);
58 + struct spi_mem_op op = SPINAND_READID_OP(
59 + naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN);
60 int ret;
61
62 ret = spi_mem_exec_op(spinand->slave, &op);
63 @@ -464,18 +466,6 @@ static int spinand_read_id_op(struct spi
64 return ret;
65 }
66
67 -static int spinand_reset_op(struct spinand_device *spinand)
68 -{
69 - struct spi_mem_op op = SPINAND_RESET_OP;
70 - int ret;
71 -
72 - ret = spi_mem_exec_op(spinand->slave, &op);
73 - if (ret)
74 - return ret;
75 -
76 - return spinand_wait(spinand, NULL);
77 -}
78 -
79 static int spinand_lock_block(struct spinand_device *spinand, u8 lock)
80 {
81 return spinand_write_reg_op(spinand, REG_BLOCK_LOCK, lock);
82 @@ -829,6 +819,7 @@ static const struct nand_ops spinand_ops
83 };
84
85 static const struct spinand_manufacturer *spinand_manufacturers[] = {
86 + &etron_spinand_manufacturer,
87 &gigadevice_spinand_manufacturer,
88 &macronix_spinand_manufacturer,
89 &micron_spinand_manufacturer,
90 @@ -836,24 +827,63 @@ static const struct spinand_manufacturer
91 &winbond_spinand_manufacturer,
92 };
93
94 -static int spinand_manufacturer_detect(struct spinand_device *spinand)
95 +static int spinand_manufacturer_match(struct spinand_device *spinand,
96 + enum spinand_readid_method rdid_method)
97 {
98 + u8 *id = spinand->id.data;
99 unsigned int i;
100 int ret;
101
102 for (i = 0; i < ARRAY_SIZE(spinand_manufacturers); i++) {
103 - ret = spinand_manufacturers[i]->ops->detect(spinand);
104 - if (ret > 0) {
105 - spinand->manufacturer = spinand_manufacturers[i];
106 - return 0;
107 - } else if (ret < 0) {
108 - return ret;
109 - }
110 + const struct spinand_manufacturer *manufacturer =
111 + spinand_manufacturers[i];
112 +
113 + if (id[0] != manufacturer->id)
114 + continue;
115 +
116 + ret = spinand_match_and_init(spinand,
117 + manufacturer->chips,
118 + manufacturer->nchips,
119 + rdid_method);
120 + if (ret < 0)
121 + continue;
122 +
123 + spinand->manufacturer = manufacturer;
124 + return 0;
125 }
126
127 return -ENOTSUPP;
128 }
129
130 +static int spinand_id_detect(struct spinand_device *spinand)
131 +{
132 + u8 *id = spinand->id.data;
133 + int ret;
134 +
135 + ret = spinand_read_id_op(spinand, 0, 0, id);
136 + if (ret)
137 + return ret;
138 + ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE);
139 + if (!ret)
140 + return 0;
141 +
142 + ret = spinand_read_id_op(spinand, 1, 0, id);
143 + if (ret)
144 + return ret;
145 + ret = spinand_manufacturer_match(spinand,
146 + SPINAND_READID_METHOD_OPCODE_ADDR);
147 + if (!ret)
148 + return 0;
149 +
150 + ret = spinand_read_id_op(spinand, 0, 1, id);
151 + if (ret)
152 + return ret;
153 + ret = spinand_manufacturer_match(spinand,
154 + SPINAND_READID_METHOD_OPCODE_DUMMY);
155 +
156 + return ret;
157 +}
158 +
159 static int spinand_manufacturer_init(struct spinand_device *spinand)
160 {
161 if (spinand->manufacturer->ops->init)
162 @@ -909,9 +939,9 @@ spinand_select_op_variant(struct spinand
163 * @spinand: SPI NAND object
164 * @table: SPI NAND device description table
165 * @table_size: size of the device description table
166 + * @rdid_method: read id method to match
167 *
168 - * Should be used by SPI NAND manufacturer drivers when they want to find a
169 - * match between a device ID retrieved through the READ_ID command and an
170 + * Match between a device ID retrieved through the READ_ID command and an
171 * entry in the SPI NAND description table. If a match is found, the spinand
172 * object will be initialized with information provided by the matching
173 * spinand_info entry.
174 @@ -920,8 +950,10 @@ spinand_select_op_variant(struct spinand
175 */
176 int spinand_match_and_init(struct spinand_device *spinand,
177 const struct spinand_info *table,
178 - unsigned int table_size, u8 devid)
179 + unsigned int table_size,
180 + enum spinand_readid_method rdid_method)
181 {
182 + u8 *id = spinand->id.data;
183 struct nand_device *nand = spinand_to_nand(spinand);
184 unsigned int i;
185
186 @@ -929,13 +961,17 @@ int spinand_match_and_init(struct spinan
187 const struct spinand_info *info = &table[i];
188 const struct spi_mem_op *op;
189
190 - if (devid != info->devid)
191 + if (rdid_method != info->devid.method)
192 + continue;
193 +
194 + if (memcmp(id + 1, info->devid.id, info->devid.len))
195 continue;
196
197 nand->memorg = table[i].memorg;
198 nand->eccreq = table[i].eccreq;
199 spinand->eccinfo = table[i].eccinfo;
200 spinand->flags = table[i].flags;
201 + spinand->id.len = 1 + table[i].devid.len;
202 spinand->select_target = table[i].select_target;
203
204 op = spinand_select_op_variant(spinand,
205 @@ -967,17 +1003,7 @@ static int spinand_detect(struct spinand
206 struct nand_device *nand = spinand_to_nand(spinand);
207 int ret;
208
209 - ret = spinand_reset_op(spinand);
210 - if (ret)
211 - return ret;
212 -
213 - ret = spinand_read_id_op(spinand, spinand->id.data);
214 - if (ret)
215 - return ret;
216 -
217 - spinand->id.len = SPINAND_MAX_ID_LEN;
218 -
219 - ret = spinand_manufacturer_detect(spinand);
220 + ret = spinand_id_detect(spinand);
221 if (ret) {
222 dev_err(spinand->slave->dev, "unknown raw ID %02x %02x %02x %02x\n",
223 spinand->id.data[0], spinand->id.data[1],
224 --- /dev/null
225 +++ b/drivers/mtd/nand/spi/etron.c
226 @@ -0,0 +1,181 @@
227 +// SPDX-License-Identifier: GPL-2.0
228 +/*
229 + * Copyright (c) 2020 Etron Technology, Inc.
230 + *
231 + */
232 +#ifndef __UBOOT__
233 +#include <malloc.h>
234 +#include <linux/device.h>
235 +#include <linux/kernel.h>
236 +#endif
237 +#include <linux/bug.h>
238 +#include <linux/mtd/spinand.h>
239 +
240 +#define SPINAND_MFR_ETRON 0xD5
241 +
242 +#define STATUS_ECC_LIMIT_BITFLIPS (3 << 4)
243 +
244 +static SPINAND_OP_VARIANTS(read_cache_variants,
245 + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
246 + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
247 + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
248 + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
249 + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
250 + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
251 +
252 +static SPINAND_OP_VARIANTS(write_cache_variants,
253 + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
254 + SPINAND_PROG_LOAD(true, 0, NULL, 0));
255 +
256 +static SPINAND_OP_VARIANTS(update_cache_variants,
257 + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
258 + SPINAND_PROG_LOAD(false, 0, NULL, 0));
259 +
260 +static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
261 + struct mtd_oob_region *region)
262 +{
263 + if (section > 3)
264 + return -ERANGE;
265 +
266 + region->offset = (14 * section) + 72;
267 + region->length = 14;
268 +
269 + return 0;
270 +}
271 +
272 +static int etron_ooblayout_free(struct mtd_info *mtd, int section,
273 + struct mtd_oob_region *region)
274 +{
275 + if (section > 3)
276 + return -ERANGE;
277 +
278 + if (section) {
279 + region->offset = 18 * section;
280 + region->length = 18;
281 + } else {
282 + /* section 0 has one byte reserved for bad block mark */
283 + region->offset = 2;
284 + region->length = 16;
285 + }
286 + return 0;
287 +}
288 +
289 +static const struct mtd_ooblayout_ops etron_ooblayout = {
290 + .ecc = etron_ooblayout_ecc,
291 + .rfree = etron_ooblayout_free,
292 +};
293 +
294 +static int etron_ecc_get_status(struct spinand_device *spinand,
295 + u8 status)
296 +{
297 + struct nand_device *nand = spinand_to_nand(spinand);
298 +
299 + switch (status & STATUS_ECC_MASK) {
300 + case STATUS_ECC_NO_BITFLIPS:
301 + return 0;
302 +
303 + case STATUS_ECC_UNCOR_ERROR:
304 + return -EBADMSG;
305 +
306 + case STATUS_ECC_HAS_BITFLIPS:
307 + return nand->eccreq.strength >> 1;
308 +
309 + case STATUS_ECC_LIMIT_BITFLIPS:
310 + return nand->eccreq.strength;
311 +
312 + default:
313 + break;
314 + }
315 +
316 + return -EINVAL;
317 +}
318 +
319 +static const struct spinand_info etron_spinand_table[] = {
320 + /* EM73C 1Gb 3.3V */
321 + SPINAND_INFO("EM73C044VCF",
322 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x25),
323 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
324 + NAND_ECCREQ(4, 512),
325 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
326 + &write_cache_variants,
327 + &update_cache_variants),
328 + SPINAND_HAS_QE_BIT,
329 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
330 + /* EM7xD 2Gb */
331 + SPINAND_INFO("EM73D044VCR",
332 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x41),
333 + NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
334 + NAND_ECCREQ(4, 512),
335 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
336 + &write_cache_variants,
337 + &update_cache_variants),
338 + SPINAND_HAS_QE_BIT,
339 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
340 + SPINAND_INFO("EM73D044VCO",
341 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x3A),
342 + NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
343 + NAND_ECCREQ(8, 512),
344 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
345 + &write_cache_variants,
346 + &update_cache_variants),
347 + SPINAND_HAS_QE_BIT,
348 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
349 + SPINAND_INFO("EM78D044VCM",
350 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x8E),
351 + NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
352 + NAND_ECCREQ(8, 512),
353 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
354 + &write_cache_variants,
355 + &update_cache_variants),
356 + SPINAND_HAS_QE_BIT,
357 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
358 + /* EM7xE 4Gb */
359 + SPINAND_INFO("EM73E044VCE",
360 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x3B),
361 + NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
362 + NAND_ECCREQ(8, 512),
363 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
364 + &write_cache_variants,
365 + &update_cache_variants),
366 + SPINAND_HAS_QE_BIT,
367 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
368 + SPINAND_INFO("EM78E044VCD",
369 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x8F),
370 + NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
371 + NAND_ECCREQ(8, 512),
372 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
373 + &write_cache_variants,
374 + &update_cache_variants),
375 + SPINAND_HAS_QE_BIT,
376 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
377 + /* EM7xF044VCA 8Gb */
378 + SPINAND_INFO("EM73F044VCA",
379 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
380 + NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
381 + NAND_ECCREQ(8, 512),
382 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
383 + &write_cache_variants,
384 + &update_cache_variants),
385 + SPINAND_HAS_QE_BIT,
386 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
387 + SPINAND_INFO("EM78F044VCA",
388 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x8D),
389 + NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
390 + NAND_ECCREQ(8, 512),
391 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
392 + &write_cache_variants,
393 + &update_cache_variants),
394 + SPINAND_HAS_QE_BIT,
395 + SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
396 +};
397 +
398 +static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
399 +};
400 +
401 +const struct spinand_manufacturer etron_spinand_manufacturer = {
402 + .id = SPINAND_MFR_ETRON,
403 + .name = "Etron",
404 + .chips = etron_spinand_table,
405 + .nchips = ARRAY_SIZE(etron_spinand_table),
406 + .ops = &etron_spinand_manuf_ops,
407 +};
408 --- a/drivers/mtd/nand/spi/gigadevice.c
409 +++ b/drivers/mtd/nand/spi/gigadevice.c
410 @@ -22,8 +22,13 @@
411
412 #define GD5FXGQXXEXXG_REG_STATUS2 0xf0
413
414 +#define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
415 +#define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
416 +#define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4)
417 +#define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4)
418 +
419 /* Q4 devices, QUADIO: Dummy bytes valid for 1 and 2 GBit variants */
420 -static SPINAND_OP_VARIANTS(gd5fxgq4_read_cache_variants,
421 +static SPINAND_OP_VARIANTS(read_cache_variants,
422 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
423 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
424 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
425 @@ -31,8 +36,17 @@ static SPINAND_OP_VARIANTS(gd5fxgq4_read
426 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
427 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
428
429 -/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */
430 -static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
431 +static SPINAND_OP_VARIANTS(read_cache_variants_f,
432 + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
433 + SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
434 + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
435 + SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
436 + SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
437 + SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
438 +
439 +/* For Q5 devices, QUADIO use different dummy byte settings */
440 +/* Q5 1Gb */
441 +static SPINAND_OP_VARIANTS(dummy2_read_cache_variants,
442 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
443 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
444 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
445 @@ -40,6 +54,15 @@ static SPINAND_OP_VARIANTS(gd5f1gq5_read
446 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
447 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
448
449 +/* Q5 2Gb & 4Gb */
450 +static SPINAND_OP_VARIANTS(dummy4_read_cache_variants,
451 + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
452 + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
453 + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
454 + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
455 + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
456 + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
457 +
458 static SPINAND_OP_VARIANTS(write_cache_variants,
459 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
460 SPINAND_PROG_LOAD(true, 0, NULL, 0));
461 @@ -48,7 +71,65 @@ static SPINAND_OP_VARIANTS(update_cache_
462 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
463 SPINAND_PROG_LOAD(false, 0, NULL, 0));
464
465 -static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
466 +static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
467 + struct mtd_oob_region *region)
468 +{
469 + if (section > 3)
470 + return -ERANGE;
471 +
472 + region->offset = (16 * section) + 8;
473 + region->length = 8;
474 +
475 + return 0;
476 +}
477 +
478 +static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
479 + struct mtd_oob_region *region)
480 +{
481 + if (section > 3)
482 + return -ERANGE;
483 +
484 + if (section) {
485 + region->offset = 16 * section;
486 + region->length = 8;
487 + } else {
488 + /* section 0 has one byte reserved for bad block mark */
489 + region->offset = 1;
490 + region->length = 7;
491 + }
492 + return 0;
493 +}
494 +
495 +static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
496 + .ecc = gd5fxgq4xa_ooblayout_ecc,
497 + .rfree = gd5fxgq4xa_ooblayout_free,
498 +};
499 +
500 +static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
501 + u8 status)
502 +{
503 + switch (status & STATUS_ECC_MASK) {
504 + case STATUS_ECC_NO_BITFLIPS:
505 + return 0;
506 +
507 + case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
508 + /* 1-7 bits are flipped. return the maximum. */
509 + return 7;
510 +
511 + case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
512 + return 8;
513 +
514 + case STATUS_ECC_UNCOR_ERROR:
515 + return -EBADMSG;
516 +
517 + default:
518 + break;
519 + }
520 +
521 + return -EINVAL;
522 +}
523 +
524 +static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
525 struct mtd_oob_region *region)
526 {
527 if (section)
528 @@ -60,7 +141,7 @@ static int gd5fxgqxxexxg_ooblayout_ecc(s
529 return 0;
530 }
531
532 -static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section,
533 +static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
534 struct mtd_oob_region *region)
535 {
536 if (section)
537 @@ -73,7 +154,13 @@ static int gd5fxgqxxexxg_ooblayout_free(
538 return 0;
539 }
540
541 -static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
542 +/* Valid for Q4/Q5 and Q6 (untested) devices */
543 +static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
544 + .ecc = gd5fxgqx_variant2_ooblayout_ecc,
545 + .rfree = gd5fxgqx_variant2_ooblayout_free,
546 +};
547 +
548 +static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
549 u8 status)
550 {
551 u8 status2;
552 @@ -152,59 +239,214 @@ static int gd5fxgq5xexxg_ecc_get_status(
553 return -EINVAL;
554 }
555
556 -static const struct mtd_ooblayout_ops gd5fxgqxxexxg_ooblayout = {
557 - .ecc = gd5fxgqxxexxg_ooblayout_ecc,
558 - .rfree = gd5fxgqxxexxg_ooblayout_free,
559 +static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
560 + u8 status)
561 +{
562 + switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
563 + case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
564 + return 0;
565 +
566 + case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
567 + return 3;
568 +
569 + case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
570 + return -EBADMSG;
571 +
572 + default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
573 + return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
574 + }
575 +
576 + return -EINVAL;
577 +}
578 +
579 +static int esmt_1_ooblayout_ecc(struct mtd_info *mtd, int section,
580 + struct mtd_oob_region *region)
581 +{
582 + if (section > 3)
583 + return -ERANGE;
584 +
585 + region->offset = (16 * section) + 8;
586 + region->length = 8;
587 +
588 + return 0;
589 +}
590 +
591 +static int esmt_1_ooblayout_free(struct mtd_info *mtd, int section,
592 + struct mtd_oob_region *region)
593 +{
594 + if (section > 3)
595 + return -ERANGE;
596 +
597 + region->offset = (16 * section) + 2;
598 + region->length = 6;
599 +
600 + return 0;
601 +}
602 +
603 +static const struct mtd_ooblayout_ops esmt_1_ooblayout = {
604 + .ecc = esmt_1_ooblayout_ecc,
605 + .rfree = esmt_1_ooblayout_free,
606 };
607
608 static const struct spinand_info gigadevice_spinand_table[] = {
609 - SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
610 - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
611 + SPINAND_INFO("F50L1G41LB",
612 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
613 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
614 NAND_ECCREQ(8, 512),
615 - SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants,
616 + SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
617 &write_cache_variants,
618 &update_cache_variants),
619 0,
620 - SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
621 - gd5fxgq4xexxg_ecc_get_status)),
622 - SPINAND_INFO("GD5F1GQ5UExxG", 0x51,
623 + SPINAND_ECCINFO(&esmt_1_ooblayout, NULL)),
624 + SPINAND_INFO("GD5F1GQ4xA",
625 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
626 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
627 + NAND_ECCREQ(8, 512),
628 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
629 + &write_cache_variants,
630 + &update_cache_variants),
631 + SPINAND_HAS_QE_BIT,
632 + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
633 + gd5fxgq4xa_ecc_get_status)),
634 + SPINAND_INFO("GD5F2GQ4xA",
635 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
636 + NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
637 + NAND_ECCREQ(8, 512),
638 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
639 + &write_cache_variants,
640 + &update_cache_variants),
641 + SPINAND_HAS_QE_BIT,
642 + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
643 + gd5fxgq4xa_ecc_get_status)),
644 + SPINAND_INFO("GD5F4GQ4xA",
645 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
646 + NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
647 + NAND_ECCREQ(8, 512),
648 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
649 + &write_cache_variants,
650 + &update_cache_variants),
651 + SPINAND_HAS_QE_BIT,
652 + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
653 + gd5fxgq4xa_ecc_get_status)),
654 + SPINAND_INFO("GD5F1GQ4UExxG",
655 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
656 + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
657 + NAND_ECCREQ(8, 512),
658 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
659 + &write_cache_variants,
660 + &update_cache_variants),
661 + SPINAND_HAS_QE_BIT,
662 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
663 + gd5fxgq4uexxg_ecc_get_status)),
664 + SPINAND_INFO("GD5F1GQ4UFxxG",
665 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
666 + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
667 + NAND_ECCREQ(8, 512),
668 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
669 + &write_cache_variants,
670 + &update_cache_variants),
671 + SPINAND_HAS_QE_BIT,
672 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
673 + gd5fxgq4ufxxg_ecc_get_status)),
674 + SPINAND_INFO("GD5F1GQ5UExxG",
675 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
676 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
677 NAND_ECCREQ(4, 512),
678 - SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
679 + SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
680 &write_cache_variants,
681 &update_cache_variants),
682 - 0,
683 - SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
684 + SPINAND_HAS_QE_BIT,
685 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
686 + gd5fxgq5xexxg_ecc_get_status)),
687 + SPINAND_INFO("GD5F2GQ5UExxG",
688 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x52),
689 + NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
690 + NAND_ECCREQ(4, 512),
691 + SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
692 + &write_cache_variants,
693 + &update_cache_variants),
694 + SPINAND_HAS_QE_BIT,
695 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
696 + gd5fxgq5xexxg_ecc_get_status)),
697 + SPINAND_INFO("GD5F4GQ6UExxG",
698 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x55),
699 + NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
700 + NAND_ECCREQ(4, 512),
701 + SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
702 + &write_cache_variants,
703 + &update_cache_variants),
704 + SPINAND_HAS_QE_BIT,
705 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
706 + gd5fxgq5xexxg_ecc_get_status)),
707 + SPINAND_INFO("GD5F1GM7UExxG",
708 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x91),
709 + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
710 + NAND_ECCREQ(8, 512),
711 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
712 + &write_cache_variants,
713 + &update_cache_variants),
714 + SPINAND_HAS_QE_BIT,
715 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
716 + gd5fxgq4uexxg_ecc_get_status)),
717 + SPINAND_INFO("GD5F2GM7UExxG",
718 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x92),
719 + NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
720 + NAND_ECCREQ(8, 512),
721 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
722 + &write_cache_variants,
723 + &update_cache_variants),
724 + SPINAND_HAS_QE_BIT,
725 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
726 + gd5fxgq4uexxg_ecc_get_status)),
727 + SPINAND_INFO("GD5F4GM8UExxG",
728 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x95),
729 + NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
730 + NAND_ECCREQ(8, 512),
731 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
732 + &write_cache_variants,
733 + &update_cache_variants),
734 + SPINAND_HAS_QE_BIT,
735 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
736 + gd5fxgq4uexxg_ecc_get_status)),
737 + SPINAND_INFO("GD5F1GQ5UExxH",
738 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x31),
739 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
740 + NAND_ECCREQ(4, 512),
741 + SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
742 + &write_cache_variants,
743 + &update_cache_variants),
744 + SPINAND_HAS_QE_BIT,
745 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
746 + gd5fxgq5xexxg_ecc_get_status)),
747 + SPINAND_INFO("GD5F2GQ5UExxH",
748 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
749 + NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
750 + NAND_ECCREQ(4, 512),
751 + SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
752 + &write_cache_variants,
753 + &update_cache_variants),
754 + SPINAND_HAS_QE_BIT,
755 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
756 + gd5fxgq5xexxg_ecc_get_status)),
757 + SPINAND_INFO("GD5F4GQ6UExxH",
758 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
759 + NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
760 + NAND_ECCREQ(4, 512),
761 + SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
762 + &write_cache_variants,
763 + &update_cache_variants),
764 + SPINAND_HAS_QE_BIT,
765 + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
766 gd5fxgq5xexxg_ecc_get_status)),
767 };
768
769 -static int gigadevice_spinand_detect(struct spinand_device *spinand)
770 -{
771 - u8 *id = spinand->id.data;
772 - int ret;
773 -
774 - /*
775 - * For GD NANDs, There is an address byte needed to shift in before IDs
776 - * are read out, so the first byte in raw_id is dummy.
777 - */
778 - if (id[1] != SPINAND_MFR_GIGADEVICE)
779 - return 0;
780 -
781 - ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
782 - ARRAY_SIZE(gigadevice_spinand_table),
783 - id[2]);
784 - if (ret)
785 - return ret;
786 -
787 - return 1;
788 -}
789 -
790 static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
791 - .detect = gigadevice_spinand_detect,
792 };
793
794 const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
795 .id = SPINAND_MFR_GIGADEVICE,
796 .name = "GigaDevice",
797 + .chips = gigadevice_spinand_table,
798 + .nchips = ARRAY_SIZE(gigadevice_spinand_table),
799 .ops = &gigadevice_spinand_manuf_ops,
800 };
801 --- a/drivers/mtd/nand/spi/macronix.c
802 +++ b/drivers/mtd/nand/spi/macronix.c
803 @@ -105,7 +105,8 @@ static int mx35lf1ge4ab_ecc_get_status(s
804 }
805
806 static const struct spinand_info macronix_spinand_table[] = {
807 - SPINAND_INFO("MX35LF1GE4AB", 0x12,
808 + SPINAND_INFO("MX35LF1GE4AB",
809 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
810 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
811 NAND_ECCREQ(4, 512),
812 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
813 @@ -114,7 +115,8 @@ static const struct spinand_info macroni
814 SPINAND_HAS_QE_BIT,
815 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
816 mx35lf1ge4ab_ecc_get_status)),
817 - SPINAND_INFO("MX35LF2GE4AB", 0x22,
818 + SPINAND_INFO("MX35LF2GE4AB",
819 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
820 NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
821 NAND_ECCREQ(4, 512),
822 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
823 @@ -122,7 +124,96 @@ static const struct spinand_info macroni
824 &update_cache_variants),
825 SPINAND_HAS_QE_BIT,
826 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
827 - SPINAND_INFO("MX35UF4GE4AD", 0xb7,
828 + SPINAND_INFO("MX35LF2GE4AD",
829 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26),
830 + NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
831 + NAND_ECCREQ(8, 512),
832 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
833 + &write_cache_variants,
834 + &update_cache_variants),
835 + SPINAND_HAS_QE_BIT,
836 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
837 + mx35lf1ge4ab_ecc_get_status)),
838 + SPINAND_INFO("MX35LF4GE4AD",
839 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
840 + NAND_MEMORG(1, 4096, 128, 64, 2048, 1, 1, 1),
841 + NAND_ECCREQ(8, 512),
842 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
843 + &write_cache_variants,
844 + &update_cache_variants),
845 + SPINAND_HAS_QE_BIT,
846 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
847 + mx35lf1ge4ab_ecc_get_status)),
848 + SPINAND_INFO("MX35LF1G24AD",
849 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
850 + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
851 + NAND_ECCREQ(8, 512),
852 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
853 + &write_cache_variants,
854 + &update_cache_variants),
855 + SPINAND_HAS_QE_BIT,
856 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
857 + SPINAND_INFO("MX35LF2G24AD",
858 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
859 + NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
860 + NAND_ECCREQ(8, 512),
861 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
862 + &write_cache_variants,
863 + &update_cache_variants),
864 + SPINAND_HAS_QE_BIT,
865 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
866 + SPINAND_INFO("MX35LF4G24AD",
867 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
868 + NAND_MEMORG(1, 4096, 256, 64, 2048, 2, 1, 1),
869 + NAND_ECCREQ(8, 512),
870 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
871 + &write_cache_variants,
872 + &update_cache_variants),
873 + SPINAND_HAS_QE_BIT,
874 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
875 + SPINAND_INFO("MX31LF1GE4BC",
876 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
877 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
878 + NAND_ECCREQ(8, 512),
879 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
880 + &write_cache_variants,
881 + &update_cache_variants),
882 + SPINAND_HAS_QE_BIT,
883 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
884 + mx35lf1ge4ab_ecc_get_status)),
885 + SPINAND_INFO("MX31UF1GE4BC",
886 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
887 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
888 + NAND_ECCREQ(8, 512),
889 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
890 + &write_cache_variants,
891 + &update_cache_variants),
892 + SPINAND_HAS_QE_BIT,
893 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
894 + mx35lf1ge4ab_ecc_get_status)),
895 +
896 + SPINAND_INFO("MX35LF2G14AC",
897 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20),
898 + NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
899 + NAND_ECCREQ(4, 512),
900 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
901 + &write_cache_variants,
902 + &update_cache_variants),
903 + SPINAND_HAS_QE_BIT,
904 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
905 + mx35lf1ge4ab_ecc_get_status)),
906 + SPINAND_INFO("MX35UF4G24AD",
907 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5),
908 + NAND_MEMORG(1, 4096, 256, 64, 2048, 2, 1, 1),
909 + NAND_ECCREQ(8, 512),
910 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
911 + &write_cache_variants,
912 + &update_cache_variants),
913 + SPINAND_HAS_QE_BIT,
914 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
915 + mx35lf1ge4ab_ecc_get_status)),
916 + SPINAND_INFO("MX35UF4GE4AD",
917 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7),
918 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
919 NAND_ECCREQ(8, 512),
920 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
921 @@ -131,7 +222,28 @@ static const struct spinand_info macroni
922 SPINAND_HAS_QE_BIT,
923 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
924 mx35lf1ge4ab_ecc_get_status)),
925 - SPINAND_INFO("MX35UF2GE4AD", 0xa6,
926 + SPINAND_INFO("MX35UF2G14AC",
927 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
928 + NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
929 + NAND_ECCREQ(4, 512),
930 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
931 + &write_cache_variants,
932 + &update_cache_variants),
933 + SPINAND_HAS_QE_BIT,
934 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
935 + mx35lf1ge4ab_ecc_get_status)),
936 + SPINAND_INFO("MX35UF2G24AD",
937 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4),
938 + NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
939 + NAND_ECCREQ(8, 512),
940 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
941 + &write_cache_variants,
942 + &update_cache_variants),
943 + SPINAND_HAS_QE_BIT,
944 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
945 + mx35lf1ge4ab_ecc_get_status)),
946 + SPINAND_INFO("MX35UF2GE4AD",
947 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6),
948 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
949 NAND_ECCREQ(8, 512),
950 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
951 @@ -140,16 +252,28 @@ static const struct spinand_info macroni
952 SPINAND_HAS_QE_BIT,
953 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
954 mx35lf1ge4ab_ecc_get_status)),
955 - SPINAND_INFO("MX35UF2GE4AC", 0xa2,
956 + SPINAND_INFO("MX35UF2GE4AC",
957 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2),
958 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
959 NAND_ECCREQ(4, 512),
960 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
961 + &write_cache_variants,
962 + &update_cache_variants),
963 + SPINAND_HAS_QE_BIT,
964 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
965 + mx35lf1ge4ab_ecc_get_status)),
966 + SPINAND_INFO("MX35UF1G14AC",
967 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90),
968 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
969 + NAND_ECCREQ(4, 512),
970 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
971 &write_cache_variants,
972 &update_cache_variants),
973 SPINAND_HAS_QE_BIT,
974 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
975 mx35lf1ge4ab_ecc_get_status)),
976 - SPINAND_INFO("MX35UF1GE4AD", 0x96,
977 + SPINAND_INFO("MX35UF1G24AD",
978 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94),
979 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
980 NAND_ECCREQ(8, 512),
981 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
982 @@ -158,7 +282,18 @@ static const struct spinand_info macroni
983 SPINAND_HAS_QE_BIT,
984 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
985 mx35lf1ge4ab_ecc_get_status)),
986 - SPINAND_INFO("MX35UF1GE4AC", 0x92,
987 + SPINAND_INFO("MX35UF1GE4AD",
988 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96),
989 + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
990 + NAND_ECCREQ(8, 512),
991 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
992 + &write_cache_variants,
993 + &update_cache_variants),
994 + SPINAND_HAS_QE_BIT,
995 + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
996 + mx35lf1ge4ab_ecc_get_status)),
997 + SPINAND_INFO("MX35UF1GE4AC",
998 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
999 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
1000 NAND_ECCREQ(4, 512),
1001 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1002 @@ -170,33 +305,13 @@ static const struct spinand_info macroni
1003
1004 };
1005
1006 -static int macronix_spinand_detect(struct spinand_device *spinand)
1007 -{
1008 - u8 *id = spinand->id.data;
1009 - int ret;
1010 -
1011 - /*
1012 - * Macronix SPI NAND read ID needs a dummy byte, so the first byte in
1013 - * raw_id is garbage.
1014 - */
1015 - if (id[1] != SPINAND_MFR_MACRONIX)
1016 - return 0;
1017 -
1018 - ret = spinand_match_and_init(spinand, macronix_spinand_table,
1019 - ARRAY_SIZE(macronix_spinand_table),
1020 - id[2]);
1021 - if (ret)
1022 - return ret;
1023 -
1024 - return 1;
1025 -}
1026 -
1027 static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
1028 - .detect = macronix_spinand_detect,
1029 };
1030
1031 const struct spinand_manufacturer macronix_spinand_manufacturer = {
1032 .id = SPINAND_MFR_MACRONIX,
1033 .name = "Macronix",
1034 + .chips = macronix_spinand_table,
1035 + .nchips = ARRAY_SIZE(macronix_spinand_table),
1036 .ops = &macronix_spinand_manuf_ops,
1037 };
1038 --- a/drivers/mtd/nand/spi/micron.c
1039 +++ b/drivers/mtd/nand/spi/micron.c
1040 @@ -120,7 +120,8 @@ static int micron_8_ecc_get_status(struc
1041
1042 static const struct spinand_info micron_spinand_table[] = {
1043 /* M79A 2Gb 3.3V */
1044 - SPINAND_INFO("MT29F2G01ABAGD", 0x24,
1045 + SPINAND_INFO("MT29F2G01ABAGD",
1046 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
1047 NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
1048 NAND_ECCREQ(8, 512),
1049 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1050 @@ -130,7 +131,8 @@ static const struct spinand_info micron_
1051 SPINAND_ECCINFO(&micron_8_ooblayout,
1052 micron_8_ecc_get_status)),
1053 /* M79A 2Gb 1.8V */
1054 - SPINAND_INFO("MT29F2G01ABBGD", 0x25,
1055 + SPINAND_INFO("MT29F2G01ABBGD",
1056 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
1057 NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
1058 NAND_ECCREQ(8, 512),
1059 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1060 @@ -140,7 +142,8 @@ static const struct spinand_info micron_
1061 SPINAND_ECCINFO(&micron_8_ooblayout,
1062 micron_8_ecc_get_status)),
1063 /* M78A 1Gb 3.3V */
1064 - SPINAND_INFO("MT29F1G01ABAFD", 0x14,
1065 + SPINAND_INFO("MT29F1G01ABAFD",
1066 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
1067 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
1068 NAND_ECCREQ(8, 512),
1069 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1070 @@ -150,7 +153,8 @@ static const struct spinand_info micron_
1071 SPINAND_ECCINFO(&micron_8_ooblayout,
1072 micron_8_ecc_get_status)),
1073 /* M78A 1Gb 1.8V */
1074 - SPINAND_INFO("MT29F1G01ABAFD", 0x15,
1075 + SPINAND_INFO("MT29F1G01ABAFD",
1076 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
1077 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
1078 NAND_ECCREQ(8, 512),
1079 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1080 @@ -160,7 +164,8 @@ static const struct spinand_info micron_
1081 SPINAND_ECCINFO(&micron_8_ooblayout,
1082 micron_8_ecc_get_status)),
1083 /* M79A 4Gb 3.3V */
1084 - SPINAND_INFO("MT29F4G01ADAGD", 0x36,
1085 + SPINAND_INFO("MT29F4G01ADAGD",
1086 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
1087 NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 2),
1088 NAND_ECCREQ(8, 512),
1089 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1090 @@ -171,7 +176,8 @@ static const struct spinand_info micron_
1091 micron_8_ecc_get_status),
1092 SPINAND_SELECT_TARGET(micron_select_target)),
1093 /* M70A 4Gb 3.3V */
1094 - SPINAND_INFO("MT29F4G01ABAFD", 0x34,
1095 + SPINAND_INFO("MT29F4G01ABAFD",
1096 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
1097 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
1098 NAND_ECCREQ(8, 512),
1099 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1100 @@ -181,7 +187,8 @@ static const struct spinand_info micron_
1101 SPINAND_ECCINFO(&micron_8_ooblayout,
1102 micron_8_ecc_get_status)),
1103 /* M70A 4Gb 1.8V */
1104 - SPINAND_INFO("MT29F4G01ABBFD", 0x35,
1105 + SPINAND_INFO("MT29F4G01ABBFD",
1106 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
1107 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
1108 NAND_ECCREQ(8, 512),
1109 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1110 @@ -191,7 +198,8 @@ static const struct spinand_info micron_
1111 SPINAND_ECCINFO(&micron_8_ooblayout,
1112 micron_8_ecc_get_status)),
1113 /* M70A 8Gb 3.3V */
1114 - SPINAND_INFO("MT29F8G01ADAFD", 0x46,
1115 + SPINAND_INFO("MT29F8G01ADAFD",
1116 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
1117 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2),
1118 NAND_ECCREQ(8, 512),
1119 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1120 @@ -202,7 +210,8 @@ static const struct spinand_info micron_
1121 micron_8_ecc_get_status),
1122 SPINAND_SELECT_TARGET(micron_select_target)),
1123 /* M70A 8Gb 1.8V */
1124 - SPINAND_INFO("MT29F8G01ADBFD", 0x47,
1125 + SPINAND_INFO("MT29F8G01ADBFD",
1126 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
1127 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2),
1128 NAND_ECCREQ(8, 512),
1129 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1130 @@ -214,26 +223,6 @@ static const struct spinand_info micron_
1131 SPINAND_SELECT_TARGET(micron_select_target)),
1132 };
1133
1134 -static int micron_spinand_detect(struct spinand_device *spinand)
1135 -{
1136 - u8 *id = spinand->id.data;
1137 - int ret;
1138 -
1139 - /*
1140 - * Micron SPI NAND read ID need a dummy byte,
1141 - * so the first byte in raw_id is dummy.
1142 - */
1143 - if (id[1] != SPINAND_MFR_MICRON)
1144 - return 0;
1145 -
1146 - ret = spinand_match_and_init(spinand, micron_spinand_table,
1147 - ARRAY_SIZE(micron_spinand_table), id[2]);
1148 - if (ret)
1149 - return ret;
1150 -
1151 - return 1;
1152 -}
1153 -
1154 static int micron_spinand_init(struct spinand_device *spinand)
1155 {
1156 /*
1157 @@ -248,12 +237,13 @@ static int micron_spinand_init(struct sp
1158 }
1159
1160 static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
1161 - .detect = micron_spinand_detect,
1162 .init = micron_spinand_init,
1163 };
1164
1165 const struct spinand_manufacturer micron_spinand_manufacturer = {
1166 .id = SPINAND_MFR_MICRON,
1167 .name = "Micron",
1168 + .chips = micron_spinand_table,
1169 + .nchips = ARRAY_SIZE(micron_spinand_table),
1170 .ops = &micron_spinand_manuf_ops,
1171 };
1172 --- a/drivers/mtd/nand/spi/toshiba.c
1173 +++ b/drivers/mtd/nand/spi/toshiba.c
1174 @@ -111,7 +111,8 @@ static int tx58cxgxsxraix_ecc_get_status
1175
1176 static const struct spinand_info toshiba_spinand_table[] = {
1177 /* 3.3V 1Gb (1st generation) */
1178 - SPINAND_INFO("TC58CVG0S3HRAIG", 0xC2,
1179 + SPINAND_INFO("TC58CVG0S3HRAIG",
1180 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
1181 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
1182 NAND_ECCREQ(8, 512),
1183 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1184 @@ -121,7 +122,8 @@ static const struct spinand_info toshiba
1185 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1186 tx58cxgxsxraix_ecc_get_status)),
1187 /* 3.3V 2Gb (1st generation) */
1188 - SPINAND_INFO("TC58CVG1S3HRAIG", 0xCB,
1189 + SPINAND_INFO("TC58CVG1S3HRAIG",
1190 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
1191 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
1192 NAND_ECCREQ(8, 512),
1193 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1194 @@ -131,7 +133,8 @@ static const struct spinand_info toshiba
1195 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1196 tx58cxgxsxraix_ecc_get_status)),
1197 /* 3.3V 4Gb (1st generation) */
1198 - SPINAND_INFO("TC58CVG2S0HRAIG", 0xCD,
1199 + SPINAND_INFO("TC58CVG2S0HRAIG",
1200 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
1201 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
1202 NAND_ECCREQ(8, 512),
1203 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1204 @@ -141,7 +144,8 @@ static const struct spinand_info toshiba
1205 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1206 tx58cxgxsxraix_ecc_get_status)),
1207 /* 1.8V 1Gb (1st generation) */
1208 - SPINAND_INFO("TC58CYG0S3HRAIG", 0xB2,
1209 + SPINAND_INFO("TC58CYG0S3HRAIG",
1210 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
1211 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
1212 NAND_ECCREQ(8, 512),
1213 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1214 @@ -151,7 +155,8 @@ static const struct spinand_info toshiba
1215 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1216 tx58cxgxsxraix_ecc_get_status)),
1217 /* 1.8V 2Gb (1st generation) */
1218 - SPINAND_INFO("TC58CYG1S3HRAIG", 0xBB,
1219 + SPINAND_INFO("TC58CYG1S3HRAIG",
1220 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
1221 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
1222 NAND_ECCREQ(8, 512),
1223 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1224 @@ -161,7 +166,8 @@ static const struct spinand_info toshiba
1225 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1226 tx58cxgxsxraix_ecc_get_status)),
1227 /* 1.8V 4Gb (1st generation) */
1228 - SPINAND_INFO("TC58CYG2S0HRAIG", 0xBD,
1229 + SPINAND_INFO("TC58CYG2S0HRAIG",
1230 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
1231 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
1232 NAND_ECCREQ(8, 512),
1233 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1234 @@ -176,7 +182,8 @@ static const struct spinand_info toshiba
1235 * QE_BIT.
1236 */
1237 /* 3.3V 1Gb (2nd generation) */
1238 - SPINAND_INFO("TC58CVG0S3HRAIJ", 0xE2,
1239 + SPINAND_INFO("TC58CVG0S3HRAIJ",
1240 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2),
1241 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
1242 NAND_ECCREQ(8, 512),
1243 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1244 @@ -186,7 +193,8 @@ static const struct spinand_info toshiba
1245 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1246 tx58cxgxsxraix_ecc_get_status)),
1247 /* 3.3V 2Gb (2nd generation) */
1248 - SPINAND_INFO("TC58CVG1S3HRAIJ", 0xEB,
1249 + SPINAND_INFO("TC58CVG1S3HRAIJ",
1250 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
1251 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
1252 NAND_ECCREQ(8, 512),
1253 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1254 @@ -196,7 +204,8 @@ static const struct spinand_info toshiba
1255 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1256 tx58cxgxsxraix_ecc_get_status)),
1257 /* 3.3V 4Gb (2nd generation) */
1258 - SPINAND_INFO("TC58CVG2S0HRAIJ", 0xED,
1259 + SPINAND_INFO("TC58CVG2S0HRAIJ",
1260 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
1261 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
1262 NAND_ECCREQ(8, 512),
1263 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1264 @@ -206,7 +215,8 @@ static const struct spinand_info toshiba
1265 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1266 tx58cxgxsxraix_ecc_get_status)),
1267 /* 3.3V 8Gb (2nd generation) */
1268 - SPINAND_INFO("TH58CVG3S0HRAIJ", 0xE4,
1269 + SPINAND_INFO("TH58CVG3S0HRAIJ",
1270 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
1271 NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
1272 NAND_ECCREQ(8, 512),
1273 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1274 @@ -216,7 +226,8 @@ static const struct spinand_info toshiba
1275 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1276 tx58cxgxsxraix_ecc_get_status)),
1277 /* 1.8V 1Gb (2nd generation) */
1278 - SPINAND_INFO("TC58CYG0S3HRAIJ", 0xD2,
1279 + SPINAND_INFO("TC58CYG0S3HRAIJ",
1280 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
1281 NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
1282 NAND_ECCREQ(8, 512),
1283 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1284 @@ -226,7 +237,8 @@ static const struct spinand_info toshiba
1285 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1286 tx58cxgxsxraix_ecc_get_status)),
1287 /* 1.8V 2Gb (2nd generation) */
1288 - SPINAND_INFO("TC58CYG1S3HRAIJ", 0xDB,
1289 + SPINAND_INFO("TC58CYG1S3HRAIJ",
1290 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
1291 NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
1292 NAND_ECCREQ(8, 512),
1293 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1294 @@ -236,7 +248,8 @@ static const struct spinand_info toshiba
1295 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1296 tx58cxgxsxraix_ecc_get_status)),
1297 /* 1.8V 4Gb (2nd generation) */
1298 - SPINAND_INFO("TC58CYG2S0HRAIJ", 0xDD,
1299 + SPINAND_INFO("TC58CYG2S0HRAIJ",
1300 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
1301 NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
1302 NAND_ECCREQ(8, 512),
1303 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1304 @@ -246,7 +259,8 @@ static const struct spinand_info toshiba
1305 SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
1306 tx58cxgxsxraix_ecc_get_status)),
1307 /* 1.8V 8Gb (2nd generation) */
1308 - SPINAND_INFO("TH58CYG3S0HRAIJ", 0xD4,
1309 + SPINAND_INFO("TH58CYG3S0HRAIJ",
1310 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
1311 NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
1312 NAND_ECCREQ(8, 512),
1313 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1314 @@ -257,33 +271,13 @@ static const struct spinand_info toshiba
1315 tx58cxgxsxraix_ecc_get_status)),
1316 };
1317
1318 -static int toshiba_spinand_detect(struct spinand_device *spinand)
1319 -{
1320 - u8 *id = spinand->id.data;
1321 - int ret;
1322 -
1323 - /*
1324 - * Toshiba SPI NAND read ID needs a dummy byte,
1325 - * so the first byte in id is garbage.
1326 - */
1327 - if (id[1] != SPINAND_MFR_TOSHIBA)
1328 - return 0;
1329 -
1330 - ret = spinand_match_and_init(spinand, toshiba_spinand_table,
1331 - ARRAY_SIZE(toshiba_spinand_table),
1332 - id[2]);
1333 - if (ret)
1334 - return ret;
1335 -
1336 - return 1;
1337 -}
1338 -
1339 static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
1340 - .detect = toshiba_spinand_detect,
1341 };
1342
1343 const struct spinand_manufacturer toshiba_spinand_manufacturer = {
1344 .id = SPINAND_MFR_TOSHIBA,
1345 .name = "Toshiba",
1346 + .chips = toshiba_spinand_table,
1347 + .nchips = ARRAY_SIZE(toshiba_spinand_table),
1348 .ops = &toshiba_spinand_manuf_ops,
1349 };
1350 --- a/drivers/mtd/nand/spi/winbond.c
1351 +++ b/drivers/mtd/nand/spi/winbond.c
1352 @@ -19,6 +19,23 @@
1353
1354 #define WINBOND_CFG_BUF_READ BIT(3)
1355
1356 +#define W25N02_N04KV_STATUS_ECC_MASK (3 << 4)
1357 +#define W25N02_N04KV_STATUS_ECC_NO_BITFLIPS (0 << 4)
1358 +#define W25N02_N04KV_STATUS_ECC_1_4_BITFLIPS (1 << 4)
1359 +#define W25N02_N04KV_STATUS_ECC_5_8_BITFLIPS (3 << 4)
1360 +#define W25N02_N04KV_STATUS_ECC_UNCOR_ERROR (2 << 4)
1361 +
1362 +#define W25N01_M02GV_STATUS_ECC_MASK (3 << 4)
1363 +#define W25N01_M02GV_STATUS_ECC_NO_BITFLIPS (0 << 4)
1364 +#define W25N01_M02GV_STATUS_ECC_1_BITFLIPS (1 << 4)
1365 +#define W25N01_M02GV_STATUS_ECC_UNCOR_ERROR (2 << 4)
1366 +
1367 +#define W25N01KV_STATUS_ECC_MASK (3 << 4)
1368 +#define W25N01KV_STATUS_ECC_NO_BITFLIPS (0 << 4)
1369 +#define W25N01KV_STATUS_ECC_1_3_BITFLIPS (1 << 4)
1370 +#define W25N01KV_STATUS_ECC_4_BITFLIPS (3 << 4)
1371 +#define W25N01KV_STATUS_ECC_UNCOR_ERROR (2 << 4)
1372 +
1373 static SPINAND_OP_VARIANTS(read_cache_variants,
1374 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
1375 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
1376 @@ -35,6 +52,35 @@ static SPINAND_OP_VARIANTS(update_cache_
1377 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
1378 SPINAND_PROG_LOAD(false, 0, NULL, 0));
1379
1380 +static int w25n02kv_n04kv_ooblayout_ecc(struct mtd_info *mtd, int section,
1381 + struct mtd_oob_region *region)
1382 +{
1383 + if (section > 3)
1384 + return -ERANGE;
1385 +
1386 + region->offset = (16 * section) + 64;
1387 + region->length = 16;
1388 +
1389 + return 0;
1390 +}
1391 +
1392 +static int w25n02kv_n04kv_ooblayout_free(struct mtd_info *mtd, int section,
1393 + struct mtd_oob_region *region)
1394 +{
1395 + if (section > 3)
1396 + return -ERANGE;
1397 +
1398 + region->offset = (16 * section) + 2;
1399 + region->length = 14;
1400 +
1401 + return 0;
1402 +}
1403 +
1404 +static const struct mtd_ooblayout_ops w25n02kv_n04kv_ooblayout = {
1405 + .ecc = w25n02kv_n04kv_ooblayout_ecc,
1406 + .rfree = w25n02kv_n04kv_ooblayout_free,
1407 +};
1408 +
1409 static int w25m02gv_ooblayout_ecc(struct mtd_info *mtd, int section,
1410 struct mtd_oob_region *region)
1411 {
1412 @@ -78,8 +124,61 @@ static int w25m02gv_select_target(struct
1413 return spi_mem_exec_op(spinand->slave, &op);
1414 }
1415
1416 +static int w25n01kv_ecc_get_status(struct spinand_device *spinand,
1417 + u8 status)
1418 +{
1419 + switch (status & W25N01KV_STATUS_ECC_MASK) {
1420 + case W25N01KV_STATUS_ECC_NO_BITFLIPS:
1421 + return 0;
1422 +
1423 + case W25N01KV_STATUS_ECC_1_3_BITFLIPS:
1424 + return 3;
1425 +
1426 + case W25N01KV_STATUS_ECC_4_BITFLIPS:
1427 + return 4;
1428 +
1429 + case W25N01KV_STATUS_ECC_UNCOR_ERROR:
1430 + return -EBADMSG;
1431 +
1432 + default:
1433 + break;
1434 + }
1435 +
1436 + return -EINVAL;
1437 +}
1438 +
1439 +static int w25n02kv_n04kv_ecc_get_status(struct spinand_device *spinand,
1440 + u8 status)
1441 +{
1442 + switch (status & W25N02_N04KV_STATUS_ECC_MASK) {
1443 + case W25N02_N04KV_STATUS_ECC_NO_BITFLIPS:
1444 + return 0;
1445 +
1446 + case W25N02_N04KV_STATUS_ECC_1_4_BITFLIPS:
1447 + return 3;
1448 +
1449 + case W25N02_N04KV_STATUS_ECC_5_8_BITFLIPS:
1450 + return 4;
1451 +
1452 + /* W25N02_N04KV_use internal 8bit ECC algorithm.
1453 + * But the ECC strength is 4 bit requried.
1454 + * Return 3 if the bit bit flip count less than 5.
1455 + * Return 4 if the bit bit flip count more than 5 to 8.
1456 + */
1457 +
1458 + case W25N02_N04KV_STATUS_ECC_UNCOR_ERROR:
1459 + return -EBADMSG;
1460 +
1461 + default:
1462 + break;
1463 + }
1464 +
1465 + return -EINVAL;
1466 +}
1467 +
1468 static const struct spinand_info winbond_spinand_table[] = {
1469 - SPINAND_INFO("W25M02GV", 0xAB,
1470 + SPINAND_INFO("W25M02GV",
1471 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
1472 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 2),
1473 NAND_ECCREQ(1, 512),
1474 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1475 @@ -88,7 +187,17 @@ static const struct spinand_info winbond
1476 0,
1477 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
1478 SPINAND_SELECT_TARGET(w25m02gv_select_target)),
1479 - SPINAND_INFO("W25N01GV", 0xAA,
1480 + SPINAND_INFO("W25N01KV",
1481 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
1482 + NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
1483 + NAND_ECCREQ(4, 512),
1484 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1485 + &write_cache_variants,
1486 + &update_cache_variants),
1487 + 0,
1488 + SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout, w25n01kv_ecc_get_status)),
1489 + SPINAND_INFO("W25N01GV",
1490 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
1491 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
1492 NAND_ECCREQ(1, 512),
1493 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1494 @@ -96,32 +205,30 @@ static const struct spinand_info winbond
1495 &update_cache_variants),
1496 0,
1497 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
1498 -};
1499 -
1500 -/**
1501 - * winbond_spinand_detect - initialize device related part in spinand_device
1502 - * struct if it is a Winbond device.
1503 - * @spinand: SPI NAND device structure
1504 - */
1505 -static int winbond_spinand_detect(struct spinand_device *spinand)
1506 -{
1507 - u8 *id = spinand->id.data;
1508 - int ret;
1509 -
1510 - /*
1511 - * Winbond SPI NAND read ID need a dummy byte,
1512 - * so the first byte in raw_id is dummy.
1513 + SPINAND_INFO("W25N02KV",
1514 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
1515 + NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
1516 + NAND_ECCREQ(4, 512),
1517 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1518 + &write_cache_variants,
1519 + &update_cache_variants),
1520 + 0,
1521 + SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout,
1522 + w25n02kv_n04kv_ecc_get_status)),
1523 + /* W25N04KV has 2-die(lun), however, it can select die automatically.
1524 + * Treat it as single die here and double block size.
1525 */
1526 - if (id[1] != SPINAND_MFR_WINBOND)
1527 - return 0;
1528 -
1529 - ret = spinand_match_and_init(spinand, winbond_spinand_table,
1530 - ARRAY_SIZE(winbond_spinand_table), id[2]);
1531 - if (ret)
1532 - return ret;
1533 -
1534 - return 1;
1535 -}
1536 + SPINAND_INFO("W25N04KV",
1537 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
1538 + NAND_MEMORG(1, 2048, 128, 64, 4096, 2, 1, 1),
1539 + NAND_ECCREQ(4, 512),
1540 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1541 + &write_cache_variants,
1542 + &update_cache_variants),
1543 + 0,
1544 + SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout,
1545 + w25n02kv_n04kv_ecc_get_status)),
1546 +};
1547
1548 static int winbond_spinand_init(struct spinand_device *spinand)
1549 {
1550 @@ -142,12 +249,13 @@ static int winbond_spinand_init(struct s
1551 }
1552
1553 static const struct spinand_manufacturer_ops winbond_spinand_manuf_ops = {
1554 - .detect = winbond_spinand_detect,
1555 .init = winbond_spinand_init,
1556 };
1557
1558 const struct spinand_manufacturer winbond_spinand_manufacturer = {
1559 .id = SPINAND_MFR_WINBOND,
1560 .name = "Winbond",
1561 + .chips = winbond_spinand_table,
1562 + .nchips = ARRAY_SIZE(winbond_spinand_table),
1563 .ops = &winbond_spinand_manuf_ops,
1564 };
1565 --- a/include/linux/mtd/spinand.h
1566 +++ b/include/linux/mtd/spinand.h
1567 @@ -39,15 +39,15 @@
1568 SPI_MEM_OP_NO_DUMMY, \
1569 SPI_MEM_OP_NO_DATA)
1570
1571 -#define SPINAND_READID_OP(ndummy, buf, len) \
1572 +#define SPINAND_READID_OP(naddr, ndummy, buf, len) \
1573 SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \
1574 - SPI_MEM_OP_NO_ADDR, \
1575 + SPI_MEM_OP_ADDR(naddr, 0, 1), \
1576 SPI_MEM_OP_DUMMY(ndummy, 1), \
1577 SPI_MEM_OP_DATA_IN(len, buf, 1))
1578
1579 #define SPINAND_SET_FEATURE_OP(reg, valptr) \
1580 SPI_MEM_OP(SPI_MEM_OP_CMD(0x1f, 1), \
1581 - SPI_MEM_OP_ADDR(1, reg, 1), \
1582 + SPI_MEM_OP_ADDR(1, reg, 1), \
1583 SPI_MEM_OP_NO_DUMMY, \
1584 SPI_MEM_OP_DATA_OUT(1, valptr, 1))
1585
1586 @@ -75,18 +75,36 @@
1587 SPI_MEM_OP_DUMMY(ndummy, 1), \
1588 SPI_MEM_OP_DATA_IN(len, buf, 1))
1589
1590 +#define SPINAND_PAGE_READ_FROM_CACHE_OP_3A(fast, addr, ndummy, buf, len)\
1591 + SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \
1592 + SPI_MEM_OP_ADDR(3, addr, 1), \
1593 + SPI_MEM_OP_DUMMY(ndummy, 1), \
1594 + SPI_MEM_OP_DATA_IN(len, buf, 1))
1595 +
1596 #define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len) \
1597 SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
1598 SPI_MEM_OP_ADDR(2, addr, 1), \
1599 SPI_MEM_OP_DUMMY(ndummy, 1), \
1600 SPI_MEM_OP_DATA_IN(len, buf, 2))
1601
1602 +#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(addr, ndummy, buf, len) \
1603 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
1604 + SPI_MEM_OP_ADDR(3, addr, 1), \
1605 + SPI_MEM_OP_DUMMY(ndummy, 1), \
1606 + SPI_MEM_OP_DATA_IN(len, buf, 2))
1607 +
1608 #define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len) \
1609 SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
1610 SPI_MEM_OP_ADDR(2, addr, 1), \
1611 SPI_MEM_OP_DUMMY(ndummy, 1), \
1612 SPI_MEM_OP_DATA_IN(len, buf, 4))
1613
1614 +#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(addr, ndummy, buf, len) \
1615 + SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
1616 + SPI_MEM_OP_ADDR(3, addr, 1), \
1617 + SPI_MEM_OP_DUMMY(ndummy, 1), \
1618 + SPI_MEM_OP_DATA_IN(len, buf, 4))
1619 +
1620 #define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len) \
1621 SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
1622 SPI_MEM_OP_ADDR(2, addr, 2), \
1623 @@ -153,37 +171,46 @@ struct spinand_device;
1624 * @data: buffer containing the id bytes. Currently 4 bytes large, but can
1625 * be extended if required
1626 * @len: ID length
1627 - *
1628 - * struct_spinand_id->data contains all bytes returned after a READ_ID command,
1629 - * including dummy bytes if the chip does not emit ID bytes right after the
1630 - * READ_ID command. The responsibility to extract real ID bytes is left to
1631 - * struct_manufacurer_ops->detect().
1632 */
1633 struct spinand_id {
1634 u8 data[SPINAND_MAX_ID_LEN];
1635 int len;
1636 };
1637
1638 +enum spinand_readid_method {
1639 + SPINAND_READID_METHOD_OPCODE,
1640 + SPINAND_READID_METHOD_OPCODE_ADDR,
1641 + SPINAND_READID_METHOD_OPCODE_DUMMY,
1642 +};
1643 +
1644 +/**
1645 + * struct spinand_devid - SPI NAND device id structure
1646 + * @id: device id of current chip
1647 + * @len: number of bytes in device id
1648 + * @method: method to read chip id
1649 + * There are 3 possible variants:
1650 + * SPINAND_READID_METHOD_OPCODE: chip id is returned immediately
1651 + * after read_id opcode.
1652 + * SPINAND_READID_METHOD_OPCODE_ADDR: chip id is returned after
1653 + * read_id opcode + 1-byte address.
1654 + * SPINAND_READID_METHOD_OPCODE_DUMMY: chip id is returned after
1655 + * read_id opcode + 1 dummy byte.
1656 + */
1657 +struct spinand_devid {
1658 + const u8 *id;
1659 + const u8 len;
1660 + const enum spinand_readid_method method;
1661 +};
1662 +
1663 /**
1664 * struct manufacurer_ops - SPI NAND manufacturer specific operations
1665 - * @detect: detect a SPI NAND device. Every time a SPI NAND device is probed
1666 - * the core calls the struct_manufacurer_ops->detect() hook of each
1667 - * registered manufacturer until one of them return 1. Note that
1668 - * the first thing to check in this hook is that the manufacturer ID
1669 - * in struct_spinand_device->id matches the manufacturer whose
1670 - * ->detect() hook has been called. Should return 1 if there's a
1671 - * match, 0 if the manufacturer ID does not match and a negative
1672 - * error code otherwise. When true is returned, the core assumes
1673 - * that properties of the NAND chip (spinand->base.memorg and
1674 - * spinand->base.eccreq) have been filled
1675 * @init: initialize a SPI NAND device
1676 * @cleanup: cleanup a SPI NAND device
1677 *
1678 * Each SPI NAND manufacturer driver should implement this interface so that
1679 - * NAND chips coming from this vendor can be detected and initialized properly.
1680 + * NAND chips coming from this vendor can be initialized properly.
1681 */
1682 struct spinand_manufacturer_ops {
1683 - int (*detect)(struct spinand_device *spinand);
1684 int (*init)(struct spinand_device *spinand);
1685 void (*cleanup)(struct spinand_device *spinand);
1686 };
1687 @@ -192,15 +219,21 @@ struct spinand_manufacturer_ops {
1688 * struct spinand_manufacturer - SPI NAND manufacturer instance
1689 * @id: manufacturer ID
1690 * @name: manufacturer name
1691 + * @devid_len: number of bytes in device ID
1692 + * @chips: supported SPI NANDs under current manufacturer
1693 + * @nchips: number of SPI NANDs available in chips array
1694 * @ops: manufacturer operations
1695 */
1696 struct spinand_manufacturer {
1697 u8 id;
1698 char *name;
1699 + const struct spinand_info *chips;
1700 + const size_t nchips;
1701 const struct spinand_manufacturer_ops *ops;
1702 };
1703
1704 /* SPI NAND manufacturers */
1705 +extern const struct spinand_manufacturer etron_spinand_manufacturer;
1706 extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
1707 extern const struct spinand_manufacturer macronix_spinand_manufacturer;
1708 extern const struct spinand_manufacturer micron_spinand_manufacturer;
1709 @@ -268,7 +301,7 @@ struct spinand_ecc_info {
1710 */
1711 struct spinand_info {
1712 const char *model;
1713 - u8 devid;
1714 + struct spinand_devid devid;
1715 u32 flags;
1716 struct nand_memory_organization memorg;
1717 struct nand_ecc_req eccreq;
1718 @@ -282,6 +315,13 @@ struct spinand_info {
1719 unsigned int target);
1720 };
1721
1722 +#define SPINAND_ID(__method, ...) \
1723 + { \
1724 + .id = (const u8[]){ __VA_ARGS__ }, \
1725 + .len = sizeof((u8[]){ __VA_ARGS__ }), \
1726 + .method = __method, \
1727 + }
1728 +
1729 #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \
1730 { \
1731 .read_cache = __read, \
1732 @@ -440,9 +480,10 @@ static inline void spinand_set_ofnode(st
1733 }
1734 #endif /* __UBOOT__ */
1735
1736 -int spinand_match_and_init(struct spinand_device *dev,
1737 +int spinand_match_and_init(struct spinand_device *spinand,
1738 const struct spinand_info *table,
1739 - unsigned int table_size, u8 devid);
1740 + unsigned int table_size,
1741 + enum spinand_readid_method rdid_method);
1742
1743 int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
1744 int spinand_select_target(struct spinand_device *spinand, unsigned int target);