All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Packham <judge.packham@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC PATCH v2] sf: support chips using 4-byte addressing
Date: Wed, 19 Oct 2016 21:36:05 +1300	[thread overview]
Message-ID: <20161019083605.17612-1-judge.packham@gmail.com> (raw)
In-Reply-To: <20161017005145.21956-2-judge.packham@gmail.com>

SPI chips with >16MB capacity use 4-byte addressing to allow
accessing beyond 16MB. When the size of the SPI flash exceeds 16MB
switch to using 4 byte addressing.

Signed-off-by: Chris Packham <judge.packham@gmail.com>

---

Changes in v2:
- automatically detect when 4 byte addressing is needed. This is similar
  to how the linux kernel does the same detection

 drivers/mtd/spi/sf_internal.h |  4 ++--
 drivers/mtd/spi/spi_flash.c   | 32 ++++++++++++++++++++++----------
 include/spi_flash.h           |  2 ++
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index cde4cfbf2e32..db4532849145 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -25,8 +25,8 @@ enum spi_nor_option_flags {
 	SNOR_F_USE_FSR		= BIT(1),
 };
 
-#define SPI_FLASH_3B_ADDR_LEN		3
-#define SPI_FLASH_CMD_LEN		(1 + SPI_FLASH_3B_ADDR_LEN)
+#define SPI_FLASE_MAX_ADDR_WIDTH	4
+#define SPI_FLASH_CMD_LEN		(1 + SPI_FLASE_MAX_ADDR_WIDTH)
 #define SPI_FLASH_16MB_BOUN		0x1000000
 
 /* CFI Manufacture ID's */
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 7f6e9ae23ea8..a3efaa129231 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -22,12 +22,19 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static void spi_flash_addr(u32 addr, u8 *cmd)
+static void spi_flash_addr(u32 addr, u8 *cmd, u8 addr_width)
 {
 	/* cmd[0] is actual command */
-	cmd[1] = addr >> 16;
-	cmd[2] = addr >> 8;
-	cmd[3] = addr >> 0;
+	if (addr_width == 4) {
+		cmd[1] = addr >> 24;
+		cmd[2] = addr >> 16;
+		cmd[3] = addr >> 8;
+		cmd[4] = addr;
+	} else {
+		cmd[1] = addr >> 16;
+		cmd[2] = addr >> 8;
+		cmd[3] = addr >> 0;
+	}
 }
 
 static int read_sr(struct spi_flash *flash, u8 *rs)
@@ -357,12 +364,13 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
 		if (ret < 0)
 			return ret;
 #endif
-		spi_flash_addr(erase_addr, cmd);
+		spi_flash_addr(erase_addr, cmd, flash->addr_width);
 
 		debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
 		      cmd[2], cmd[3], erase_addr);
 
-		ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
+		ret = spi_flash_write_common(flash, cmd, flash->addr_width + 1,
+					     NULL, 0);
 		if (ret < 0) {
 			debug("SF: erase failed\n");
 			break;
@@ -415,12 +423,12 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
 			chunk_len = min(chunk_len,
 					(size_t)spi->max_write_size);
 
-		spi_flash_addr(write_addr, cmd);
+		spi_flash_addr(write_addr, cmd, flash->addr_width);
 
 		debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
 		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
 
-		ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
+		ret = spi_flash_write_common(flash, cmd, flash->addr_width + 1,
 					buf + actual, chunk_len);
 		if (ret < 0) {
 			debug("SF: write failed\n");
@@ -492,7 +500,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		return 0;
 	}
 
-	cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
+	cmdsz = flash->addr_width + 1 + flash->dummy_byte;
 	cmd = calloc(1, cmdsz);
 	if (!cmd) {
 		debug("SF: Failed to allocate cmd\n");
@@ -520,7 +528,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		else
 			read_len = remain_len;
 
-		spi_flash_addr(read_addr, cmd);
+		spi_flash_addr(read_addr, cmd, flash->addr_width);
 
 		ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
 		if (ret < 0) {
@@ -1154,6 +1162,10 @@ int spi_flash_scan(struct spi_flash *flash)
 	if (flash->dual_flash & SF_DUAL_STACKED_FLASH)
 		flash->size <<= 1;
 #endif
+	if (flash->size > SPI_FLASH_16MB_BOUN)
+		flash->addr_width = 4;
+	else
+		flash->addr_width = 3;
 
 #ifdef CONFIG_SPI_FLASH_USE_4K_SECTORS
 	/* Compute erase sector and command */
diff --git a/include/spi_flash.h b/include/spi_flash.h
index be2fe3f84cb9..c65bf22aee8b 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -39,6 +39,7 @@ struct spi_slave;
  * @flags:		Indication of spi flash flags
  * @size:		Total flash size
  * @page_size:		Write (page) size
+ * @addr_width:		number of address bytes
  * @sector_size:	Sector size
  * @erase_size:		Erase size
  * @bank_read_cmd:	Bank read cmd
@@ -72,6 +73,7 @@ struct spi_flash {
 
 	u32 size;
 	u32 page_size;
+	u8 addr_width;
 	u32 sector_size;
 	u32 erase_size;
 #ifdef CONFIG_SPI_FLASH_BAR
-- 
2.10.0.479.g7c56b16

  reply	other threads:[~2016-10-19  8:36 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-17  0:51 [U-Boot] [RFC PATCH 0/1] 4-byte SPI flash addressing Chris Packham
2016-10-17  0:51 ` [U-Boot] [RFC PATCH 1/1] sf: support chips using 4-byte addressing Chris Packham
2016-10-19  8:36   ` Chris Packham [this message]
2016-10-19 11:50     ` [U-Boot] [RFC PATCH v2] " Siva Durga Prasad Paladugu
2016-10-20  4:35       ` Vignesh R

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161019083605.17612-1-judge.packham@gmail.com \
    --to=judge.packham@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.