From: Siva Durga Prasad Paladugu Date: Tue, 28 May 2019 07:33:09 +0000 (+0530) Subject: mtd: spi: Split read transactions per bank X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c744e9e6f66b158968c066f58e606d170e79923a;p=thirdparty%2Fu-boot.git mtd: spi: Split read transactions per bank 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 Signed-off-by: Michal Simek --- diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 860a802fa28..72f0e9fa224 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -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 diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index e5b0e6d949d..7913c501b97 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -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)