From patchwork Thu Jul 20 07:48:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenyou Yang X-Patchwork-Id: 791493 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xCnJP6bcfz9s82 for ; Thu, 20 Jul 2017 18:34:45 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id AECF2C21D56; Thu, 20 Jul 2017 08:34:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=RCVD_IN_DNSWL_MED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 0D0DCC21D54; Thu, 20 Jul 2017 07:56:14 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 45219C21D8C; Thu, 20 Jul 2017 07:56:12 +0000 (UTC) Received: from DVREDG02.corp.atmel.com (nasmtp01.atmel.com [192.199.1.246]) by lists.denx.de (Postfix) with ESMTPS id 5D377C21D82 for ; Thu, 20 Jul 2017 07:54:46 +0000 (UTC) Received: from apsmtp01.atmel.com (10.168.254.31) by DVREDG02.corp.atmel.com (10.42.103.31) with Microsoft SMTP Server (TLS) id 14.3.235.1; Thu, 20 Jul 2017 01:54:34 -0600 Received: from shaarm01.corp.atmel.com (10.168.254.13) by apsmtp01.atmel.com (10.168.254.31) with Microsoft SMTP Server id 14.3.235.1; Thu, 20 Jul 2017 15:56:30 +0800 From: Wenyou Yang To: U-Boot Mailing List Date: Thu, 20 Jul 2017 15:48:48 +0800 Message-ID: <20170720074849.6787-8-wenyou.yang@microchip.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170720074849.6787-1-wenyou.yang@microchip.com> References: <20170720074849.6787-1-wenyou.yang@microchip.com> MIME-Version: 1.0 Cc: Marek Vasut , Cyrille Pitchen , Jagan Teki Subject: [U-Boot] [PATCH v2 7/8] sf: add support to Microchip SST26 QSPI memories X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Cyrille Pitchen 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 Signed-off-by: Wenyou Yang --- 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) },