[U-Boot] [PATCH 10/18] sf: move support of SST flash into generic spi_flash_write_alg()

Cyrille Pitchen cyrille.pitchen at atmel.com
Tue Mar 15 19:12:32 CET 2016


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 <cyrille.pitchen at atmel.com>
---
 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
-- 
1.8.2.2



More information about the U-Boot mailing list