[U-Boot] [PATCH 7/8] sf: add support to Microchip SST26 QSPI memories

Cyrille Pitchen cyrille.pitchen at atmel.com
Fri May 19 14:59:45 UTC 2017


This patch adds support to Microchip SST26 QSPI memories.

Erase blocks are protected at power up and must be unlocked first before
being erased then programmed.

Also, the erase block sizes are not uniform. The memory layout is uniform
only for the 4K sector blocks. The 64K Block Erase (D8h) op code cannot be
used as currently done by the SPI FLASH sub-system.
The 4K Sector Erase (20h) op code should be chosen instead even if
CONFIG_SPI_FLASH_USE_4K_SECTORS is not set.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
---
 drivers/mtd/spi/sf_internal.h   |  3 +++
 drivers/mtd/spi/spi_flash.c     | 33 ++++++++++++++++++++++++++++++---
 drivers/mtd/spi/spi_flash_ids.c |  5 +++++
 3 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 30994f9f460c..4354a2aa532f 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -104,6 +104,7 @@ enum spi_nor_option_flags {
 #ifdef CONFIG_SPI_FLASH_SST
 # define CMD_SST_BP		0x02    /* Byte Program */
 # define CMD_SST_AAI_WP		0xAD	/* Auto Address Incr Word Program */
+# define CMD_SST_ULBPR		0x98	/* Global Block Protection Unlock */
 
 int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len,
 		const void *buf);
@@ -151,6 +152,8 @@ struct spi_flash_info {
 					 * 4-byte address instruction set
 					 * NOT supported
 					 */
+#define SECT_4K_ONLY		BIT(9)  /* use only CMD_ERASE_4K */
+#define SST_ULBPR		BIT(10)	/* use SST unlock block protection */
 };
 
 extern const struct spi_flash_info spi_flash_ids[];
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 695c8555db3f..307e4140826b 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -891,6 +891,22 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len)
 }
 #endif
 
+#ifdef CONFIG_SPI_FLASH_SST
+static int sst26_unlock(struct spi_flash *flash)
+{
+	struct spi_flash_command cmd;
+	int ret;
+
+	spi_flash_command_init(&cmd, CMD_SST_ULBPR, 0, SPI_FCMD_WRITE_REG);
+	ret = spi_flash_write_common(flash, &cmd);
+	if (ret) {
+		debug("SF: SST26 is still locked (read-only)\n");
+		return ret;
+	}
+
+	return 0;
+}
+#endif
 
 #ifdef CONFIG_SPI_FLASH_MACRONIX
 static int macronix_quad_enable(struct spi_flash *flash)
@@ -920,7 +936,8 @@ static int macronix_quad_enable(struct spi_flash *flash)
 }
 #endif
 
-#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) ||\
+    defined(CONFIG_SPI_FLASH_SST)
 static int spansion_quad_enable(struct spi_flash *flash)
 {
 	u8 qeb_status;
@@ -981,9 +998,11 @@ static int set_quad_mode(struct spi_flash *flash,
 	case SPI_FLASH_CFI_MFR_MACRONIX:
 		return macronix_quad_enable(flash);
 #endif
-#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) ||\
+    defined(CONFIG_SPI_FLASH_SST)
 	case SPI_FLASH_CFI_MFR_SPANSION:
 	case SPI_FLASH_CFI_MFR_WINBOND:
+	case SPI_FLASH_CFI_MFR_SST:
 		return spansion_quad_enable(flash);
 #endif
 #ifdef CONFIG_SPI_FLASH_STMICRO
@@ -1040,6 +1059,11 @@ int spi_flash_scan(struct spi_flash *flash)
 	    JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_SST)
 		write_sr(flash, 0);
 
+#ifdef CONFIG_SPI_FLASH_SST
+	if (info->flags & SST_ULBPR)
+		sst26_unlock(flash);
+#endif
+
 	flash->name = info->name;
 	flash->memory_map = spi->memory_map;
 
@@ -1099,7 +1123,10 @@ int spi_flash_scan(struct spi_flash *flash)
 		flash->erase_size = 4096 << flash->shift;
 	} else
 #endif
-	{
+	if (info->flags & SECT_4K_ONLY) {
+		flash->erase_cmd = CMD_ERASE_4K;
+		flash->erase_size = 4096 << flash->shift;
+	} else {
 		flash->erase_cmd = CMD_ERASE_64K;
 		flash->erase_size = flash->sector_size;
 	}
diff --git a/drivers/mtd/spi/spi_flash_ids.c b/drivers/mtd/spi/spi_flash_ids.c
index edca94e30cf0..3d3132bc3b22 100644
--- a/drivers/mtd/spi/spi_flash_ids.c
+++ b/drivers/mtd/spi/spi_flash_ids.c
@@ -146,6 +146,11 @@ const struct spi_flash_info spi_flash_ids[] = {
 	{"sst25wf040",	   INFO(0xbf2504, 0x0,	64 * 1024,     8, SECT_4K | SST_WR) },
 	{"sst25wf040b",	   INFO(0x621613, 0x0,	64 * 1024,     8, SECT_4K) },
 	{"sst25wf080",	   INFO(0xbf2505, 0x0,	64 * 1024,    16, SECT_4K | SST_WR) },
+	{"sst26vf016b",	   INFO(0xbf2641, 0x0,   4 * 1024,   512, SECT_4K_ONLY | SST_ULBPR | RD_FULL) },
+	{"sst26vf032b",	   INFO(0xbf2642, 0x0,   4 * 1024,  1024, SECT_4K_ONLY | SST_ULBPR | RD_FULL) },
+	{"sst26vf064b",	   INFO(0xbf2643, 0x0,   4 * 1024,  2048, SECT_4K_ONLY | SST_ULBPR | RD_FULL) },
+	{"sst26wf040b",	   INFO(0xbf2654, 0x0,   4 * 1024,   128, SECT_4K_ONLY | SST_ULBPR | RD_FULL) },
+	{"sst26wf080b",	   INFO(0xbf2658, 0x0,   4 * 1024,   256, SECT_4K_ONLY | SST_ULBPR | RD_FULL) },
 #endif
 #ifdef CONFIG_SPI_FLASH_WINBOND		/* WINBOND */
 	{"w25p80",	   INFO(0xef2014, 0x0,	64 * 1024,    16, 0) },
-- 
2.7.4



More information about the U-Boot mailing list