From: Hou Zhiqiang <zhiqiang....@freescale.com> For more than 16MiB SPI flash chips, there are 3-Byte and 4-Byte address mode, and only the 3-Byte address mode is supported in U-Boot so far. So, reset the SPI flash to 3-Byte address mode in probe to ensure the SPI flash work correctly, because it may has been set to 4-Byte address mode after warm boot.
Signed-off-by: Hou Zhiqiang <zhiqiang....@freescale.com> --- Tested on T1023RDB. V7: - Generate this patch base on the latest code. - Correct the condition for SF_DUAL_STACKED_FLASH to switch the addressing mode. V6: - Add the spi_release_bus. V5: - 1. Removed #ifdef for STMICRO. - 2. Add support for Spansion chips (>16MiB) switch to 3-Byte address mode. V4: - Split the the patch to 2 patches for clear FSR and SPI flash address mode. V3: - Generate the patch based on the latest tree git://git.denx.de/u-boot.git. V2: - Add the operation of enter 3 Byte address mode in probe. V1: - Based on git://git.denx.de/u-boot.git. drivers/mtd/spi/sf_internal.h | 7 ++++++ drivers/mtd/spi/spi_flash.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 56936e5..d2b2251 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -93,6 +93,10 @@ enum spi_nor_option_flags { #define CMD_FLAG_STATUS 0x70 #define CMD_READ_EVCR 0x65 +/* Used for Micron, Macronix and Winbond flashes */ +#define CMD_ENTER_4B_ADDR 0xB7 +#define CMD_EXIT_4B_ADDR 0xE9 + /* Bank addr access commands */ # define CMD_BANKADDR_BRWR 0x17 # define CMD_BANKADDR_BRRD 0x16 @@ -223,6 +227,9 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, size_t len, void *data); +int spi_flash_cmd_4B_addr_switch(struct spi_flash *flash, + int enable, u8 idcode0); + #ifdef CONFIG_SPI_FLASH_MTD int spi_flash_mtd_register(struct spi_flash *flash); void spi_flash_mtd_unregister(void); diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 8a60c72..719dcde 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -527,6 +527,47 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, return ret; } +int spi_flash_cmd_4B_addr_switch(struct spi_flash *flash, + int enable, u8 idcode0) +{ + int ret; + u8 cmd, bar; + bool need_wren = false; + + ret = spi_claim_bus(flash->spi); + if (ret) { + debug("SF: unable to claim SPI bus\n"); + return ret; + } + + switch (idcode0) { + case SPI_FLASH_CFI_MFR_STMICRO: + /* Some Micron need WREN command; all will accept it */ + need_wren = true; + case SPI_FLASH_CFI_MFR_MACRONIX: + case SPI_FLASH_CFI_MFR_WINBOND: + if (need_wren) + spi_flash_cmd_write_enable(flash); + + cmd = enable ? CMD_ENTER_4B_ADDR : CMD_EXIT_4B_ADDR; + ret = spi_flash_cmd(flash->spi, cmd, NULL, 0); + if (need_wren) + spi_flash_cmd_write_disable(flash); + + break; + default: + /* Spansion style */ + bar = enable << 7; + cmd = CMD_BANKADDR_BRWR; + ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &bar, 1); + break; + } + + spi_release_bus(flash->spi); + + return ret; +} + #ifdef CONFIG_SPI_FLASH_SST static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) { @@ -1079,6 +1120,17 @@ int spi_flash_scan(struct spi_flash *flash) flash->size <<= 1; #endif + /* + * So far, the 4-byte address mode haven't been supported in U-Boot, + * and make sure the chip (> 16MiB) in default 3-byte address mode, + * in case of warm bootup, the chip was set to 4-byte mode in kernel. + */ + if (flash->size >> (flash->dual_flash & SF_DUAL_STACKED_FLASH ? 1 : 0) + > SPI_FLASH_16MB_BOUN) { + if (spi_flash_cmd_4B_addr_switch(flash, false, idcode[0]) < 0) + debug("SF: enter 3B address mode failed\n"); + } + /* Compute erase sector and command */ if (params->flags & SECT_4K) { flash->erase_cmd = CMD_ERASE_4K; -- 2.1.0.27.g96db324 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot