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 clear sticky prorietary SR bits. */ 12 #define USE_CLSR BIT(0) 13 14 #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ 15 #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */ 16 #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */ 17 #define SPINOR_REG_CYPRESS_CFR1V 0x00800002 18 #define SPINOR_REG_CYPRESS_CFR1V_QUAD_EN BIT(1) /* Quad Enable */ 19 #define SPINOR_REG_CYPRESS_CFR2V 0x00800003 20 #define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24 0xb 21 #define SPINOR_REG_CYPRESS_CFR3V 0x00800004 22 #define SPINOR_REG_CYPRESS_CFR3V_PGSZ BIT(4) /* Page size. */ 23 #define SPINOR_REG_CYPRESS_CFR5V 0x00800006 24 #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN 0x3 25 #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS 0 26 #define SPINOR_OP_CYPRESS_RD_FAST 0xee 27 28 /* Cypress SPI NOR flash operations. */ 29 #define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \ 30 SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 0), \ 31 SPI_MEM_OP_ADDR(naddr, addr, 0), \ 32 SPI_MEM_OP_NO_DUMMY, \ 33 SPI_MEM_OP_DATA_OUT(ndata, buf, 0)) 34 35 #define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, buf) \ 36 SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0), \ 37 SPI_MEM_OP_ADDR(naddr, addr, 0), \ 38 SPI_MEM_OP_NO_DUMMY, \ 39 SPI_MEM_OP_DATA_IN(1, buf, 0)) 40 41 #define SPANSION_CLSR_OP \ 42 SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0), \ 43 SPI_MEM_OP_NO_ADDR, \ 44 SPI_MEM_OP_NO_DUMMY, \ 45 SPI_MEM_OP_NO_DATA) 46 47 static int cypress_nor_octal_dtr_en(struct spi_nor *nor) 48 { 49 struct spi_mem_op op; 50 u8 *buf = nor->bouncebuf; 51 int ret; 52 u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; 53 54 /* Use 24 dummy cycles for memory array reads. */ 55 *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24; 56 op = (struct spi_mem_op) 57 CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 58 SPINOR_REG_CYPRESS_CFR2V, 1, buf); 59 60 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 61 if (ret) 62 return ret; 63 64 nor->read_dummy = 24; 65 66 /* Set the octal and DTR enable bits. */ 67 buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN; 68 op = (struct spi_mem_op) 69 CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 70 SPINOR_REG_CYPRESS_CFR5V, 1, buf); 71 72 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 73 if (ret) 74 return ret; 75 76 /* Read flash ID to make sure the switch was successful. */ 77 ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf, 78 SNOR_PROTO_8_8_8_DTR); 79 if (ret) { 80 dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret); 81 return ret; 82 } 83 84 if (memcmp(buf, nor->info->id, nor->info->id_len)) 85 return -EINVAL; 86 87 return 0; 88 } 89 90 static int cypress_nor_octal_dtr_dis(struct spi_nor *nor) 91 { 92 struct spi_mem_op op; 93 u8 *buf = nor->bouncebuf; 94 int ret; 95 96 /* 97 * The register is 1-byte wide, but 1-byte transactions are not allowed 98 * in 8D-8D-8D mode. Since there is no register at the next location, 99 * just initialize the value to 0 and let the transaction go on. 100 */ 101 buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS; 102 buf[1] = 0; 103 op = (struct spi_mem_op) 104 CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, 105 SPINOR_REG_CYPRESS_CFR5V, 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, nor->info->id_len)) 118 return -EINVAL; 119 120 return 0; 121 } 122 123 /** 124 * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile 125 * register. 126 * @nor: pointer to a 'struct spi_nor' 127 * 128 * It is recommended to update volatile registers in the field application due 129 * to a risk of the non-volatile registers corruption by power interrupt. This 130 * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable 131 * bit in the CFR1 non-volatile in advance (typically by a Flash programmer 132 * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is 133 * also set during Flash power-up. 134 * 135 * Return: 0 on success, -errno otherwise. 136 */ 137 static int cypress_nor_quad_enable_volatile(struct spi_nor *nor) 138 { 139 struct spi_mem_op op; 140 u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; 141 u8 cfr1v_written; 142 int ret; 143 144 op = (struct spi_mem_op) 145 CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, 146 SPINOR_REG_CYPRESS_CFR1V, 147 nor->bouncebuf); 148 149 ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto); 150 if (ret) 151 return ret; 152 153 if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR1V_QUAD_EN) 154 return 0; 155 156 /* Update the Quad Enable bit. */ 157 nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1V_QUAD_EN; 158 op = (struct spi_mem_op) 159 CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, 160 SPINOR_REG_CYPRESS_CFR1V, 1, 161 nor->bouncebuf); 162 ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); 163 if (ret) 164 return ret; 165 166 cfr1v_written = nor->bouncebuf[0]; 167 168 /* Read back and check it. */ 169 op = (struct spi_mem_op) 170 CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, 171 SPINOR_REG_CYPRESS_CFR1V, 172 nor->bouncebuf); 173 ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto); 174 if (ret) 175 return ret; 176 177 if (nor->bouncebuf[0] != cfr1v_written) { 178 dev_err(nor->dev, "CFR1: Read back test failed\n"); 179 return -EIO; 180 } 181 182 return 0; 183 } 184 185 /** 186 * cypress_nor_set_page_size() - Set page size which corresponds to the flash 187 * configuration. 188 * @nor: pointer to a 'struct spi_nor' 189 * 190 * The BFPT table advertises a 512B or 256B page size depending on part but the 191 * page size is actually configurable (with the default being 256B). Read from 192 * CFR3V[4] and set the correct size. 193 * 194 * Return: 0 on success, -errno otherwise. 195 */ 196 static int cypress_nor_set_page_size(struct spi_nor *nor) 197 { 198 struct spi_mem_op op = 199 CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes, 200 SPINOR_REG_CYPRESS_CFR3V, 201 nor->bouncebuf); 202 int ret; 203 204 ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto); 205 if (ret) 206 return ret; 207 208 if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3V_PGSZ) 209 nor->params->page_size = 512; 210 else 211 nor->params->page_size = 256; 212 213 return 0; 214 } 215 216 static int 217 s25hx_t_post_bfpt_fixup(struct spi_nor *nor, 218 const struct sfdp_parameter_header *bfpt_header, 219 const struct sfdp_bfpt *bfpt) 220 { 221 /* Replace Quad Enable with volatile version */ 222 nor->params->quad_enable = cypress_nor_quad_enable_volatile; 223 224 return cypress_nor_set_page_size(nor); 225 } 226 227 static void s25hx_t_post_sfdp_fixup(struct spi_nor *nor) 228 { 229 struct spi_nor_erase_type *erase_type = 230 nor->params->erase_map.erase_type; 231 unsigned int i; 232 233 /* 234 * In some parts, 3byte erase opcodes are advertised by 4BAIT. 235 * Convert them to 4byte erase opcodes. 236 */ 237 for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) { 238 switch (erase_type[i].opcode) { 239 case SPINOR_OP_SE: 240 erase_type[i].opcode = SPINOR_OP_SE_4B; 241 break; 242 case SPINOR_OP_BE_4K: 243 erase_type[i].opcode = SPINOR_OP_BE_4K_4B; 244 break; 245 default: 246 break; 247 } 248 } 249 } 250 251 static void s25hx_t_late_init(struct spi_nor *nor) 252 { 253 struct spi_nor_flash_parameter *params = nor->params; 254 255 /* Fast Read 4B requires mode cycles */ 256 params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8; 257 258 /* The writesize should be ECC data unit size */ 259 params->writesize = 16; 260 } 261 262 static struct spi_nor_fixups s25hx_t_fixups = { 263 .post_bfpt = s25hx_t_post_bfpt_fixup, 264 .post_sfdp = s25hx_t_post_sfdp_fixup, 265 .late_init = s25hx_t_late_init, 266 }; 267 268 /** 269 * cypress_nor_octal_dtr_enable() - Enable octal DTR on Cypress flashes. 270 * @nor: pointer to a 'struct spi_nor' 271 * @enable: whether to enable or disable Octal DTR 272 * 273 * This also sets the memory access latency cycles to 24 to allow the flash to 274 * run at up to 200MHz. 275 * 276 * Return: 0 on success, -errno otherwise. 277 */ 278 static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable) 279 { 280 return enable ? cypress_nor_octal_dtr_en(nor) : 281 cypress_nor_octal_dtr_dis(nor); 282 } 283 284 static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor) 285 { 286 /* 287 * On older versions of the flash the xSPI Profile 1.0 table has the 288 * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE. 289 */ 290 if (nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0) 291 nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode = 292 SPINOR_OP_CYPRESS_RD_FAST; 293 294 /* This flash is also missing the 4-byte Page Program opcode bit. */ 295 spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP], 296 SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1); 297 /* 298 * Since xSPI Page Program opcode is backward compatible with 299 * Legacy SPI, use Legacy SPI opcode there as well. 300 */ 301 spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP_8_8_8_DTR], 302 SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR); 303 304 /* 305 * The xSPI Profile 1.0 table advertises the number of additional 306 * address bytes needed for Read Status Register command as 0 but the 307 * actual value for that is 4. 308 */ 309 nor->params->rdsr_addr_nbytes = 4; 310 } 311 312 static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor, 313 const struct sfdp_parameter_header *bfpt_header, 314 const struct sfdp_bfpt *bfpt) 315 { 316 return cypress_nor_set_page_size(nor); 317 } 318 319 static void s28hx_t_late_init(struct spi_nor *nor) 320 { 321 nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable; 322 nor->params->writesize = 16; 323 } 324 325 static const struct spi_nor_fixups s28hx_t_fixups = { 326 .post_sfdp = s28hx_t_post_sfdp_fixup, 327 .post_bfpt = s28hx_t_post_bfpt_fixup, 328 .late_init = s28hx_t_late_init, 329 }; 330 331 static int 332 s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor, 333 const struct sfdp_parameter_header *bfpt_header, 334 const struct sfdp_bfpt *bfpt) 335 { 336 /* 337 * The S25FS-S chip family reports 512-byte pages in BFPT but 338 * in reality the write buffer still wraps at the safe default 339 * of 256 bytes. Overwrite the page size advertised by BFPT 340 * to get the writes working. 341 */ 342 nor->params->page_size = 256; 343 344 return 0; 345 } 346 347 static const struct spi_nor_fixups s25fs_s_nor_fixups = { 348 .post_bfpt = s25fs_s_nor_post_bfpt_fixups, 349 }; 350 351 static const struct flash_info spansion_nor_parts[] = { 352 /* Spansion/Cypress -- single (large) sector size only, at least 353 * for the chips listed here (without boot sectors). 354 */ 355 { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64) 356 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 357 { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128) 358 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 359 { "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64) 360 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 361 MFR_FLAGS(USE_CLSR) 362 }, 363 { "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256) 364 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 365 MFR_FLAGS(USE_CLSR) 366 }, 367 { "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128) 368 NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | 369 SPI_NOR_QUAD_READ) 370 MFR_FLAGS(USE_CLSR) 371 }, 372 { "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512) 373 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 374 MFR_FLAGS(USE_CLSR) 375 }, 376 { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256) 377 FLAGS(SPI_NOR_HAS_LOCK) 378 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 379 MFR_FLAGS(USE_CLSR) 380 }, 381 { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256) 382 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 383 MFR_FLAGS(USE_CLSR) 384 .fixups = &s25fs_s_nor_fixups, }, 385 { "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128) 386 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 387 MFR_FLAGS(USE_CLSR) 388 }, 389 { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512) 390 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 391 MFR_FLAGS(USE_CLSR) 392 }, 393 { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256) 394 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 395 MFR_FLAGS(USE_CLSR) 396 .fixups = &s25fs_s_nor_fixups, }, 397 { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) }, 398 { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) }, 399 { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64) 400 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 401 MFR_FLAGS(USE_CLSR) 402 }, 403 { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256) 404 NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 405 MFR_FLAGS(USE_CLSR) 406 }, 407 { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8) }, 408 { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16) }, 409 { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32) }, 410 { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64) }, 411 { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128) }, 412 { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8) 413 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 414 SPI_NOR_QUAD_READ) }, 415 { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16) 416 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 417 SPI_NOR_QUAD_READ) }, 418 { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32) 419 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 420 SPI_NOR_QUAD_READ) }, 421 { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128) 422 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 423 SPI_NOR_QUAD_READ) }, 424 { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32) 425 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 426 SPI_NOR_QUAD_READ) }, 427 { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64) 428 NO_SFDP_FLAGS(SECT_4K) }, 429 { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128) 430 NO_SFDP_FLAGS(SECT_4K) }, 431 { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8) 432 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) }, 433 { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16) 434 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) }, 435 { "s25fl064l", INFO(0x016017, 0, 64 * 1024, 128) 436 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 437 FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 438 { "s25fl128l", INFO(0x016018, 0, 64 * 1024, 256) 439 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 440 FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 441 { "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512) 442 NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 443 FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 444 { "s25hl512t", INFO6(0x342a1a, 0x0f0390, 256 * 1024, 256) 445 PARSE_SFDP 446 MFR_FLAGS(USE_CLSR) 447 .fixups = &s25hx_t_fixups }, 448 { "s25hl01gt", INFO6(0x342a1b, 0x0f0390, 256 * 1024, 512) 449 PARSE_SFDP 450 MFR_FLAGS(USE_CLSR) 451 .fixups = &s25hx_t_fixups }, 452 { "s25hs512t", INFO6(0x342b1a, 0x0f0390, 256 * 1024, 256) 453 PARSE_SFDP 454 MFR_FLAGS(USE_CLSR) 455 .fixups = &s25hx_t_fixups }, 456 { "s25hs01gt", INFO6(0x342b1b, 0x0f0390, 256 * 1024, 512) 457 PARSE_SFDP 458 MFR_FLAGS(USE_CLSR) 459 .fixups = &s25hx_t_fixups }, 460 { "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1) 461 FLAGS(SPI_NOR_NO_ERASE) }, 462 { "s28hl512t", INFO(0x345a1a, 0, 256 * 1024, 256) 463 PARSE_SFDP 464 .fixups = &s28hx_t_fixups, 465 }, 466 { "s28hl01gt", INFO(0x345a1b, 0, 256 * 1024, 512) 467 PARSE_SFDP 468 .fixups = &s28hx_t_fixups, 469 }, 470 { "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256) 471 PARSE_SFDP 472 .fixups = &s28hx_t_fixups, 473 }, 474 { "s28hs01gt", INFO(0x345b1b, 0, 256 * 1024, 512) 475 PARSE_SFDP 476 .fixups = &s28hx_t_fixups, 477 }, 478 }; 479 480 /** 481 * spansion_nor_clear_sr() - Clear the Status Register. 482 * @nor: pointer to 'struct spi_nor'. 483 */ 484 static void spansion_nor_clear_sr(struct spi_nor *nor) 485 { 486 int ret; 487 488 if (nor->spimem) { 489 struct spi_mem_op op = SPANSION_CLSR_OP; 490 491 spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); 492 493 ret = spi_mem_exec_op(nor->spimem, &op); 494 } else { 495 ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR, 496 NULL, 0); 497 } 498 499 if (ret) 500 dev_dbg(nor->dev, "error %d clearing SR\n", ret); 501 } 502 503 /** 504 * spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the 505 * flash is ready for new commands and clear it if there are any errors. 506 * @nor: pointer to 'struct spi_nor'. 507 * 508 * Return: 1 if ready, 0 if not ready, -errno on errors. 509 */ 510 static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor) 511 { 512 int ret; 513 514 ret = spi_nor_read_sr(nor, nor->bouncebuf); 515 if (ret) 516 return ret; 517 518 if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) { 519 if (nor->bouncebuf[0] & SR_E_ERR) 520 dev_err(nor->dev, "Erase Error occurred\n"); 521 else 522 dev_err(nor->dev, "Programming Error occurred\n"); 523 524 spansion_nor_clear_sr(nor); 525 526 /* 527 * WEL bit remains set to one when an erase or page program 528 * error occurs. Issue a Write Disable command to protect 529 * against inadvertent writes that can possibly corrupt the 530 * contents of the memory. 531 */ 532 ret = spi_nor_write_disable(nor); 533 if (ret) 534 return ret; 535 536 return -EIO; 537 } 538 539 return !(nor->bouncebuf[0] & SR_WIP); 540 } 541 542 static void spansion_nor_late_init(struct spi_nor *nor) 543 { 544 if (nor->params->size > SZ_16M) { 545 nor->flags |= SNOR_F_4B_OPCODES; 546 /* No small sector erase for 4-byte command set */ 547 nor->erase_opcode = SPINOR_OP_SE; 548 nor->mtd.erasesize = nor->info->sector_size; 549 } 550 551 if (nor->info->mfr_flags & USE_CLSR) 552 nor->params->ready = spansion_nor_sr_ready_and_clear; 553 } 554 555 static const struct spi_nor_fixups spansion_nor_fixups = { 556 .late_init = spansion_nor_late_init, 557 }; 558 559 const struct spi_nor_manufacturer spi_nor_spansion = { 560 .name = "spansion", 561 .parts = spansion_nor_parts, 562 .nparts = ARRAY_SIZE(spansion_nor_parts), 563 .fixups = &spansion_nor_fixups, 564 }; 565