openwrt/target/linux/layerscape/patches-4.4/1110-mtd-spi-nor-fsl-quad-add-flash-S25FS-extra-support.patch
Yutang Jiang 15a14cf166 layerscape: add 64b/32b target for ls1012ardb device
The QorIQ LS1012A processor, optimized for battery-backed or
USB-powered, integrates a single ARM Cortex-A53 core with a hardware
packet forwarding engine and high-speed interfaces to deliver
line-rate networking performance.
QorIQ LS1012A Reference Design System (LS1012ARDB) is a high-performance
development platform, with a complete debugging environment.
The LS1012ARDB board supports the QorIQ LS1012A processor and is
optimized to support the high-bandwidth DDR3L memory and
a full complement of high-speed SerDes ports.

LEDE/OPENWRT will auto strip executable program file while make. So we
need select CONFIG_NO_STRIP=y while make menuconfig to avoid the ppfe network
fiemware be destroyed, then run make to build ls1012ardb firmware.

The fsl-quadspi flash with jffs2 fs is unstable and arise some failed message.
This issue have noticed the IP owner for investigate, hope he can solve it
earlier. So the ls1012ardb now also provide a xx-firmware.ext4.bin as default
firmware, and the uboot bootcmd will run wrtboot_ext4rfs for "rootfstype=ext4"
bootargs.

Signed-off-by: Yutang Jiang <yutang.jiang@nxp.com>
2016-10-31 17:00:10 +01:00

158 lines
5.4 KiB
Diff

From 034dd6241b55ab2256eecb845e941fa9b45da38e Mon Sep 17 00:00:00 2001
From: Yunhui Cui <yunhui.cui@nxp.com>
Date: Thu, 28 Apr 2016 17:03:57 +0800
Subject: [PATCH 110/113] mtd: spi-nor: fsl-quad: add flash S25FS extra
support
[context adjustment]
not apply changes of arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
There are some boards have the same QSPI controller but have
different vendor flash, So, the controller can use the same
compatible and share the driver, just for a different flash to do
the appropriate adaptation. Based on this, we need add the vendor
field in spi-nor, Because we will use the field to distribute
corresponding LUT for different flash operations.
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
---
drivers/mtd/spi-nor/fsl-quadspi.c | 47 ++++++++++++++++++++++++++++++-------
drivers/mtd/spi-nor/spi-nor.c | 5 ++--
include/linux/mtd/spi-nor.h | 1 +
3 files changed, 42 insertions(+), 11 deletions(-)
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -213,6 +213,9 @@
#define QUADSPI_MIN_IOMAP SZ_4M
+#define FLASH_VENDOR_SPANSION_FS "s25fs"
+#define SPANSION_S25FS_FAMILY (1 << 1)
+
enum fsl_qspi_devtype {
FSL_QUADSPI_VYBRID,
FSL_QUADSPI_IMX6SX,
@@ -329,6 +332,18 @@ static inline int has_added_amba_base_in
return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
}
+static u32 fsl_get_nor_vendor(struct spi_nor *nor)
+{
+ u32 vendor_id;
+
+ if (nor->vendor) {
+ if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS,
+ sizeof(FLASH_VENDOR_SPANSION_FS) - 1))
+ vendor_id = SPANSION_S25FS_FAMILY;
+ }
+ return vendor_id;
+}
+
/*
* R/W functions for big- or little-endian registers:
* The qSPI controller's endian is independent of the CPU core's endian.
@@ -394,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl
int rxfifo = q->devtype_data->rxfifo;
u32 lut_base;
int i;
- const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
+ u32 vendor;
struct spi_nor *nor = &q->nor[0];
u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
u8 read_op = nor->read_opcode;
u8 read_dm = nor->read_dummy;
+ vendor = fsl_get_nor_vendor(nor);
+
fsl_qspi_unlock_lut(q);
/* Clear all the LUT table */
@@ -418,12 +435,25 @@ static void fsl_qspi_init_lut(struct fsl
LUT1(FSL_READ, PAD1, rxfifo),
base + QUADSPI_LUT(lut_base + 1));
} else if (nor->flash_read == SPI_NOR_QUAD) {
- qspi_writel(q, LUT0(CMD, PAD1, read_op) |
- LUT1(ADDR, PAD1, addrlen),
- base + QUADSPI_LUT(lut_base));
- qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
- LUT1(FSL_READ, PAD4, rxfifo),
- base + QUADSPI_LUT(lut_base + 1));
+ if (q->nor_size == 0x4000000) {
+ read_op = 0xEC;
+ qspi_writel(q,
+ LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen),
+ base + QUADSPI_LUT(lut_base));
+ qspi_writel(q,
+ LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm),
+ base + QUADSPI_LUT(lut_base + 1));
+ qspi_writel(q,
+ LUT0(FSL_READ, PAD4, rxfifo),
+ base + QUADSPI_LUT(lut_base + 2));
+ } else {
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
+ LUT1(ADDR, PAD1, addrlen),
+ base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
+ LUT1(FSL_READ, PAD4, rxfifo),
+ base + QUADSPI_LUT(lut_base + 1));
+ }
} else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
/* read mode : 1-4-4, such as Spansion s25fl128s. */
qspi_writel(q, LUT0(CMD, PAD1, read_op)
@@ -510,7 +540,8 @@ static void fsl_qspi_init_lut(struct fsl
* use the same value 0x65. But it indicates different meaning.
*/
lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
- if (devtype_data->devtype == FSL_QUADSPI_LS2080A) {
+
+ if (vendor == SPANSION_S25FS_FAMILY) {
/*
* Read any device register.
* Used for Spansion S25FS-S family flash only.
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -796,7 +796,6 @@ static const struct flash_info spi_nor_i
{ "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
- { "s25fs512s", INFO6(0x010220, 0x4d0081, 128 * 1024, 512, 0)},
{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
{ "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
@@ -963,11 +962,9 @@ static int spansion_s25fs_disable_4kb_er
ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
if (ret)
return ret;
-/*
if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
return -EPERM;
-*/
return 0;
}
@@ -1334,6 +1331,8 @@ int spi_nor_scan(struct spi_nor *nor, co
if (!mtd->name)
mtd->name = dev_name(dev);
+ if (info->name)
+ nor->vendor = info->name;
mtd->priv = nor;
mtd->type = MTD_NORFLASH;
mtd->writesize = 1;
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -172,6 +172,7 @@ struct spi_nor {
bool sst_write_second;
u32 flags;
u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
+ char *vendor;
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);