>From e4139e66b956d17a9157a7b6d055e9f8c585041d Mon Sep 17 00:00:00 2001 From: Sourav Poddar Date: Fri, 7 Jun 2013 17:15:36 +0530 Subject: [PATCH 4/5] drivers: mtd: spi: Modify read/write command for sfl256s flash. Reading using the already supported read command is causing regression even while reading 4k bytes, as a result doing a page by page read. At the end of the write sequence, write enable latch should be disabled and re enabled while doing the next page programming. Signed-off-by: Sourav Poddar --- drivers/mtd/spi/spi_flash.c | 39 ++++++++++++++++++++++++++++++++++----- 1 files changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 111185a..8c3a2cf 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -117,6 +117,12 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset, if (ret) break; + ret = spi_flash_cmd_write_disable(flash); + if (ret < 0) { + printf("SF: disabling write failed\n"); + break; + } + byte_addr += chunk_len; if (byte_addr == page_size) { page_addr++; @@ -147,17 +153,40 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, size_t len, void *data) { - u8 cmd[5]; + unsigned long page_addr, byte_addr, page_size; + size_t chunk_len, actual; + int ret = 0; + u8 cmd[4]; /* Handle memory-mapped SPI */ if (flash->memory_map) memcpy(data, flash->memory_map + offset, len); + page_size = flash->page_size; + page_addr = offset / page_size; + byte_addr = offset % page_size; + + cmd[0] = CMD_READ_ARRAY_SLOW; + for (actual = 0; actual < len; actual += chunk_len) { + chunk_len = min(len - actual, page_size - byte_addr); + + cmd[1] = page_addr >> 8; + cmd[2] = page_addr; + cmd[3] = byte_addr; + + ret = spi_flash_read_common(flash, cmd, sizeof(cmd), data + actual, chunk_len); + if (ret < 0) { + debug("SF: read failed"); + break; + } - cmd[0] = CMD_READ_ARRAY_FAST; - spi_flash_addr(offset, cmd); - cmd[4] = 0x00; + byte_addr += chunk_len; + if (byte_addr == page_size) { + page_addr++; + byte_addr = 0; + } + } - return spi_flash_read_common(flash, cmd, sizeof(cmd), data, len); + return ret; } int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout, -- 1.7.1