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