From: Cyrille Pitchen <cyrille.pitc...@atmel.com>

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.pitc...@atmel.com>
Signed-off-by: Wenyou Yang <wenyou.y...@microchip.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mtd/spi/sf_internal.h   |  3 +++
 drivers/mtd/spi/spi_flash.c     | 36 ++++++++++++++++++++++++++++++++----
 drivers/mtd/spi/spi_flash_ids.c |  5 +++++
 3 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 30994f9f46..4354a2aa53 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 89ceae2221..503059cacd 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -73,7 +73,8 @@ static int write_sr(struct spi_flash *flash, u8 ws)
        return 0;
 }
 
-#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 read_cr(struct spi_flash *flash, u8 *rc)
 {
        struct spi_flash_command cmd;
@@ -891,6 +892,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 +937,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 +999,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
@@ -1039,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;
 
@@ -1098,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 edca94e30c..3d3132bc3b 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.13.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to