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

Goldschmidt Simon sgoldschmidt at de.pepperl-fuchs.com
Tue Oct 17 11:47:15 UTC 2017


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 at 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);
+
 	/* Configure the BAR - discover bank cmds and read current bank */
 #ifdef CONFIG_SPI_FLASH_BAR
 	ret = read_bar(flash, info);
-- 
2.12.2.windows.2



More information about the U-Boot mailing list