Updated the spi_flash framework to handle all sizes of flashes
using bank/extd addr reg facility

The current implementation in spi_flash supports 3-byte address mode
due to this up to 16Mbytes amount of flash is able to access for those
flashes which has an actual size of > 16MB.

As most of the flashes introduces a bank/extd address registers
for accessing the flashes in 16Mbytes of banks if the flash size
is > 16Mbytes, this new scheme will add the bank selection feature
for performing write/erase operations on all flashes.

Signed-off-by: Jagannadha Sutradharudu Teki <jaga...@xilinx.com>
---
Changes for v2:
        - none

 drivers/mtd/spi/spi_flash.c | 39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 4576a16..5386884 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -74,11 +74,9 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 
offset,
        unsigned long page_addr, byte_addr, page_size;
        size_t chunk_len, actual;
        int ret;
-       u8 cmd[4];
+       u8 cmd[4], bank_sel;
 
        page_size = flash->page_size;
-       page_addr = offset / page_size;
-       byte_addr = offset % page_size;
 
        ret = spi_claim_bus(flash->spi);
        if (ret) {
@@ -88,6 +86,16 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 
offset,
 
        cmd[0] = CMD_PAGE_PROGRAM;
        for (actual = 0; actual < len; actual += chunk_len) {
+               bank_sel = offset / SPI_FLASH_16MB_BOUN;
+
+               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
+               if (ret) {
+                       debug("SF: fail to set bank%d\n", bank_sel);
+                       return ret;
+               }
+
+               page_addr = offset / page_size;
+               byte_addr = offset % page_size;
                chunk_len = min(len - actual, page_size - byte_addr);
 
                if (flash->spi->max_write_size)
@@ -117,11 +125,7 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 
offset,
                if (ret)
                        break;
 
-               byte_addr += chunk_len;
-               if (byte_addr == page_size) {
-                       page_addr++;
-                       byte_addr = 0;
-               }
+               offset += chunk_len;
        }
 
        spi_release_bus(flash->spi);
@@ -204,9 +208,9 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, 
unsigned long timeout)
 
 int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
-       u32 end, erase_size;
+       u32 erase_size;
        int ret;
-       u8 cmd[4];
+       u8 cmd[4], bank_sel;
 
        erase_size = flash->sector_size;
        if (offset % erase_size || len % erase_size) {
@@ -224,11 +228,17 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 
offset, size_t len)
                cmd[0] = CMD_ERASE_4K;
        else
                cmd[0] = CMD_ERASE_64K;
-       end = offset + len;
 
-       while (offset < end) {
+       while (len) {
+               bank_sel = offset / SPI_FLASH_16MB_BOUN;
+
+               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
+               if (ret) {
+                       debug("SF: fail to set bank%d\n", bank_sel);
+                       return ret;
+               }
+
                spi_flash_addr(offset, cmd);
-               offset += erase_size;
 
                debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
                      cmd[2], cmd[3], offset);
@@ -244,6 +254,9 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 
offset, size_t len)
                ret = spi_flash_cmd_wait_ready(flash, 
SPI_FLASH_PAGE_ERASE_TIMEOUT);
                if (ret)
                        goto out;
+
+               offset += erase_size;
+               len -= erase_size;
        }
 
  out:
-- 
1.8.3


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to