1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2017 exceet electronics GmbH
4 *
5 * Authors:
6 * Frieder Schrempf <frieder.schrempf@exceet.de>
7 * Boris Brezillon <boris.brezillon@bootlin.com>
8 */
9
10 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #include <linux/mtd/spinand.h>
13 #include <linux/units.h>
14 #include <linux/delay.h>
15
16 #define SPINAND_MFR_WINBOND 0xEF
17
18 #define WINBOND_CFG_BUF_READ BIT(3)
19
20 #define W25N04KV_STATUS_ECC_5_8_BITFLIPS (3 << 4)
21
22 #define W25N0XJW_SR4 0xD0
23 #define W25N0XJW_SR4_HS BIT(2)
24
25 #define W35N01JW_VCR_IO_MODE 0x00
26 #define W35N01JW_VCR_IO_MODE_SINGLE_SDR 0xFF
27 #define W35N01JW_VCR_IO_MODE_OCTAL_SDR 0xDF
28 #define W35N01JW_VCR_IO_MODE_OCTAL_DDR_DS 0xE7
29 #define W35N01JW_VCR_IO_MODE_OCTAL_DDR 0xC7
30 #define W35N01JW_VCR_DUMMY_CLOCK_REG 0x01
31
32 /*
33 * "X2" in the core is equivalent to "dual output" in the datasheets,
34 * "X4" in the core is equivalent to "quad output" in the datasheets.
35 * Quad and octal capable chips feature an absolute maximum frequency of 166MHz.
36 */
37
38 static SPINAND_OP_VARIANTS(read_cache_octal_variants,
39 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP(0, 3, NULL, 0, 120 * HZ_PER_MHZ),
40 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP(0, 2, NULL, 0, 105 * HZ_PER_MHZ),
41 SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP(0, 20, NULL, 0, 0),
42 SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP(0, 16, NULL, 0, 162 * HZ_PER_MHZ),
43 SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP(0, 12, NULL, 0, 124 * HZ_PER_MHZ),
44 SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP(0, 8, NULL, 0, 86 * HZ_PER_MHZ),
45 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_8S_OP(0, 2, NULL, 0, 0),
46 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_8S_OP(0, 1, NULL, 0, 133 * HZ_PER_MHZ),
47 SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0),
48 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0));
49
50 static SPINAND_OP_VARIANTS(write_cache_octal_variants,
51 SPINAND_PROG_LOAD_1S_8S_8S_OP(true, 0, NULL, 0),
52 SPINAND_PROG_LOAD_1S_1S_8S_OP(0, NULL, 0),
53 SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0));
54
55 static SPINAND_OP_VARIANTS(update_cache_octal_variants,
56 SPINAND_PROG_LOAD_1S_8S_8S_OP(false, 0, NULL, 0),
57 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0));
58
59 static SPINAND_OP_VARIANTS(read_cache_dual_quad_dtr_variants,
60 SPINAND_PAGE_READ_FROM_CACHE_1S_4D_4D_OP(0, 8, NULL, 0, 80 * HZ_PER_MHZ),
61 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_4D_OP(0, 2, NULL, 0, 80 * HZ_PER_MHZ),
62 SPINAND_PAGE_READ_FROM_CACHE_1S_4S_4S_OP(0, 4, NULL, 0, 0),
63 SPINAND_PAGE_READ_FROM_CACHE_1S_4S_4S_OP(0, 2, NULL, 0, 104 * HZ_PER_MHZ),
64 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0),
65 SPINAND_PAGE_READ_FROM_CACHE_1S_2D_2D_OP(0, 4, NULL, 0, 80 * HZ_PER_MHZ),
66 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_2D_OP(0, 2, NULL, 0, 80 * HZ_PER_MHZ),
67 SPINAND_PAGE_READ_FROM_CACHE_1S_2S_2S_OP(0, 2, NULL, 0, 0),
68 SPINAND_PAGE_READ_FROM_CACHE_1S_2S_2S_OP(0, 1, NULL, 0, 104 * HZ_PER_MHZ),
69 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0),
70 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_1D_OP(0, 2, NULL, 0, 80 * HZ_PER_MHZ),
71 SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0),
72 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 54 * HZ_PER_MHZ));
73
74 static SPINAND_OP_VARIANTS(read_cache_variants,
75 SPINAND_PAGE_READ_FROM_CACHE_1S_4S_4S_OP(0, 2, NULL, 0, 0),
76 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0),
77 SPINAND_PAGE_READ_FROM_CACHE_1S_2S_2S_OP(0, 1, NULL, 0, 0),
78 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0),
79 SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0),
80 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0));
81
82 static SPINAND_OP_VARIANTS(write_cache_variants,
83 SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0),
84 SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0));
85
86 static SPINAND_OP_VARIANTS(update_cache_variants,
87 SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0),
88 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0));
89
w25m02gv_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)90 static int w25m02gv_ooblayout_ecc(struct mtd_info *mtd, int section,
91 struct mtd_oob_region *region)
92 {
93 if (section > 3)
94 return -ERANGE;
95
96 region->offset = (16 * section) + 8;
97 region->length = 8;
98
99 return 0;
100 }
101
w25m02gv_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)102 static int w25m02gv_ooblayout_free(struct mtd_info *mtd, int section,
103 struct mtd_oob_region *region)
104 {
105 if (section > 3)
106 return -ERANGE;
107
108 region->offset = (16 * section) + 2;
109 region->length = 6;
110
111 return 0;
112 }
113
114 static const struct mtd_ooblayout_ops w25m02gv_ooblayout = {
115 .ecc = w25m02gv_ooblayout_ecc,
116 .free = w25m02gv_ooblayout_free,
117 };
118
w25m02gv_select_target(struct spinand_device * spinand,unsigned int target)119 static int w25m02gv_select_target(struct spinand_device *spinand,
120 unsigned int target)
121 {
122 struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0xc2, 1),
123 SPI_MEM_OP_NO_ADDR,
124 SPI_MEM_OP_NO_DUMMY,
125 SPI_MEM_OP_DATA_OUT(1,
126 spinand->scratchbuf,
127 1));
128
129 *spinand->scratchbuf = target;
130 return spi_mem_exec_op(spinand->spimem, &op);
131 }
132
w25n01kv_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)133 static int w25n01kv_ooblayout_ecc(struct mtd_info *mtd, int section,
134 struct mtd_oob_region *region)
135 {
136 if (section > 3)
137 return -ERANGE;
138
139 region->offset = 64 + (8 * section);
140 region->length = 7;
141
142 return 0;
143 }
144
w25n02kv_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)145 static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
146 struct mtd_oob_region *region)
147 {
148 if (section > 3)
149 return -ERANGE;
150
151 region->offset = 64 + (16 * section);
152 region->length = 13;
153
154 return 0;
155 }
156
w25n02kv_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)157 static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section,
158 struct mtd_oob_region *region)
159 {
160 if (section > 3)
161 return -ERANGE;
162
163 region->offset = (16 * section) + 2;
164 region->length = 14;
165
166 return 0;
167 }
168
169 static const struct mtd_ooblayout_ops w25n01kv_ooblayout = {
170 .ecc = w25n01kv_ooblayout_ecc,
171 .free = w25n02kv_ooblayout_free,
172 };
173
174 static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
175 .ecc = w25n02kv_ooblayout_ecc,
176 .free = w25n02kv_ooblayout_free,
177 };
178
w35n01jw_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)179 static int w35n01jw_ooblayout_ecc(struct mtd_info *mtd, int section,
180 struct mtd_oob_region *region)
181 {
182 if (section > 7)
183 return -ERANGE;
184
185 region->offset = (16 * section) + 12;
186 region->length = 4;
187
188 return 0;
189 }
190
w35n01jw_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)191 static int w35n01jw_ooblayout_free(struct mtd_info *mtd, int section,
192 struct mtd_oob_region *region)
193 {
194 if (section > 7)
195 return -ERANGE;
196
197 region->offset = 16 * section;
198 region->length = 12;
199
200 /* Extract BBM */
201 if (!section) {
202 region->offset += 2;
203 region->length -= 2;
204 }
205
206 return 0;
207 }
208
209 static const struct mtd_ooblayout_ops w35n01jw_ooblayout = {
210 .ecc = w35n01jw_ooblayout_ecc,
211 .free = w35n01jw_ooblayout_free,
212 };
213
w25n02kv_ecc_get_status(struct spinand_device * spinand,u8 status)214 static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
215 u8 status)
216 {
217 struct nand_device *nand = spinand_to_nand(spinand);
218 u8 mbf = 0;
219 struct spi_mem_op op = SPINAND_GET_FEATURE_1S_1S_1S_OP(0x30, spinand->scratchbuf);
220
221 switch (status & STATUS_ECC_MASK) {
222 case STATUS_ECC_NO_BITFLIPS:
223 return 0;
224
225 case STATUS_ECC_UNCOR_ERROR:
226 return -EBADMSG;
227
228 case STATUS_ECC_HAS_BITFLIPS:
229 case W25N04KV_STATUS_ECC_5_8_BITFLIPS:
230 /*
231 * Let's try to retrieve the real maximum number of bitflips
232 * in order to avoid forcing the wear-leveling layer to move
233 * data around if it's not necessary.
234 */
235 if (spi_mem_exec_op(spinand->spimem, &op))
236 return nanddev_get_ecc_conf(nand)->strength;
237
238 mbf = *(spinand->scratchbuf) >> 4;
239
240 if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
241 return nanddev_get_ecc_conf(nand)->strength;
242
243 return mbf;
244
245 default:
246 break;
247 }
248
249 return -EINVAL;
250 }
251
w25n0xjw_hs_cfg(struct spinand_device * spinand)252 static int w25n0xjw_hs_cfg(struct spinand_device *spinand)
253 {
254 const struct spi_mem_op *op;
255 bool hs;
256 u8 sr4;
257 int ret;
258
259 op = spinand->op_templates.read_cache;
260 if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
261 hs = false;
262 else if (op->cmd.buswidth == 1 && op->addr.buswidth == 1 &&
263 op->dummy.buswidth == 1 && op->data.buswidth == 1)
264 hs = false;
265 else if (!op->max_freq)
266 hs = true;
267 else
268 hs = false;
269
270 ret = spinand_read_reg_op(spinand, W25N0XJW_SR4, &sr4);
271 if (ret)
272 return ret;
273
274 if (hs)
275 sr4 |= W25N0XJW_SR4_HS;
276 else
277 sr4 &= ~W25N0XJW_SR4_HS;
278
279 ret = spinand_write_reg_op(spinand, W25N0XJW_SR4, sr4);
280 if (ret)
281 return ret;
282
283 return 0;
284 }
285
w35n0xjw_write_vcr(struct spinand_device * spinand,u8 reg,u8 val)286 static int w35n0xjw_write_vcr(struct spinand_device *spinand, u8 reg, u8 val)
287 {
288 struct spi_mem_op op =
289 SPI_MEM_OP(SPI_MEM_OP_CMD(0x81, 1),
290 SPI_MEM_OP_ADDR(3, reg, 1),
291 SPI_MEM_OP_NO_DUMMY,
292 SPI_MEM_OP_DATA_OUT(1, spinand->scratchbuf, 1));
293 int ret;
294
295 *spinand->scratchbuf = val;
296
297 ret = spinand_write_enable_op(spinand);
298 if (ret)
299 return ret;
300
301 ret = spi_mem_exec_op(spinand->spimem, &op);
302 if (ret)
303 return ret;
304
305 /*
306 * Write VCR operation doesn't set the busy bit in SR, which means we
307 * cannot perform a status poll. Minimum time of 50ns is needed to
308 * complete the write.
309 */
310 ndelay(50);
311
312 return 0;
313 }
314
w35n0xjw_vcr_cfg(struct spinand_device * spinand)315 static int w35n0xjw_vcr_cfg(struct spinand_device *spinand)
316 {
317 const struct spi_mem_op *op;
318 unsigned int dummy_cycles;
319 bool dtr, single;
320 u8 io_mode;
321 int ret;
322
323 op = spinand->op_templates.read_cache;
324
325 single = (op->cmd.buswidth == 1 && op->addr.buswidth == 1 && op->data.buswidth == 1);
326 dtr = (op->cmd.dtr || op->addr.dtr || op->data.dtr);
327 if (single && !dtr)
328 io_mode = W35N01JW_VCR_IO_MODE_SINGLE_SDR;
329 else if (!single && !dtr)
330 io_mode = W35N01JW_VCR_IO_MODE_OCTAL_SDR;
331 else if (!single && dtr)
332 io_mode = W35N01JW_VCR_IO_MODE_OCTAL_DDR;
333 else
334 return -EINVAL;
335
336 ret = w35n0xjw_write_vcr(spinand, W35N01JW_VCR_IO_MODE, io_mode);
337 if (ret)
338 return ret;
339
340 dummy_cycles = ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
341 switch (dummy_cycles) {
342 case 8:
343 case 12:
344 case 16:
345 case 20:
346 case 24:
347 case 28:
348 break;
349 default:
350 return -EINVAL;
351 }
352 ret = w35n0xjw_write_vcr(spinand, W35N01JW_VCR_DUMMY_CLOCK_REG, dummy_cycles);
353 if (ret)
354 return ret;
355
356 return 0;
357 }
358
359 static const struct spinand_info winbond_spinand_table[] = {
360 /* 512M-bit densities */
361 SPINAND_INFO("W25N512GW", /* 1.8V */
362 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x20),
363 NAND_MEMORG(1, 2048, 64, 64, 512, 10, 1, 1, 1),
364 NAND_ECCREQ(1, 512),
365 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
366 &write_cache_variants,
367 &update_cache_variants),
368 0,
369 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
370 /* 1G-bit densities */
371 SPINAND_INFO("W25N01GV", /* 3.3V */
372 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
373 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
374 NAND_ECCREQ(1, 512),
375 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
376 &write_cache_variants,
377 &update_cache_variants),
378 0,
379 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
380 SPINAND_INFO("W25N01GW", /* 1.8V */
381 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21),
382 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
383 NAND_ECCREQ(1, 512),
384 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
385 &write_cache_variants,
386 &update_cache_variants),
387 0,
388 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
389 SPINAND_INFO("W25N01JW", /* high-speed 1.8V */
390 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
391 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
392 NAND_ECCREQ(1, 512),
393 SPINAND_INFO_OP_VARIANTS(&read_cache_dual_quad_dtr_variants,
394 &write_cache_variants,
395 &update_cache_variants),
396 0,
397 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
398 SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)),
399 SPINAND_INFO("W25N01KV", /* 3.3V */
400 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
401 NAND_MEMORG(1, 2048, 96, 64, 1024, 20, 1, 1, 1),
402 NAND_ECCREQ(4, 512),
403 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
404 &write_cache_variants,
405 &update_cache_variants),
406 0,
407 SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)),
408 SPINAND_INFO("W35N01JW", /* 1.8V */
409 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdc, 0x21),
410 NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 1, 1),
411 NAND_ECCREQ(1, 512),
412 SPINAND_INFO_OP_VARIANTS(&read_cache_octal_variants,
413 &write_cache_octal_variants,
414 &update_cache_octal_variants),
415 0,
416 SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
417 SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
418 SPINAND_INFO("W35N02JW", /* 1.8V */
419 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x22),
420 NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 2, 1),
421 NAND_ECCREQ(1, 512),
422 SPINAND_INFO_OP_VARIANTS(&read_cache_octal_variants,
423 &write_cache_octal_variants,
424 &update_cache_octal_variants),
425 0,
426 SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
427 SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
428 SPINAND_INFO("W35N04JW", /* 1.8V */
429 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x23),
430 NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 4, 1),
431 NAND_ECCREQ(1, 512),
432 SPINAND_INFO_OP_VARIANTS(&read_cache_octal_variants,
433 &write_cache_octal_variants,
434 &update_cache_octal_variants),
435 0,
436 SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
437 SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
438 /* 2G-bit densities */
439 SPINAND_INFO("W25M02GV", /* 2x1G-bit 3.3V */
440 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
441 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
442 NAND_ECCREQ(1, 512),
443 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
444 &write_cache_variants,
445 &update_cache_variants),
446 0,
447 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
448 SPINAND_SELECT_TARGET(w25m02gv_select_target)),
449 SPINAND_INFO("W25N02JW", /* high-speed 1.8V */
450 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
451 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
452 NAND_ECCREQ(1, 512),
453 SPINAND_INFO_OP_VARIANTS(&read_cache_dual_quad_dtr_variants,
454 &write_cache_variants,
455 &update_cache_variants),
456 0,
457 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
458 SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)),
459 SPINAND_INFO("W25N02KV", /* 3.3V */
460 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
461 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
462 NAND_ECCREQ(8, 512),
463 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
464 &write_cache_variants,
465 &update_cache_variants),
466 0,
467 SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
468 SPINAND_INFO("W25N02KW", /* 1.8V */
469 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22),
470 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
471 NAND_ECCREQ(8, 512),
472 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
473 &write_cache_variants,
474 &update_cache_variants),
475 0,
476 SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
477 /* 4G-bit densities */
478 SPINAND_INFO("W25N04KV", /* 3.3V */
479 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
480 NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1),
481 NAND_ECCREQ(8, 512),
482 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
483 &write_cache_variants,
484 &update_cache_variants),
485 0,
486 SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
487 SPINAND_INFO("W25N04KW", /* 1.8V */
488 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x23),
489 NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 1, 1, 1),
490 NAND_ECCREQ(8, 512),
491 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
492 &write_cache_variants,
493 &update_cache_variants),
494 0,
495 SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
496 };
497
winbond_spinand_init(struct spinand_device * spinand)498 static int winbond_spinand_init(struct spinand_device *spinand)
499 {
500 struct nand_device *nand = spinand_to_nand(spinand);
501 unsigned int i;
502
503 /*
504 * Make sure all dies are in buffer read mode and not continuous read
505 * mode.
506 */
507 for (i = 0; i < nand->memorg.ntargets; i++) {
508 spinand_select_target(spinand, i);
509 spinand_upd_cfg(spinand, WINBOND_CFG_BUF_READ,
510 WINBOND_CFG_BUF_READ);
511 }
512
513 return 0;
514 }
515
516 static const struct spinand_manufacturer_ops winbond_spinand_manuf_ops = {
517 .init = winbond_spinand_init,
518 };
519
520 const struct spinand_manufacturer winbond_spinand_manufacturer = {
521 .id = SPINAND_MFR_WINBOND,
522 .name = "Winbond",
523 .chips = winbond_spinand_table,
524 .nchips = ARRAY_SIZE(winbond_spinand_table),
525 .ops = &winbond_spinand_manuf_ops,
526 };
527