layerscape: add 64b/32b target for ls1012ardb device
[openwrt/openwrt.git] / package / boot / uboot-layerscape / patches / 0031-mtd-sf-add-exceed-flash-16MB-support-for-qspi.patch
1 From 6cfe5c5e7f6a4b3d46f65967fe10820ee2e3d2fa Mon Sep 17 00:00:00 2001
2 From: Yunhui Cui <yunhui.cui@nxp.com>
3 Date: Fri, 13 May 2016 16:30:33 +0800
4 Subject: [PATCH 31/93] mtd: sf: add exceed flash 16MB support for qspi
5
6 spi/spi_flash.c: The flash S25FS512S cannot legacy commands
7 such as Bank Address Related Command, So we need add the exceed
8 16MB suuport. So we extend the cmd[] size to support 32-bit address,
9 what's more, as to spi/fsl_qspi.c need to a flag to pionts the address
10 mask, So add the magic num '0xaa' into cmd[].
11
12 Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
13 ---
14 arch/arm/dts/fsl-ls1012a.dtsi | 2 +-
15 drivers/mtd/spi/sf_internal.h | 7 ++++
16 drivers/mtd/spi/spi_flash.c | 73 ++++++++++++++++++++++++++++++--------
17 drivers/spi/fsl_qspi.c | 30 ++++++++++++++--
18 include/configs/ls1012a_common.h | 3 +-
19 5 files changed, 95 insertions(+), 20 deletions(-)
20
21 diff --git a/arch/arm/dts/fsl-ls1012a.dtsi b/arch/arm/dts/fsl-ls1012a.dtsi
22 index 87a287a..2549c91 100644
23 --- a/arch/arm/dts/fsl-ls1012a.dtsi
24 +++ b/arch/arm/dts/fsl-ls1012a.dtsi
25 @@ -108,7 +108,7 @@
26 #address-cells = <1>;
27 #size-cells = <0>;
28 reg = <0x0 0x1550000 0x0 0x10000>,
29 - <0x0 0x40000000 0x0 0x4000000>;
30 + <0x0 0x40000000 0x0 0x8000000>;
31 reg-names = "QuadSPI", "QuadSPI-memory";
32 num-cs = <2>;
33 big-endian;
34 diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
35 index c778b60..3c38425 100644
36 --- a/drivers/mtd/spi/sf_internal.h
37 +++ b/drivers/mtd/spi/sf_internal.h
38 @@ -57,6 +57,13 @@ enum spi_nor_option_flags {
39 #define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN)
40 #define SPI_FLASH_16MB_BOUN 0x1000000
41
42 +#define SPI_FLASH_ADDR_MAGIC 0xaa
43 +#define SPI_FLASH_ADDR_MAGIC_LEN 1
44 +#define SPI_FLASH_4B_ADDR_LEN 4
45 +#define SPI_FLASH_CMD_LEN_EXT (1 + SPI_FLASH_4B_ADDR_LEN + \
46 + SPI_FLASH_ADDR_MAGIC_LEN)
47 +#define SPI_FLASH_64MB_BOUN 0x4000000
48 +
49 /* CFI Manufacture ID's */
50 #define SPI_FLASH_CFI_MFR_SPANSION 0x01
51 #define SPI_FLASH_CFI_MFR_STMICRO 0x20
52 diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
53 index 97e53c7..9d61ac0 100644
54 --- a/drivers/mtd/spi/spi_flash.c
55 +++ b/drivers/mtd/spi/spi_flash.c
56 @@ -21,12 +21,20 @@
57
58 DECLARE_GLOBAL_DATA_PTR;
59
60 -static void spi_flash_addr(u32 addr, u8 *cmd)
61 +static void spi_flash_addr(u32 addr, u8 *cmd, u32 offset_ext)
62 {
63 - /* cmd[0] is actual command */
64 - cmd[1] = addr >> 16;
65 - cmd[2] = addr >> 8;
66 - cmd[3] = addr >> 0;
67 + if (offset_ext >= SPI_FLASH_16MB_BOUN) {
68 + /* cmd[0] is actual command */
69 + cmd[1] = addr >> 24;
70 + cmd[2] = addr >> 16;
71 + cmd[3] = addr >> 8;
72 + cmd[4] = addr >> 0;
73 + cmd[5] = SPI_FLASH_ADDR_MAGIC;
74 + } else {
75 + cmd[1] = addr >> 16;
76 + cmd[2] = addr >> 8;
77 + cmd[3] = addr >> 0;
78 + }
79 }
80
81 /* Read commands array */
82 @@ -302,9 +310,11 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
83 int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
84 {
85 u32 erase_size, erase_addr;
86 - u8 cmd[SPI_FLASH_CMD_LEN];
87 + u8 *cmd, cmdsz;
88 int ret = -1;
89 + u32 offset_ext;
90
91 + offset_ext = offset;
92 erase_size = flash->erase_size;
93 if (offset % erase_size || len % erase_size) {
94 debug("SF: Erase offset/length not multiple of erase size\n");
95 @@ -319,7 +329,18 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
96 }
97 }
98
99 + if (offset > SPI_FLASH_16MB_BOUN)
100 + cmdsz = SPI_FLASH_CMD_LEN_EXT + flash->dummy_byte;
101 + else
102 + cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
103 + cmd = calloc(1, cmdsz);
104 + if (!cmd) {
105 + debug("SF: Failed to allocate cmd\n");
106 + return -ENOMEM;
107 + }
108 + memset(cmd, 0x0, cmdsz);
109 cmd[0] = flash->erase_cmd;
110 +
111 while (len) {
112 erase_addr = offset;
113
114 @@ -332,7 +353,7 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
115 if (ret < 0)
116 return ret;
117 #endif
118 - spi_flash_addr(erase_addr, cmd);
119 + spi_flash_addr(erase_addr, cmd, offset_ext);
120
121 debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
122 cmd[2], cmd[3], erase_addr);
123 @@ -347,6 +368,7 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
124 len -= erase_size;
125 }
126
127 + free(cmd);
128 return ret;
129 }
130
131 @@ -356,9 +378,11 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
132 unsigned long byte_addr, page_size;
133 u32 write_addr;
134 size_t chunk_len, actual;
135 - u8 cmd[SPI_FLASH_CMD_LEN];
136 + u8 *cmd, cmdsz;
137 int ret = -1;
138 + u32 offset_ext;
139
140 + offset_ext = offset;
141 page_size = flash->page_size;
142
143 if (flash->flash_is_locked) {
144 @@ -369,6 +393,16 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
145 }
146 }
147
148 + if (offset > SPI_FLASH_16MB_BOUN)
149 + cmdsz = SPI_FLASH_CMD_LEN_EXT + flash->dummy_byte;
150 + else
151 + cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
152 + cmd = calloc(1, cmdsz);
153 + if (!cmd) {
154 + debug("SF: Failed to allocate cmd\n");
155 + return -ENOMEM;
156 + }
157 + memset(cmd, 0x0, cmdsz);
158 cmd[0] = flash->write_cmd;
159 for (actual = 0; actual < len; actual += chunk_len) {
160 write_addr = offset;
161 @@ -389,7 +423,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
162 chunk_len = min(chunk_len,
163 (size_t)flash->spi->max_write_size);
164
165 - spi_flash_addr(write_addr, cmd);
166 + spi_flash_addr(write_addr, cmd, offset_ext);
167
168 debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
169 buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
170 @@ -404,6 +438,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
171 offset += chunk_len;
172 }
173
174 + free(cmd);
175 return ret;
176 }
177
178 @@ -442,6 +477,9 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
179 u32 remain_len, read_len, read_addr;
180 int bank_sel = 0;
181 int ret = -1;
182 + u32 offset_ext;
183 +
184 + offset_ext = offset;
185
186 /* Handle memory-mapped SPI */
187 if (flash->memory_map) {
188 @@ -456,15 +494,18 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
189 spi_release_bus(flash->spi);
190 return 0;
191 }
192 -
193 - cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
194 + if (offset > SPI_FLASH_16MB_BOUN)
195 + cmdsz = SPI_FLASH_CMD_LEN_EXT + flash->dummy_byte;
196 + else
197 + cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
198 cmd = calloc(1, cmdsz);
199 if (!cmd) {
200 debug("SF: Failed to allocate cmd\n");
201 return -ENOMEM;
202 }
203 -
204 + memset(cmd, 0x0, cmdsz);
205 cmd[0] = flash->read_cmd;
206 +
207 while (len) {
208 read_addr = offset;
209
210 @@ -478,14 +519,18 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
211 return ret;
212 bank_sel = flash->bank_curr;
213 #endif
214 - remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) *
215 + if (offset_ext >= SPI_FLASH_16MB_BOUN) {
216 + remain_len = flash->size - offset;
217 + } else {
218 + remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) *
219 (bank_sel + 1)) - offset;
220 + }
221 if (len < remain_len)
222 read_len = len;
223 else
224 read_len = remain_len;
225
226 - spi_flash_addr(read_addr, cmd);
227 + spi_flash_addr(read_addr, cmd, offset_ext);
228
229 ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
230 if (ret < 0) {
231 diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
232 index 2b20038..09759fa 100644
233 --- a/drivers/spi/fsl_qspi.c
234 +++ b/drivers/spi/fsl_qspi.c
235 @@ -26,6 +26,9 @@ DECLARE_GLOBAL_DATA_PTR;
236 #endif
237
238 #define OFFSET_BITS_MASK GENMASK(23, 0)
239 +/* the qspi contrller memmap space ,instead of flash space */
240 +#define OFFSET_BITS_MASK_QSPI_SPACE GENMASK(27, 0)
241 +#define SPI_FLASH_ADDR_EXT_MAGIC 0xaa
242
243 #define FLASH_STATUS_WEL 0x02
244
245 @@ -757,6 +760,13 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen,
246 u32 bytes = DIV_ROUND_UP(bitlen, 8);
247 static u32 wr_sfaddr;
248 u32 txbuf;
249 + u8 offset_ext = 0;
250 + u32 flash_offset;
251 +
252 + if (((u8 *)dout)[5] == SPI_FLASH_ADDR_EXT_MAGIC) {
253 + offset_ext = 1;
254 + memcpy(&flash_offset, dout + 1, 4);
255 + }
256
257 if (dout) {
258 if (flags & SPI_XFER_BEGIN) {
259 @@ -772,14 +782,28 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen,
260
261 if (priv->cur_seqid == QSPI_CMD_FAST_READ ||
262 priv->cur_seqid == QSPI_CMD_RDAR) {
263 - priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
264 + if (offset_ext)
265 + priv->sf_addr = swab32(flash_offset) &
266 + OFFSET_BITS_MASK_QSPI_SPACE;
267 + else
268 + priv->sf_addr = swab32(txbuf) &
269 + OFFSET_BITS_MASK;
270 } else if ((priv->cur_seqid == QSPI_CMD_SE) ||
271 (priv->cur_seqid == QSPI_CMD_BE_4K)) {
272 - priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
273 + if (offset_ext)
274 + priv->sf_addr = swab32(flash_offset) &
275 + OFFSET_BITS_MASK_QSPI_SPACE;
276 + else
277 + priv->sf_addr = swab32(txbuf) &
278 + OFFSET_BITS_MASK;
279 qspi_op_erase(priv);
280 } else if (priv->cur_seqid == QSPI_CMD_PP ||
281 priv->cur_seqid == QSPI_CMD_WRAR) {
282 - wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK;
283 + if (offset_ext)
284 + wr_sfaddr = swab32(flash_offset) &
285 + OFFSET_BITS_MASK_QSPI_SPACE;
286 + else
287 + wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK;
288 } else if ((priv->cur_seqid == QSPI_CMD_BRWR) ||
289 (priv->cur_seqid == QSPI_CMD_WREAR)) {
290 #ifdef CONFIG_SPI_FLASH_BAR
291 diff --git a/include/configs/ls1012a_common.h b/include/configs/ls1012a_common.h
292 index 3fd360a..150444d 100644
293 --- a/include/configs/ls1012a_common.h
294 +++ b/include/configs/ls1012a_common.h
295 @@ -63,9 +63,8 @@
296 #define QSPI0_AMBA_BASE 0x40000000
297 #define CONFIG_SPI_FLASH_SPANSION
298 #define CONFIG_DM_SPI_FLASH
299 -#define CONFIG_SPI_FLASH_BAR
300
301 -#define FSL_QSPI_FLASH_SIZE (1 << 24)
302 +#define FSL_QSPI_FLASH_SIZE (1 << 26)
303 #define FSL_QSPI_FLASH_NUM 2
304
305 /*
306 --
307 1.7.9.5
308