[U-Boot] [RFC/PATCH 4/7] drivers: mtd: spi: Modify read/write command for sfl256s flash.

Sourav Poddar
2013-07-10T11:25:38Z

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.

Looking for help from community on this patch.
I am using S25fl256s flash and already existing framework does not
work on my board. So, I have modified the read function to do page read.

IF i use the already existing framework, read happend till 4k boundary, after
which everything is read as zero. Write happens for a single page, if I dont
provide a write disable at the end of the write function.

Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
---
drivers/mtd/spi/spi_flash.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 111185a..e7f1188 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,50 @@ 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;

/* Handle memory-mapped SPI */
if (flash->memory_map)
memcpy(data, flash->memory_map + offset, len);

+#ifdef CONFIG_TI_QSPI
+ u8 cmd[4];
+ 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;
+ }
+
+ byte_addr += chunk_len;
+ if (byte_addr == page_size) {
+ page_addr++;
+ byte_addr = 0;
+ }
+ }
+
+ return ret;
+#else
+ u8 cmd[5];
cmd[0] = CMD_READ_ARRAY_FAST;
spi_flash_addr(offset, cmd);
cmd[4] = 0x00;

return spi_flash_read_common(flash, cmd, sizeof(cmd), data, len);
+#endif
}

int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
--
1.7.1