blob: 1e8c5a2c66c0084e02d86e2c45d5e4327a1f63b9 [file] [log] [blame]
Kuldeep Singh5a0f9da2020-12-09 14:02:39 +05301// SPDX-License-Identifier: BSD-3-Clause
2/*
3 * NXP FlexSpi Controller Driver.
4 * Copyright 2021 NXP
5 *
6 */
7#include <endian.h>
8#include <stdint.h>
9#include <stdio.h>
10#include <string.h>
11
12#include <common/debug.h>
13#include <flash_info.h>
14#include "fspi.h"
15#include <fspi_api.h>
16#include <xspi_error_codes.h>
17
18#ifdef DEBUG_FLEXSPI
19#define PR printf("In [%s][%d]\n", __func__, __LINE__)
20#define PRA(a, b) printf("In [%s][%d] %s="a"\n", __func__, __LINE__, #b, b)
21#else
22#define PR
23#define PRA(a, b)
24#endif
25
26/*
27 * This errata is valid for all NXP SoC.
28 */
29#define ERRATA_FLASH_A050272 1
30
31static uintptr_t fspi_base_reg_addr;
32static uintptr_t fspi_flash_base_addr;
33
34static void fspi_RDSR(uint32_t *, const void *, uint32_t);
35
36static void fspi_writel(uint32_t x_addr, uint32_t x_val)
37{
38 fspi_out32((uint32_t *)(fspi_base_reg_addr + x_addr),
39 (uint32_t) x_val);
40}
41
42static uint32_t fspi_readl(uint32_t x_addr)
43{
44 return fspi_in32((uint32_t *)(fspi_base_reg_addr + x_addr));
45}
46
47static void fspi_MDIS(uint8_t x_disable)
48{
49 uint32_t ui_reg;
50
51 ui_reg = fspi_readl(FSPI_MCR0);
52 if (x_disable != 0U) {
53 ui_reg |= FSPI_MCR0_MDIS;
54 } else {
55 ui_reg &= (uint32_t) (~FSPI_MCR0_MDIS);
56 }
57
58 fspi_writel(FSPI_MCR0, ui_reg);
59}
60
61static void fspi_lock_LUT(void)
62{
63 fspi_writel(FSPI_LUTKEY, FSPI_LUTKEY_VALUE);
64 VERBOSE("%s 0x%x\n", __func__, fspi_readl(FSPI_LCKCR));
65 fspi_writel(FSPI_LCKCR, FSPI_LCKER_LOCK);
66 VERBOSE("%s 0x%x\n", __func__, fspi_readl(FSPI_LCKCR));
67}
68
69static void fspi_unlock_LUT(void)
70{
71 fspi_writel(FSPI_LUTKEY, FSPI_LUTKEY_VALUE);
72 VERBOSE("%s 0x%x\n", __func__, fspi_readl(FSPI_LCKCR));
73 fspi_writel(FSPI_LCKCR, FSPI_LCKER_UNLOCK);
74 VERBOSE("%s 0x%x\n", __func__, fspi_readl(FSPI_LCKCR));
75}
76
77static void fspi_op_setup(uint32_t fspi_op_seq_id, bool ignore_flash_sz)
78{
79 uint32_t x_addr, x_instr0 = 0, x_instr1 = 0, x_instr2 = 0;
80 uint32_t cmd_id1, cmd_id2;
81
82 VERBOSE("In func %s\n", __func__);
83
84 switch (fspi_op_seq_id) {
85 case FSPI_READ_SEQ_ID:
86 cmd_id1 = FSPI_NOR_CMD_READ;
87 cmd_id2 = FSPI_NOR_CMD_READ_4B;
88 x_instr2 = FSPI_INSTR_OPRND0(0) | FSPI_INSTR_PAD0(FSPI_LUT_PAD1)
89 | FSPI_INSTR_OPCODE0(FSPI_LUT_READ);
90 break;
91 case FSPI_FASTREAD_SEQ_ID:
92 cmd_id1 = FSPI_NOR_CMD_FASTREAD;
93 cmd_id2 = FSPI_NOR_CMD_FASTREAD_4B;
94 x_instr2 = FSPI_INSTR_OPRND0(8) | FSPI_INSTR_PAD0(FSPI_LUT_PAD1)
95 | FSPI_INSTR_OPCODE0(FSPI_DUMMY_SDR)
96 | FSPI_INSTR_OPRND1(0)
97 | FSPI_INSTR_PAD1(FSPI_LUT_PAD1)
98 | FSPI_INSTR_OPCODE1(FSPI_LUT_READ);
99 break;
100 case FSPI_WRITE_SEQ_ID:
101 cmd_id1 = FSPI_NOR_CMD_PP;
102 cmd_id2 = FSPI_NOR_CMD_PP_4B;
103 x_instr2 = FSPI_INSTR_OPRND0(0) | FSPI_INSTR_PAD0(FSPI_LUT_PAD1)
104 | FSPI_INSTR_OPCODE0(FSPI_LUT_WRITE);
105 break;
106 case FSPI_WREN_SEQ_ID:
107 cmd_id1 = FSPI_NOR_CMD_WREN;
108 cmd_id2 = FSPI_NOR_CMD_WREN;
109 break;
110 case FSPI_SE_SEQ_ID:
111 cmd_id1 = FSPI_NOR_CMD_SE_64K;
112 cmd_id2 = FSPI_NOR_CMD_SE_64K_4B;
113 break;
114 case FSPI_4K_SEQ_ID:
115 cmd_id1 = FSPI_NOR_CMD_SE_4K;
116 cmd_id2 = FSPI_NOR_CMD_SE_4K_4B;
117 break;
118 case FSPI_BE_SEQ_ID:
119 cmd_id1 = FSPI_NOR_CMD_BE;
120 cmd_id2 = FSPI_NOR_CMD_BE;
121 break;
122 case FSPI_RDSR_SEQ_ID:
123 cmd_id1 = FSPI_NOR_CMD_RDSR;
124 cmd_id2 = FSPI_NOR_CMD_RDSR;
125 break;
Jiafei Panb27cc462022-05-13 09:42:58 +0800126 default:
127 ERROR("Unsupported command\n");
128 return;
Kuldeep Singh5a0f9da2020-12-09 14:02:39 +0530129 }
130
131 x_addr = FSPI_LUTREG_OFFSET + (uint32_t)(0x10 * fspi_op_seq_id);
132 if ((F_FLASH_SIZE_BYTES <= SZ_16M_BYTES) || (ignore_flash_sz)) {
133 x_instr0 = FSPI_INSTR_OPRND0(cmd_id1);
134 x_instr1 = FSPI_INSTR_OPRND1(FSPI_LUT_ADDR24BIT);
135 VERBOSE("CMD_ID = %x offset = 0x%x\n", cmd_id1, x_addr);
136 } else {
137 x_instr0 = FSPI_INSTR_OPRND0(cmd_id2);
138 x_instr1 = FSPI_INSTR_OPRND1(FSPI_LUT_ADDR32BIT);
139 VERBOSE("CMD_ID = %x offset = 0x%x\n", cmd_id2, x_addr);
140 }
141 x_instr0 |= FSPI_INSTR_PAD0(FSPI_LUT_PAD1)
142 | FSPI_INSTR_OPCODE0(FSPI_LUT_CMD);
143
144 x_instr1 |= FSPI_INSTR_PAD1(FSPI_LUT_PAD1)
145 | FSPI_INSTR_OPCODE1(FSPI_LUT_ADDR);
146
147 if (fspi_op_seq_id == FSPI_RDSR_SEQ_ID) {
148 x_instr0 |= FSPI_INSTR_OPRND1(1) | FSPI_INSTR_PAD1(FSPI_LUT_PAD1)
149 | FSPI_INSTR_OPCODE1(FSPI_LUT_READ);
150 } else if ((fspi_op_seq_id != FSPI_BE_SEQ_ID)
151 && (fspi_op_seq_id != FSPI_WREN_SEQ_ID)) {
152 x_instr0 |= x_instr1;
153 }
154
155 fspi_writel((x_addr), x_instr0);
156 fspi_writel((x_addr + U(0x4)), x_instr2);
157 fspi_writel((x_addr + U(0x8)), (uint32_t) 0x0); /* STOP command */
158 fspi_writel((x_addr + U(0xc)), (uint32_t) 0x0); /* STOP command */
159}
160
161static void fspi_setup_LUT(void)
162{
163 VERBOSE("In func %s\n", __func__);
164 fspi_unlock_LUT();
165
166 /* LUT Setup for READ Command 3-Byte low Frequency */
167 fspi_op_setup(FSPI_READ_SEQ_ID, false);
168
169 /* LUT Setup for FAST READ Command 3-Byte/4-Byte high Frequency */
170 fspi_op_setup(FSPI_FASTREAD_SEQ_ID, false);
171
172 /* LUT Setup for Page Program */
173 fspi_op_setup(FSPI_WRITE_SEQ_ID, false);
174
175 /* LUT Setup for WREN */
176 fspi_op_setup(FSPI_WREN_SEQ_ID, true);
177
178 /* LUT Setup for Sector_Erase */
179 fspi_op_setup(FSPI_SE_SEQ_ID, false);
180
181 /* LUT Setup for Sub Sector 4K Erase */
182 fspi_op_setup(FSPI_4K_SEQ_ID, false);
183
184 /* LUT Setup for Bulk_Erase */
185 fspi_op_setup(FSPI_BE_SEQ_ID, true);
186
187 /* Read Status */
188 fspi_op_setup(FSPI_RDSR_SEQ_ID, true);
189
190 fspi_lock_LUT();
191}
192
193static inline void fspi_ahb_invalidate(void)
194{
195 uint32_t reg;
196
197 VERBOSE("In func %s %d\n", __func__, __LINE__);
198 reg = fspi_readl(FSPI_MCR0);
199 reg |= FSPI_MCR0_SWRST;
200 fspi_writel(FSPI_MCR0, reg);
201 while ((fspi_readl(FSPI_MCR0) & FSPI_MCR0_SWRST) != 0)
202 ; /* FSPI_MCR0_SWRESET_MASK */
203 VERBOSE("In func %s %d\n", __func__, __LINE__);
204}
205
206#if defined(CONFIG_FSPI_AHB)
207static void fspi_init_ahb(void)
208{
209 uint32_t i, x_flash_cr2, seq_id;
210
211 x_flash_cr2 = 0;
212 /* Reset AHB RX buffer CR configuration */
213 for (i = 0; i < 8; i++) {
214 fspi_writel((FSPI_AHBRX_BUF0CR0 + 4 * i), 0U);
215 }
216
217 /* Set ADATSZ with the maximum AHB buffer size */
218 fspi_writel(FSPI_AHBRX_BUF7CR0,
219 ((uint32_t) ((FSPI_RX_MAX_AHBBUF_SIZE / 8U) |
220 FSPI_AHBRXBUF0CR7_PREF)));
221
222 /* Known limitation handling: prefetch and
223 * no start address alignment.*/
224 fspi_writel(FSPI_AHBCR, FSPI_AHBCR_PREF_EN);
225 INFO("xAhbcr=0x%x\n", fspi_readl(FSPI_AHBCR));
226
227 // Setup AHB READ sequenceID for all flashes.
228 x_flash_cr2 = fspi_readl(FSPI_FLSHA1CR2);
229 INFO("x_flash_cr2=0x%x\n", x_flash_cr2);
230
231 seq_id = CONFIG_FSPI_FASTREAD ?
232 FSPI_FASTREAD_SEQ_ID : FSPI_READ_SEQ_ID;
233 x_flash_cr2 |= ((seq_id << FSPI_FLSHXCR2_ARDSEQI_SHIFT) & 0x1f);
234
235 INFO("x_flash_cr2=0x%x\n", x_flash_cr2);
236
237 fspi_writel(FSPI_FLSHA1CR2, x_flash_cr2);
238 x_flash_cr2 = fspi_readl(FSPI_FLSHA1CR2);
239 INFO("x_flash_cr2=0x%x\n", x_flash_cr2);
240}
241#endif
242
243int xspi_read(uint32_t pc_rx_addr, uint32_t *pc_rx_buf, uint32_t x_size_bytes)
244{
245 if (x_size_bytes == 0) {
246 ERROR("Zero length reads are not allowed\n");
247 return XSPI_READ_FAIL;
248 }
249
250#if defined(CONFIG_FSPI_AHB)
251 return xspi_ahb_read(pc_rx_addr, pc_rx_buf, x_size_bytes);
252#else
253 return xspi_ip_read(pc_rx_addr, pc_rx_buf, x_size_bytes);
254#endif
255}
256#if defined(CONFIG_FSPI_AHB)
257int xspi_ahb_read(uint32_t pc_rx_addr, uint32_t *pc_rx_buf, uint32_t x_size_bytes)
258{
259 VERBOSE("In func %s 0x%x\n", __func__, (pc_rx_addr));
260
261 if (F_FLASH_SIZE_BYTES <= SZ_16M_BYTES) {
262 pc_rx_addr = ((uint32_t)(pcRxAddr & MASK_24BIT_ADDRESS));
263 } else {
264 pc_rx_addr = ((uint32_t)(pcRxAddr & MASK_32BIT_ADDRESS));
265 }
266
267 pc_rx_addr = ((uint32_t)(pcRxAddr + fspi_flash_base_addr));
268
269 if (((pc_rx_addr % 4) != 0) || (((uintptr_t)pc_rx_buf % 4) != 0)) {
270 WARN("%s: unaligned Start Address src=%ld dst=0x%p\n",
271 __func__, (pc_rx_addr - fspi_flash_base_addr), pc_rx_buf);
272 }
273
274 /* Directly copy from AHB Buffer */
275 memcpy(pc_rx_buf, (void *)(uintptr_t)pc_rx_addr, x_size_bytes);
276
277 fspi_ahb_invalidate();
278 return XSPI_SUCCESS;
279}
280#endif
281
282int xspi_ip_read(uint32_t pc_rx_addr, uint32_t *pv_rx_buf, uint32_t ui_len)
283{
284
285 uint32_t i = 0U, j = 0U, x_rem = 0U;
286 uint32_t x_iteration = 0U, x_size_rx = 0U, x_size_wm, temp_size;
287 uint32_t data = 0U;
288 uint32_t x_len_bytes;
289 uint32_t x_addr, sts0, intr, seq_id;
290
291 x_addr = (uint32_t) pc_rx_addr;
292 x_len_bytes = ui_len;
293
294 /* Watermark level : 8 bytes. (BY DEFAULT) */
295 x_size_wm = 8U;
296
297 /* Clear RX Watermark interrupt in INT register, if any existing. */
298 fspi_writel(FSPI_INTR, FSPI_INTR_IPRXWA);
299 PRA("0x%x", fspi_readl(FSPI_INTR));
300 /* Invalid the RXFIFO, to run next IP Command */
301 /* Clears data entries in IP Rx FIFOs, Also reset R/W pointers */
302 fspi_writel(FSPI_IPRXFCR, FSPI_IPRXFCR_CLR);
303 fspi_writel(FSPI_INTR, FSPI_INTEN_IPCMDDONE);
304
305 while (x_len_bytes) {
306
307 /* FlexSPI can store no more than FSPI_RX_IPBUF_SIZE */
308 x_size_rx = (x_len_bytes > FSPI_RX_IPBUF_SIZE) ?
309 FSPI_RX_IPBUF_SIZE : x_len_bytes;
310
311 /* IP Control Register0 - SF Address to be read */
312 fspi_writel(FSPI_IPCR0, x_addr);
313 PRA("0x%x", fspi_readl(FSPI_IPCR0));
314 /* IP Control Register1 - SEQID_READ operation, Size */
315
316 seq_id = CONFIG_FSPI_FASTREAD ?
317 FSPI_FASTREAD_SEQ_ID : FSPI_READ_SEQ_ID;
318
319 fspi_writel(FSPI_IPCR1,
320 (uint32_t)(seq_id << FSPI_IPCR1_ISEQID_SHIFT) |
321 (uint16_t) x_size_rx);
322
323 PRA("0x%x", fspi_readl(FSPI_IPCR1));
324
325 do {
326 sts0 = fspi_readl(FSPI_STS0);
327 } while (((sts0 & FSPI_STS0_ARB_IDLE) == 0) &&
328 ((sts0 & FSPI_STS0_SEQ_IDLE) == 0));
329
330 /* Trigger IP Read Command */
331 fspi_writel(FSPI_IPCMD, FSPI_IPCMD_TRG_MASK);
332 PRA("0x%x", fspi_readl(FSPI_IPCMD));
333
334 intr = fspi_readl(FSPI_INTR);
335 if (((intr & FSPI_INTR_IPCMDGE) != 0) ||
336 ((intr & FSPI_INTR_IPCMDERR) != 0)) {
337 ERROR("Error in IP READ INTR=0x%x\n", intr);
338 return -XSPI_IP_READ_FAIL;
339 }
340 /* Will read in n iterations of each 8 FIFO's(WM level) */
341 x_iteration = x_size_rx / x_size_wm;
342 for (i = 0U; i < x_iteration; i++) {
343 if ((fspi_readl(FSPI_INTR) & FSPI_INTR_IPRXWA_MASK) == 0) {
344 PRA("0x%x", fspi_readl(FSPI_INTR));
345 }
346 /* Wait for IP Rx Watermark Fill event */
347 while (!(fspi_readl(FSPI_INTR) & FSPI_INTR_IPRXWA_MASK)) {
348 PRA("0x%x", fspi_readl(FSPI_INTR));
349 }
350
351 /* Read RX FIFO's(upto WM level) & copy to rxbuffer */
352 for (j = 0U; j < x_size_wm; j += 4U) {
353 /* Read FIFO Data Register */
354 data = fspi_readl(FSPI_RFDR + j);
355#if FSPI_IPDATA_SWAP /* Just In case you want swap */
356 data = bswap32(data);
357#endif
358 memcpy(pv_rx_buf++, &data, 4);
359 }
360
361 /* Clear IP_RX_WATERMARK Event in INTR register */
362 /* Reset FIFO Read pointer for next iteration.*/
363 fspi_writel(FSPI_INTR, FSPI_INTR_IPRXWA);
364 }
365
366 x_rem = x_size_rx % x_size_wm;
367
368 if (x_rem != 0U) {
369 /* Wait for data filled */
370 while (!(fspi_readl(FSPI_IPRXFSTS) & FSPI_IPRXFSTS_FILL_MASK)) {
371 PRA("0x%x", fspi_readl(FSPI_IPRXFSTS));
372 }
373
374 temp_size = 0;
375 j = 0U;
376 while (x_rem > 0U) {
377 data = 0U;
378 data = fspi_readl(FSPI_RFDR + j);
379#if FSPI_IPDATA_SWAP /* Just In case you want swap */
380 data = bswap32(data);
381#endif
382 temp_size = (x_rem < 4) ? x_rem : 4;
383 memcpy(pv_rx_buf++, &data, temp_size);
384 x_rem -= temp_size;
385 }
386 }
387
388
389 while (!(fspi_readl(FSPI_INTR) & FSPI_INTR_IPCMDDONE_MASK)) {
390 PRA("0x%x", fspi_readl(FSPI_INTR));
391 }
392
393 /* Invalid the RX FIFO, to run next IP Command */
394 fspi_writel(FSPI_IPRXFCR, FSPI_IPRXFCR_CLR);
395 /* Clear IP Command Done flag in interrupt register*/
396 fspi_writel(FSPI_INTR, FSPI_INTR_IPCMDDONE_MASK);
397
398 /* Update remaining len, Increment x_addr read pointer. */
399 x_len_bytes -= x_size_rx;
400 x_addr += x_size_rx;
401 }
402 PR;
403 return XSPI_SUCCESS;
404}
405
406void xspi_ip_write(uint32_t pc_wr_addr, uint32_t *pv_wr_buf, uint32_t ui_len)
407{
408
409 uint32_t x_iteration = 0U, x_rem = 0U;
410 uint32_t x_size_tx = 0U, x_size_wm, temp_size;
411 uint32_t i = 0U, j = 0U;
412 uint32_t ui_data = 0U;
413 uint32_t x_addr, x_len_bytes;
414
415
416 x_size_wm = 8U; /* Default TX WaterMark level: 8 Bytes. */
417 x_addr = (uint32_t)pc_wr_addr;
418 x_len_bytes = ui_len;
419 VERBOSE("In func %s[%d] x_addr =0x%x xLen_bytes=%d\n",
420 __func__, __LINE__, x_addr, x_len_bytes);
421
422 while (x_len_bytes != 0U) {
423
424 x_size_tx = (x_len_bytes > FSPI_TX_IPBUF_SIZE) ?
425 FSPI_TX_IPBUF_SIZE : x_len_bytes;
426
427 /* IP Control Register0 - SF Address to be read */
428 fspi_writel(FSPI_IPCR0, x_addr);
429 INFO("In func %s[%d] x_addr =0x%x xLen_bytes=%d\n",
430 __func__, __LINE__, x_addr, x_len_bytes);
431
432 /*
433 * Fill TX FIFO's..
434 *
435 */
436
437 x_iteration = x_size_tx / x_size_wm;
438 for (i = 0U; i < x_iteration; i++) {
439
440 /* Ensure TX FIFO Watermark Available */
441 while ((fspi_readl(FSPI_INTR) & FSPI_INTR_IPTXWE_MASK) == 0)
442 ;
443
444
445 /* Fill TxFIFO's ( upto watermark level) */
446 for (j = 0U; j < x_size_wm; j += 4U) {
447 memcpy(&ui_data, pv_wr_buf++, 4);
448 /* Write TX FIFO Data Register */
449 fspi_writel((FSPI_TFDR + j), ui_data);
450
451 }
452
453 /* Clear IP_TX_WATERMARK Event in INTR register */
454 /* Reset the FIFO Write pointer for next iteration */
455 fspi_writel(FSPI_INTR, FSPI_INTR_IPTXWE);
456 }
457
458 x_rem = x_size_tx % x_size_wm;
459
460 if (x_rem != 0U) {
461 /* Wait for TXFIFO empty */
462 while (!(fspi_readl(FSPI_INTR) & FSPI_INTR_IPTXWE))
463 ;
464
465 temp_size = 0U;
466 j = 0U;
467 while (x_rem > 0U) {
468 ui_data = 0U;
469 temp_size = (x_rem < 4U) ? x_rem : 4U;
470 memcpy(&ui_data, pv_wr_buf++, temp_size);
471 INFO("%d ---> pv_wr_buf=0x%p\n", __LINE__, pv_wr_buf);
472 fspi_writel((FSPI_TFDR + j), ui_data);
473 x_rem -= temp_size;
474 j += 4U ; /* TODO: May not be needed*/
475 }
476 /* Clear IP_TX_WATERMARK Event in INTR register */
477 /* Reset FIFO's Write pointer for next iteration.*/
478 fspi_writel(FSPI_INTR, FSPI_INTR_IPTXWE);
479 }
480
481 /* IP Control Register1 - SEQID_WRITE operation, Size */
482 fspi_writel(FSPI_IPCR1, (uint32_t)(FSPI_WRITE_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT) | (uint16_t) x_size_tx);
483 /* Trigger IP Write Command */
484 fspi_writel(FSPI_IPCMD, FSPI_IPCMD_TRG_MASK);
485
486 /* Wait for IP Write command done */
487 while (!(fspi_readl(FSPI_INTR) & FSPI_INTR_IPCMDDONE_MASK))
488 ;
489
490 /* Invalidate TX FIFOs & acknowledge IP_CMD_DONE event */
491 fspi_writel(FSPI_IPTXFCR, FSPI_IPTXFCR_CLR);
492 fspi_writel(FSPI_INTR, FSPI_INTR_IPCMDDONE_MASK);
493
494 /* for next iteration */
495 x_len_bytes -= x_size_tx;
496 x_addr += x_size_tx;
497 }
498
499}
500
501int xspi_write(uint32_t pc_wr_addr, void *pv_wr_buf, uint32_t ui_len)
502{
503
504 uint32_t x_addr;
505 uint32_t x_page1_len = 0U, x_page_l_len = 0U;
506 uint32_t i, j = 0U;
507 void *buf = pv_wr_buf;
508
509 VERBOSE("\nIn func %s\n", __func__);
510
511 x_addr = (uint32_t)(pc_wr_addr);
512 if ((ui_len <= F_PAGE_256) && ((x_addr % F_PAGE_256) == 0)) {
513 x_page1_len = ui_len;
514 INFO("%d ---> x_page1_len=0x%x x_page_l_len =0x%x j=0x%x\n", __LINE__, x_page1_len, x_page_l_len, j);
515 } else if ((ui_len <= F_PAGE_256) && ((x_addr % F_PAGE_256) != 0)) {
516 x_page1_len = (F_PAGE_256 - (x_addr % F_PAGE_256));
517 if (ui_len > x_page1_len) {
518 x_page_l_len = (ui_len - x_page1_len) % F_PAGE_256;
519 } else {
520 x_page1_len = ui_len;
521 x_page_l_len = 0;
522 }
523 j = 0U;
524 INFO("%d 0x%x 0x%x\n", x_addr % F_PAGE_256, x_addr % F_PAGE_256, F_PAGE_256);
525 INFO("%d ---> x_page1_len=0x%x x_page_l_len =0x%x j=0x%x\n", __LINE__, x_page1_len, x_page_l_len, j);
526 } else if ((ui_len > F_PAGE_256) && ((x_addr % F_PAGE_256) == 0)) {
527 j = ui_len / F_PAGE_256;
528 x_page_l_len = ui_len % F_PAGE_256;
529 INFO("%d ---> x_page1_len=0x%x x_page_l_len =0x%x j=0x%x\n", __LINE__, x_page1_len, x_page_l_len, j);
530 } else if ((ui_len > F_PAGE_256) && ((x_addr % F_PAGE_256) != 0)) {
531 x_page1_len = (F_PAGE_256 - (x_addr % F_PAGE_256));
532 j = (ui_len - x_page1_len) / F_PAGE_256;
533 x_page_l_len = (ui_len - x_page1_len) % F_PAGE_256;
534 INFO("%d ---> x_page1_len=0x%x x_page_l_len =0x%x j=0x%x\n", __LINE__, x_page1_len, x_page_l_len, j);
535 }
536
537 if (x_page1_len != 0U) {
538 xspi_wren(x_addr);
539 xspi_ip_write(x_addr, (uint32_t *)buf, x_page1_len);
540 while (is_flash_busy())
541 ;
542 INFO("%d Initial pc_wr_addr=0x%x, Final x_addr=0x%x, Initial ui_len=0x%x Final ui_len=0x%x\n",
543 __LINE__, pc_wr_addr, x_addr, ui_len, (x_addr-pc_wr_addr));
544 INFO("Initial Buf pv_wr_buf=%p, final Buf=%p\n", pv_wr_buf, buf);
545 x_addr += x_page1_len;
546 /* TODO What is buf start is not 4 aligned */
547 buf = buf + x_page1_len;
548 }
549
550 for (i = 0U; i < j; i++) {
551 INFO("In for loop Buf pv_wr_buf=%p, final Buf=%p x_addr=0x%x offset_buf %d.\n",
552 pv_wr_buf, buf, x_addr, x_page1_len/4);
553 xspi_wren(x_addr);
554 xspi_ip_write(x_addr, (uint32_t *)buf, F_PAGE_256);
555 while (is_flash_busy())
556 ;
557 INFO("%d Initial pc_wr_addr=0x%x, Final x_addr=0x%x, Initial ui_len=0x%x Final ui_len=0x%x\n",
558 __LINE__, pc_wr_addr, x_addr, ui_len, (x_addr-pc_wr_addr));
559 x_addr += F_PAGE_256;
560 /* TODO What is buf start is not 4 aligned */
561 buf = buf + F_PAGE_256;
562 INFO("Initial Buf pv_wr_buf=%p, final Buf=%p\n", pv_wr_buf, buf);
563 }
564
565 if (x_page_l_len != 0U) {
566 INFO("%d Initial Buf pv_wr_buf=%p, final Buf=%p x_page_l_len=0x%x\n", __LINE__, pv_wr_buf, buf, x_page_l_len);
567 xspi_wren(x_addr);
568 xspi_ip_write(x_addr, (uint32_t *)buf, x_page_l_len);
569 while (is_flash_busy())
570 ;
571 INFO("%d Initial pc_wr_addr=0x%x, Final x_addr=0x%x, Initial ui_len=0x%x Final ui_len=0x%x\n",
572 __LINE__, pc_wr_addr, x_addr, ui_len, (x_addr-pc_wr_addr));
573 }
574
575 VERBOSE("Now calling func call Invalidate%s\n", __func__);
576 fspi_ahb_invalidate();
577 return XSPI_SUCCESS;
578}
579
580int xspi_wren(uint32_t pc_wr_addr)
581{
582 VERBOSE("In func %s Addr=0x%x\n", __func__, pc_wr_addr);
583
584 fspi_writel(FSPI_IPTXFCR, FSPI_IPTXFCR_CLR);
585
586 fspi_writel(FSPI_IPCR0, (uint32_t)pc_wr_addr);
587 fspi_writel(FSPI_IPCR1, ((FSPI_WREN_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT) | 0));
588 fspi_writel(FSPI_IPCMD, FSPI_IPCMD_TRG_MASK);
589
590 while ((fspi_readl(FSPI_INTR) & FSPI_INTR_IPCMDDONE_MASK) == 0)
591 ;
592
593 fspi_writel(FSPI_INTR, FSPI_INTR_IPCMDDONE_MASK);
594 return XSPI_SUCCESS;
595}
596
597static void fspi_bbluk_er(void)
598{
599 VERBOSE("In func %s\n", __func__);
600 fspi_writel(FSPI_IPCR0, 0x0);
601 fspi_writel(FSPI_IPCR1, ((FSPI_BE_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT) | 20));
602 fspi_writel(FSPI_IPCMD, FSPI_IPCMD_TRG_MASK);
603
604 while ((fspi_readl(FSPI_INTR) & FSPI_INTR_IPCMDDONE_MASK) == 0)
605 ;
606 fspi_writel(FSPI_INTR, FSPI_INTR_IPCMDDONE_MASK);
607
608}
609
610static void fspi_RDSR(uint32_t *rxbuf, const void *p_addr, uint32_t size)
611{
612 uint32_t iprxfcr = 0U;
613 uint32_t data = 0U;
614
615 iprxfcr = fspi_readl(FSPI_IPRXFCR);
616 /* IP RX FIFO would be read by processor */
617 iprxfcr = iprxfcr & (uint32_t)~FSPI_IPRXFCR_CLR;
618 /* Invalid data entries in IP RX FIFO */
619 iprxfcr = iprxfcr | FSPI_IPRXFCR_CLR;
620 fspi_writel(FSPI_IPRXFCR, iprxfcr);
621
622 fspi_writel(FSPI_IPCR0, (uintptr_t) p_addr);
623 fspi_writel(FSPI_IPCR1,
624 (uint32_t) ((FSPI_RDSR_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT)
625 | (uint16_t) size));
626 /* Trigger the command */
627 fspi_writel(FSPI_IPCMD, FSPI_IPCMD_TRG_MASK);
628 /* Wait for command done */
629 while ((fspi_readl(FSPI_INTR) & FSPI_INTR_IPCMDDONE_MASK) == 0)
630 ;
631 fspi_writel(FSPI_INTR, FSPI_INTR_IPCMDDONE_MASK);
632
633 data = fspi_readl(FSPI_RFDR);
634 memcpy(rxbuf, &data, size);
635
636 /* Rx FIFO invalidation needs to be done prior w1c of INTR.IPRXWA bit */
637 fspi_writel(FSPI_IPRXFCR, FSPI_IPRXFCR_CLR);
638 fspi_writel(FSPI_INTR, FSPI_INTR_IPRXWA_MASK);
639 fspi_writel(FSPI_INTR, FSPI_INTR_IPCMDDONE_MASK);
640
641}
642
643bool is_flash_busy(void)
644{
645#define FSPI_ONE_BYTE 1
646 uint8_t data[4];
647
648 VERBOSE("In func %s\n\n", __func__);
649 fspi_RDSR((uint32_t *) data, 0, FSPI_ONE_BYTE);
650
651 return !!((uint32_t) data[0] & FSPI_NOR_SR_WIP_MASK);
652}
653
654int xspi_bulk_erase(void)
655{
656 VERBOSE("In func %s\n", __func__);
657 xspi_wren((uint32_t) 0x0);
658 fspi_bbluk_er();
659 while (is_flash_busy())
660 ;
661 fspi_ahb_invalidate();
662 return XSPI_SUCCESS;
663}
664
665static void fspi_sec_er(uint32_t pc_wr_addr)
666{
667 uint32_t x_addr;
668
669 VERBOSE("In func %s\n", __func__);
670 x_addr = (uint32_t)(pc_wr_addr);
671
672 fspi_writel(FSPI_IPCR0, x_addr);
673 INFO("In [%s][%d] Erase address 0x%x\n", __func__, __LINE__, (x_addr));
674#if CONFIG_FSPI_ERASE_4K
675 fspi_writel(FSPI_IPCR1, ((FSPI_4K_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT) | 0));
676#else
677 fspi_writel(FSPI_IPCR1, ((FSPI_SE_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT) | 0));
678#endif
679 fspi_writel(FSPI_IPCMD, FSPI_IPCMD_TRG_MASK);
680
681 while ((fspi_readl(FSPI_INTR) & FSPI_INTR_IPCMDDONE_MASK) == 0) {
682 PRA("0x%x", fspi_readl(FSPI_INTR));
683 }
684 fspi_writel(FSPI_INTR, FSPI_INTR_IPCMDDONE_MASK);
685}
686
687int xspi_sector_erase(uint32_t pc_wr_addr, uint32_t ui_len)
688{
689 uint32_t x_addr, x_len_bytes, i, num_sector = 0U;
690
691 VERBOSE("In func %s\n", __func__);
692 x_addr = (uint32_t)(pc_wr_addr);
693 if ((x_addr % F_SECTOR_ERASE_SZ) != 0) {
694 ERROR("!!! In func %s, unalinged start address can only be in multiples of 0x%x\n",
695 __func__, F_SECTOR_ERASE_SZ);
696 return -XSPI_ERASE_FAIL;
697 }
698
699 x_len_bytes = ui_len * 1;
700 if (x_len_bytes < F_SECTOR_ERASE_SZ) {
701 ERROR("!!! In func %s, Less than 1 sector can only be in multiples of 0x%x\n",
702 __func__, F_SECTOR_ERASE_SZ);
703 return -XSPI_ERASE_FAIL;
704 }
705
706 num_sector = x_len_bytes/F_SECTOR_ERASE_SZ;
707 num_sector += x_len_bytes % F_SECTOR_ERASE_SZ ? 1U : 0U;
708 INFO("F_SECTOR_ERASE_SZ: 0x%08x, num_sector: %d\n", F_SECTOR_ERASE_SZ, num_sector);
709
710 for (i = 0U; i < num_sector ; i++) {
711 xspi_wren(x_addr + (F_SECTOR_ERASE_SZ * i));
712 fspi_sec_er(x_addr + (F_SECTOR_ERASE_SZ * i));
713 while (is_flash_busy())
714 ;
715 }
716 fspi_ahb_invalidate();
717 return XSPI_SUCCESS;
718}
719
720
721__attribute__((unused)) static void fspi_delay_ms(uint32_t x)
722{
723 volatile unsigned long ul_count;
724
725 for (ul_count = 0U; ul_count < (30U * x); ul_count++)
726 ;
727
728}
729
730
731#if defined(DEBUG_FLEXSPI)
732static void fspi_dump_regs(void)
733{
734 uint32_t i;
735
736 VERBOSE("\nRegisters Dump:\n");
737 VERBOSE("Flexspi: Register FSPI_MCR0(0x%x) = 0x%08x\n", FSPI_MCR0, fspi_readl(FSPI_MCR0));
738 VERBOSE("Flexspi: Register FSPI_MCR2(0x%x) = 0x%08x\n", FSPI_MCR2, fspi_readl(FSPI_MCR2));
739 VERBOSE("Flexspi: Register FSPI_DLL_A_CR(0x%x) = 0x%08x\n", FSPI_DLLACR, fspi_readl(FSPI_DLLACR));
740 VERBOSE("\n");
741
742 for (i = 0U; i < 8U; i++) {
743 VERBOSE("Flexspi: Register FSPI_AHBRX_BUF0CR0(0x%x) = 0x%08x\n", FSPI_AHBRX_BUF0CR0 + i * 4, fspi_readl((FSPI_AHBRX_BUF0CR0 + i * 4)));
744 }
745 VERBOSE("\n");
746
747 VERBOSE("Flexspi: Register FSPI_AHBRX_BUF7CR0(0x%x) = 0x%08x\n", FSPI_AHBRX_BUF7CR0, fspi_readl(FSPI_AHBRX_BUF7CR0));
748 VERBOSE("Flexspi: Register FSPI_AHB_CR(0x%x) \t = 0x%08x\n", FSPI_AHBCR, fspi_readl(FSPI_AHBCR));
749 VERBOSE("\n");
750
751 for (i = 0U; i < 4U; i++) {
752 VERBOSE("Flexspi: Register FSPI_FLSH_A1_CR2,(0x%x) = 0x%08x\n", FSPI_FLSHA1CR2 + i * 4, fspi_readl(FSPI_FLSHA1CR2 + i * 4));
753 }
754}
755#endif
756
757int fspi_init(uint32_t base_reg_addr, uint32_t flash_start_addr)
758{
759 uint32_t mcrx;
760 uint32_t flash_size;
761
762 if (fspi_base_reg_addr != 0U) {
763 INFO("FSPI is already initialized.\n");
764 return XSPI_SUCCESS;
765 }
766
767 fspi_base_reg_addr = base_reg_addr;
768 fspi_flash_base_addr = flash_start_addr;
769
770 INFO("Flexspi driver: Version v1.0\n");
771 INFO("Flexspi: Default MCR0 = 0x%08x, before reset\n", fspi_readl(FSPI_MCR0));
772 VERBOSE("Flexspi: Resetting controller...\n");
773
774 /* Reset FlexSpi Controller */
775 fspi_writel(FSPI_MCR0, FSPI_MCR0_SWRST);
776 while ((fspi_readl(FSPI_MCR0) & FSPI_MCR0_SWRST))
777 ; /* FSPI_MCR0_SWRESET_MASK */
778
779
780 /* Disable Controller Module before programming its registersi, especially MCR0 (Master Control Register0) */
781 fspi_MDIS(1);
782 /*
783 * Program MCR0 with default values, AHB Timeout(0xff), IP Timeout(0xff). {FSPI_MCR0- 0xFFFF0000}
784 */
785
786 /* Timeout wait cycle for AHB command grant */
787 mcrx = fspi_readl(FSPI_MCR0);
788 mcrx |= (uint32_t)((FSPI_MAX_TIMEOUT_AHBCMD << FSPI_MCR0_AHBGRANTWAIT_SHIFT) & (FSPI_MCR0_AHBGRANTWAIT_MASK));
789
790 /* Time out wait cycle for IP command grant*/
791 mcrx |= (uint32_t) (FSPI_MAX_TIMEOUT_IPCMD << FSPI_MCR0_IPGRANTWAIT_SHIFT) & (FSPI_MCR0_IPGRANTWAIT_MASK);
792
793 /* TODO why BE64 set BE32*/
794 mcrx |= (uint32_t) (FSPI_ENDCFG_LE64 << FSPI_MCR0_ENDCFG_SHIFT) & FSPI_MCR0_ENDCFG_MASK;
795
796 fspi_writel(FSPI_MCR0, mcrx);
797
798 /* Reset the DLL register to default value */
799 fspi_writel(FSPI_DLLACR, FSPI_DLLACR_OVRDEN);
800 fspi_writel(FSPI_DLLBCR, FSPI_DLLBCR_OVRDEN);
801
802#if ERRATA_FLASH_A050272 /* ERRATA DLL */
803 for (uint8_t delay = 100U; delay > 0U; delay--) {
804 __asm__ volatile ("nop");
805 }
806#endif
807
808 /* Configure flash control registers for different chip select */
809 flash_size = (F_FLASH_SIZE_BYTES * FLASH_NUM) / FSPI_BYTES_PER_KBYTES;
810 fspi_writel(FSPI_FLSHA1CR0, flash_size);
811 fspi_writel(FSPI_FLSHA2CR0, 0U);
812 fspi_writel(FSPI_FLSHB1CR0, 0U);
813 fspi_writel(FSPI_FLSHB2CR0, 0U);
814
815#if defined(CONFIG_FSPI_AHB)
816 fspi_init_ahb();
817#endif
818 /* RE-Enable Controller Module */
819 fspi_MDIS(0);
820 INFO("Flexspi: After MCR0 = 0x%08x,\n", fspi_readl(FSPI_MCR0));
821 fspi_setup_LUT();
822
823 /* Dump of all registers, ensure controller not disabled anymore*/
824#if defined(DEBUG_FLEXSPI)
825 fspi_dump_regs();
826#endif
827
828 INFO("Flexspi: Init done!!\n");
829
830#if DEBUG_FLEXSPI
831
832 uint32_t xspi_addr = SZ_57M;
833
834 /*
835 * Second argument of fspi_test is the size of buffer(s) passed
836 * to the function.
837 * SIZE_BUFFER defined in test_fspi.c is kept large enough to
838 * accommodate variety of sizes for regressive tests.
839 */
840 fspi_test(xspi_addr, 0x40, 0);
841 fspi_test(xspi_addr, 0x15, 2);
842 fspi_test(xspi_addr, 0x80, 0);
843 fspi_test(xspi_addr, 0x81, 0);
844 fspi_test(xspi_addr, 0x79, 3);
845
846 fspi_test(xspi_addr + 0x11, 0x15, 0);
847 fspi_test(xspi_addr + 0x11, 0x40, 0);
848 fspi_test(xspi_addr + 0xff, 0x40, 1);
849 fspi_test(xspi_addr + 0x25, 0x81, 2);
850 fspi_test(xspi_addr + 0xef, 0x6f, 3);
851
852 fspi_test((xspi_addr - F_SECTOR_ERASE_SZ), 0x229, 0);
853#endif
854
855 return XSPI_SUCCESS;
856}