layerscape: add 64b/32b target for ls1012ardb device
[openwrt/staging/yousong.git] / target / linux / layerscape / patches-4.4 / 1110-mtd-spi-nor-fsl-quad-add-flash-S25FS-extra-support.patch
diff --git a/target/linux/layerscape/patches-4.4/1110-mtd-spi-nor-fsl-quad-add-flash-S25FS-extra-support.patch b/target/linux/layerscape/patches-4.4/1110-mtd-spi-nor-fsl-quad-add-flash-S25FS-extra-support.patch
new file mode 100644 (file)
index 0000000..2b21b11
--- /dev/null
@@ -0,0 +1,157 @@
+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);