From patchwork Tue Mar 15 18:12:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyrille Pitchen X-Patchwork-Id: 597765 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3qPjgQ39PNz9sDC for ; Wed, 16 Mar 2016 05:24:02 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0E415A75C6; Tue, 15 Mar 2016 19:20:37 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id TXfNSsqDLSkm; Tue, 15 Mar 2016 19:20:36 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 98524A76DC; Tue, 15 Mar 2016 19:19:47 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 46F63A74E0 for ; Tue, 15 Mar 2016 19:18:08 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hsrme_YUocrL for ; Tue, 15 Mar 2016 19:18:08 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from eusmtp01.atmel.com (eusmtp01.atmel.com [212.144.249.243]) by theia.denx.de (Postfix) with ESMTPS id 16246A745C for ; Tue, 15 Mar 2016 19:18:07 +0100 (CET) Received: from tenerife.corp.atmel.com (10.161.101.13) by eusmtp01.atmel.com (10.161.101.31) with Microsoft SMTP Server id 14.3.235.1; Tue, 15 Mar 2016 19:12:34 +0100 From: Cyrille Pitchen To: Date: Tue, 15 Mar 2016 19:12:32 +0100 Message-ID: X-Mailer: git-send-email 1.8.2.2 In-Reply-To: References: MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 15 Mar 2016 19:18:57 +0100 Cc: marex@denx.de, u-boot@lists.denx.de, Cyrille Pitchen Subject: [U-Boot] [PATCH 10/18] sf: move support of SST flash into generic spi_flash_write_alg() X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 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" This patch makes the support of SST flashes available to all UCLASS_SPI_FLASH drivers, not only the sf_probe.c one. Signed-off-by: Cyrille Pitchen --- drivers/mtd/spi/sf_internal.h | 8 ++--- drivers/mtd/spi/sf_probe.c | 9 ----- drivers/mtd/spi/spi_flash.c | 76 +++++++++++++++++++++++-------------------- 3 files changed, 43 insertions(+), 50 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 15a5fa9c2afd..c5966fb37ac8 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -51,7 +51,8 @@ enum { enum spi_nor_option_flags { SNOR_F_SST_WR = BIT(0), - SNOR_F_USE_FSR = BIT(1), + SNOR_F_SST_WR_2ND = BIT(1), + SNOR_F_USE_FSR = BIT(2), }; #define SPI_FLASH_3B_ADDR_LEN 3 @@ -118,11 +119,6 @@ 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 */ - -int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, - const void *buf); -int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, - const void *buf); #endif /** diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index fbd7d4740b51..837535fdb7a5 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -140,15 +140,6 @@ static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, { struct spi_flash *flash = dev_get_uclass_priv(dev); -#if defined(CONFIG_SPI_FLASH_SST) - if (flash->flags & SNOR_F_SST_WR) { - if (flash->spi->mode & SPI_TX_BYTE) - return sst_write_bp(flash, offset, len, buf); - else - return sst_write_wp(flash, offset, len, buf); - } -#endif - return spi_flash_cmd_write_ops(flash, offset, len, buf); } diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 4f269eacc591..7f5341a87c07 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -364,6 +364,14 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) return spi_flash_erase_alg(flash, offset, len, spi_flash_erase_impl); } +#if defined(CONFIG_SPI_FLASH_SST) +static int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, + const void *buf, spi_flash_write_fn write_fn); + +static int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, + const void *buf, spi_flash_write_fn write_fn); +#endif + int spi_flash_write_alg(struct spi_flash *flash, u32 offset, size_t len, const void *buf, spi_flash_write_fn write_fn) { @@ -373,6 +381,15 @@ int spi_flash_write_alg(struct spi_flash *flash, u32 offset, size_t len, size_t chunk_len, actual; int ret = -1; +#if defined(CONFIG_SPI_FLASH_SST) + if (flash->flags & SNOR_F_SST_WR) { + if (spi->mode & SPI_TX_BYTE) + return sst_write_bp(flash, offset, len, buf, write_fn); + else + return sst_write_wp(flash, offset, len, buf, write_fn); + } +#endif + page_size = flash->page_size; ret = spi_claim_bus(spi); @@ -448,6 +465,10 @@ static int spi_flash_write_impl(struct spi_flash *flash, u32 offset, cmd[0] = flash->write_cmd; spi_flash_addr(offset, cmd); +#ifdef CONFIG_SPI_FLASH_SST + if (flash->flags & SNOR_F_SST_WR_2ND) + cmdsz = 1; +#endif return spi_flash_cmd_write(spi, cmd, cmdsz, buf, len); } @@ -567,38 +588,33 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, } #ifdef CONFIG_SPI_FLASH_SST -static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) +static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf, + spi_flash_write_fn write_fn) { struct spi_slave *spi = flash->spi; int ret; - u8 cmd[4] = { - CMD_SST_BP, - offset >> 16, - offset >> 8, - offset, - }; + flash->write_cmd = CMD_SST_BP; debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", - spi_w8r8(spi, CMD_READ_STATUS), buf, cmd[0], offset); + spi_w8r8(spi, CMD_READ_STATUS), buf, flash->write_cmd, offset); ret = spi_flash_cmd_write_enable(flash); if (ret) return ret; - ret = spi_flash_cmd_write(spi, cmd, sizeof(cmd), buf, 1); + ret = write_fn(flash, offset, 1, buf); if (ret) return ret; return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); } -int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, - const void *buf) +static int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, + const void *buf, spi_flash_write_fn write_fn) { struct spi_slave *spi = flash->spi; - size_t actual, cmd_len; + size_t actual; int ret; - u8 cmd[4]; ret = spi_claim_bus(spi); if (ret) { @@ -606,10 +622,12 @@ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, return ret; } + flash->flags &= ~SNOR_F_SST_WR_2ND; + /* If the data is not word aligned, write out leading single byte */ actual = offset % 2; if (actual) { - ret = sst_byte_write(flash, offset, buf); + ret = sst_byte_write(flash, offset, buf, write_fn); if (ret) goto done; } @@ -619,19 +637,14 @@ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, if (ret) goto done; - cmd_len = 4; - cmd[0] = CMD_SST_AAI_WP; - cmd[1] = offset >> 16; - cmd[2] = offset >> 8; - cmd[3] = offset; + flash->write_cmd = CMD_SST_AAI_WP; for (; actual < len - 1; actual += 2) { debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", spi_w8r8(spi, CMD_READ_STATUS), buf + actual, - cmd[0], offset); + flash->write_cmd, offset); - ret = spi_flash_cmd_write(spi, cmd, cmd_len, - buf + actual, 2); + ret = write_fn(flash, offset, 2, buf + actual); if (ret) { debug("SF: sst word program failed\n"); break; @@ -641,16 +654,17 @@ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, if (ret) break; - cmd_len = 1; + flash->flags |= SNOR_F_SST_WR_2ND; offset += 2; } + flash->flags &= ~SNOR_F_SST_WR_2ND; if (!ret) ret = spi_flash_cmd_write_disable(flash); /* If there is a single trailing byte, write it out */ if (!ret && actual != len) - ret = sst_byte_write(flash, offset, buf + actual); + ret = sst_byte_write(flash, offset, buf + actual, write_fn); done: debug("SF: sst: program %s %zu bytes @ 0x%zx\n", @@ -660,8 +674,8 @@ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, return ret; } -int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, - const void *buf) +static int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, + const void *buf, spi_flash_write_fn write_fn) { struct spi_slave *spi = flash->spi; size_t actual; @@ -674,7 +688,7 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, } for (actual = 0; actual < len; actual++) { - ret = sst_byte_write(flash, offset, buf + actual); + ret = sst_byte_write(flash, offset, buf + actual, write_fn); if (ret) { debug("SF: sst byte program failed\n"); break; @@ -993,14 +1007,6 @@ int spi_flash_scan(struct spi_flash *flash) flash->read_reg = spi_flash_cmd_read_reg_ops; flash->write_reg = spi_flash_cmd_write_reg_ops; flash->write = spi_flash_cmd_write_ops; -#if defined(CONFIG_SPI_FLASH_SST) - if (flash->flags & SNOR_F_SST_WR) { - if (spi->mode & SPI_TX_BYTE) - flash->write = sst_write_bp; - else - flash->write = sst_write_wp; - } -#endif flash->erase = spi_flash_cmd_erase_ops; flash->read = spi_flash_cmd_read_ops; #endif