[U-Boot] [PATCH 1/2] sf: Disable hybrid mode for SPANSION S25FS-S family

Rajat Srivastava rajat.srivastava at nxp.com
Mon Oct 16 07:24:21 UTC 2017


The S25FS-S family physical sectors may be configured as a hybrid
combination of eight 4-kB parameter sectors at the top or bottom
of the address space with all but one of the remaining sectors
being uniform size.
The default status of the flash is the hybrid architecture.
The parameter sectors and the uniform sectors have different erase
commands.

This patch disables the hybrid sector architecture. The flash will
have uniform sector size and uniform erase command.
This configuration is temporary and the flash will revert to hybrid
architecture after power on reset.

Signed-off-by: Yuan Yao <yao.yuan at nxp.com>
Signed-off-by: Suresh Gupta <suresh.gupta at nxp.com>
Signed-off-by: Rajat Srivastava <rajat.srivastava at nxp.com>
---
 drivers/mtd/spi/sf_internal.h |  7 +++++
 drivers/mtd/spi/spi_flash.c   | 65 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 839cdbe..228960c 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -63,6 +63,12 @@ enum spi_nor_option_flags {
 #define CMD_READ_CONFIG			0x35
 #define CMD_FLAG_STATUS			0x70
 
+/* Spansion specific commands */
+#ifdef CONFIG_SPI_FLASH_SPANSION
+#define CMD_SPANSION_RDAR		0x65
+#define CMD_SPANSION_WRAR		0x71
+#endif
+
 /* Bank addr access commands */
 #ifdef CONFIG_SPI_FLASH_BAR
 # define CMD_BANKADDR_BRWR		0x17
@@ -99,6 +105,7 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len,
 #define JEDEC_MFR(info)		((info)->id[0])
 #define JEDEC_ID(info)		(((info)->id[1]) << 8 | ((info)->id[2]))
 #define JEDEC_EXT(info)		(((info)->id[3]) << 8 | ((info)->id[4]))
+#define JEDEC_FAM_ID(info)	((info)->id[5])
 #define SPI_FLASH_MAX_ID_LEN	6
 
 struct spi_flash_info {
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 34f6888..5152afd 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -937,6 +937,45 @@ int spi_flash_decode_fdt(struct spi_flash *flash)
 }
 #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
 
+#ifdef CONFIG_SPI_FLASH_SPANSION
+static int spansion_s25fss_disable_hybrid_mode(struct spi_slave *spi)
+{
+	u8 cmd[4];
+	u32 offset = 0x800004; /* CR3V register offset */
+	u8 cr3v;
+	int ret;
+
+	cmd[0] = CMD_SPANSION_RDAR;
+	cmd[1] = offset >> 16;
+	cmd[2] = offset >> 8;
+	cmd[3] = offset >> 0;
+
+	ret = spi_flash_cmd_read(spi, cmd, 4, &cr3v, 1);
+	if (ret)
+		return -EIO;
+
+	/* CR3V bit3: 4-KB Erase */
+	if (cr3v & 0x8)
+		return 0;
+
+	cmd[0] = CMD_SPANSION_WRAR;
+	cr3v |= 0x8;
+	ret = spi_flash_cmd_write(spi, cmd, 4, &cr3v, 1);
+	if (ret)
+		return -EIO;
+
+	cmd[0] = CMD_SPANSION_RDAR;
+	ret = spi_flash_cmd_read(spi, cmd, 4, &cr3v, 1);
+	if (ret)
+		return -EIO;
+
+	if (!(cr3v & 0x8))
+		return -EFAULT;
+
+	return 0;
+}
+#endif
+
 int spi_flash_scan(struct spi_flash *flash)
 {
 	struct spi_slave *spi = flash->spi;
@@ -1034,6 +1073,32 @@ int spi_flash_scan(struct spi_flash *flash)
 	/* Now erase size becomes valid sector size */
 	flash->sector_size = flash->erase_size;
 
+#ifdef CONFIG_SPI_FLASH_SPANSION
+	/*
+	 * The S25FS-S family physical sectors may be configured as a
+	 * hybrid combination of eight 4-kB parameter sectors
+	 * at the top or bottom of the address space with all
+	 * but one of the remaining sectors being uniform size.
+	 * The Parameter Sector Erase commands (20h or 21h) must
+	 * be used to erase the 4-kB parameter sectors individually.
+	 * The Sector (uniform sector) Erase commands (D8h or DCh)
+	 * must be used to erase any of the remaining
+	 * sectors, including the portion of highest or lowest address
+	 * sector that is not overlaid by the parameter sectors.
+	 * The uniform sector erase command has no effect on parameter sectors.
+	 * The following code removes the 4-kB parameter sectors from the
+	 * address map i.e. it disables the hybrid mode so that all sectors are
+	 * uniform size.
+	 */
+
+	if ((JEDEC_ID(info) == 0x0219 || JEDEC_ID(info) == 0x0220) &&
+	    (JEDEC_EXT(info) & 0xff00) == 0x4d00 &&
+	    JEDEC_FAM_ID(info) == 0x81) {
+		ret = spansion_s25fss_disable_hybrid_mode(spi);
+		if (ret)
+			return ret;
+	}
+#endif
 	/* Look for read commands */
 	flash->read_cmd = CMD_READ_ARRAY_FAST;
 	if (spi->mode & SPI_RX_SLOW)
-- 
2.7.4



More information about the U-Boot mailing list