Commit 8c927809ea960596345c33b02294af6e236d4ad4

Authored by Vignesh R
Committed by Jagan Teki
1 parent 0c6f187cdb

mtd: spi: spi-nor-core: Add back U-Boot specific features

For legacy reasons, we will have to keep around U-Boot specific
SPI_FLASH_BAR and SPI_TX_BYTE. Add them back to the new framework

Signed-off-by: Vignesh R <vigneshr@ti.com>
Reviewed-by: Jagan Teki <jagan@openedev.com>
Tested-by: Jagan Teki <jagan@amarulasolutions.com> #zynq-microzed

Showing 2 changed files with 168 additions and 3 deletions Side-by-side Diff

drivers/mtd/spi/spi-nor-core.c
... ... @@ -291,6 +291,7 @@
291 291 return mtd->priv;
292 292 }
293 293  
  294 +#ifndef CONFIG_SPI_FLASH_BAR
294 295 static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
295 296 {
296 297 size_t i;
... ... @@ -365,6 +366,7 @@
365 366 nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode);
366 367 nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
367 368 }
  369 +#endif /* !CONFIG_SPI_FLASH_BAR */
368 370  
369 371 /* Enable/disable 4-byte addressing mode. */
370 372 static int set_4byte(struct spi_nor *nor, const struct flash_info *info,
371 373  
... ... @@ -499,7 +501,80 @@
499 501 DEFAULT_READY_WAIT_JIFFIES);
500 502 }
501 503  
  504 +#ifdef CONFIG_SPI_FLASH_BAR
502 505 /*
  506 + * This "clean_bar" is necessary in a situation when one was accessing
  507 + * spi flash memory > 16 MiB by using Bank Address Register's BA24 bit.
  508 + *
  509 + * After it the BA24 bit shall be cleared to allow access to correct
  510 + * memory region after SW reset (by calling "reset" command).
  511 + *
  512 + * Otherwise, the BA24 bit may be left set and then after reset, the
  513 + * ROM would read/write/erase SPL from 16 MiB * bank_sel address.
  514 + */
  515 +static int clean_bar(struct spi_nor *nor)
  516 +{
  517 + u8 cmd, bank_sel = 0;
  518 +
  519 + if (nor->bank_curr == 0)
  520 + return 0;
  521 + cmd = nor->bank_write_cmd;
  522 + nor->bank_curr = 0;
  523 + write_enable(nor);
  524 +
  525 + return nor->write_reg(nor, cmd, &bank_sel, 1);
  526 +}
  527 +
  528 +static int write_bar(struct spi_nor *nor, u32 offset)
  529 +{
  530 + u8 cmd, bank_sel;
  531 + int ret;
  532 +
  533 + bank_sel = offset / SZ_16M;
  534 + if (bank_sel == nor->bank_curr)
  535 + goto bar_end;
  536 +
  537 + cmd = nor->bank_write_cmd;
  538 + write_enable(nor);
  539 + ret = nor->write_reg(nor, cmd, &bank_sel, 1);
  540 + if (ret < 0) {
  541 + debug("SF: fail to write bank register\n");
  542 + return ret;
  543 + }
  544 +
  545 +bar_end:
  546 + nor->bank_curr = bank_sel;
  547 + return nor->bank_curr;
  548 +}
  549 +
  550 +static int read_bar(struct spi_nor *nor, const struct flash_info *info)
  551 +{
  552 + u8 curr_bank = 0;
  553 + int ret;
  554 +
  555 + switch (JEDEC_MFR(info)) {
  556 + case SNOR_MFR_SPANSION:
  557 + nor->bank_read_cmd = SPINOR_OP_BRRD;
  558 + nor->bank_write_cmd = SPINOR_OP_BRWR;
  559 + break;
  560 + default:
  561 + nor->bank_read_cmd = SPINOR_OP_RDEAR;
  562 + nor->bank_write_cmd = SPINOR_OP_WREAR;
  563 + }
  564 +
  565 + ret = nor->read_reg(nor, nor->bank_read_cmd,
  566 + &curr_bank, 1);
  567 + if (ret) {
  568 + debug("SF: fail to read bank addr register\n");
  569 + return ret;
  570 + }
  571 + nor->bank_curr = curr_bank;
  572 +
  573 + return 0;
  574 +}
  575 +#endif
  576 +
  577 +/*
503 578 * Initiate the erasure of a single sector
504 579 */
505 580 static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
... ... @@ -543,6 +618,11 @@
543 618 len = instr->len;
544 619  
545 620 while (len) {
  621 +#ifdef CONFIG_SPI_FLASH_BAR
  622 + ret = write_bar(nor, addr);
  623 + if (ret < 0)
  624 + return ret;
  625 +#endif
546 626 write_enable(nor);
547 627  
548 628 ret = spi_nor_erase_sector(nor, addr);
549 629  
... ... @@ -557,9 +637,12 @@
557 637 goto erase_err;
558 638 }
559 639  
  640 +erase_err:
  641 +#ifdef CONFIG_SPI_FLASH_BAR
  642 + ret = clean_bar(nor);
  643 +#endif
