Message ID | FD897F46D140444CAB8DC80B08F0742B0185ABE4E4@PFDE-MX11.EU.P-F.BIZ |
---|---|
State | Deferred |
Delegated to: | Tom Rini |
Headers | show |
Series | [U-Boot] sf: ensure flash device is in 3-byte address mode | expand |
Hi Simon, > On some boards where the spi flash is not reset during warm reboot, > the chip has to be manually set into 3-byte address mode. > > Signed-off-by: Simon Goldschmidt <sgoldschmidt@de.pepperl-fuchs.com> Reviewed-by: Lukasz Majewski <lukma@denx.de> > --- > drivers/mtd/spi/sf_internal.h | 2 ++ > drivers/mtd/spi/spi_flash.c | 53 > +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 > insertions(+) > > diff --git a/drivers/mtd/spi/sf_internal.h > b/drivers/mtd/spi/sf_internal.h index 839cdbe1b0..06dee0a4ea 100644 > --- a/drivers/mtd/spi/sf_internal.h > +++ b/drivers/mtd/spi/sf_internal.h > @@ -62,6 +62,8 @@ enum spi_nor_option_flags { > #define CMD_READ_STATUS1 0x35 > #define CMD_READ_CONFIG 0x35 > #define CMD_FLAG_STATUS 0x70 > +#define CMD_EN4B 0xB7 > +#define CMD_EX4B 0xE9 > > /* Bank addr access commands */ > #ifdef CONFIG_SPI_FLASH_BAR > diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c > index 34f68881ed..8db2882075 100644 > --- a/drivers/mtd/spi/spi_flash.c > +++ b/drivers/mtd/spi/spi_flash.c > @@ -165,6 +165,55 @@ bar_end: > } > #endif > > +static int set_4byte(struct spi_flash *flash, const struct > spi_flash_info *info, > + u8 enable) > +{ > + int ret; > + bool need_wren = false; > + u8 cmd; > + > + if (flash->size <= SPI_FLASH_16MB_BOUN) > + return 0; > + > + switch (JEDEC_MFR(info)) { > + 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: > + ret = spi_claim_bus(flash->spi); > + if (ret) { > + debug("SF: Unable to claim SPI bus\n"); > + return ret; > + } > + > + if (need_wren) { > + ret = spi_flash_cmd_write_enable(flash); > + if (ret < 0) { > + debug("SF: enabling write failed\n"); > + spi_release_bus(flash->spi); > + return ret; > + } > + } > + > + cmd = enable ? CMD_EN4B : CMD_EX4B; > + ret = spi_flash_cmd_write(flash->spi, &cmd, 1, NULL, > 0); > + if (ret) { > + debug("SF: fail to %s 4-byte address mode\n", > + enable ? "enter" : "exit"); > + } > + if (need_wren) > + if (spi_flash_cmd_write_disable(flash) < 0) > + debug("SF: disabling write > failed\n"); > + spi_release_bus(flash->spi); > + return ret; > + default: > + /* Spansion style handled by bar_write */ > + break; > + } > + return 0; > +} > + > #ifdef CONFIG_SF_DUAL_FLASH > static void spi_flash_dual(struct spi_flash *flash, u32 *addr) > { > @@ -1086,6 +1135,10 @@ int spi_flash_scan(struct spi_flash *flash) > flash->flags |= SNOR_F_USE_FSR; > #endif > > + /* disable 4-byte addressing if the device exceeds 16MiB */ > + if (flash->size > SPI_FLASH_16MB_BOUN) > + set_4byte(flash, info, 0); > + > /* Configure the BAR - discover bank cmds and read current > bank */ #ifdef CONFIG_SPI_FLASH_BAR > ret = read_bar(flash, info); Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
On Tue, Oct 17, 2017 at 5:17 PM, Goldschmidt Simon <sgoldschmidt@de.pepperl-fuchs.com> wrote: > On some boards where the spi flash is not reset during warm reboot, > the chip has to be manually set into 3-byte address mode. > > Signed-off-by: Simon Goldschmidt <sgoldschmidt@de.pepperl-fuchs.com> > --- > drivers/mtd/spi/sf_internal.h | 2 ++ > drivers/mtd/spi/spi_flash.c | 53 +++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 55 insertions(+) > > diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h > index 839cdbe1b0..06dee0a4ea 100644 > --- a/drivers/mtd/spi/sf_internal.h > +++ b/drivers/mtd/spi/sf_internal.h > @@ -62,6 +62,8 @@ enum spi_nor_option_flags { > #define CMD_READ_STATUS1 0x35 > #define CMD_READ_CONFIG 0x35 > #define CMD_FLAG_STATUS 0x70 > +#define CMD_EN4B 0xB7 > +#define CMD_EX4B 0xE9 > > /* Bank addr access commands */ > #ifdef CONFIG_SPI_FLASH_BAR > diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c > index 34f68881ed..8db2882075 100644 > --- a/drivers/mtd/spi/spi_flash.c > +++ b/drivers/mtd/spi/spi_flash.c > @@ -165,6 +165,55 @@ bar_end: > } > #endif > > +static int set_4byte(struct spi_flash *flash, const struct spi_flash_info *info, > + u8 enable) > +{ > + int ret; > + bool need_wren = false; > + u8 cmd; > + > + if (flash->size <= SPI_FLASH_16MB_BOUN) > + return 0; > + > + switch (JEDEC_MFR(info)) { > + 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: > + ret = spi_claim_bus(flash->spi); > + if (ret) { > + debug("SF: Unable to claim SPI bus\n"); > + return ret; > + } > + > + if (need_wren) { > + ret = spi_flash_cmd_write_enable(flash); > + if (ret < 0) { > + debug("SF: enabling write failed\n"); > + spi_release_bus(flash->spi); > + return ret; > + } > + } > + > + cmd = enable ? CMD_EN4B : CMD_EX4B; > + ret = spi_flash_cmd_write(flash->spi, &cmd, 1, NULL, 0); > + if (ret) { > + debug("SF: fail to %s 4-byte address mode\n", > + enable ? "enter" : "exit"); > + } > + if (need_wren) > + if (spi_flash_cmd_write_disable(flash) < 0) > + debug("SF: disabling write failed\n"); > + spi_release_bus(flash->spi); > + return ret; > + default: > + /* Spansion style handled by bar_write */ > + break; > + } > + return 0; > +} > + > #ifdef CONFIG_SF_DUAL_FLASH > static void spi_flash_dual(struct spi_flash *flash, u32 *addr) > { > @@ -1086,6 +1135,10 @@ int spi_flash_scan(struct spi_flash *flash) > flash->flags |= SNOR_F_USE_FSR; > #endif > > + /* disable 4-byte addressing if the device exceeds 16MiB */ > + if (flash->size > SPI_FLASH_16MB_BOUN) > + set_4byte(flash, info, 0); > + I've similar change on my patchwork, since no-one tested Will CC you by re-basing it please have test? thanks!
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 839cdbe1b0..06dee0a4ea 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -62,6 +62,8 @@ enum spi_nor_option_flags { #define CMD_READ_STATUS1 0x35 #define CMD_READ_CONFIG 0x35 #define CMD_FLAG_STATUS 0x70 +#define CMD_EN4B 0xB7 +#define CMD_EX4B 0xE9 /* Bank addr access commands */ #ifdef CONFIG_SPI_FLASH_BAR diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 34f68881ed..8db2882075 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -165,6 +165,55 @@ bar_end: } #endif +static int set_4byte(struct spi_flash *flash, const struct spi_flash_info *info, + u8 enable) +{ + int ret; + bool need_wren = false; + u8 cmd; + + if (flash->size <= SPI_FLASH_16MB_BOUN) + return 0; + + switch (JEDEC_MFR(info)) { + 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: + ret = spi_claim_bus(flash->spi); + if (ret) { + debug("SF: Unable to claim SPI bus\n"); + return ret; + } + + if (need_wren) { + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { + debug("SF: enabling write failed\n"); + spi_release_bus(flash->spi); + return ret; + } + } + + cmd = enable ? CMD_EN4B : CMD_EX4B; + ret = spi_flash_cmd_write(flash->spi, &cmd, 1, NULL, 0); + if (ret) { + debug("SF: fail to %s 4-byte address mode\n", + enable ? "enter" : "exit"); + } + if (need_wren) + if (spi_flash_cmd_write_disable(flash) < 0) + debug("SF: disabling write failed\n"); + spi_release_bus(flash->spi); + return ret; + default: + /* Spansion style handled by bar_write */ + break; + } + return 0; +} + #ifdef CONFIG_SF_DUAL_FLASH static void spi_flash_dual(struct spi_flash *flash, u32 *addr) { @@ -1086,6 +1135,10 @@ int spi_flash_scan(struct spi_flash *flash) flash->flags |= SNOR_F_USE_FSR; #endif + /* disable 4-byte addressing if the device exceeds 16MiB */ + if (flash->size > SPI_FLASH_16MB_BOUN) + set_4byte(flash, info, 0); + /* Configure the BAR - discover bank cmds and read current bank */ #ifdef CONFIG_SPI_FLASH_BAR ret = read_bar(flash, info);
On some boards where the spi flash is not reset during warm reboot, the chip has to be manually set into 3-byte address mode. Signed-off-by: Simon Goldschmidt <sgoldschmidt@de.pepperl-fuchs.com> --- drivers/mtd/spi/sf_internal.h | 2 ++ drivers/mtd/spi/spi_flash.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+)