
-----Original Message----- From: Jagan Teki [mailto:jteki@openedev.com] Sent: 2015年8月11日 19:45 To: Hou Zhiqiang-B48286 Cc: u-boot@lists.denx.de; Siva Durga Prasad Paladugu; Sun York-R58495 Subject: Re: [U-Boot] [PATCH V5 2/2] sf: Turn SPI flash chip into 3-Byte address mode
On 11 August 2015 at 16:25, Zhiqiang Hou B48286@freescale.com wrote:
From: Hou Zhiqiang B48286@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 B48286@freescale.com
Tested on T1042RDB board.
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/sf_ops.c | 36
++++++++++++++++++++++++++++++++++++
drivers/mtd/spi/sf_probe.c | 10 ++++++++++ 3 files changed, 53 insertions(+)
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 1de1dac..9519bd8 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -75,6 +75,10 @@ enum { #define CMD_FLAG_STATUS 0x70 #define CMD_CLEAR_FLAG_STATUS 0x50
+/* Used for Micron, Macronix and Winbond flashes */ +#define CMD_ENTER_4B_ADDR 0xB7 +#define CMD_EXIT_4B_ADDR 0xE9
/* Read commands */ #define CMD_READ_ARRAY_SLOW 0x03 #define CMD_READ_ARRAY_FAST 0x0b @@ -231,6 +235,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/sf_ops.c b/drivers/mtd/spi/sf_ops.c index deebcab..ace1156 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -93,6 +93,42 @@ int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc) } #endif
+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);
return ret;
default:
/* Spansion style */
bar = enable << 7;
cmd = CMD_BANKADDR_BRWR;
return spi_flash_cmd_write(flash->spi, &cmd, 1, &bar,
1);
}
+}
#ifdef CONFIG_SPI_FLASH_BAR static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel) { diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index e0283dc..3b204f8 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -170,6 +170,16 @@ static int spi_flash_validate_params(struct
spi_slave *spi, u8 *idcode,
flash->page_size <<= flash->shift; flash->sector_size = params->sector_size << flash->shift; flash->size = flash->sector_size * params->nr_sectors <<
flash->shift;
/*
* 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 > SPI_FLASH_16MB_BOUN) {
if (spi_flash_cmd_4B_addr_switch(flash, false,
idcode[0]) < 0)
debug("SF: enter 3B address mode failed\n");
}
Flash can operate > 16MiB w/o switching to 4B addressing so, this will fire an issue who all using BAR.
No, it won't fire the issue, because this operation switching to 3B mode in the front of func spi_flash_validate_params, and the 3B address mode is the default mode, as if the system cold boot up. If the chip always using BAR, the post process will re-initial the BAR to 4B addressing.
#ifdef CONFIG_SF_DUAL_FLASH if (flash->dual_flash & SF_DUAL_STACKED_FLASH) flash->size <<= 1;
thanks!
Jagan | openedev.
Thanks, Zhiqiang