diff options
Diffstat (limited to 'package/boot/uboot-layerscape/patches/0031-mtd-sf-add-exceed-flash-16MB-support-for-qspi.patch')
-rw-r--r-- | package/boot/uboot-layerscape/patches/0031-mtd-sf-add-exceed-flash-16MB-support-for-qspi.patch | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/package/boot/uboot-layerscape/patches/0031-mtd-sf-add-exceed-flash-16MB-support-for-qspi.patch b/package/boot/uboot-layerscape/patches/0031-mtd-sf-add-exceed-flash-16MB-support-for-qspi.patch new file mode 100644 index 0000000000..aa39699f63 --- /dev/null +++ b/package/boot/uboot-layerscape/patches/0031-mtd-sf-add-exceed-flash-16MB-support-for-qspi.patch @@ -0,0 +1,308 @@ +From 6cfe5c5e7f6a4b3d46f65967fe10820ee2e3d2fa Mon Sep 17 00:00:00 2001 +From: Yunhui Cui <yunhui.cui@nxp.com> +Date: Fri, 13 May 2016 16:30:33 +0800 +Subject: [PATCH 31/93] mtd: sf: add exceed flash 16MB support for qspi + +spi/spi_flash.c: The flash S25FS512S cannot legacy commands +such as Bank Address Related Command, So we need add the exceed +16MB suuport. So we extend the cmd[] size to support 32-bit address, +what's more, as to spi/fsl_qspi.c need to a flag to pionts the address +mask, So add the magic num '0xaa' into cmd[]. + +Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com> +--- + arch/arm/dts/fsl-ls1012a.dtsi | 2 +- + drivers/mtd/spi/sf_internal.h | 7 ++++ + drivers/mtd/spi/spi_flash.c | 73 ++++++++++++++++++++++++++++++-------- + drivers/spi/fsl_qspi.c | 30 ++++++++++++++-- + include/configs/ls1012a_common.h | 3 +- + 5 files changed, 95 insertions(+), 20 deletions(-) + +diff --git a/arch/arm/dts/fsl-ls1012a.dtsi b/arch/arm/dts/fsl-ls1012a.dtsi +index 87a287a..2549c91 100644 +--- a/arch/arm/dts/fsl-ls1012a.dtsi ++++ b/arch/arm/dts/fsl-ls1012a.dtsi +@@ -108,7 +108,7 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x1550000 0x0 0x10000>, +- <0x0 0x40000000 0x0 0x4000000>; ++ <0x0 0x40000000 0x0 0x8000000>; + reg-names = "QuadSPI", "QuadSPI-memory"; + num-cs = <2>; + big-endian; +diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h +index c778b60..3c38425 100644 +--- a/drivers/mtd/spi/sf_internal.h ++++ b/drivers/mtd/spi/sf_internal.h +@@ -57,6 +57,13 @@ enum spi_nor_option_flags { + #define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN) + #define SPI_FLASH_16MB_BOUN 0x1000000 + ++#define SPI_FLASH_ADDR_MAGIC 0xaa ++#define SPI_FLASH_ADDR_MAGIC_LEN 1 ++#define SPI_FLASH_4B_ADDR_LEN 4 ++#define SPI_FLASH_CMD_LEN_EXT (1 + SPI_FLASH_4B_ADDR_LEN + \ ++ SPI_FLASH_ADDR_MAGIC_LEN) ++#define SPI_FLASH_64MB_BOUN 0x4000000 ++ + /* CFI Manufacture ID's */ + #define SPI_FLASH_CFI_MFR_SPANSION 0x01 + #define SPI_FLASH_CFI_MFR_STMICRO 0x20 +diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c +index 97e53c7..9d61ac0 100644 +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -21,12 +21,20 @@ + + DECLARE_GLOBAL_DATA_PTR; + +-static void spi_flash_addr(u32 addr, u8 *cmd) ++static void spi_flash_addr(u32 addr, u8 *cmd, u32 offset_ext) + { +- /* cmd[0] is actual command */ +- cmd[1] = addr >> 16; +- cmd[2] = addr >> 8; +- cmd[3] = addr >> 0; ++ if (offset_ext >= SPI_FLASH_16MB_BOUN) { ++ /* cmd[0] is actual command */ ++ cmd[1] = addr >> 24; ++ cmd[2] = addr >> 16; ++ cmd[3] = addr >> 8; ++ cmd[4] = addr >> 0; ++ cmd[5] = SPI_FLASH_ADDR_MAGIC; ++ } else { ++ cmd[1] = addr >> 16; ++ cmd[2] = addr >> 8; ++ cmd[3] = addr >> 0; ++ } + } + + /* Read commands array */ +@@ -302,9 +310,11 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, + int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) + { + u32 erase_size, erase_addr; +- u8 cmd[SPI_FLASH_CMD_LEN]; ++ u8 *cmd, cmdsz; + int ret = -1; ++ u32 offset_ext; + ++ offset_ext = offset; + erase_size = flash->erase_size; + if (offset % erase_size || len % erase_size) { + debug("SF: Erase offset/length not multiple of erase size\n"); +@@ -319,7 +329,18 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) + } + } + ++ if (offset > SPI_FLASH_16MB_BOUN) ++ cmdsz = SPI_FLASH_CMD_LEN_EXT + flash->dummy_byte; ++ else ++ cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; ++ cmd = calloc(1, cmdsz); ++ if (!cmd) { ++ debug("SF: Failed to allocate cmd\n"); ++ return -ENOMEM; ++ } ++ memset(cmd, 0x0, cmdsz); + cmd[0] = flash->erase_cmd; ++ + while (len) { + erase_addr = offset; + +@@ -332,7 +353,7 @@ 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, offset_ext); + + debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], + cmd[2], cmd[3], erase_addr); +@@ -347,6 +368,7 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) + len -= erase_size; + } + ++ free(cmd); + return ret; + } + +@@ -356,9 +378,11 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, + unsigned long byte_addr, page_size; + u32 write_addr; + size_t chunk_len, actual; +- u8 cmd[SPI_FLASH_CMD_LEN]; ++ u8 *cmd, cmdsz; + int ret = -1; ++ u32 offset_ext; + ++ offset_ext = offset; + page_size = flash->page_size; + + if (flash->flash_is_locked) { +@@ -369,6 +393,16 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, + } + } + ++ if (offset > SPI_FLASH_16MB_BOUN) ++ cmdsz = SPI_FLASH_CMD_LEN_EXT + flash->dummy_byte; ++ else ++ cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; ++ cmd = calloc(1, cmdsz); ++ if (!cmd) { ++ debug("SF: Failed to allocate cmd\n"); ++ return -ENOMEM; ++ } ++ memset(cmd, 0x0, cmdsz); + cmd[0] = flash->write_cmd; + for (actual = 0; actual < len; actual += chunk_len) { + write_addr = offset; +@@ -389,7 +423,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, + chunk_len = min(chunk_len, + (size_t)flash->spi->max_write_size); + +- spi_flash_addr(write_addr, cmd); ++ spi_flash_addr(write_addr, cmd, offset_ext); + + 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); +@@ -404,6 +438,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, + offset += chunk_len; + } + ++ free(cmd); + return ret; + } + +@@ -442,6 +477,9 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, + u32 remain_len, read_len, read_addr; + int bank_sel = 0; + int ret = -1; ++ u32 offset_ext; ++ ++ offset_ext = offset; + + /* Handle memory-mapped SPI */ + if (flash->memory_map) { +@@ -456,15 +494,18 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, + spi_release_bus(flash->spi); + return 0; + } +- +- cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; ++ if (offset > SPI_FLASH_16MB_BOUN) ++ cmdsz = SPI_FLASH_CMD_LEN_EXT + flash->dummy_byte; ++ else ++ cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; + cmd = calloc(1, cmdsz); + if (!cmd) { + debug("SF: Failed to allocate cmd\n"); + return -ENOMEM; + } +- ++ memset(cmd, 0x0, cmdsz); + cmd[0] = flash->read_cmd; ++ + while (len) { + read_addr = offset; + +@@ -478,14 +519,18 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, + return ret; + bank_sel = flash->bank_curr; + #endif +- remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) * ++ if (offset_ext >= SPI_FLASH_16MB_BOUN) { ++ remain_len = flash->size - offset; ++ } else { ++ remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) * + (bank_sel + 1)) - offset; ++ } + if (len < remain_len) + read_len = len; + else + read_len = remain_len; + +- spi_flash_addr(read_addr, cmd); ++ spi_flash_addr(read_addr, cmd, offset_ext); + + ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len); + if (ret < 0) { +diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c +index 2b20038..09759fa 100644 +--- a/drivers/spi/fsl_qspi.c ++++ b/drivers/spi/fsl_qspi.c +@@ -26,6 +26,9 @@ DECLARE_GLOBAL_DATA_PTR; + #endif + + #define OFFSET_BITS_MASK GENMASK(23, 0) ++/* the qspi contrller memmap space ,instead of flash space */ ++#define OFFSET_BITS_MASK_QSPI_SPACE GENMASK(27, 0) ++#define SPI_FLASH_ADDR_EXT_MAGIC 0xaa + + #define FLASH_STATUS_WEL 0x02 + +@@ -757,6 +760,13 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, + u32 bytes = DIV_ROUND_UP(bitlen, 8); + static u32 wr_sfaddr; + u32 txbuf; ++ u8 offset_ext = 0; ++ u32 flash_offset; ++ ++ if (((u8 *)dout)[5] == SPI_FLASH_ADDR_EXT_MAGIC) { ++ offset_ext = 1; ++ memcpy(&flash_offset, dout + 1, 4); ++ } + + if (dout) { + if (flags & SPI_XFER_BEGIN) { +@@ -772,14 +782,28 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, + + if (priv->cur_seqid == QSPI_CMD_FAST_READ || + priv->cur_seqid == QSPI_CMD_RDAR) { +- priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; ++ if (offset_ext) ++ priv->sf_addr = swab32(flash_offset) & ++ OFFSET_BITS_MASK_QSPI_SPACE; ++ else ++ priv->sf_addr = swab32(txbuf) & ++ OFFSET_BITS_MASK; + } else if ((priv->cur_seqid == QSPI_CMD_SE) || + (priv->cur_seqid == QSPI_CMD_BE_4K)) { +- priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; ++ if (offset_ext) ++ priv->sf_addr = swab32(flash_offset) & ++ OFFSET_BITS_MASK_QSPI_SPACE; ++ else ++ priv->sf_addr = swab32(txbuf) & ++ OFFSET_BITS_MASK; + qspi_op_erase(priv); + } else if (priv->cur_seqid == QSPI_CMD_PP || + priv->cur_seqid == QSPI_CMD_WRAR) { +- wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK; ++ if (offset_ext) ++ wr_sfaddr = swab32(flash_offset) & ++ OFFSET_BITS_MASK_QSPI_SPACE; ++ else ++ wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK; + } else if ((priv->cur_seqid == QSPI_CMD_BRWR) || + (priv->cur_seqid == QSPI_CMD_WREAR)) { + #ifdef CONFIG_SPI_FLASH_BAR +diff --git a/include/configs/ls1012a_common.h b/include/configs/ls1012a_common.h +index 3fd360a..150444d 100644 +--- a/include/configs/ls1012a_common.h ++++ b/include/configs/ls1012a_common.h +@@ -63,9 +63,8 @@ + #define QSPI0_AMBA_BASE 0x40000000 + #define CONFIG_SPI_FLASH_SPANSION + #define CONFIG_DM_SPI_FLASH +-#define CONFIG_SPI_FLASH_BAR + +-#define FSL_QSPI_FLASH_SIZE (1 << 24) ++#define FSL_QSPI_FLASH_SIZE (1 << 26) + #define FSL_QSPI_FLASH_NUM 2 + + /* +-- +1.7.9.5 + |