
Add support to use 4 byte addresses for SPI flash, configured with SPI_FLASH_USE_4B_ADDR. The Macronix MX25L25735F only supports 4 byte addresses, but has the same ID as the MX25L25635E, which supports 3 and 4 byte address modes. When using the MX25L25735F, flash reads and writes were corrupted with no notification to the user. When in 4 byte mode, SPI_FLASH_BAR is not required.
CONFIG_SPI_FLASH_USE_4B_ADDR - use 4 byte addresses for all SPI flash data read, write and erase operations.
CONFIG_SPI_FLASH_LARGE_NONE - dummy option if SPI_FLASH_BAR and SPI_FLASH_USE_4B_ADDR are not selected
Signed-off-by: Tim Chick tim.chick@mediatek.com ---
Changes in v2: - Fix Kconfig failure caused by incorectly adding extra help into Kconfig
drivers/mtd/spi/Kconfig | 36 ++++++++++++++++++++++++++++++++++++ drivers/mtd/spi/sf_internal.h | 5 +++++ drivers/mtd/spi/spi_flash.c | 11 +++++++++-- 3 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 3f7433c..f605de7 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -34,6 +34,26 @@ config SPI_FLASH
If unsure, say N
+choice + prompt "Large SPI flash support" + default SPI_FLASH_LARGE_NONE + help + Large SPI flash support + + Choose scheme to use SPI flash chip larger than 16MBytes. + SPI flash normally uses 3 bytes of addressing, limit the + directly addressable flash size to 16MBytes. + +config SPI_FLASH_LARGE_NONE + bool "None" + depends on SPI_FLASH + help + For SPI flash chips 16MByte or smaller + + This is a dummy option, and no special method is used to + address large flash chips. Only the bottom 16MByte of + any flash chip will be addressable. + config SPI_FLASH_BAR bool "SPI flash Bank/Extended address register support" depends on SPI_FLASH @@ -42,6 +62,22 @@ config SPI_FLASH_BAR Bank/Extended address registers are used to access the flash which has size > 16MiB in 3-byte addressing.
+config SPI_FLASH_USE_4B_ADDR + bool "Use 4 byte flash address instead of 3 bytes" + depends on SPI_FLASH + help + Some SPI flash chips only support 4 byte addresses. Always use + 4-byte addresses. SPI_FLASH_BAR should be turned off, as 4 byte + address allows 4GB of flash space. + + Selecting this option for a flash chip which is not 4 byte address + only will cause flash reads and writes to be corrupted. Most flash + chips support 3 byte mode. + + If unsure, say N + +endchoice + if SPI_FLASH
config SPI_FLASH_ATMEL diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 007a5a0..4d05a7b 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -54,7 +54,12 @@ enum spi_nor_option_flags { };
#define SPI_FLASH_3B_ADDR_LEN 3 +#define SPI_FLASH_4B_ADDR_LEN 4 +#ifdef CONFIG_SPI_FLASH_USE_4B_ADDR +#define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_4B_ADDR_LEN) +#else #define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN) +#endif #define SPI_FLASH_16MB_BOUN 0x1000000
/* CFI Manufacture ID's */ diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 44d9e9b..10594cc 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -25,9 +25,16 @@ DECLARE_GLOBAL_DATA_PTR; static void spi_flash_addr(u32 addr, u8 *cmd) { /* cmd[0] is actual command */ +#ifdef CONFIG_SPI_FLASH_USE_4B_ADDR + cmd[1] = addr >> 24; + cmd[2] = addr >> 16; + cmd[3] = addr >> 8; + cmd[4] = addr >> 0; +#else cmd[1] = addr >> 16; cmd[2] = addr >> 8; cmd[3] = addr >> 0; +#endif }
static int read_sr(struct spi_flash *flash, u8 *rs) @@ -1180,13 +1187,13 @@ int spi_flash_scan(struct spi_flash *flash) puts("\n"); #endif
-#ifndef CONFIG_SPI_FLASH_BAR +#if !(defined CONFIG_SPI_FLASH_BAR) && !(defined CONFIG_SPI_FLASH_USE_4B_ADDR) if (((flash->dual_flash == SF_SINGLE_FLASH) && (flash->size > SPI_FLASH_16MB_BOUN)) || ((flash->dual_flash > SF_SINGLE_FLASH) && (flash->size > SPI_FLASH_16MB_BOUN << 1))) { puts("SF: Warning - Only lower 16MiB accessible,"); - puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); + puts(" Full access #define CONFIG_SPI_FLASH_BAR or CONFIG_SPI_FLASH_USE_4B_ADDR\n"); } #endif