xref: /OK3568_Linux_fs/u-boot/drivers/spi/fsl_qspi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2013-2015 Freescale Semiconductor, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Freescale Quad Serial Peripheral Interface (QSPI) driver
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <common.h>
10*4882a593Smuzhiyun #include <malloc.h>
11*4882a593Smuzhiyun #include <spi.h>
12*4882a593Smuzhiyun #include <asm/io.h>
13*4882a593Smuzhiyun #include <linux/sizes.h>
14*4882a593Smuzhiyun #include <dm.h>
15*4882a593Smuzhiyun #include <errno.h>
16*4882a593Smuzhiyun #include <watchdog.h>
17*4882a593Smuzhiyun #include <wait_bit.h>
18*4882a593Smuzhiyun #include "fsl_qspi.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define RX_BUFFER_SIZE		0x80
23*4882a593Smuzhiyun #if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \
24*4882a593Smuzhiyun 	defined(CONFIG_MX6ULL) || defined(CONFIG_MX7D)
25*4882a593Smuzhiyun #define TX_BUFFER_SIZE		0x200
26*4882a593Smuzhiyun #else
27*4882a593Smuzhiyun #define TX_BUFFER_SIZE		0x40
28*4882a593Smuzhiyun #endif
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define OFFSET_BITS_MASK	GENMASK(23, 0)
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define FLASH_STATUS_WEL	0x02
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /* SEQID */
35*4882a593Smuzhiyun #define SEQID_WREN		1
36*4882a593Smuzhiyun #define SEQID_FAST_READ		2
37*4882a593Smuzhiyun #define SEQID_RDSR		3
38*4882a593Smuzhiyun #define SEQID_SE		4
39*4882a593Smuzhiyun #define SEQID_CHIP_ERASE	5
40*4882a593Smuzhiyun #define SEQID_PP		6
41*4882a593Smuzhiyun #define SEQID_RDID		7
42*4882a593Smuzhiyun #define SEQID_BE_4K		8
43*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
44*4882a593Smuzhiyun #define SEQID_BRRD		9
45*4882a593Smuzhiyun #define SEQID_BRWR		10
46*4882a593Smuzhiyun #define SEQID_RDEAR		11
47*4882a593Smuzhiyun #define SEQID_WREAR		12
48*4882a593Smuzhiyun #endif
49*4882a593Smuzhiyun #define SEQID_WRAR		13
50*4882a593Smuzhiyun #define SEQID_RDAR		14
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /* QSPI CMD */
53*4882a593Smuzhiyun #define QSPI_CMD_PP		0x02	/* Page program (up to 256 bytes) */
54*4882a593Smuzhiyun #define QSPI_CMD_RDSR		0x05	/* Read status register */
55*4882a593Smuzhiyun #define QSPI_CMD_WREN		0x06	/* Write enable */
56*4882a593Smuzhiyun #define QSPI_CMD_FAST_READ	0x0b	/* Read data bytes (high frequency) */
57*4882a593Smuzhiyun #define QSPI_CMD_BE_4K		0x20    /* 4K erase */
58*4882a593Smuzhiyun #define QSPI_CMD_CHIP_ERASE	0xc7	/* Erase whole flash chip */
59*4882a593Smuzhiyun #define QSPI_CMD_SE		0xd8	/* Sector erase (usually 64KiB) */
60*4882a593Smuzhiyun #define QSPI_CMD_RDID		0x9f	/* Read JEDEC ID */
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun /* Used for Micron, winbond and Macronix flashes */
63*4882a593Smuzhiyun #define	QSPI_CMD_WREAR		0xc5	/* EAR register write */
64*4882a593Smuzhiyun #define	QSPI_CMD_RDEAR		0xc8	/* EAR reigster read */
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /* Used for Spansion flashes only. */
67*4882a593Smuzhiyun #define	QSPI_CMD_BRRD		0x16	/* Bank register read */
68*4882a593Smuzhiyun #define	QSPI_CMD_BRWR		0x17	/* Bank register write */
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /* Used for Spansion S25FS-S family flash only. */
71*4882a593Smuzhiyun #define QSPI_CMD_RDAR		0x65	/* Read any device register */
72*4882a593Smuzhiyun #define QSPI_CMD_WRAR		0x71	/* Write any device register */
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun /* 4-byte address QSPI CMD - used on Spansion and some Macronix flashes */
75*4882a593Smuzhiyun #define QSPI_CMD_FAST_READ_4B	0x0c    /* Read data bytes (high frequency) */
76*4882a593Smuzhiyun #define QSPI_CMD_PP_4B		0x12    /* Page program (up to 256 bytes) */
77*4882a593Smuzhiyun #define QSPI_CMD_SE_4B		0xdc    /* Sector erase (usually 64KiB) */
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /* fsl_qspi_platdata flags */
80*4882a593Smuzhiyun #define QSPI_FLAG_REGMAP_ENDIAN_BIG	BIT(0)
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /* default SCK frequency, unit: HZ */
83*4882a593Smuzhiyun #define FSL_QSPI_DEFAULT_SCK_FREQ	50000000
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun /* QSPI max chipselect signals number */
86*4882a593Smuzhiyun #define FSL_QSPI_MAX_CHIPSELECT_NUM     4
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun #ifdef CONFIG_DM_SPI
89*4882a593Smuzhiyun /**
90*4882a593Smuzhiyun  * struct fsl_qspi_platdata - platform data for Freescale QSPI
91*4882a593Smuzhiyun  *
92*4882a593Smuzhiyun  * @flags: Flags for QSPI QSPI_FLAG_...
93*4882a593Smuzhiyun  * @speed_hz: Default SCK frequency
94*4882a593Smuzhiyun  * @reg_base: Base address of QSPI registers
95*4882a593Smuzhiyun  * @amba_base: Base address of QSPI memory mapping
96*4882a593Smuzhiyun  * @amba_total_size: size of QSPI memory mapping
97*4882a593Smuzhiyun  * @flash_num: Number of active slave devices
98*4882a593Smuzhiyun  * @num_chipselect: Number of QSPI chipselect signals
99*4882a593Smuzhiyun  */
100*4882a593Smuzhiyun struct fsl_qspi_platdata {
101*4882a593Smuzhiyun 	u32 flags;
102*4882a593Smuzhiyun 	u32 speed_hz;
103*4882a593Smuzhiyun 	fdt_addr_t reg_base;
104*4882a593Smuzhiyun 	fdt_addr_t amba_base;
105*4882a593Smuzhiyun 	fdt_size_t amba_total_size;
106*4882a593Smuzhiyun 	u32 flash_num;
107*4882a593Smuzhiyun 	u32 num_chipselect;
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun #endif
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /**
112*4882a593Smuzhiyun  * struct fsl_qspi_priv - private data for Freescale QSPI
113*4882a593Smuzhiyun  *
114*4882a593Smuzhiyun  * @flags: Flags for QSPI QSPI_FLAG_...
115*4882a593Smuzhiyun  * @bus_clk: QSPI input clk frequency
116*4882a593Smuzhiyun  * @speed_hz: Default SCK frequency
117*4882a593Smuzhiyun  * @cur_seqid: current LUT table sequence id
118*4882a593Smuzhiyun  * @sf_addr: flash access offset
119*4882a593Smuzhiyun  * @amba_base: Base address of QSPI memory mapping of every CS
120*4882a593Smuzhiyun  * @amba_total_size: size of QSPI memory mapping
121*4882a593Smuzhiyun  * @cur_amba_base: Base address of QSPI memory mapping of current CS
122*4882a593Smuzhiyun  * @flash_num: Number of active slave devices
123*4882a593Smuzhiyun  * @num_chipselect: Number of QSPI chipselect signals
124*4882a593Smuzhiyun  * @regs: Point to QSPI register structure for I/O access
125*4882a593Smuzhiyun  */
126*4882a593Smuzhiyun struct fsl_qspi_priv {
127*4882a593Smuzhiyun 	u32 flags;
128*4882a593Smuzhiyun 	u32 bus_clk;
129*4882a593Smuzhiyun 	u32 speed_hz;
130*4882a593Smuzhiyun 	u32 cur_seqid;
131*4882a593Smuzhiyun 	u32 sf_addr;
132*4882a593Smuzhiyun 	u32 amba_base[FSL_QSPI_MAX_CHIPSELECT_NUM];
133*4882a593Smuzhiyun 	u32 amba_total_size;
134*4882a593Smuzhiyun 	u32 cur_amba_base;
135*4882a593Smuzhiyun 	u32 flash_num;
136*4882a593Smuzhiyun 	u32 num_chipselect;
137*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs;
138*4882a593Smuzhiyun };
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun #ifndef CONFIG_DM_SPI
141*4882a593Smuzhiyun struct fsl_qspi {
142*4882a593Smuzhiyun 	struct spi_slave slave;
143*4882a593Smuzhiyun 	struct fsl_qspi_priv priv;
144*4882a593Smuzhiyun };
145*4882a593Smuzhiyun #endif
146*4882a593Smuzhiyun 
qspi_read32(u32 flags,u32 * addr)147*4882a593Smuzhiyun static u32 qspi_read32(u32 flags, u32 *addr)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	return flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ?
150*4882a593Smuzhiyun 		in_be32(addr) : in_le32(addr);
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
qspi_write32(u32 flags,u32 * addr,u32 val)153*4882a593Smuzhiyun static void qspi_write32(u32 flags, u32 *addr, u32 val)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ?
156*4882a593Smuzhiyun 		out_be32(addr, val) : out_le32(addr, val);
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun /* QSPI support swapping the flash read/write data
160*4882a593Smuzhiyun  * in hardware for LS102xA, but not for VF610 */
qspi_endian_xchg(u32 data)161*4882a593Smuzhiyun static inline u32 qspi_endian_xchg(u32 data)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun #ifdef CONFIG_VF610
164*4882a593Smuzhiyun 	return swab32(data);
165*4882a593Smuzhiyun #else
166*4882a593Smuzhiyun 	return data;
167*4882a593Smuzhiyun #endif
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
qspi_set_lut(struct fsl_qspi_priv * priv)170*4882a593Smuzhiyun static void qspi_set_lut(struct fsl_qspi_priv *priv)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
173*4882a593Smuzhiyun 	u32 lut_base;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	/* Unlock the LUT */
176*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lutkey, LUT_KEY_VALUE);
177*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lckcr, QSPI_LCKCR_UNLOCK);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	/* Write Enable */
180*4882a593Smuzhiyun 	lut_base = SEQID_WREN * 4;
181*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_WREN) |
182*4882a593Smuzhiyun 		PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
183*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
184*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
185*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	/* Fast Read */
188*4882a593Smuzhiyun 	lut_base = SEQID_FAST_READ * 4;
189*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
190*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base],
191*4882a593Smuzhiyun 		     OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) |
192*4882a593Smuzhiyun 		     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
193*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
194*4882a593Smuzhiyun #else
195*4882a593Smuzhiyun 	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
196*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->lut[lut_base],
197*4882a593Smuzhiyun 			     OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) |
198*4882a593Smuzhiyun 			     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
199*4882a593Smuzhiyun 			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
200*4882a593Smuzhiyun 	else
201*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->lut[lut_base],
202*4882a593Smuzhiyun 			     OPRND0(QSPI_CMD_FAST_READ_4B) |
203*4882a593Smuzhiyun 			     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) |
204*4882a593Smuzhiyun 			     OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) |
205*4882a593Smuzhiyun 			     INSTR1(LUT_ADDR));
206*4882a593Smuzhiyun #endif
207*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
208*4882a593Smuzhiyun 		     OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |
209*4882a593Smuzhiyun 		     OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) |
210*4882a593Smuzhiyun 		     INSTR1(LUT_READ));
211*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
212*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	/* Read Status */
215*4882a593Smuzhiyun 	lut_base = SEQID_RDSR * 4;
216*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDSR) |
217*4882a593Smuzhiyun 		PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
218*4882a593Smuzhiyun 		PAD1(LUT_PAD1) | INSTR1(LUT_READ));
219*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
220*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
221*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	/* Erase a sector */
224*4882a593Smuzhiyun 	lut_base = SEQID_SE * 4;
225*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
226*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_SE) |
227*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
228*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
229*4882a593Smuzhiyun #else
230*4882a593Smuzhiyun 	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
231*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->lut[lut_base],
232*4882a593Smuzhiyun 			     OPRND0(QSPI_CMD_SE) | PAD0(LUT_PAD1) |
233*4882a593Smuzhiyun 			     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
234*4882a593Smuzhiyun 			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
235*4882a593Smuzhiyun 	else
236*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->lut[lut_base],
237*4882a593Smuzhiyun 			     OPRND0(QSPI_CMD_SE_4B) | PAD0(LUT_PAD1) |
238*4882a593Smuzhiyun 			     INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
239*4882a593Smuzhiyun 			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
240*4882a593Smuzhiyun #endif
241*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
242*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
243*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	/* Erase the whole chip */
246*4882a593Smuzhiyun 	lut_base = SEQID_CHIP_ERASE * 4;
247*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base],
248*4882a593Smuzhiyun 		     OPRND0(QSPI_CMD_CHIP_ERASE) |
249*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
250*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
251*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
252*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	/* Page Program */
255*4882a593Smuzhiyun 	lut_base = SEQID_PP * 4;
256*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
257*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_PP) |
258*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
259*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
260*4882a593Smuzhiyun #else
261*4882a593Smuzhiyun 	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
262*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->lut[lut_base],
263*4882a593Smuzhiyun 			     OPRND0(QSPI_CMD_PP) | PAD0(LUT_PAD1) |
264*4882a593Smuzhiyun 			     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
265*4882a593Smuzhiyun 			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
266*4882a593Smuzhiyun 	else
267*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->lut[lut_base],
268*4882a593Smuzhiyun 			     OPRND0(QSPI_CMD_PP_4B) | PAD0(LUT_PAD1) |
269*4882a593Smuzhiyun 			     INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
270*4882a593Smuzhiyun 			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
271*4882a593Smuzhiyun #endif
272*4882a593Smuzhiyun #if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \
273*4882a593Smuzhiyun 	defined(CONFIG_MX6ULL) || defined(CONFIG_MX7D)
274*4882a593Smuzhiyun 	/*
275*4882a593Smuzhiyun 	 * To MX6SX, OPRND0(TX_BUFFER_SIZE) can not work correctly.
276*4882a593Smuzhiyun 	 * So, Use IDATSZ in IPCR to determine the size and here set 0.
277*4882a593Smuzhiyun 	 */
278*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1], OPRND0(0) |
279*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
280*4882a593Smuzhiyun #else
281*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
282*4882a593Smuzhiyun 		     OPRND0(TX_BUFFER_SIZE) |
283*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
284*4882a593Smuzhiyun #endif
285*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
286*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/* READ ID */
289*4882a593Smuzhiyun 	lut_base = SEQID_RDID * 4;
290*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDID) |
291*4882a593Smuzhiyun 		PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) |
292*4882a593Smuzhiyun 		PAD1(LUT_PAD1) | INSTR1(LUT_READ));
293*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
294*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
295*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	/* SUB SECTOR 4K ERASE */
298*4882a593Smuzhiyun 	lut_base = SEQID_BE_4K * 4;
299*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) |
300*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
301*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
304*4882a593Smuzhiyun 	/*
305*4882a593Smuzhiyun 	 * BRRD BRWR RDEAR WREAR are all supported, because it is hard to
306*4882a593Smuzhiyun 	 * dynamically check whether to set BRRD BRWR or RDEAR WREAR during
307*4882a593Smuzhiyun 	 * initialization.
308*4882a593Smuzhiyun 	 */
309*4882a593Smuzhiyun 	lut_base = SEQID_BRRD * 4;
310*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BRRD) |
311*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
312*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_READ));
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	lut_base = SEQID_BRWR * 4;
315*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BRWR) |
316*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
317*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	lut_base = SEQID_RDEAR * 4;
320*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) |
321*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
322*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_READ));
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	lut_base = SEQID_WREAR * 4;
325*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_WREAR) |
326*4882a593Smuzhiyun 		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
327*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));
328*4882a593Smuzhiyun #endif
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	/*
331*4882a593Smuzhiyun 	 * Read any device register.
332*4882a593Smuzhiyun 	 * Used for Spansion S25FS-S family flash only.
333*4882a593Smuzhiyun 	 */
334*4882a593Smuzhiyun 	lut_base = SEQID_RDAR * 4;
335*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base],
336*4882a593Smuzhiyun 		     OPRND0(QSPI_CMD_RDAR) | PAD0(LUT_PAD1) |
337*4882a593Smuzhiyun 		     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
338*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
339*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
340*4882a593Smuzhiyun 		     OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |
341*4882a593Smuzhiyun 		     OPRND1(1) | PAD1(LUT_PAD1) |
342*4882a593Smuzhiyun 		     INSTR1(LUT_READ));
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	/*
345*4882a593Smuzhiyun 	 * Write any device register.
346*4882a593Smuzhiyun 	 * Used for Spansion S25FS-S family flash only.
347*4882a593Smuzhiyun 	 */
348*4882a593Smuzhiyun 	lut_base = SEQID_WRAR * 4;
349*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base],
350*4882a593Smuzhiyun 		     OPRND0(QSPI_CMD_WRAR) | PAD0(LUT_PAD1) |
351*4882a593Smuzhiyun 		     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
352*4882a593Smuzhiyun 		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
353*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
354*4882a593Smuzhiyun 		     OPRND0(1) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	/* Lock the LUT */
357*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lutkey, LUT_KEY_VALUE);
358*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->lckcr, QSPI_LCKCR_LOCK);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun #if defined(CONFIG_SYS_FSL_QSPI_AHB)
362*4882a593Smuzhiyun /*
363*4882a593Smuzhiyun  * If we have changed the content of the flash by writing or erasing,
364*4882a593Smuzhiyun  * we need to invalidate the AHB buffer. If we do not do so, we may read out
365*4882a593Smuzhiyun  * the wrong data. The spec tells us reset the AHB domain and Serial Flash
366*4882a593Smuzhiyun  * domain at the same time.
367*4882a593Smuzhiyun  */
qspi_ahb_invalid(struct fsl_qspi_priv * priv)368*4882a593Smuzhiyun static inline void qspi_ahb_invalid(struct fsl_qspi_priv *priv)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
371*4882a593Smuzhiyun 	u32 reg;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	reg = qspi_read32(priv->flags, &regs->mcr);
374*4882a593Smuzhiyun 	reg |= QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK;
375*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, reg);
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	/*
378*4882a593Smuzhiyun 	 * The minimum delay : 1 AHB + 2 SFCK clocks.
379*4882a593Smuzhiyun 	 * Delay 1 us is enough.
380*4882a593Smuzhiyun 	 */
381*4882a593Smuzhiyun 	udelay(1);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	reg &= ~(QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK);
384*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, reg);
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun /* Read out the data from the AHB buffer. */
qspi_ahb_read(struct fsl_qspi_priv * priv,u8 * rxbuf,int len)388*4882a593Smuzhiyun static inline void qspi_ahb_read(struct fsl_qspi_priv *priv, u8 *rxbuf, int len)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
391*4882a593Smuzhiyun 	u32 mcr_reg;
392*4882a593Smuzhiyun 	void *rx_addr = NULL;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr,
397*4882a593Smuzhiyun 		     QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
398*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	rx_addr = (void *)(uintptr_t)(priv->cur_amba_base + priv->sf_addr);
401*4882a593Smuzhiyun 	/* Read out the data directly from the AHB buffer. */
402*4882a593Smuzhiyun 	memcpy(rxbuf, rx_addr, len);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun 
qspi_enable_ddr_mode(struct fsl_qspi_priv * priv)407*4882a593Smuzhiyun static void qspi_enable_ddr_mode(struct fsl_qspi_priv *priv)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	u32 reg, reg2;
410*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	reg = qspi_read32(priv->flags, &regs->mcr);
413*4882a593Smuzhiyun 	/* Disable the module */
414*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, reg | QSPI_MCR_MDIS_MASK);
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	/* Set the Sampling Register for DDR */
417*4882a593Smuzhiyun 	reg2 = qspi_read32(priv->flags, &regs->smpr);
418*4882a593Smuzhiyun 	reg2 &= ~QSPI_SMPR_DDRSMP_MASK;
419*4882a593Smuzhiyun 	reg2 |= (2 << QSPI_SMPR_DDRSMP_SHIFT);
420*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->smpr, reg2);
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	/* Enable the module again (enable the DDR too) */
423*4882a593Smuzhiyun 	reg |= QSPI_MCR_DDR_EN_MASK;
424*4882a593Smuzhiyun 	/* Enable bit 29 for imx6sx */
425*4882a593Smuzhiyun 	reg |= BIT(29);
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, reg);
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun /*
431*4882a593Smuzhiyun  * There are two different ways to read out the data from the flash:
432*4882a593Smuzhiyun  *  the "IP Command Read" and the "AHB Command Read".
433*4882a593Smuzhiyun  *
434*4882a593Smuzhiyun  * The IC guy suggests we use the "AHB Command Read" which is faster
435*4882a593Smuzhiyun  * then the "IP Command Read". (What's more is that there is a bug in
436*4882a593Smuzhiyun  * the "IP Command Read" in the Vybrid.)
437*4882a593Smuzhiyun  *
438*4882a593Smuzhiyun  * After we set up the registers for the "AHB Command Read", we can use
439*4882a593Smuzhiyun  * the memcpy to read the data directly. A "missed" access to the buffer
440*4882a593Smuzhiyun  * causes the controller to clear the buffer, and use the sequence pointed
441*4882a593Smuzhiyun  * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
442*4882a593Smuzhiyun  */
qspi_init_ahb_read(struct fsl_qspi_priv * priv)443*4882a593Smuzhiyun static void qspi_init_ahb_read(struct fsl_qspi_priv *priv)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	/* AHB configuration for access buffer 0/1/2 .*/
448*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->buf0cr, QSPI_BUFXCR_INVALID_MSTRID);
449*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->buf1cr, QSPI_BUFXCR_INVALID_MSTRID);
450*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->buf2cr, QSPI_BUFXCR_INVALID_MSTRID);
451*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->buf3cr, QSPI_BUF3CR_ALLMST_MASK |
452*4882a593Smuzhiyun 		     (0x80 << QSPI_BUF3CR_ADATSZ_SHIFT));
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	/* We only use the buffer3 */
455*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->buf0ind, 0);
456*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->buf1ind, 0);
457*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->buf2ind, 0);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	/*
460*4882a593Smuzhiyun 	 * Set the default lut sequence for AHB Read.
461*4882a593Smuzhiyun 	 * Parallel mode is disabled.
462*4882a593Smuzhiyun 	 */
463*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->bfgencr,
464*4882a593Smuzhiyun 		     SEQID_FAST_READ << QSPI_BFGENCR_SEQID_SHIFT);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	/*Enable DDR Mode*/
467*4882a593Smuzhiyun 	qspi_enable_ddr_mode(priv);
468*4882a593Smuzhiyun }
469*4882a593Smuzhiyun #endif
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
472*4882a593Smuzhiyun /* Bank register read/write, EAR register read/write */
qspi_op_rdbank(struct fsl_qspi_priv * priv,u8 * rxbuf,u32 len)473*4882a593Smuzhiyun static void qspi_op_rdbank(struct fsl_qspi_priv *priv, u8 *rxbuf, u32 len)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
476*4882a593Smuzhiyun 	u32 reg, mcr_reg, data, seqid;
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
479*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr,
480*4882a593Smuzhiyun 		     QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
481*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
482*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	if (priv->cur_seqid == QSPI_CMD_BRRD)
487*4882a593Smuzhiyun 		seqid = SEQID_BRRD;
488*4882a593Smuzhiyun 	else
489*4882a593Smuzhiyun 		seqid = SEQID_RDEAR;
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->ipcr,
492*4882a593Smuzhiyun 		     (seqid << QSPI_IPCR_SEQID_SHIFT) | len);
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	/* Wait previous command complete */
495*4882a593Smuzhiyun 	while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
496*4882a593Smuzhiyun 		;
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	while (1) {
499*4882a593Smuzhiyun 		WATCHDOG_RESET();
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 		reg = qspi_read32(priv->flags, &regs->rbsr);
502*4882a593Smuzhiyun 		if (reg & QSPI_RBSR_RDBFL_MASK) {
503*4882a593Smuzhiyun 			data = qspi_read32(priv->flags, &regs->rbdr[0]);
504*4882a593Smuzhiyun 			data = qspi_endian_xchg(data);
505*4882a593Smuzhiyun 			memcpy(rxbuf, &data, len);
506*4882a593Smuzhiyun 			qspi_write32(priv->flags, &regs->mcr,
507*4882a593Smuzhiyun 				     qspi_read32(priv->flags, &regs->mcr) |
508*4882a593Smuzhiyun 				     QSPI_MCR_CLR_RXF_MASK);
509*4882a593Smuzhiyun 			break;
510*4882a593Smuzhiyun 		}
511*4882a593Smuzhiyun 	}
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun #endif
516*4882a593Smuzhiyun 
qspi_op_rdid(struct fsl_qspi_priv * priv,u32 * rxbuf,u32 len)517*4882a593Smuzhiyun static void qspi_op_rdid(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
518*4882a593Smuzhiyun {
519*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
520*4882a593Smuzhiyun 	u32 mcr_reg, rbsr_reg, data, size;
521*4882a593Smuzhiyun 	int i;
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
524*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr,
525*4882a593Smuzhiyun 		     QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
526*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
527*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->ipcr,
532*4882a593Smuzhiyun 		     (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0);
533*4882a593Smuzhiyun 	while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
534*4882a593Smuzhiyun 		;
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	i = 0;
537*4882a593Smuzhiyun 	while ((RX_BUFFER_SIZE >= len) && (len > 0)) {
538*4882a593Smuzhiyun 		WATCHDOG_RESET();
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 		rbsr_reg = qspi_read32(priv->flags, &regs->rbsr);
541*4882a593Smuzhiyun 		if (rbsr_reg & QSPI_RBSR_RDBFL_MASK) {
542*4882a593Smuzhiyun 			data = qspi_read32(priv->flags, &regs->rbdr[i]);
543*4882a593Smuzhiyun 			data = qspi_endian_xchg(data);
544*4882a593Smuzhiyun 			size = (len < 4) ? len : 4;
545*4882a593Smuzhiyun 			memcpy(rxbuf, &data, size);
546*4882a593Smuzhiyun 			len -= size;
547*4882a593Smuzhiyun 			rxbuf++;
548*4882a593Smuzhiyun 			i++;
549*4882a593Smuzhiyun 		}
550*4882a593Smuzhiyun 	}
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
553*4882a593Smuzhiyun }
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun /* If not use AHB read, read data from ip interface */
qspi_op_read(struct fsl_qspi_priv * priv,u32 * rxbuf,u32 len)556*4882a593Smuzhiyun static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
559*4882a593Smuzhiyun 	u32 mcr_reg, data;
560*4882a593Smuzhiyun 	int i, size;
561*4882a593Smuzhiyun 	u32 to_or_from;
562*4882a593Smuzhiyun 	u32 seqid;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	if (priv->cur_seqid == QSPI_CMD_RDAR)
565*4882a593Smuzhiyun 		seqid = SEQID_RDAR;
566*4882a593Smuzhiyun 	else
567*4882a593Smuzhiyun 		seqid = SEQID_FAST_READ;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
570*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr,
571*4882a593Smuzhiyun 		     QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
572*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
573*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 	to_or_from = priv->sf_addr + priv->cur_amba_base;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	while (len > 0) {
578*4882a593Smuzhiyun 		WATCHDOG_RESET();
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->sfar, to_or_from);
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 		size = (len > RX_BUFFER_SIZE) ?
583*4882a593Smuzhiyun 			RX_BUFFER_SIZE : len;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->ipcr,
586*4882a593Smuzhiyun 			     (seqid << QSPI_IPCR_SEQID_SHIFT) |
587*4882a593Smuzhiyun 			     size);
588*4882a593Smuzhiyun 		while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
589*4882a593Smuzhiyun 			;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 		to_or_from += size;
592*4882a593Smuzhiyun 		len -= size;
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 		i = 0;
595*4882a593Smuzhiyun 		while ((RX_BUFFER_SIZE >= size) && (size > 0)) {
596*4882a593Smuzhiyun 			data = qspi_read32(priv->flags, &regs->rbdr[i]);
597*4882a593Smuzhiyun 			data = qspi_endian_xchg(data);
598*4882a593Smuzhiyun 			if (size < 4)
599*4882a593Smuzhiyun 				memcpy(rxbuf, &data, size);
600*4882a593Smuzhiyun 			else
601*4882a593Smuzhiyun 				memcpy(rxbuf, &data, 4);
602*4882a593Smuzhiyun 			rxbuf++;
603*4882a593Smuzhiyun 			size -= 4;
604*4882a593Smuzhiyun 			i++;
605*4882a593Smuzhiyun 		}
606*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->mcr,
607*4882a593Smuzhiyun 			     qspi_read32(priv->flags, &regs->mcr) |
608*4882a593Smuzhiyun 			     QSPI_MCR_CLR_RXF_MASK);
609*4882a593Smuzhiyun 	}
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun 
qspi_op_write(struct fsl_qspi_priv * priv,u8 * txbuf,u32 len)614*4882a593Smuzhiyun static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len)
615*4882a593Smuzhiyun {
616*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
617*4882a593Smuzhiyun 	u32 mcr_reg, data, reg, status_reg, seqid;
618*4882a593Smuzhiyun 	int i, size, tx_size;
619*4882a593Smuzhiyun 	u32 to_or_from = 0;
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
622*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr,
623*4882a593Smuzhiyun 		     QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
624*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
625*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	status_reg = 0;
628*4882a593Smuzhiyun 	while ((status_reg & FLASH_STATUS_WEL) != FLASH_STATUS_WEL) {
629*4882a593Smuzhiyun 		WATCHDOG_RESET();
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->ipcr,
632*4882a593Smuzhiyun 			     (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
633*4882a593Smuzhiyun 		while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
634*4882a593Smuzhiyun 			;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->ipcr,
637*4882a593Smuzhiyun 			     (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1);
638*4882a593Smuzhiyun 		while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
639*4882a593Smuzhiyun 			;
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 		reg = qspi_read32(priv->flags, &regs->rbsr);
642*4882a593Smuzhiyun 		if (reg & QSPI_RBSR_RDBFL_MASK) {
643*4882a593Smuzhiyun 			status_reg = qspi_read32(priv->flags, &regs->rbdr[0]);
644*4882a593Smuzhiyun 			status_reg = qspi_endian_xchg(status_reg);
645*4882a593Smuzhiyun 		}
646*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->mcr,
647*4882a593Smuzhiyun 			     qspi_read32(priv->flags, &regs->mcr) |
648*4882a593Smuzhiyun 			     QSPI_MCR_CLR_RXF_MASK);
649*4882a593Smuzhiyun 	}
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	/* Default is page programming */
652*4882a593Smuzhiyun 	seqid = SEQID_PP;
653*4882a593Smuzhiyun 	if (priv->cur_seqid == QSPI_CMD_WRAR)
654*4882a593Smuzhiyun 		seqid = SEQID_WRAR;
655*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
656*4882a593Smuzhiyun 	if (priv->cur_seqid == QSPI_CMD_BRWR)
657*4882a593Smuzhiyun 		seqid = SEQID_BRWR;
658*4882a593Smuzhiyun 	else if (priv->cur_seqid == QSPI_CMD_WREAR)
659*4882a593Smuzhiyun 		seqid = SEQID_WREAR;
660*4882a593Smuzhiyun #endif
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	to_or_from = priv->sf_addr + priv->cur_amba_base;
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->sfar, to_or_from);
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	tx_size = (len > TX_BUFFER_SIZE) ?
667*4882a593Smuzhiyun 		TX_BUFFER_SIZE : len;
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	size = tx_size / 16;
670*4882a593Smuzhiyun 	/*
671*4882a593Smuzhiyun 	 * There must be atleast 128bit data
672*4882a593Smuzhiyun 	 * available in TX FIFO for any pop operation
673*4882a593Smuzhiyun 	 */
674*4882a593Smuzhiyun 	if (tx_size % 16)
675*4882a593Smuzhiyun 		size++;
676*4882a593Smuzhiyun 	for (i = 0; i < size * 4; i++) {
677*4882a593Smuzhiyun 		memcpy(&data, txbuf, 4);
678*4882a593Smuzhiyun 		data = qspi_endian_xchg(data);
679*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->tbdr, data);
680*4882a593Smuzhiyun 		txbuf += 4;
681*4882a593Smuzhiyun 	}
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->ipcr,
684*4882a593Smuzhiyun 		     (seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size);
685*4882a593Smuzhiyun 	while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
686*4882a593Smuzhiyun 		;
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun 
qspi_op_rdsr(struct fsl_qspi_priv * priv,void * rxbuf,u32 len)691*4882a593Smuzhiyun static void qspi_op_rdsr(struct fsl_qspi_priv *priv, void *rxbuf, u32 len)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
694*4882a593Smuzhiyun 	u32 mcr_reg, reg, data;
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
697*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr,
698*4882a593Smuzhiyun 		     QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
699*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
700*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->ipcr,
705*4882a593Smuzhiyun 		     (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0);
706*4882a593Smuzhiyun 	while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
707*4882a593Smuzhiyun 		;
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	while (1) {
710*4882a593Smuzhiyun 		WATCHDOG_RESET();
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 		reg = qspi_read32(priv->flags, &regs->rbsr);
713*4882a593Smuzhiyun 		if (reg & QSPI_RBSR_RDBFL_MASK) {
714*4882a593Smuzhiyun 			data = qspi_read32(priv->flags, &regs->rbdr[0]);
715*4882a593Smuzhiyun 			data = qspi_endian_xchg(data);
716*4882a593Smuzhiyun 			memcpy(rxbuf, &data, len);
717*4882a593Smuzhiyun 			qspi_write32(priv->flags, &regs->mcr,
718*4882a593Smuzhiyun 				     qspi_read32(priv->flags, &regs->mcr) |
719*4882a593Smuzhiyun 				     QSPI_MCR_CLR_RXF_MASK);
720*4882a593Smuzhiyun 			break;
721*4882a593Smuzhiyun 		}
722*4882a593Smuzhiyun 	}
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
725*4882a593Smuzhiyun }
726*4882a593Smuzhiyun 
qspi_op_erase(struct fsl_qspi_priv * priv)727*4882a593Smuzhiyun static void qspi_op_erase(struct fsl_qspi_priv *priv)
728*4882a593Smuzhiyun {
729*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs = priv->regs;
730*4882a593Smuzhiyun 	u32 mcr_reg;
731*4882a593Smuzhiyun 	u32 to_or_from = 0;
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
734*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr,
735*4882a593Smuzhiyun 		     QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
736*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
737*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 	to_or_from = priv->sf_addr + priv->cur_amba_base;
740*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->sfar, to_or_from);
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->ipcr,
743*4882a593Smuzhiyun 		     (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
744*4882a593Smuzhiyun 	while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
745*4882a593Smuzhiyun 		;
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	if (priv->cur_seqid == QSPI_CMD_SE) {
748*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->ipcr,
749*4882a593Smuzhiyun 			     (SEQID_SE << QSPI_IPCR_SEQID_SHIFT) | 0);
750*4882a593Smuzhiyun 	} else if (priv->cur_seqid == QSPI_CMD_BE_4K) {
751*4882a593Smuzhiyun 		qspi_write32(priv->flags, &regs->ipcr,
752*4882a593Smuzhiyun 			     (SEQID_BE_4K << QSPI_IPCR_SEQID_SHIFT) | 0);
753*4882a593Smuzhiyun 	}
754*4882a593Smuzhiyun 	while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
755*4882a593Smuzhiyun 		;
756*4882a593Smuzhiyun 
757*4882a593Smuzhiyun 	qspi_write32(priv->flags, &regs->mcr, mcr_reg);
758*4882a593Smuzhiyun }
759*4882a593Smuzhiyun 
qspi_xfer(struct fsl_qspi_priv * priv,unsigned int bitlen,const void * dout,void * din,unsigned long flags)760*4882a593Smuzhiyun int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen,
761*4882a593Smuzhiyun 		const void *dout, void *din, unsigned long flags)
762*4882a593Smuzhiyun {
763*4882a593Smuzhiyun 	u32 bytes = DIV_ROUND_UP(bitlen, 8);
764*4882a593Smuzhiyun 	static u32 wr_sfaddr;
765*4882a593Smuzhiyun 	u32 txbuf;
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 	WATCHDOG_RESET();
768*4882a593Smuzhiyun 
769*4882a593Smuzhiyun 	if (dout) {
770*4882a593Smuzhiyun 		if (flags & SPI_XFER_BEGIN) {
771*4882a593Smuzhiyun 			priv->cur_seqid = *(u8 *)dout;
772*4882a593Smuzhiyun 			memcpy(&txbuf, dout, 4);
773*4882a593Smuzhiyun 		}
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 		if (flags == SPI_XFER_END) {
776*4882a593Smuzhiyun 			priv->sf_addr = wr_sfaddr;
777*4882a593Smuzhiyun 			qspi_op_write(priv, (u8 *)dout, bytes);
778*4882a593Smuzhiyun 			return 0;
779*4882a593Smuzhiyun 		}
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun 		if (priv->cur_seqid == QSPI_CMD_FAST_READ ||
782*4882a593Smuzhiyun 		    priv->cur_seqid == QSPI_CMD_RDAR) {
783*4882a593Smuzhiyun 			priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
784*4882a593Smuzhiyun 		} else if ((priv->cur_seqid == QSPI_CMD_SE) ||
785*4882a593Smuzhiyun 			   (priv->cur_seqid == QSPI_CMD_BE_4K)) {
786*4882a593Smuzhiyun 			priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
787*4882a593Smuzhiyun 			qspi_op_erase(priv);
788*4882a593Smuzhiyun 		} else if (priv->cur_seqid == QSPI_CMD_PP ||
789*4882a593Smuzhiyun 			   priv->cur_seqid == QSPI_CMD_WRAR) {
790*4882a593Smuzhiyun 			wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK;
791*4882a593Smuzhiyun 		} else if ((priv->cur_seqid == QSPI_CMD_BRWR) ||
792*4882a593Smuzhiyun 			 (priv->cur_seqid == QSPI_CMD_WREAR)) {
793*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
794*4882a593Smuzhiyun 			wr_sfaddr = 0;
795*4882a593Smuzhiyun #endif
796*4882a593Smuzhiyun 		}
797*4882a593Smuzhiyun 	}
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun 	if (din) {
800*4882a593Smuzhiyun 		if (priv->cur_seqid == QSPI_CMD_FAST_READ) {
801*4882a593Smuzhiyun #ifdef CONFIG_SYS_FSL_QSPI_AHB
802*4882a593Smuzhiyun 			qspi_ahb_read(priv, din, bytes);
803*4882a593Smuzhiyun #else
804*4882a593Smuzhiyun 			qspi_op_read(priv, din, bytes);
805*4882a593Smuzhiyun #endif
806*4882a593Smuzhiyun 		} else if (priv->cur_seqid == QSPI_CMD_RDAR) {
807*4882a593Smuzhiyun 			qspi_op_read(priv, din, bytes);
808*4882a593Smuzhiyun 		} else if (priv->cur_seqid == QSPI_CMD_RDID)
809*4882a593Smuzhiyun 			qspi_op_rdid(priv, din, bytes);
810*4882a593Smuzhiyun 		else if (priv->cur_seqid == QSPI_CMD_RDSR)
811*4882a593Smuzhiyun 			qspi_op_rdsr(priv, din, bytes);
812*4882a593Smuzhiyun #ifdef CONFIG_SPI_FLASH_BAR
813*4882a593Smuzhiyun 		else if ((priv->cur_seqid == QSPI_CMD_BRRD) ||
814*4882a593Smuzhiyun 			 (priv->cur_seqid == QSPI_CMD_RDEAR)) {
815*4882a593Smuzhiyun 			priv->sf_addr = 0;
816*4882a593Smuzhiyun 			qspi_op_rdbank(priv, din, bytes);
817*4882a593Smuzhiyun 		}
818*4882a593Smuzhiyun #endif
819*4882a593Smuzhiyun 	}
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun #ifdef CONFIG_SYS_FSL_QSPI_AHB
822*4882a593Smuzhiyun 	if ((priv->cur_seqid == QSPI_CMD_SE) ||
823*4882a593Smuzhiyun 	    (priv->cur_seqid == QSPI_CMD_PP) ||
824*4882a593Smuzhiyun 	    (priv->cur_seqid == QSPI_CMD_BE_4K) ||
825*4882a593Smuzhiyun 	    (priv->cur_seqid == QSPI_CMD_WREAR) ||
826*4882a593Smuzhiyun 	    (priv->cur_seqid == QSPI_CMD_BRWR))
827*4882a593Smuzhiyun 		qspi_ahb_invalid(priv);
828*4882a593Smuzhiyun #endif
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	return 0;
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun 
qspi_module_disable(struct fsl_qspi_priv * priv,u8 disable)833*4882a593Smuzhiyun void qspi_module_disable(struct fsl_qspi_priv *priv, u8 disable)
834*4882a593Smuzhiyun {
835*4882a593Smuzhiyun 	u32 mcr_val;
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun 	mcr_val = qspi_read32(priv->flags, &priv->regs->mcr);
838*4882a593Smuzhiyun 	if (disable)
839*4882a593Smuzhiyun 		mcr_val |= QSPI_MCR_MDIS_MASK;
840*4882a593Smuzhiyun 	else
841*4882a593Smuzhiyun 		mcr_val &= ~QSPI_MCR_MDIS_MASK;
842*4882a593Smuzhiyun 	qspi_write32(priv->flags, &priv->regs->mcr, mcr_val);
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun 
qspi_cfg_smpr(struct fsl_qspi_priv * priv,u32 clear_bits,u32 set_bits)845*4882a593Smuzhiyun void qspi_cfg_smpr(struct fsl_qspi_priv *priv, u32 clear_bits, u32 set_bits)
846*4882a593Smuzhiyun {
847*4882a593Smuzhiyun 	u32 smpr_val;
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun 	smpr_val = qspi_read32(priv->flags, &priv->regs->smpr);
850*4882a593Smuzhiyun 	smpr_val &= ~clear_bits;
851*4882a593Smuzhiyun 	smpr_val |= set_bits;
852*4882a593Smuzhiyun 	qspi_write32(priv->flags, &priv->regs->smpr, smpr_val);
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun #ifndef CONFIG_DM_SPI
855*4882a593Smuzhiyun static unsigned long spi_bases[] = {
856*4882a593Smuzhiyun 	QSPI0_BASE_ADDR,
857*4882a593Smuzhiyun #ifdef CONFIG_MX6SX
858*4882a593Smuzhiyun 	QSPI1_BASE_ADDR,
859*4882a593Smuzhiyun #endif
860*4882a593Smuzhiyun };
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun static unsigned long amba_bases[] = {
863*4882a593Smuzhiyun 	QSPI0_AMBA_BASE,
864*4882a593Smuzhiyun #ifdef CONFIG_MX6SX
865*4882a593Smuzhiyun 	QSPI1_AMBA_BASE,
866*4882a593Smuzhiyun #endif
867*4882a593Smuzhiyun };
868*4882a593Smuzhiyun 
to_qspi_spi(struct spi_slave * slave)869*4882a593Smuzhiyun static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave)
870*4882a593Smuzhiyun {
871*4882a593Smuzhiyun 	return container_of(slave, struct fsl_qspi, slave);
872*4882a593Smuzhiyun }
873*4882a593Smuzhiyun 
spi_setup_slave(unsigned int bus,unsigned int cs,unsigned int max_hz,unsigned int mode)874*4882a593Smuzhiyun struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
875*4882a593Smuzhiyun 		unsigned int max_hz, unsigned int mode)
876*4882a593Smuzhiyun {
877*4882a593Smuzhiyun 	u32 mcr_val;
878*4882a593Smuzhiyun 	struct fsl_qspi *qspi;
879*4882a593Smuzhiyun 	struct fsl_qspi_regs *regs;
880*4882a593Smuzhiyun 	u32 total_size;
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 	if (bus >= ARRAY_SIZE(spi_bases))
883*4882a593Smuzhiyun 		return NULL;
884*4882a593Smuzhiyun 
885*4882a593Smuzhiyun 	if (cs >= FSL_QSPI_FLASH_NUM)
886*4882a593Smuzhiyun 		return NULL;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	qspi = spi_alloc_slave(struct fsl_qspi, bus, cs);
889*4882a593Smuzhiyun 	if (!qspi)
890*4882a593Smuzhiyun 		return NULL;
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun #ifdef CONFIG_SYS_FSL_QSPI_BE
893*4882a593Smuzhiyun 	qspi->priv.flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG;
894*4882a593Smuzhiyun #endif
895*4882a593Smuzhiyun 
896*4882a593Smuzhiyun 	regs = (struct fsl_qspi_regs *)spi_bases[bus];
897*4882a593Smuzhiyun 	qspi->priv.regs = regs;
898*4882a593Smuzhiyun 	/*
899*4882a593Smuzhiyun 	 * According cs, use different amba_base to choose the
900*4882a593Smuzhiyun 	 * corresponding flash devices.
901*4882a593Smuzhiyun 	 *
902*4882a593Smuzhiyun 	 * If not, only one flash device is used even if passing
903*4882a593Smuzhiyun 	 * different cs using `sf probe`
904*4882a593Smuzhiyun 	 */
905*4882a593Smuzhiyun 	qspi->priv.cur_amba_base = amba_bases[bus] + cs * FSL_QSPI_FLASH_SIZE;
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun 	qspi->slave.max_write_size = TX_BUFFER_SIZE;
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun 	mcr_val = qspi_read32(qspi->priv.flags, &regs->mcr);
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	/* Set endianness to LE for i.mx */
912*4882a593Smuzhiyun 	if (IS_ENABLED(CONFIG_MX6) || IS_ENABLED(CONFIG_MX7))
913*4882a593Smuzhiyun 		mcr_val = QSPI_MCR_END_CFD_LE;
914*4882a593Smuzhiyun 
915*4882a593Smuzhiyun 	qspi_write32(qspi->priv.flags, &regs->mcr,
916*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |
917*4882a593Smuzhiyun 		     (mcr_val & QSPI_MCR_END_CFD_MASK));
918*4882a593Smuzhiyun 
919*4882a593Smuzhiyun 	qspi_cfg_smpr(&qspi->priv,
920*4882a593Smuzhiyun 		      ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK |
921*4882a593Smuzhiyun 		      QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0);
922*4882a593Smuzhiyun 
923*4882a593Smuzhiyun 	total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM;
924*4882a593Smuzhiyun 	/*
925*4882a593Smuzhiyun 	 * Any read access to non-implemented addresses will provide
926*4882a593Smuzhiyun 	 * undefined results.
927*4882a593Smuzhiyun 	 *
928*4882a593Smuzhiyun 	 * In case single die flash devices, TOP_ADDR_MEMA2 and
929*4882a593Smuzhiyun 	 * TOP_ADDR_MEMB2 should be initialized/programmed to
930*4882a593Smuzhiyun 	 * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect,
931*4882a593Smuzhiyun 	 * setting the size of these devices to 0.  This would ensure
932*4882a593Smuzhiyun 	 * that the complete memory map is assigned to only one flash device.
933*4882a593Smuzhiyun 	 */
934*4882a593Smuzhiyun 	qspi_write32(qspi->priv.flags, &regs->sfa1ad,
935*4882a593Smuzhiyun 		     FSL_QSPI_FLASH_SIZE | amba_bases[bus]);
936*4882a593Smuzhiyun 	qspi_write32(qspi->priv.flags, &regs->sfa2ad,
937*4882a593Smuzhiyun 		     FSL_QSPI_FLASH_SIZE | amba_bases[bus]);
938*4882a593Smuzhiyun 	qspi_write32(qspi->priv.flags, &regs->sfb1ad,
939*4882a593Smuzhiyun 		     total_size | amba_bases[bus]);
940*4882a593Smuzhiyun 	qspi_write32(qspi->priv.flags, &regs->sfb2ad,
941*4882a593Smuzhiyun 		     total_size | amba_bases[bus]);
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	qspi_set_lut(&qspi->priv);
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun #ifdef CONFIG_SYS_FSL_QSPI_AHB
946*4882a593Smuzhiyun 	qspi_init_ahb_read(&qspi->priv);
947*4882a593Smuzhiyun #endif
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun 	qspi_module_disable(&qspi->priv, 0);
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	return &qspi->slave;
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun 
spi_free_slave(struct spi_slave * slave)954*4882a593Smuzhiyun void spi_free_slave(struct spi_slave *slave)
955*4882a593Smuzhiyun {
956*4882a593Smuzhiyun 	struct fsl_qspi *qspi = to_qspi_spi(slave);
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 	free(qspi);
959*4882a593Smuzhiyun }
960*4882a593Smuzhiyun 
spi_claim_bus(struct spi_slave * slave)961*4882a593Smuzhiyun int spi_claim_bus(struct spi_slave *slave)
962*4882a593Smuzhiyun {
963*4882a593Smuzhiyun 	return 0;
964*4882a593Smuzhiyun }
965*4882a593Smuzhiyun 
spi_release_bus(struct spi_slave * slave)966*4882a593Smuzhiyun void spi_release_bus(struct spi_slave *slave)
967*4882a593Smuzhiyun {
968*4882a593Smuzhiyun 	/* Nothing to do */
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun 
spi_xfer(struct spi_slave * slave,unsigned int bitlen,const void * dout,void * din,unsigned long flags)971*4882a593Smuzhiyun int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
972*4882a593Smuzhiyun 		const void *dout, void *din, unsigned long flags)
973*4882a593Smuzhiyun {
974*4882a593Smuzhiyun 	struct fsl_qspi *qspi = to_qspi_spi(slave);
975*4882a593Smuzhiyun 
976*4882a593Smuzhiyun 	return qspi_xfer(&qspi->priv, bitlen, dout, din, flags);
977*4882a593Smuzhiyun }
978*4882a593Smuzhiyun 
spi_init(void)979*4882a593Smuzhiyun void spi_init(void)
980*4882a593Smuzhiyun {
981*4882a593Smuzhiyun 	/* Nothing to do */
982*4882a593Smuzhiyun }
983*4882a593Smuzhiyun #else
fsl_qspi_child_pre_probe(struct udevice * dev)984*4882a593Smuzhiyun static int fsl_qspi_child_pre_probe(struct udevice *dev)
985*4882a593Smuzhiyun {
986*4882a593Smuzhiyun 	struct spi_slave *slave = dev_get_parent_priv(dev);
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 	slave->max_write_size = TX_BUFFER_SIZE;
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 	return 0;
991*4882a593Smuzhiyun }
992*4882a593Smuzhiyun 
fsl_qspi_probe(struct udevice * bus)993*4882a593Smuzhiyun static int fsl_qspi_probe(struct udevice *bus)
994*4882a593Smuzhiyun {
995*4882a593Smuzhiyun 	u32 mcr_val;
996*4882a593Smuzhiyun 	u32 amba_size_per_chip;
997*4882a593Smuzhiyun 	struct fsl_qspi_platdata *plat = dev_get_platdata(bus);
998*4882a593Smuzhiyun 	struct fsl_qspi_priv *priv = dev_get_priv(bus);
999*4882a593Smuzhiyun 	struct dm_spi_bus *dm_spi_bus;
1000*4882a593Smuzhiyun 	int i, ret;
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun 	dm_spi_bus = bus->uclass_priv;
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun 	dm_spi_bus->max_hz = plat->speed_hz;
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	priv->regs = (struct fsl_qspi_regs *)(uintptr_t)plat->reg_base;
1007*4882a593Smuzhiyun 	priv->flags = plat->flags;
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 	priv->speed_hz = plat->speed_hz;
1010*4882a593Smuzhiyun 	/*
1011*4882a593Smuzhiyun 	 * QSPI SFADR width is 32bits, the max dest addr is 4GB-1.
1012*4882a593Smuzhiyun 	 * AMBA memory zone should be located on the 0~4GB space
1013*4882a593Smuzhiyun 	 * even on a 64bits cpu.
1014*4882a593Smuzhiyun 	 */
1015*4882a593Smuzhiyun 	priv->amba_base[0] = (u32)plat->amba_base;
1016*4882a593Smuzhiyun 	priv->amba_total_size = (u32)plat->amba_total_size;
1017*4882a593Smuzhiyun 	priv->flash_num = plat->flash_num;
1018*4882a593Smuzhiyun 	priv->num_chipselect = plat->num_chipselect;
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun 	/* make sure controller is not busy anywhere */
1021*4882a593Smuzhiyun 	ret = wait_for_bit_le32(&priv->regs->sr,
1022*4882a593Smuzhiyun 				QSPI_SR_BUSY_MASK |
1023*4882a593Smuzhiyun 				QSPI_SR_AHB_ACC_MASK |
1024*4882a593Smuzhiyun 				QSPI_SR_IP_ACC_MASK,
1025*4882a593Smuzhiyun 				false, 100, false);
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	if (ret) {
1028*4882a593Smuzhiyun 		debug("ERROR : The controller is busy\n");
1029*4882a593Smuzhiyun 		return ret;
1030*4882a593Smuzhiyun 	}
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 	mcr_val = qspi_read32(priv->flags, &priv->regs->mcr);
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 	/* Set endianness to LE for i.mx */
1035*4882a593Smuzhiyun 	if (IS_ENABLED(CONFIG_MX6) || IS_ENABLED(CONFIG_MX7))
1036*4882a593Smuzhiyun 		mcr_val = QSPI_MCR_END_CFD_LE;
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun 	qspi_write32(priv->flags, &priv->regs->mcr,
1039*4882a593Smuzhiyun 		     QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |
1040*4882a593Smuzhiyun 		     (mcr_val & QSPI_MCR_END_CFD_MASK));
1041*4882a593Smuzhiyun 
1042*4882a593Smuzhiyun 	qspi_cfg_smpr(priv, ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK |
1043*4882a593Smuzhiyun 		QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0);
1044*4882a593Smuzhiyun 
1045*4882a593Smuzhiyun 	/*
1046*4882a593Smuzhiyun 	 * Assign AMBA memory zone for every chipselect
1047*4882a593Smuzhiyun 	 * QuadSPI has two channels, every channel has two chipselects.
1048*4882a593Smuzhiyun 	 * If the property 'num-cs' in dts is 2, the AMBA memory will be divided
1049*4882a593Smuzhiyun 	 * into two parts and assign to every channel. This indicate that every
1050*4882a593Smuzhiyun 	 * channel only has one valid chipselect.
1051*4882a593Smuzhiyun 	 * If the property 'num-cs' in dts is 4, the AMBA memory will be divided
1052*4882a593Smuzhiyun 	 * into four parts and assign to every chipselect.
1053*4882a593Smuzhiyun 	 * Every channel will has two valid chipselects.
1054*4882a593Smuzhiyun 	 */
1055*4882a593Smuzhiyun 	amba_size_per_chip = priv->amba_total_size >>
1056*4882a593Smuzhiyun 			     (priv->num_chipselect >> 1);
1057*4882a593Smuzhiyun 	for (i = 1 ; i < priv->num_chipselect ; i++)
1058*4882a593Smuzhiyun 		priv->amba_base[i] =
1059*4882a593Smuzhiyun 			amba_size_per_chip + priv->amba_base[i - 1];
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	/*
1062*4882a593Smuzhiyun 	 * Any read access to non-implemented addresses will provide
1063*4882a593Smuzhiyun 	 * undefined results.
1064*4882a593Smuzhiyun 	 *
1065*4882a593Smuzhiyun 	 * In case single die flash devices, TOP_ADDR_MEMA2 and
1066*4882a593Smuzhiyun 	 * TOP_ADDR_MEMB2 should be initialized/programmed to
1067*4882a593Smuzhiyun 	 * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect,
1068*4882a593Smuzhiyun 	 * setting the size of these devices to 0.  This would ensure
1069*4882a593Smuzhiyun 	 * that the complete memory map is assigned to only one flash device.
1070*4882a593Smuzhiyun 	 */
1071*4882a593Smuzhiyun 	qspi_write32(priv->flags, &priv->regs->sfa1ad,
1072*4882a593Smuzhiyun 		     priv->amba_base[0] + amba_size_per_chip);
1073*4882a593Smuzhiyun 	switch (priv->num_chipselect) {
1074*4882a593Smuzhiyun 	case 1:
1075*4882a593Smuzhiyun 		break;
1076*4882a593Smuzhiyun 	case 2:
1077*4882a593Smuzhiyun 		qspi_write32(priv->flags, &priv->regs->sfa2ad,
1078*4882a593Smuzhiyun 			     priv->amba_base[1]);
1079*4882a593Smuzhiyun 		qspi_write32(priv->flags, &priv->regs->sfb1ad,
1080*4882a593Smuzhiyun 			     priv->amba_base[1] + amba_size_per_chip);
1081*4882a593Smuzhiyun 		qspi_write32(priv->flags, &priv->regs->sfb2ad,
1082*4882a593Smuzhiyun 			     priv->amba_base[1] + amba_size_per_chip);
1083*4882a593Smuzhiyun 		break;
1084*4882a593Smuzhiyun 	case 4:
1085*4882a593Smuzhiyun 		qspi_write32(priv->flags, &priv->regs->sfa2ad,
1086*4882a593Smuzhiyun 			     priv->amba_base[2]);
1087*4882a593Smuzhiyun 		qspi_write32(priv->flags, &priv->regs->sfb1ad,
1088*4882a593Smuzhiyun 			     priv->amba_base[3]);
1089*4882a593Smuzhiyun 		qspi_write32(priv->flags, &priv->regs->sfb2ad,
1090*4882a593Smuzhiyun 			     priv->amba_base[3] + amba_size_per_chip);
1091*4882a593Smuzhiyun 		break;
1092*4882a593Smuzhiyun 	default:
1093*4882a593Smuzhiyun 		debug("Error: Unsupported chipselect number %u!\n",
1094*4882a593Smuzhiyun 		      priv->num_chipselect);
1095*4882a593Smuzhiyun 		qspi_module_disable(priv, 1);
1096*4882a593Smuzhiyun 		return -EINVAL;
1097*4882a593Smuzhiyun 	}
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 	qspi_set_lut(priv);
1100*4882a593Smuzhiyun 
1101*4882a593Smuzhiyun #ifdef CONFIG_SYS_FSL_QSPI_AHB
1102*4882a593Smuzhiyun 	qspi_init_ahb_read(priv);
1103*4882a593Smuzhiyun #endif
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun 	qspi_module_disable(priv, 0);
1106*4882a593Smuzhiyun 
1107*4882a593Smuzhiyun 	return 0;
1108*4882a593Smuzhiyun }
1109*4882a593Smuzhiyun 
fsl_qspi_ofdata_to_platdata(struct udevice * bus)1110*4882a593Smuzhiyun static int fsl_qspi_ofdata_to_platdata(struct udevice *bus)
1111*4882a593Smuzhiyun {
1112*4882a593Smuzhiyun 	struct fdt_resource res_regs, res_mem;
1113*4882a593Smuzhiyun 	struct fsl_qspi_platdata *plat = bus->platdata;
1114*4882a593Smuzhiyun 	const void *blob = gd->fdt_blob;
1115*4882a593Smuzhiyun 	int node = dev_of_offset(bus);
1116*4882a593Smuzhiyun 	int ret, flash_num = 0, subnode;
1117*4882a593Smuzhiyun 
1118*4882a593Smuzhiyun 	if (fdtdec_get_bool(blob, node, "big-endian"))
1119*4882a593Smuzhiyun 		plat->flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG;
1120*4882a593Smuzhiyun 
1121*4882a593Smuzhiyun 	ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
1122*4882a593Smuzhiyun 				     "QuadSPI", &res_regs);
1123*4882a593Smuzhiyun 	if (ret) {
1124*4882a593Smuzhiyun 		debug("Error: can't get regs base addresses(ret = %d)!\n", ret);
1125*4882a593Smuzhiyun 		return -ENOMEM;
1126*4882a593Smuzhiyun 	}
1127*4882a593Smuzhiyun 	ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
1128*4882a593Smuzhiyun 				     "QuadSPI-memory", &res_mem);
1129*4882a593Smuzhiyun 	if (ret) {
1130*4882a593Smuzhiyun 		debug("Error: can't get AMBA base addresses(ret = %d)!\n", ret);
1131*4882a593Smuzhiyun 		return -ENOMEM;
1132*4882a593Smuzhiyun 	}
1133*4882a593Smuzhiyun 
1134*4882a593Smuzhiyun 	/* Count flash numbers */
1135*4882a593Smuzhiyun 	fdt_for_each_subnode(subnode, blob, node)
1136*4882a593Smuzhiyun 		++flash_num;
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun 	if (flash_num == 0) {
1139*4882a593Smuzhiyun 		debug("Error: Missing flashes!\n");
1140*4882a593Smuzhiyun 		return -ENODEV;
1141*4882a593Smuzhiyun 	}
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun 	plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
1144*4882a593Smuzhiyun 					FSL_QSPI_DEFAULT_SCK_FREQ);
1145*4882a593Smuzhiyun 	plat->num_chipselect = fdtdec_get_int(blob, node, "num-cs",
1146*4882a593Smuzhiyun 					      FSL_QSPI_MAX_CHIPSELECT_NUM);
1147*4882a593Smuzhiyun 
1148*4882a593Smuzhiyun 	plat->reg_base = res_regs.start;
1149*4882a593Smuzhiyun 	plat->amba_base = res_mem.start;
1150*4882a593Smuzhiyun 	plat->amba_total_size = res_mem.end - res_mem.start + 1;
1151*4882a593Smuzhiyun 	plat->flash_num = flash_num;
1152*4882a593Smuzhiyun 
1153*4882a593Smuzhiyun 	debug("%s: regs=<0x%llx> <0x%llx, 0x%llx>, max-frequency=%d, endianess=%s\n",
1154*4882a593Smuzhiyun 	      __func__,
1155*4882a593Smuzhiyun 	      (u64)plat->reg_base,
1156*4882a593Smuzhiyun 	      (u64)plat->amba_base,
1157*4882a593Smuzhiyun 	      (u64)plat->amba_total_size,
1158*4882a593Smuzhiyun 	      plat->speed_hz,
1159*4882a593Smuzhiyun 	      plat->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le"
1160*4882a593Smuzhiyun 	      );
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 	return 0;
1163*4882a593Smuzhiyun }
1164*4882a593Smuzhiyun 
fsl_qspi_xfer(struct udevice * dev,unsigned int bitlen,const void * dout,void * din,unsigned long flags)1165*4882a593Smuzhiyun static int fsl_qspi_xfer(struct udevice *dev, unsigned int bitlen,
1166*4882a593Smuzhiyun 		const void *dout, void *din, unsigned long flags)
1167*4882a593Smuzhiyun {
1168*4882a593Smuzhiyun 	struct fsl_qspi_priv *priv;
1169*4882a593Smuzhiyun 	struct udevice *bus;
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 	bus = dev->parent;
1172*4882a593Smuzhiyun 	priv = dev_get_priv(bus);
1173*4882a593Smuzhiyun 
1174*4882a593Smuzhiyun 	return qspi_xfer(priv, bitlen, dout, din, flags);
1175*4882a593Smuzhiyun }
1176*4882a593Smuzhiyun 
fsl_qspi_claim_bus(struct udevice * dev)1177*4882a593Smuzhiyun static int fsl_qspi_claim_bus(struct udevice *dev)
1178*4882a593Smuzhiyun {
1179*4882a593Smuzhiyun 	struct fsl_qspi_priv *priv;
1180*4882a593Smuzhiyun 	struct udevice *bus;
1181*4882a593Smuzhiyun 	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
1182*4882a593Smuzhiyun 	int ret;
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun 	bus = dev->parent;
1185*4882a593Smuzhiyun 	priv = dev_get_priv(bus);
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 	/* make sure controller is not busy anywhere */
1188*4882a593Smuzhiyun 	ret = wait_for_bit_le32(&priv->regs->sr,
1189*4882a593Smuzhiyun 				QSPI_SR_BUSY_MASK |
1190*4882a593Smuzhiyun 				QSPI_SR_AHB_ACC_MASK |
1191*4882a593Smuzhiyun 				QSPI_SR_IP_ACC_MASK,
1192*4882a593Smuzhiyun 				false, 100, false);
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun 	if (ret) {
1195*4882a593Smuzhiyun 		debug("ERROR : The controller is busy\n");
1196*4882a593Smuzhiyun 		return ret;
1197*4882a593Smuzhiyun 	}
1198*4882a593Smuzhiyun 
1199*4882a593Smuzhiyun 	priv->cur_amba_base = priv->amba_base[slave_plat->cs];
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun 	qspi_module_disable(priv, 0);
1202*4882a593Smuzhiyun 
1203*4882a593Smuzhiyun 	return 0;
1204*4882a593Smuzhiyun }
1205*4882a593Smuzhiyun 
fsl_qspi_release_bus(struct udevice * dev)1206*4882a593Smuzhiyun static int fsl_qspi_release_bus(struct udevice *dev)
1207*4882a593Smuzhiyun {
1208*4882a593Smuzhiyun 	struct fsl_qspi_priv *priv;
1209*4882a593Smuzhiyun 	struct udevice *bus;
1210*4882a593Smuzhiyun 
1211*4882a593Smuzhiyun 	bus = dev->parent;
1212*4882a593Smuzhiyun 	priv = dev_get_priv(bus);
1213*4882a593Smuzhiyun 
1214*4882a593Smuzhiyun 	qspi_module_disable(priv, 1);
1215*4882a593Smuzhiyun 
1216*4882a593Smuzhiyun 	return 0;
1217*4882a593Smuzhiyun }
1218*4882a593Smuzhiyun 
fsl_qspi_set_speed(struct udevice * bus,uint speed)1219*4882a593Smuzhiyun static int fsl_qspi_set_speed(struct udevice *bus, uint speed)
1220*4882a593Smuzhiyun {
1221*4882a593Smuzhiyun 	/* Nothing to do */
1222*4882a593Smuzhiyun 	return 0;
1223*4882a593Smuzhiyun }
1224*4882a593Smuzhiyun 
fsl_qspi_set_mode(struct udevice * bus,uint mode)1225*4882a593Smuzhiyun static int fsl_qspi_set_mode(struct udevice *bus, uint mode)
1226*4882a593Smuzhiyun {
1227*4882a593Smuzhiyun 	/* Nothing to do */
1228*4882a593Smuzhiyun 	return 0;
1229*4882a593Smuzhiyun }
1230*4882a593Smuzhiyun 
1231*4882a593Smuzhiyun static const struct dm_spi_ops fsl_qspi_ops = {
1232*4882a593Smuzhiyun 	.claim_bus	= fsl_qspi_claim_bus,
1233*4882a593Smuzhiyun 	.release_bus	= fsl_qspi_release_bus,
1234*4882a593Smuzhiyun 	.xfer		= fsl_qspi_xfer,
1235*4882a593Smuzhiyun 	.set_speed	= fsl_qspi_set_speed,
1236*4882a593Smuzhiyun 	.set_mode	= fsl_qspi_set_mode,
1237*4882a593Smuzhiyun };
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun static const struct udevice_id fsl_qspi_ids[] = {
1240*4882a593Smuzhiyun 	{ .compatible = "fsl,vf610-qspi" },
1241*4882a593Smuzhiyun 	{ .compatible = "fsl,imx6sx-qspi" },
1242*4882a593Smuzhiyun 	{ .compatible = "fsl,imx6ul-qspi" },
1243*4882a593Smuzhiyun 	{ .compatible = "fsl,imx7d-qspi" },
1244*4882a593Smuzhiyun 	{ }
1245*4882a593Smuzhiyun };
1246*4882a593Smuzhiyun 
1247*4882a593Smuzhiyun U_BOOT_DRIVER(fsl_qspi) = {
1248*4882a593Smuzhiyun 	.name	= "fsl_qspi",
1249*4882a593Smuzhiyun 	.id	= UCLASS_SPI,
1250*4882a593Smuzhiyun 	.of_match = fsl_qspi_ids,
1251*4882a593Smuzhiyun 	.ops	= &fsl_qspi_ops,
1252*4882a593Smuzhiyun 	.ofdata_to_platdata = fsl_qspi_ofdata_to_platdata,
1253*4882a593Smuzhiyun 	.platdata_auto_alloc_size = sizeof(struct fsl_qspi_platdata),
1254*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct fsl_qspi_priv),
1255*4882a593Smuzhiyun 	.probe	= fsl_qspi_probe,
1256*4882a593Smuzhiyun 	.child_pre_probe = fsl_qspi_child_pre_probe,
1257*4882a593Smuzhiyun };
1258*4882a593Smuzhiyun #endif
1259