[U-Boot] [PATCH 7/8] sf: add support to Microchip SST26 QSPI memories
Yang, Wenyou
Wenyou.Yang at Microchip.com
Mon May 22 01:20:40 UTC 2017
On 2017/5/19 22:59, Cyrille Pitchen wrote:
> 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>
Acked-by Wenyou Yang <wenyou.yang at atmel.com>
Best Regards,
Wenyou Yang
> ---
> 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) },
More information about the U-Boot
mailing list