1 From 034dd6241b55ab2256eecb845e941fa9b45da38e Mon Sep 17 00:00:00 2001
2 From: Yunhui Cui <yunhui.cui@nxp.com>
3 Date: Thu, 28 Apr 2016 17:03:57 +0800
4 Subject: [PATCH 110/113] mtd: spi-nor: fsl-quad: add flash S25FS extra
8 not apply changes of arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
10 There are some boards have the same QSPI controller but have
11 different vendor flash, So, the controller can use the same
12 compatible and share the driver, just for a different flash to do
13 the appropriate adaptation. Based on this, we need add the vendor
14 field in spi-nor, Because we will use the field to distribute
15 corresponding LUT for different flash operations.
17 Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
18 Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
19 Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
20 Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
22 drivers/mtd/spi-nor/fsl-quadspi.c | 47 ++++++++++++++++++++++++++++++-------
23 drivers/mtd/spi-nor/spi-nor.c | 5 ++--
24 include/linux/mtd/spi-nor.h | 1 +
25 3 files changed, 42 insertions(+), 11 deletions(-)
27 --- a/drivers/mtd/spi-nor/fsl-quadspi.c
28 +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
31 #define QUADSPI_MIN_IOMAP SZ_4M
33 +#define FLASH_VENDOR_SPANSION_FS "s25fs"
34 +#define SPANSION_S25FS_FAMILY (1 << 1)
36 enum fsl_qspi_devtype {
39 @@ -329,6 +332,18 @@ static inline int has_added_amba_base_in
40 return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
43 +static u32 fsl_get_nor_vendor(struct spi_nor *nor)
48 + if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS,
49 + sizeof(FLASH_VENDOR_SPANSION_FS) - 1))
50 + vendor_id = SPANSION_S25FS_FAMILY;
56 * R/W functions for big- or little-endian registers:
57 * The qSPI controller's endian is independent of the CPU core's endian.
58 @@ -394,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl
59 int rxfifo = q->devtype_data->rxfifo;
62 - const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
65 struct spi_nor *nor = &q->nor[0];
66 u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
67 u8 read_op = nor->read_opcode;
68 u8 read_dm = nor->read_dummy;
70 + vendor = fsl_get_nor_vendor(nor);
72 fsl_qspi_unlock_lut(q);
74 /* Clear all the LUT table */
75 @@ -418,12 +435,25 @@ static void fsl_qspi_init_lut(struct fsl
76 LUT1(FSL_READ, PAD1, rxfifo),
77 base + QUADSPI_LUT(lut_base + 1));
78 } else if (nor->flash_read == SPI_NOR_QUAD) {
79 - qspi_writel(q, LUT0(CMD, PAD1, read_op) |
80 - LUT1(ADDR, PAD1, addrlen),
81 - base + QUADSPI_LUT(lut_base));
82 - qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
83 - LUT1(FSL_READ, PAD4, rxfifo),
84 - base + QUADSPI_LUT(lut_base + 1));
85 + if (q->nor_size == 0x4000000) {
88 + LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen),
89 + base + QUADSPI_LUT(lut_base));
91 + LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm),
92 + base + QUADSPI_LUT(lut_base + 1));
94 + LUT0(FSL_READ, PAD4, rxfifo),
95 + base + QUADSPI_LUT(lut_base + 2));
97 + qspi_writel(q, LUT0(CMD, PAD1, read_op) |
98 + LUT1(ADDR, PAD1, addrlen),
99 + base + QUADSPI_LUT(lut_base));
100 + qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
101 + LUT1(FSL_READ, PAD4, rxfifo),
102 + base + QUADSPI_LUT(lut_base + 1));
104 } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
105 /* read mode : 1-4-4, such as Spansion s25fl128s. */
106 qspi_writel(q, LUT0(CMD, PAD1, read_op)
107 @@ -510,7 +540,8 @@ static void fsl_qspi_init_lut(struct fsl
108 * use the same value 0x65. But it indicates different meaning.
110 lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
111 - if (devtype_data->devtype == FSL_QUADSPI_LS2080A) {
113 + if (vendor == SPANSION_S25FS_FAMILY) {
115 * Read any device register.
116 * Used for Spansion S25FS-S family flash only.
117 --- a/drivers/mtd/spi-nor/spi-nor.c
118 +++ b/drivers/mtd/spi-nor/spi-nor.c
119 @@ -797,7 +797,6 @@ static const struct flash_info spi_nor_i
120 { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
121 { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
122 { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
123 - { "s25fs512s", INFO6(0x010220, 0x4d0081, 128 * 1024, 512, 0)},
124 { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
125 { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
126 { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
127 @@ -964,11 +963,9 @@ static int spansion_s25fs_disable_4kb_er
128 ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
132 if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
139 @@ -1335,6 +1332,8 @@ int spi_nor_scan(struct spi_nor *nor, co
142 mtd->name = dev_name(dev);
144 + nor->vendor = info->name;
146 mtd->type = MTD_NORFLASH;
148 --- a/include/linux/mtd/spi-nor.h
149 +++ b/include/linux/mtd/spi-nor.h
150 @@ -172,6 +172,7 @@ struct spi_nor {
151 bool sst_write_second;
153 u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
156 int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
157 void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);