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
next prev parent 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.