]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
mtd: spi: Split read transactions per bank
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Tue, 28 May 2019 07:33:09 +0000 (13:03 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 4 Jun 2019 10:48:10 +0000 (12:48 +0200)
The patch splits the read transaction into multiple
read transactions which means incase of read requested
across multiple banks, it splits and sends one read per
bank. This can be enabled using new config option
CONFIG_SPI_FLASH_SPLIT_READ.

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/mtd/spi/Kconfig
drivers/mtd/spi/spi_flash.c

index 860a802fa287b2f48e9ec3366d52be68043aefc3..72f0e9fa224030f0499d61b232efc114ffa7ddf5 100644 (file)
@@ -110,6 +110,15 @@ config SPI_FLASH_XMC
 
 endif
 
+config SPI_FLASH_SPLIT_READ
+       bool "Enable split read transfers"
+       help
+         Some flash devices have multiple dies stacked together in it and in
+         such cases a single read that spans across mutiple dies will not work
+         So, enabling this config option splits a read that was requested across
+         multiple banks into one read per bank so that it fixes the issue with
+         a read across multple banks.
+
 config SPI_FLASH_USE_4K_SECTORS
        bool "Use small 4096 B erase sectors"
        depends on SPI_FLASH
index e5b0e6d949d6d5df851e18659b67d1b3962398f5..7913c501b97b7b9734ede49ed84bb5c6bb74cedc 100644 (file)
@@ -749,6 +749,27 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
                                read_len = SPI_FLASH_16MB_BOUN << flash->shift;
                        else
                                read_len = len;
+
+#ifdef CONFIG_SPI_FLASH_SPLIT_READ
+                       /*
+                        * Some flash devices like N25Q512 have multiple dies
+                        * in it and one read transaction across multiple dies
+                        * is not possible. So, split a read transaction that
+                        * spans across multiple banks into one read per bank
+                        * to fix these scenarios.
+                        */
+                       u32 bank_size = (SPI_FLASH_16MB_BOUN << flash->shift);
+                       u8 cur = offset / bank_size;
+                       u8 nxt = (offset + len) / bank_size;
+
+                       if (cur != nxt) {
+                               remain_len = (bank_size * (cur + 1)) - offset;
+                               if (len < remain_len)
+                                       read_len = len;
+                               else
+                                       read_len = remain_len;
+                       }
+#endif
                }
 
                if (spi->max_read_size)