560 644 write_disable(nor);
561 645  
562   -erase_err:
563 646 return ret;
564 647 }
565 648  
566 649  
... ... @@ -1144,8 +1227,23 @@
1144 1227  
1145 1228 while (len) {
1146 1229 loff_t addr = from;
  1230 + size_t read_len = len;
1147 1231  
1148   - ret = nor->read(nor, addr, len, buf);
  1232 +#ifdef CONFIG_SPI_FLASH_BAR
  1233 + u32 remain_len;
  1234 +
  1235 + ret = write_bar(nor, addr);
  1236 + if (ret < 0)
  1237 + return log_ret(ret);
  1238 + remain_len = (SZ_16M * (nor->bank_curr + 1)) - addr;
  1239 +
  1240 + if (len < remain_len)
  1241 + read_len = len;
  1242 + else
  1243 + read_len = remain_len;
  1244 +#endif
  1245 +
  1246 + ret = nor->read(nor, addr, read_len, buf);
1149 1247 if (ret == 0) {
1150 1248 /* We shouldn't see 0-length reads */
1151 1249 ret = -EIO;
1152 1250  
1153 1251  
1154 1252  
... ... @@ -1162,18 +1260,49 @@
1162 1260 ret = 0;
1163 1261  
1164 1262 read_err:
  1263 +#ifdef CONFIG_SPI_FLASH_BAR
  1264 + ret = clean_bar(nor);
  1265 +#endif
1165 1266 return ret;
1166 1267 }
1167 1268  
1168 1269 #ifdef CONFIG_SPI_FLASH_SST
  1270 +static int sst_write_byteprogram(struct spi_nor *nor, loff_t to, size_t len,
  1271 + size_t *retlen, const u_char *buf)
  1272 +{
  1273 + size_t actual;
  1274 + int ret = 0;
  1275 +
  1276 + for (actual = 0; actual < len; actual++) {
  1277 + nor->program_opcode = SPINOR_OP_BP;
  1278 +
  1279 + write_enable(nor);
  1280 + /* write one byte. */
  1281 + ret = nor->write(nor, to, 1, buf + actual);
  1282 + if (ret < 0)
  1283 + goto sst_write_err;
  1284 + ret = spi_nor_wait_till_ready(nor);
  1285 + if (ret)
  1286 + goto sst_write_err;
  1287 + to++;
  1288 + }
  1289 +
  1290 +sst_write_err:
  1291 + write_disable(nor);
  1292 + return ret;
  1293 +}
  1294 +
1169 1295 static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
1170 1296 size_t *retlen, const u_char *buf)
1171 1297 {
1172 1298 struct spi_nor *nor = mtd_to_spi_nor(mtd);
  1299 + struct spi_slave *spi = nor->spi;
1173 1300 size_t actual;
1174 1301 int ret;
1175 1302  
1176 1303 dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
  1304 + if (spi->mode & SPI_TX_BYTE)
  1305 + return sst_write_byteprogram(nor, to, len, retlen, buf);
1177 1306  
1178 1307 write_enable(nor);
1179 1308  
... ... @@ -1271,6 +1400,11 @@
1271 1400 page_remain = min_t(size_t,
1272 1401 nor->page_size - page_offset, len - i);
1273 1402  
  1403 +#ifdef CONFIG_SPI_FLASH_BAR
  1404 + ret = write_bar(nor, addr);
  1405 + if (ret < 0)
  1406 + return ret;
  1407 +#endif
1274 1408 write_enable(nor);
1275 1409 ret = nor->write(nor, addr, page_remain, buf + i);
1276 1410 if (ret < 0)
... ... @@ -1289,6 +1423,9 @@
1289 1423 }
1290 1424  
1291 1425 write_err:
  1426 +#ifdef CONFIG_SPI_FLASH_BAR
  1427 + ret = clean_bar(nor);
  1428 +#endif
