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 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 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 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 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 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 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 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 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 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 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 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 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 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