diff options
Diffstat (limited to 'drivers/mtd/spi/spi_flash.c')
-rw-r--r-- | drivers/mtd/spi/spi_flash.c | 184 |
1 files changed, 92 insertions, 92 deletions
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 03cecef..a329850 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -68,6 +68,51 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, return spi_flash_read_write(spi, cmd, cmd_len, data, NULL, data_len); } +int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) +{ + struct spi_slave *spi = flash->spi; + unsigned long timebase; + int ret; + u8 status; + u8 check_status = 0x0; + u8 poll_bit = STATUS_WIP; + u8 cmd = flash->poll_cmd; + + if (cmd == CMD_FLAG_STATUS) { + poll_bit = STATUS_PEC; + check_status = poll_bit; + } + + ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN); + 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_write_common(struct spi_flash *flash, const u8 *cmd, size_t cmd_len, const void *buf, size_t buf_len) { @@ -109,6 +154,53 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, return ret; } +int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) +{ + u32 erase_size; + u8 cmd[4]; + int ret = -1; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { + debug("SF: Erase offset/length not multiple of erase size\n"); + return -1; + } + + if (erase_size == 4096) + cmd[0] = CMD_ERASE_4K; + else + cmd[0] = CMD_ERASE_64K; + + while (len) { +#ifdef CONFIG_SPI_FLASH_BAR + u8 bank_sel; + + 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; + } +#endif + spi_flash_addr(offset, cmd); + + debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], + cmd[2], cmd[3], offset); + + ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); + if (ret < 0) { + debug("SF: erase failed\n"); + break; + } + + offset += erase_size; + len -= erase_size; + } + + return ret; +} + int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, size_t len, const void *buf) { @@ -218,98 +310,6 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, return ret; } -int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) -{ - struct spi_slave *spi = flash->spi; - unsigned long timebase; - int ret; - u8 status; - u8 check_status = 0x0; - u8 poll_bit = STATUS_WIP; - u8 cmd = flash->poll_cmd; - - if (cmd == CMD_FLAG_STATUS) { - poll_bit = STATUS_PEC; - check_status = poll_bit; - } - - ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN); - 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_erase(struct spi_flash *flash, u32 offset, size_t len) -{ - u32 erase_size; - u8 cmd[4]; - int ret = -1; - - erase_size = flash->sector_size; - if (offset % erase_size || len % erase_size) { - debug("SF: Erase offset/length not multiple of erase size\n"); - return -1; - } - - if (erase_size == 4096) - cmd[0] = CMD_ERASE_4K; - else - cmd[0] = CMD_ERASE_64K; - - while (len) { -#ifdef CONFIG_SPI_FLASH_BAR - u8 bank_sel; - - 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; - } -#endif - spi_flash_addr(offset, cmd); - - debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], - cmd[2], cmd[3], offset); - - ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); - if (ret < 0) { - debug("SF: erase failed\n"); - break; - } - - offset += erase_size; - len -= erase_size; - } - - return ret; -} - int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr) { u8 cmd; |