1292 1429 return ret;
1293 1430 }
1294 1431  
1295 1432  
... ... @@ -2532,12 +2669,20 @@
2532 2669 /* already configured from SFDP */
2533 2670 } else if (info->addr_width) {
2534 2671 nor->addr_width = info->addr_width;
2535   - } else if (mtd->size > 0x1000000) {
  2672 + } else if (mtd->size > SZ_16M) {
  2673 +#ifndef CONFIG_SPI_FLASH_BAR
2536 2674 /* enable 4-byte addressing if the device exceeds 16MiB */
2537 2675 nor->addr_width = 4;
2538 2676 if (JEDEC_MFR(info) == SNOR_MFR_SPANSION ||
2539 2677 info->flags & SPI_NOR_4B_OPCODES)
2540 2678 spi_nor_set_4byte_opcodes(nor, info);
  2679 +#else
  2680 + /* Configure the BAR - discover bank cmds and read current bank */
  2681 + nor->addr_width = 3;
  2682 + ret = read_bar(nor, info);
  2683 + if (ret < 0)
  2684 + return ret;
  2685 +#endif
2541 2686 } else {
2542 2687 nor->addr_width = 3;
2543 2688 }
... ... @@ -2568,5 +2713,16 @@
2568 2713 #endif
2569 2714  
2570 2715 return 0;
  2716 +}
  2717 +
  2718 +/* U-Boot specific functions, need to extend MTD to support these */
  2719 +int spi_flash_cmd_get_sw_write_prot(struct spi_nor *nor)
  2720 +{
  2721 + int sr = read_sr(nor);
  2722 +
  2723 + if (sr < 0)
  2724 + return sr;
  2725 +
  2726 + return (sr >> 2) & 7;
2571 2727 }
include/linux/mtd/spi-nor.h
... ... @@ -105,6 +105,7 @@
105 105  
106 106 /* Used for Spansion flashes only. */
107 107 #define SPINOR_OP_BRWR 0x17 /* Bank register write */
  108 +#define SPINOR_OP_BRRD 0x16 /* Bank register read */
108 109 #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
109 110  
110 111 /* Used for Micron flashes only. */
... ... @@ -256,6 +257,9 @@
256 257 * @read_opcode: the read opcode
257 258 * @read_dummy: the dummy needed by the read operation
258 259 * @program_opcode: the program opcode
  260 + * @bank_read_cmd: Bank read cmd
  261 + * @bank_write_cmd: Bank write cmd
  262 + * @bank_curr: Current flash bank
259 263 * @sst_write_second: used by the SST write operation
260 264 * @flags: flag options for the current SPI-NOR (SNOR_F_*)
261 265 * @read_proto: the SPI protocol for read operations
... ... @@ -291,6 +295,11 @@
291 295 u8 read_opcode;
292 296 u8 read_dummy;
293 297 u8 program_opcode;
  298 +#ifdef CONFIG_SPI_FLASH_BAR
  299 + u8 bank_read_cmd;
  300 + u8 bank_write_cmd;
  301 + u8 bank_curr;
  302 +#endif
294 303 enum spi_nor_protocol read_proto;
295 304 enum spi_nor_protocol write_proto;
296 305 enum spi_nor_protocol reg_proto;