Skip to contentSkip to conversation

sf: ensure flash device is in 3-byte address mode

PATCH New Goldschmidt Simon 3 participants 3 messages Oct 17, 2017 – Oct 30, 2017 Memory technology devices (MTD)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 sf: ensure flash device is in 3-byte address mode

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.

---
 drivers/mtd/spi/sf_internal.h |  2 ++
 drivers/mtd/spi/spi_flash.c   | 53 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
drivers/mtd/spi/sf_internal.h +2 -0
index 839cdbe1b0..06dee0a4ea 100644
@@ -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
drivers/mtd/spi/spi_flash.c +53 -0

65 lines not on this page · raw message

Signature · 1 line
2.12.2.windows.2
#1 lore raw

PATCH 1/1 sf: ensure flash device is in 3-byte address mode

Hi Simon,

Quoted 4 lines

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.

Quoted 92 lines
---
 drivers/mtd/spi/sf_internal.h |  2 ++
 drivers/mtd/spi/spi_flash.c   | 53

+++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+)

(quoted diff) +0 -0

b/drivers/mtd/spi/sf_internal.h index 839cdbe1b0..06dee0a4ea 100644

drivers/mtd/spi/sf_internal.h +2 -0
@@ -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
drivers/mtd/spi/spi_flash.c +40 -0
index 34f68881ed..8db2882075 100644
@@ -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");

drivers/mtd/spi/spi_flash.c +13 -0
+		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
Quoted 2 lines

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 at denx.de

#2 lore raw

PATCH 1/1 sf: ensure flash device is in 3-byte address mode

In reply to Goldschmidt Simon
Quoted 83 lines · Goldschmidt 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.

---
 drivers/mtd/spi/sf_internal.h |  2 ++
 drivers/mtd/spi/spi_flash.c   | 53 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
drivers/mtd/spi/sf_internal.h +2 -0
index 839cdbe1b0..06dee0a4ea 100644
@@ -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
drivers/mtd/spi/spi_flash.c +49 -0
index 34f68881ed..8db2882075 100644
@@ -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)
 {

drivers/mtd/spi/spi_flash.c int spi_flash_scan(struct spi_flash *flash) · line 1141

Quoted 7 lines
drivers/mtd/spi/spi_flash.c +4 -0
@@ -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!

Signature · 4 lines
Jagan Teki
Free Software Engineer | www.openedev.com
U-Boot, Linux | Upstream Maintainer
Hyderabad, India.