From 24ea6ac892b98e5093402f863cd70aa4985298a1 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Fri, 4 Sep 2015 18:25:45 +0530 Subject: sf: params: Add IS25LP032 part support Added support for IS25LP032 flash part. Signed-off-by: Jagan Teki Cc: Siva Durga Prasad Paladugu Cc: Michal Simek --- drivers/mtd/spi/sf_params.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c index 8f5bdda3d7..43fb555eee 100644 --- a/drivers/mtd/spi/sf_params.c +++ b/drivers/mtd/spi/sf_params.c @@ -35,6 +35,9 @@ const struct spi_flash_params spi_flash_params_table[] = { {"GD25Q64B", 0xc84017, 0x0, 64 * 1024, 128, RD_NORM, SECT_4K}, {"GD25LQ32", 0xc86016, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K}, #endif +#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */ + {"IS25LP032", 0x9d6016, 0x0, 64 * 1024, 64, RD_NORM, 0}, +#endif #ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */ {"MX25L2006E", 0xc22012, 0x0, 64 * 1024, 4, RD_NORM, 0}, {"MX25L4005", 0xc22013, 0x0, 64 * 1024, 8, RD_NORM, 0}, -- cgit From 65a75b6f7a96e3db962005f9e29e6f847e5c64c0 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Fri, 4 Sep 2015 18:27:58 +0530 Subject: sf: params: Add IS25LP064 part support Added support for IS25LP064 flash part. Signed-off-by: Jagan Teki Cc: Siva Durga Prasad Paladugu Cc: Michal Simek --- drivers/mtd/spi/sf_params.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c index 43fb555eee..44863ac16e 100644 --- a/drivers/mtd/spi/sf_params.c +++ b/drivers/mtd/spi/sf_params.c @@ -37,6 +37,7 @@ const struct spi_flash_params spi_flash_params_table[] = { #endif #ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */ {"IS25LP032", 0x9d6016, 0x0, 64 * 1024, 64, RD_NORM, 0}, + {"IS25LP064", 0x9d6017, 0x0, 64 * 1024, 128, RD_NORM, 0}, #endif #ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */ {"MX25L2006E", 0xc22012, 0x0, 64 * 1024, 4, RD_NORM, 0}, -- cgit From 720e5e54ebc81ddbee171dbd1bab4e394b97fb81 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Fri, 4 Sep 2015 18:29:12 +0530 Subject: sf: params: Add IS25LP128 part support Added support for IS25LP128 flash part. Signed-off-by: Jagan Teki Cc: Siva Durga Prasad Paladugu Cc: Michal Simek --- drivers/mtd/spi/sf_params.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c index 44863ac16e..4f37e33eb0 100644 --- a/drivers/mtd/spi/sf_params.c +++ b/drivers/mtd/spi/sf_params.c @@ -38,6 +38,7 @@ const struct spi_flash_params spi_flash_params_table[] = { #ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */ {"IS25LP032", 0x9d6016, 0x0, 64 * 1024, 64, RD_NORM, 0}, {"IS25LP064", 0x9d6017, 0x0, 64 * 1024, 128, RD_NORM, 0}, + {"IS25LP128", 0x9d6018, 0x0, 64 * 1024, 256, RD_NORM, 0}, #endif #ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */ {"MX25L2006E", 0xc22012, 0x0, 64 * 1024, 4, RD_NORM, 0}, -- cgit From 3c75ade2b38ea987b79b7ef74d64301b49aa306d Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 2 Sep 2015 11:39:46 +0530 Subject: sf: Return bank_sel, if flash->bank_curr == bank_sel If computed bank_sel is same as flash->bank_curr which is computed at probe time, then return the bank_sel instead of zero. Cc: Michal Simek Cc: Siva Durga Prasad Paladugu Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 900ec1f2a9..b33fe5a1b2 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -102,7 +102,7 @@ static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel) if (flash->bank_curr == bank_sel) { debug("SF: not require to enable bank%d\n", bank_sel); - return 0; + return bank_sel; } cmd = flash->bank_write_cmd; -- cgit From 234a9e1c605c45748c7a9503e4424c405738fb0c Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 2 Sep 2015 11:39:47 +0530 Subject: sf: Add spi_flash_read_bar Add spi_flash_read_bar function for reading bar and discovering bar commands at probe time. Cc: Michal Simek Cc: Siva Durga Prasad Paladugu Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_probe.c | 53 +++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 19 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 954376de15..f17ec173bf 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -99,6 +99,37 @@ static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) } } +#ifdef CONFIG_SPI_FLASH_BAR +static int spi_flash_read_bank(struct spi_flash *flash, u8 idcode0) +{ + u8 curr_bank = 0; + int ret; + + if (flash->size <= SPI_FLASH_16MB_BOUN) + goto bank_end; + + switch (idcode0) { + case SPI_FLASH_CFI_MFR_SPANSION: + flash->bank_read_cmd = CMD_BANKADDR_BRRD; + flash->bank_write_cmd = CMD_BANKADDR_BRWR; + default: + flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; + flash->bank_write_cmd = CMD_EXTNADDR_WREAR; + } + + ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, + &curr_bank, 1); + if (ret) { + debug("SF: fail to read bank addr register\n"); + return ret; + } + +bank_end: + flash->bank_curr = curr_bank; + return 0; +} +#endif + static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, struct spi_flash *flash) { @@ -235,25 +266,9 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, /* Configure the BAR - discover bank cmds and read current bank */ #ifdef CONFIG_SPI_FLASH_BAR - u8 curr_bank = 0; - if (flash->size > SPI_FLASH_16MB_BOUN) { - int ret; - - flash->bank_read_cmd = (idcode[0] == 0x01) ? - CMD_BANKADDR_BRRD : CMD_EXTNADDR_RDEAR; - flash->bank_write_cmd = (idcode[0] == 0x01) ? - CMD_BANKADDR_BRWR : CMD_EXTNADDR_WREAR; - - ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, - &curr_bank, 1); - if (ret) { - debug("SF: fail to read bank addr register\n"); - return ret; - } - flash->bank_curr = curr_bank; - } else { - flash->bank_curr = curr_bank; - } + int ret = spi_flash_read_bank(flash, idcode[0]); + if (ret < 0) + return ret; #endif /* Flash powers up read-only, so clear BP# bits */ -- cgit From 70ccf5940650a2c37cc9d70ce3c866abe97e9eb5 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 2 Sep 2015 11:39:48 +0530 Subject: sf: Optimize BAR write code Optimized spi-flash bar writing code and also removed unnecessary bank_sel in read_ops. Cc: Simon Glass Cc: Michal Simek Cc: Siva Durga Prasad Paladugu Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_ops.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index b33fe5a1b2..6e457ecbfc 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -95,15 +95,14 @@ int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc) #endif #ifdef CONFIG_SPI_FLASH_BAR -static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel) +static int spi_flash_write_bank(struct spi_flash *flash, u32 offset) { - u8 cmd; + u8 cmd, bank_sel; int ret; - if (flash->bank_curr == bank_sel) { - debug("SF: not require to enable bank%d\n", bank_sel); - return bank_sel; - } + bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift); + if (bank_sel == flash->bank_curr) + goto bar_end; cmd = flash->bank_write_cmd; ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); @@ -111,25 +110,10 @@ static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel) debug("SF: fail to write bank register\n"); return ret; } - flash->bank_curr = bank_sel; - - return 0; -} - -static int spi_flash_bank(struct spi_flash *flash, u32 offset) -{ - u8 bank_sel; - int ret; - - bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift); - - ret = spi_flash_cmd_bankaddr_write(flash, bank_sel); - if (ret) { - debug("SF: fail to set bank%d\n", bank_sel); - return ret; - } - return bank_sel; +bar_end: + flash->bank_curr = bank_sel; + return flash->bank_curr; } #endif @@ -285,7 +269,7 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) spi_flash_dual_flash(flash, &erase_addr); #endif #ifdef CONFIG_SPI_FLASH_BAR - ret = spi_flash_bank(flash, erase_addr); + ret = spi_flash_write_bank(flash, erase_addr); if (ret < 0) return ret; #endif @@ -327,7 +311,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, spi_flash_dual_flash(flash, &write_addr); #endif #ifdef CONFIG_SPI_FLASH_BAR - ret = spi_flash_bank(flash, write_addr); + ret = spi_flash_write_bank(flash, write_addr); if (ret < 0) return ret; #endif @@ -422,9 +406,10 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, spi_flash_dual_flash(flash, &read_addr); #endif #ifdef CONFIG_SPI_FLASH_BAR - bank_sel = spi_flash_bank(flash, read_addr); - if (bank_sel < 0) + ret = spi_flash_write_bank(flash, read_addr); + if (ret < 0) return ret; + bank_sel = flash->bank_curr; #endif remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) * (bank_sel + 1)) - offset; -- cgit From 1fabefddfce1bc79a3d704501efdaa053442b8c1 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 29 Sep 2015 11:17:02 +0530 Subject: sf: Make flash->flags use for generic usage Use the flash->flags for generic usage, not only for dm-spi-flash, this will be used for future flag additions. [Correct the spi flash flags detect logic] Signed-off-by: Bin Meng Tested-by: Bin Meng Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 4 ++++ drivers/mtd/spi/sf_probe.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 9c95d5616e..53998fca45 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -51,6 +51,10 @@ enum { #define SST_WR (SST_BP | SST_WP) +enum spi_nor_option_flags { + SNOR_F_SST_WR = (1 << 0), +}; + #define SPI_FLASH_3B_ADDR_LEN 3 #define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN) #define SPI_FLASH_16MB_BOUN 0x1000000 diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index f17ec173bf..2634e90666 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -163,15 +163,15 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, flash->name = params->name; flash->memory_map = spi->memory_map; flash->dual_flash = flash->spi->option; -#ifdef CONFIG_DM_SPI_FLASH - flash->flags = params->flags; -#endif /* Assign spi_flash ops */ #ifndef CONFIG_DM_SPI_FLASH flash->write = spi_flash_cmd_write_ops; #if defined(CONFIG_SPI_FLASH_SST) - if (params->flags & SST_WR) { + if (params->flags & SST_WR) + flash->flags |= SNOR_F_SST_WR; + + if (params->flags & SNOR_F_SST_WR) { if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) flash->write = sst_write_bp; else @@ -466,7 +466,7 @@ int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, struct spi_flash *flash = dev_get_uclass_priv(dev); #if defined(CONFIG_SPI_FLASH_SST) - if (flash->flags & SST_WR) { + if (flash->flags & SNOR_F_SST_WR) { if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) return sst_write_bp(flash, offset, len, buf); else -- cgit From 4efad20a175119f1a82b58d3197df4c20ae85934 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 2 Sep 2015 11:39:50 +0530 Subject: sf: Update status reg check in spi_flash_cmd_wait_ready Current flash wait_ready logic is not modular to add new register status check, hence updated the status check for adding few more register checks in future. Below are the sf speed runs with 'sf update' on whole flash, 16MiB. => sf update 0x100 0x0 0x1000000 device 0 whole chip 16777216 bytes written, 0 bytes skipped in 59.564s, speed 289262 B/s => sf update 0x100 0x0 0x1000000 device 0 whole chip 16777216 bytes written, 0 bytes skipped in 62.549s, speed 275036 B/s => sf update 0x100 0x0 0x1000000 device 0 whole chip 16777216 bytes written, 0 bytes skipped in 61.276s, speed 284359 B/s Cc: Simon Glass Cc: Marek Vasut Cc: Michal Simek Cc: Siva Durga Prasad Paladugu Cc: Stefan Roese Cc: Tom Warren Cc: Tom Rini Tested-by: Jagan Teki Signed-off-by: Jagan Teki Tested-by: Bin Meng --- drivers/mtd/spi/sf_ops.c | 71 +++++++++--------------------------------------- 1 file changed, 13 insertions(+), 58 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 6e457ecbfc..c820d48b6c 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -139,72 +139,27 @@ static void spi_flash_dual_flash(struct spi_flash *flash, u32 *addr) } #endif -static int spi_flash_poll_status(struct spi_slave *spi, unsigned long timeout, - u8 cmd, u8 poll_bit) -{ - unsigned long timebase; - unsigned long flags = SPI_XFER_BEGIN; - int ret; - u8 status; - u8 check_status = 0x0; - - if (cmd == CMD_FLAG_STATUS) - check_status = poll_bit; - -#ifdef CONFIG_SF_DUAL_FLASH - if (spi->flags & SPI_XFER_U_PAGE) - flags |= SPI_XFER_U_PAGE; -#endif - ret = spi_xfer(spi, 8, &cmd, NULL, flags); - if (ret) { - debug("SF: fail to read %s status register\n", - cmd == CMD_READ_STATUS ? "read" : "flag"); - return ret; - } - - timebase = get_timer(0); - do { - WATCHDOG_RESET(); - - ret = spi_xfer(spi, 8, NULL, &status, 0); - if (ret) - return -1; - - if ((status & poll_bit) == check_status) - break; - - } while (get_timer(timebase) < timeout); - - spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END); - - if ((status & poll_bit) == check_status) - return 0; - - /* Timed out */ - debug("SF: time out!\n"); - return -1; -} - int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) { - struct spi_slave *spi = flash->spi; - int ret; - u8 poll_bit = STATUS_WIP; - u8 cmd = CMD_READ_STATUS; + u8 sr; + int timebase, ret; - ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit); - if (ret < 0) - return ret; + timebase = get_timer(0); - if (flash->poll_cmd == CMD_FLAG_STATUS) { - poll_bit = STATUS_PEC; - cmd = CMD_FLAG_STATUS; - ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit); + while (get_timer(timebase) < timeout) { + ret = spi_flash_cmd_read_status(flash, &sr); if (ret < 0) return ret; + + if (!(sr & STATUS_WIP)) + return 0; + else + break; } - return 0; + printf("SF: Timeout!\n"); + + return -ETIMEDOUT; } int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, -- cgit From baaaa7539c7511e7e90453ecf0f20d8eaeeb70c6 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 29 Sep 2015 16:54:31 +0530 Subject: sf: Add FSR support to spi_flash_cmd_wait_ready This patch adds flag status register reading support to spi_flash_cmd_wait_ready. Cc: Simon Glass Cc: Marek Vasut Cc: Michal Simek Cc: Siva Durga Prasad Paladugu Cc: Stefan Roese Cc: Tom Warren Cc: Tom Rini Cc: Hou Zhiqiang Tested-by: Jagan Teki Tested-by: Bin Meng Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 1 + drivers/mtd/spi/sf_ops.c | 64 +++++++++++++++++++++++++++++++++++++++---- drivers/mtd/spi/sf_probe.c | 4 +-- 3 files changed, 60 insertions(+), 9 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 53998fca45..8a3e5ec3d7 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -53,6 +53,7 @@ enum { enum spi_nor_option_flags { SNOR_F_SST_WR = (1 << 0), + SNOR_F_USE_FSR = (1 << 1), }; #define SPI_FLASH_3B_ADDR_LEN 3 diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index c820d48b6c..f2a9244a14 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -41,6 +41,20 @@ int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs) return 0; } +static int read_fsr(struct spi_flash *flash, u8 *fsr) +{ + int ret; + const u8 cmd = CMD_FLAG_STATUS; + + ret = spi_flash_read_common(flash, &cmd, 1, fsr, 1); + if (ret < 0) { + debug("SF: fail to read flag status register\n"); + return ret; + } + + return 0; +} + int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws) { u8 cmd; @@ -139,22 +153,60 @@ static void spi_flash_dual_flash(struct spi_flash *flash, u32 *addr) } #endif -int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) +static int spi_flash_sr_ready(struct spi_flash *flash) { u8 sr; + int ret; + + ret = spi_flash_cmd_read_status(flash, &sr); + if (ret < 0) + return ret; + + return !(sr & STATUS_WIP); +} + +static int spi_flash_fsr_ready(struct spi_flash *flash) +{ + u8 fsr; + int ret; + + ret = read_fsr(flash, &fsr); + if (ret < 0) + return ret; + + return fsr & STATUS_PEC; +} + +static int spi_flash_ready(struct spi_flash *flash) +{ + int sr, fsr; + + sr = spi_flash_sr_ready(flash); + if (sr < 0) + return sr; + + fsr = 1; + if (flash->flags & SNOR_F_USE_FSR) { + fsr = spi_flash_fsr_ready(flash); + if (fsr < 0) + return fsr; + } + + return sr && fsr; +} + +int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) +{ int timebase, ret; timebase = get_timer(0); while (get_timer(timebase) < timeout) { - ret = spi_flash_cmd_read_status(flash, &sr); + ret = spi_flash_ready(flash); if (ret < 0) return ret; - - if (!(sr & STATUS_WIP)) + if (ret) return 0; - else - break; } printf("SF: Timeout!\n"); diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 2634e90666..f591ab140b 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -257,11 +257,9 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, flash->dummy_byte = 1; } - /* Poll cmd selection */ - flash->poll_cmd = CMD_READ_STATUS; #ifdef CONFIG_SPI_FLASH_STMICRO if (params->flags & E_FSR) - flash->poll_cmd = CMD_FLAG_STATUS; + flash->flags |= SNOR_F_USE_FSR; #endif /* Configure the BAR - discover bank cmds and read current bank */ -- cgit