1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2005, Intec Automation Inc. 4 * Copyright (C) 2014, Freescale Semiconductor, Inc. 5 */ 6 7 #include <linux/mtd/spi-nor.h> 8 9 #include "core.h" 10 11 /* flash_info mfr_flag. Used to read proprietary FSR register. */ 12 #define USE_FSR BIT(0) 13 14 #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ 15 #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ 16 #define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */ 17 #define SPINOR_OP_MT_RD_ANY_REG 0x85 /* Read volatile register */ 18 #define SPINOR_OP_MT_WR_ANY_REG 0x81 /* Write volatile register */ 19 #define SPINOR_REG_MT_CFR0V 0x00 /* For setting octal DTR mode */ 20 #define SPINOR_REG_MT_CFR1V 0x01 /* For setting dummy cycles */ 21 #define SPINOR_REG_MT_CFR1V_DEF 0x1f /* Default dummy cycles */ 22 #define SPINOR_MT_OCT_DTR 0xe7 /* Enable Octal DTR. */ 23 #define SPINOR_MT_EXSPI 0xff /* Enable Extended SPI (default) */ 24 25 /* Flag Status Register bits */ 26 #define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */ 27 #define FSR_E_ERR BIT(5) /* Erase operation status */ 28 #define FSR_P_ERR BIT(4) /* Program operation status */ 29 #define FSR_PT_ERR BIT(1) /* Protection error bit */ 30 31 /* Micron ST SPI NOR flash operations. */ 32 #define MICRON_ST_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \ 33 SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_MT_WR_ANY_REG, 0), \ 34 SPI_MEM_OP_ADDR(naddr, addr, 0), \ 35 SPI_MEM_OP_NO_DUMMY, \ 36 SPI_MEM_OP_DATA_OUT(ndata, buf, 0)) 37 38 #define MICRON_ST_RDFSR_OP(buf) \ 39 SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 0), \ 40 SPI_MEM_OP_NO_ADDR, \ 41 SPI_MEM_OP_NO_DUMMY, \ 42 SPI_MEM_OP_DATA_IN(1, buf, 0)) 43 44 #define MICRON_ST_CLFSR_OP \ 45 SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 0), \ 46 SPI_MEM_OP_NO_ADDR, \ 47 SPI_MEM_OP_NO_DUMMY, \ 48 SPI_MEM_OP_NO_DATA) 49 50 static int micron_st_nor_octal_dtr_en(struct spi_nor *nor) 51 { 52 struct spi_mem_op op; 53 u8 *buf = nor->bouncebuf; 54 int ret; 55 u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; 56 57 /* Use 20 dummy cycles for memory array reads. */ 58 *buf = 20; 59 op = (struct spi_mem_op) 60 MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 61 SPINOR_REG_MT_CFR1V, 1, buf); 62 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 63 if (ret) 64 return ret; 65 66 buf[0] = SPINOR_MT_OCT_DTR; 67 op = (struct spi_mem_op) 68 MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 69 SPINOR_REG_MT_CFR0V, 1, buf); 70 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 71 if (ret) 72 return ret; 73 74 /* Read flash ID to make sure the switch was successful. */ 75 ret = spi_nor_read_id(nor, 0, 8, buf, SNOR_PROTO_8_8_8_DTR); 76 if (ret) { 77 dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret); 78 return ret; 79 } 80 81 if (memcmp(buf, nor->info->id->bytes, nor->info->id->len)) 82 return -EINVAL; 83 84 return 0; 85 } 86 87 static int micron_st_nor_octal_dtr_dis(struct spi_nor *nor) 88 { 89 struct spi_mem_op op; 90 u8 *buf = nor->bouncebuf; 91 int ret; 92 93 /* 94 * The register is 1-byte wide, but 1-byte transactions are not allowed 95 * in 8D-8D-8D mode. The next register is the dummy cycle configuration 96 * register. Since the transaction needs to be at least 2 bytes wide, 97 * set the next register to its default value. This also makes sense 98 * because the value was changed when enabling 8D-8D-8D mode, it should 99 * be reset when disabling. 100 */ 101 buf[0] = SPINOR_MT_EXSPI; 102 buf[1] = SPINOR_REG_MT_CFR1V_DEF; 103 op = (struct spi_mem_op) 104 MICRON_ST_NOR_WR_ANY_REG_OP(nor->addr_nbytes, 105 SPINOR_REG_MT_CFR0V, 2, buf); 106 ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR); 107 if (ret) 108 return ret; 109 110 /* Read flash ID to make sure the switch was successful. */ 111 ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1); 112 if (ret) { 113 dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret); 114 return ret; 115 } 116 117 if (memcmp(buf, nor->info->id->bytes, nor->info->id->len)) 118 return -EINVAL; 119 120 return 0; 121 } 122 123 static int micron_st_nor_set_octal_dtr(struct spi_nor *nor, bool enable) 124 { 125 return enable ? micron_st_nor_octal_dtr_en(nor) : 126 micron_st_nor_octal_dtr_dis(nor); 127 } 128 129 static void mt35xu512aba_default_init(struct spi_nor *nor) 130 { 131 nor->params->set_octal_dtr = micron_st_nor_set_octal_dtr; 132 } 133 134 static int mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor) 135 { 136 /* Set the Fast Read settings. */ 137 nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR; 138 spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_8_8_8_DTR], 139 0, 20, SPINOR_OP_MT_DTR_RD, 140 SNOR_PROTO_8_8_8_DTR); 141 142 nor->cmd_ext_type = SPI_NOR_EXT_REPEAT; 143 nor->params->rdsr_dummy = 8; 144 nor->params->rdsr_addr_nbytes = 0; 145 146 /* 147 * The BFPT quad enable field is set to a reserved value so the quad 148 * enable function is ignored by spi_nor_parse_bfpt(). Make sure we 149 * disable it. 150 */ 151 nor->params->quad_enable = NULL; 152 153 return 0; 154 } 155 156 static const struct spi_nor_fixups mt35xu512aba_fixups = { 157 .default_init = mt35xu512aba_default_init, 158 .post_sfdp = mt35xu512aba_post_sfdp_fixup, 159 }; 160 161 static const struct flash_info micron_nor_parts[] = { 162 { 163 .id = SNOR_ID(0x2c, 0x5b, 0x1a), 164 .name = "mt35xu512aba", 165 .sector_size = SZ_128K, 166 .size = SZ_64M, 167 .no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ | 168 SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP, 169 .mfr_flags = USE_FSR, 170 .fixup_flags = SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE, 171 .fixups = &mt35xu512aba_fixups, 172 }, { 173 .id = SNOR_ID(0x2c, 0x5b, 0x1c), 174 .name = "mt35xu02g", 175 .sector_size = SZ_128K, 176 .size = SZ_256M, 177 .no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ, 178 .mfr_flags = USE_FSR, 179 .fixup_flags = SPI_NOR_4B_OPCODES, 180 }, 181 }; 182 183 static int mt25qu512a_post_bfpt_fixup(struct spi_nor *nor, 184 const struct sfdp_parameter_header *bfpt_header, 185 const struct sfdp_bfpt *bfpt) 186 { 187 nor->flags &= ~SNOR_F_HAS_16BIT_SR; 188 return 0; 189 } 190 191 static struct spi_nor_fixups mt25qu512a_fixups = { 192 .post_bfpt = mt25qu512a_post_bfpt_fixup, 193 }; 194 195 static const struct flash_info st_nor_parts[] = { 196 { 197 .name = "m25p05-nonjedec", 198 .sector_size = SZ_32K, 199 .size = SZ_64K, 200 }, { 201 .name = "m25p10-nonjedec", 202 .sector_size = SZ_32K, 203 .size = SZ_128K, 204 }, { 205 .name = "m25p20-nonjedec", 206 .size = SZ_256K, 207 }, { 208 .name = "m25p40-nonjedec", 209 .size = SZ_512K, 210 }, { 211 .name = "m25p80-nonjedec", 212 .size = SZ_1M, 213 }, { 214 .name = "m25p16-nonjedec", 215 .size = SZ_2M, 216 }, { 217 .name = "m25p32-nonjedec", 218 .size = SZ_4M, 219 }, { 220 .name = "m25p64-nonjedec", 221 .size = SZ_8M, 222 }, { 223 .name = "m25p128-nonjedec", 224 .sector_size = SZ_256K, 225 .size = SZ_16M, 226 }, { 227 .id = SNOR_ID(0x20, 0x20, 0x10), 228 .name = "m25p05", 229 .sector_size = SZ_32K, 230 .size = SZ_64K, 231 }, { 232 .id = SNOR_ID(0x20, 0x20, 0x11), 233 .name = "m25p10", 234 .sector_size = SZ_32K, 235 .size = SZ_128K, 236 }, { 237 .id = SNOR_ID(0x20, 0x20, 0x12), 238 .name = "m25p20", 239 .size = SZ_256K, 240 }, { 241 .id = SNOR_ID(0x20, 0x20, 0x13), 242 .name = "m25p40", 243 .size = SZ_512K, 244 }, { 245 .id = SNOR_ID(0x20, 0x20, 0x14), 246 .name = "m25p80", 247 .size = SZ_1M, 248 }, { 249 .id = SNOR_ID(0x20, 0x20, 0x15), 250 .name = "m25p16", 251 .size = SZ_2M, 252 }, { 253 .id = SNOR_ID(0x20, 0x20, 0x16), 254 .name = "m25p32", 255 .size = SZ_4M, 256 }, { 257 .id = SNOR_ID(0x20, 0x20, 0x17), 258 .name = "m25p64", 259 .size = SZ_8M, 260 }, { 261 .id = SNOR_ID(0x20, 0x20, 0x18), 262 .name = "m25p128", 263 .sector_size = SZ_256K, 264 .size = SZ_16M, 265 }, { 266 .id = SNOR_ID(0x20, 0x40, 0x11), 267 .name = "m45pe10", 268 .size = SZ_128K, 269 }, { 270 .id = SNOR_ID(0x20, 0x40, 0x14), 271 .name = "m45pe80", 272 .size = SZ_1M, 273 }, { 274 .id = SNOR_ID(0x20, 0x40, 0x15), 275 .name = "m45pe16", 276 .size = SZ_2M, 277 }, { 278 .id = SNOR_ID(0x20, 0x63, 0x16), 279 .name = "m25px32-s1", 280 .size = SZ_4M, 281 .no_sfdp_flags = SECT_4K, 282 }, { 283 .id = SNOR_ID(0x20, 0x71, 0x14), 284 .name = "m25px80", 285 .size = SZ_1M, 286 }, { 287 .id = SNOR_ID(0x20, 0x71, 0x15), 288 .name = "m25px16", 289 .size = SZ_2M, 290 .no_sfdp_flags = SECT_4K, 291 }, { 292 .id = SNOR_ID(0x20, 0x71, 0x16), 293 .name = "m25px32", 294 .size = SZ_4M, 295 .no_sfdp_flags = SECT_4K, 296 }, { 297 .id = SNOR_ID(0x20, 0x71, 0x17), 298 .name = "m25px64", 299 .size = SZ_8M, 300 }, { 301 .id = SNOR_ID(0x20, 0x73, 0x16), 302 .name = "m25px32-s0", 303 .size = SZ_4M, 304 .no_sfdp_flags = SECT_4K, 305 }, { 306 .id = SNOR_ID(0x20, 0x80, 0x12), 307 .name = "m25pe20", 308 .size = SZ_256K, 309 }, { 310 .id = SNOR_ID(0x20, 0x80, 0x14), 311 .name = "m25pe80", 312 .size = SZ_1M, 313 }, { 314 .id = SNOR_ID(0x20, 0x80, 0x15), 315 .name = "m25pe16", 316 .size = SZ_2M, 317 .no_sfdp_flags = SECT_4K, 318 }, { 319 .id = SNOR_ID(0x20, 0xba, 0x16), 320 .name = "n25q032", 321 .size = SZ_4M, 322 .no_sfdp_flags = SPI_NOR_QUAD_READ, 323 }, { 324 .id = SNOR_ID(0x20, 0xba, 0x17), 325 .name = "n25q064", 326 .size = SZ_8M, 327 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 328 }, { 329 .id = SNOR_ID(0x20, 0xba, 0x18), 330 .name = "n25q128a13", 331 .size = SZ_16M, 332 .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 333 SPI_NOR_BP3_SR_BIT6, 334 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 335 .mfr_flags = USE_FSR, 336 }, { 337 .id = SNOR_ID(0x20, 0xba, 0x19, 0x10, 0x44, 0x00), 338 .name = "mt25ql256a", 339 .size = SZ_32M, 340 .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, 341 .fixup_flags = SPI_NOR_4B_OPCODES, 342 .mfr_flags = USE_FSR, 343 }, { 344 .id = SNOR_ID(0x20, 0xba, 0x19), 345 .name = "n25q256a", 346 .size = SZ_32M, 347 .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, 348 .mfr_flags = USE_FSR, 349 }, { 350 .id = SNOR_ID(0x20, 0xba, 0x20, 0x10, 0x44, 0x00), 351 .name = "mt25ql512a", 352 .size = SZ_64M, 353 .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, 354 .fixup_flags = SPI_NOR_4B_OPCODES, 355 .mfr_flags = USE_FSR, 356 }, { 357 .id = SNOR_ID(0x20, 0xba, 0x20), 358 .name = "n25q512ax3", 359 .size = SZ_64M, 360 .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 361 SPI_NOR_BP3_SR_BIT6, 362 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 363 .mfr_flags = USE_FSR, 364 }, { 365 .id = SNOR_ID(0x20, 0xba, 0x21), 366 .name = "n25q00", 367 .size = SZ_128M, 368 .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 369 SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE, 370 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 371 .mfr_flags = USE_FSR, 372 }, { 373 .id = SNOR_ID(0x20, 0xba, 0x22), 374 .name = "mt25ql02g", 375 .size = SZ_256M, 376 .flags = NO_CHIP_ERASE, 377 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 378 .mfr_flags = USE_FSR, 379 }, { 380 .id = SNOR_ID(0x20, 0xbb, 0x15), 381 .name = "n25q016a", 382 .size = SZ_2M, 383 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 384 }, { 385 .id = SNOR_ID(0x20, 0xbb, 0x16), 386 .name = "n25q032a", 387 .size = SZ_4M, 388 .no_sfdp_flags = SPI_NOR_QUAD_READ, 389 }, { 390 .id = SNOR_ID(0x20, 0xbb, 0x17), 391 .name = "n25q064a", 392 .size = SZ_8M, 393 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 394 }, { 395 .id = SNOR_ID(0x20, 0xbb, 0x18), 396 .name = "n25q128a11", 397 .size = SZ_16M, 398 .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 399 SPI_NOR_BP3_SR_BIT6, 400 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 401 .mfr_flags = USE_FSR, 402 }, { 403 .id = SNOR_ID(0x20, 0xbb, 0x19, 0x10, 0x44, 0x00), 404 .name = "mt25qu256a", 405 .size = SZ_32M, 406 .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 407 SPI_NOR_BP3_SR_BIT6, 408 .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, 409 .fixup_flags = SPI_NOR_4B_OPCODES, 410 .mfr_flags = USE_FSR, 411 }, { 412 .id = SNOR_ID(0x20, 0xbb, 0x19), 413 .name = "n25q256ax1", 414 .size = SZ_32M, 415 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 416 .mfr_flags = USE_FSR, 417 }, { 418 .id = SNOR_ID(0x20, 0xbb, 0x20, 0x10, 0x44, 0x00), 419 .name = "mt25qu512a", 420 .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 421 SPI_NOR_BP3_SR_BIT6, 422 .mfr_flags = USE_FSR, 423 .fixups = &mt25qu512a_fixups, 424 }, { 425 .id = SNOR_ID(0x20, 0xbb, 0x20), 426 .name = "n25q512a", 427 .size = SZ_64M, 428 .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | 429 SPI_NOR_BP3_SR_BIT6, 430 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 431 .mfr_flags = USE_FSR, 432 }, { 433 .id = SNOR_ID(0x20, 0xbb, 0x21), 434 .name = "n25q00a", 435 .size = SZ_128M, 436 .flags = NO_CHIP_ERASE, 437 .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, 438 .mfr_flags = USE_FSR, 439 }, { 440 .id = SNOR_ID(0x20, 0xbb, 0x22), 441 .name = "mt25qu02g", 442 .size = SZ_256M, 443 .flags = NO_CHIP_ERASE, 444 .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, 445 .mfr_flags = USE_FSR, 446 } 447 }; 448 449 /** 450 * micron_st_nor_read_fsr() - Read the Flag Status Register. 451 * @nor: pointer to 'struct spi_nor' 452 * @fsr: pointer to a DMA-able buffer where the value of the 453 * Flag Status Register will be written. Should be at least 2 454 * bytes. 455 * 456 * Return: 0 on success, -errno otherwise. 457 */ 458 static int micron_st_nor_read_fsr(struct spi_nor *nor, u8 *fsr) 459 { 460 int ret; 461 462 if (nor->spimem) { 463 struct spi_mem_op op = MICRON_ST_RDFSR_OP(fsr); 464 465 if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) { 466 op.addr.nbytes = nor->params->rdsr_addr_nbytes; 467 op.dummy.nbytes = nor->params->rdsr_dummy; 468 /* 469 * We don't want to read only one byte in DTR mode. So, 470 * read 2 and then discard the second byte. 471 */ 472 op.data.nbytes = 2; 473 } 474 475 spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); 476 477 ret = spi_mem_exec_op(nor->spimem, &op); 478 } else { 479 ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDFSR, fsr, 480 1); 481 } 482 483 if (ret) 484 dev_dbg(nor->dev, "error %d reading FSR\n", ret); 485 486 return ret; 487 } 488 489 /** 490 * micron_st_nor_clear_fsr() - Clear the Flag Status Register. 491 * @nor: pointer to 'struct spi_nor'. 492 */ 493 static void micron_st_nor_clear_fsr(struct spi_nor *nor) 494 { 495 int ret; 496 497 if (nor->spimem) { 498 struct spi_mem_op op = MICRON_ST_CLFSR_OP; 499 500 spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); 501 502 ret = spi_mem_exec_op(nor->spimem, &op); 503 } else { 504 ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLFSR, 505 NULL, 0); 506 } 507 508 if (ret) 509 dev_dbg(nor->dev, "error %d clearing FSR\n", ret); 510 } 511 512 /** 513 * micron_st_nor_ready() - Query the Status Register as well as the Flag Status 514 * Register to see if the flash is ready for new commands. If there are any 515 * errors in the FSR clear them. 516 * @nor: pointer to 'struct spi_nor'. 517 * 518 * Return: 1 if ready, 0 if not ready, -errno on errors. 519 */ 520 static int micron_st_nor_ready(struct spi_nor *nor) 521 { 522 int sr_ready, ret; 523 524 sr_ready = spi_nor_sr_ready(nor); 525 if (sr_ready < 0) 526 return sr_ready; 527 528 ret = micron_st_nor_read_fsr(nor, nor->bouncebuf); 529 if (ret) { 530 /* 531 * Some controllers, such as Intel SPI, do not support low 532 * level operations such as reading the flag status 533 * register. They only expose small amount of high level 534 * operations to the software. If this is the case we use 535 * only the status register value. 536 */ 537 return ret == -EOPNOTSUPP ? sr_ready : ret; 538 } 539 540 if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) { 541 if (nor->bouncebuf[0] & FSR_E_ERR) 542 dev_err(nor->dev, "Erase operation failed.\n"); 543 else 544 dev_err(nor->dev, "Program operation failed.\n"); 545 546 if (nor->bouncebuf[0] & FSR_PT_ERR) 547 dev_err(nor->dev, 548 "Attempted to modify a protected sector.\n"); 549 550 micron_st_nor_clear_fsr(nor); 551 552 /* 553 * WEL bit remains set to one when an erase or page program 554 * error occurs. Issue a Write Disable command to protect 555 * against inadvertent writes that can possibly corrupt the 556 * contents of the memory. 557 */ 558 ret = spi_nor_write_disable(nor); 559 if (ret) 560 return ret; 561 562 return -EIO; 563 } 564 565 return sr_ready && !!(nor->bouncebuf[0] & FSR_READY); 566 } 567 568 static void micron_st_nor_default_init(struct spi_nor *nor) 569 { 570 nor->flags |= SNOR_F_HAS_LOCK; 571 nor->flags &= ~SNOR_F_HAS_16BIT_SR; 572 nor->params->quad_enable = NULL; 573 } 574 575 static int micron_st_nor_late_init(struct spi_nor *nor) 576 { 577 struct spi_nor_flash_parameter *params = nor->params; 578 579 if (nor->info->mfr_flags & USE_FSR) 580 params->ready = micron_st_nor_ready; 581 582 if (!params->set_4byte_addr_mode) 583 params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_wren_en4b_ex4b; 584 585 return 0; 586 } 587 588 static const struct spi_nor_fixups micron_st_nor_fixups = { 589 .default_init = micron_st_nor_default_init, 590 .late_init = micron_st_nor_late_init, 591 }; 592 593 const struct spi_nor_manufacturer spi_nor_micron = { 594 .name = "micron", 595 .parts = micron_nor_parts, 596 .nparts = ARRAY_SIZE(micron_nor_parts), 597 .fixups = µn_st_nor_fixups, 598 }; 599 600 const struct spi_nor_manufacturer spi_nor_st = { 601 .name = "st", 602 .parts = st_nor_parts, 603 .nparts = ARRAY_SIZE(st_nor_parts), 604 .fixups = µn_st_nor_fixups, 605 }; 606