diff mbox series

[U-Boot] sf: ensure flash device is in 3-byte address mode

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

Commit Message

Simon Goldschmidt Oct. 17, 2017, 11:47 a.m. UTC
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(+)

Comments

Lukasz Majewski Oct. 18, 2017, 8:42 p.m. UTC | #1
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
Jagan Teki Oct. 30, 2017, 6:26 a.m. UTC | #2
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 mbox series

Patch

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);