xref: /OK3568_Linux_fs/u-boot/drivers/spi/stm32_qspi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2016
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Michael Kurz, <michi.kurz@gmail.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * STM32 QSPI driver
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <common.h>
12*4882a593Smuzhiyun #include <malloc.h>
13*4882a593Smuzhiyun #include <spi.h>
14*4882a593Smuzhiyun #include <spi_flash.h>
15*4882a593Smuzhiyun #include <asm/io.h>
16*4882a593Smuzhiyun #include <dm.h>
17*4882a593Smuzhiyun #include <errno.h>
18*4882a593Smuzhiyun #include <asm/arch/stm32.h>
19*4882a593Smuzhiyun #include <asm/arch/stm32_defs.h>
20*4882a593Smuzhiyun #include <clk.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun struct stm32_qspi_regs {
25*4882a593Smuzhiyun 	u32 cr;		/* 0x00 */
26*4882a593Smuzhiyun 	u32 dcr;	/* 0x04 */
27*4882a593Smuzhiyun 	u32 sr;		/* 0x08 */
28*4882a593Smuzhiyun 	u32 fcr;	/* 0x0C */
29*4882a593Smuzhiyun 	u32 dlr;	/* 0x10 */
30*4882a593Smuzhiyun 	u32 ccr;	/* 0x14 */
31*4882a593Smuzhiyun 	u32 ar;		/* 0x18 */
32*4882a593Smuzhiyun 	u32 abr;	/* 0x1C */
33*4882a593Smuzhiyun 	u32 dr;		/* 0x20 */
34*4882a593Smuzhiyun 	u32 psmkr;	/* 0x24 */
35*4882a593Smuzhiyun 	u32 psmar;	/* 0x28 */
36*4882a593Smuzhiyun 	u32 pir;	/* 0x2C */
37*4882a593Smuzhiyun 	u32 lptr;	/* 0x30 */
38*4882a593Smuzhiyun };
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /*
41*4882a593Smuzhiyun  * QUADSPI control register
42*4882a593Smuzhiyun  */
43*4882a593Smuzhiyun #define STM32_QSPI_CR_EN		BIT(0)
44*4882a593Smuzhiyun #define STM32_QSPI_CR_ABORT		BIT(1)
45*4882a593Smuzhiyun #define STM32_QSPI_CR_DMAEN		BIT(2)
46*4882a593Smuzhiyun #define STM32_QSPI_CR_TCEN		BIT(3)
47*4882a593Smuzhiyun #define STM32_QSPI_CR_SSHIFT		BIT(4)
48*4882a593Smuzhiyun #define STM32_QSPI_CR_DFM		BIT(6)
49*4882a593Smuzhiyun #define STM32_QSPI_CR_FSEL		BIT(7)
50*4882a593Smuzhiyun #define STM32_QSPI_CR_FTHRES_MASK	GENMASK(4, 0)
51*4882a593Smuzhiyun #define STM32_QSPI_CR_FTHRES_SHIFT	(8)
52*4882a593Smuzhiyun #define STM32_QSPI_CR_TEIE		BIT(16)
53*4882a593Smuzhiyun #define STM32_QSPI_CR_TCIE		BIT(17)
54*4882a593Smuzhiyun #define STM32_QSPI_CR_FTIE		BIT(18)
55*4882a593Smuzhiyun #define STM32_QSPI_CR_SMIE		BIT(19)
56*4882a593Smuzhiyun #define STM32_QSPI_CR_TOIE		BIT(20)
57*4882a593Smuzhiyun #define STM32_QSPI_CR_APMS		BIT(22)
58*4882a593Smuzhiyun #define STM32_QSPI_CR_PMM		BIT(23)
59*4882a593Smuzhiyun #define STM32_QSPI_CR_PRESCALER_MASK	GENMASK(7, 0)
60*4882a593Smuzhiyun #define STM32_QSPI_CR_PRESCALER_SHIFT	(24)
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun /*
63*4882a593Smuzhiyun  * QUADSPI device configuration register
64*4882a593Smuzhiyun  */
65*4882a593Smuzhiyun #define STM32_QSPI_DCR_CKMODE		BIT(0)
66*4882a593Smuzhiyun #define STM32_QSPI_DCR_CSHT_MASK	GENMASK(2, 0)
67*4882a593Smuzhiyun #define STM32_QSPI_DCR_CSHT_SHIFT	(8)
68*4882a593Smuzhiyun #define STM32_QSPI_DCR_FSIZE_MASK	GENMASK(4, 0)
69*4882a593Smuzhiyun #define STM32_QSPI_DCR_FSIZE_SHIFT	(16)
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /*
72*4882a593Smuzhiyun  * QUADSPI status register
73*4882a593Smuzhiyun  */
74*4882a593Smuzhiyun #define STM32_QSPI_SR_TEF		BIT(0)
75*4882a593Smuzhiyun #define STM32_QSPI_SR_TCF		BIT(1)
76*4882a593Smuzhiyun #define STM32_QSPI_SR_FTF		BIT(2)
77*4882a593Smuzhiyun #define STM32_QSPI_SR_SMF		BIT(3)
78*4882a593Smuzhiyun #define STM32_QSPI_SR_TOF		BIT(4)
79*4882a593Smuzhiyun #define STM32_QSPI_SR_BUSY		BIT(5)
80*4882a593Smuzhiyun #define STM32_QSPI_SR_FLEVEL_MASK	GENMASK(5, 0)
81*4882a593Smuzhiyun #define STM32_QSPI_SR_FLEVEL_SHIFT	(8)
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /*
84*4882a593Smuzhiyun  * QUADSPI flag clear register
85*4882a593Smuzhiyun  */
86*4882a593Smuzhiyun #define STM32_QSPI_FCR_CTEF		BIT(0)
87*4882a593Smuzhiyun #define STM32_QSPI_FCR_CTCF		BIT(1)
88*4882a593Smuzhiyun #define STM32_QSPI_FCR_CSMF		BIT(3)
89*4882a593Smuzhiyun #define STM32_QSPI_FCR_CTOF		BIT(4)
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /*
92*4882a593Smuzhiyun  * QUADSPI communication configuration register
93*4882a593Smuzhiyun  */
94*4882a593Smuzhiyun #define STM32_QSPI_CCR_DDRM		BIT(31)
95*4882a593Smuzhiyun #define STM32_QSPI_CCR_DHHC		BIT(30)
96*4882a593Smuzhiyun #define STM32_QSPI_CCR_SIOO		BIT(28)
97*4882a593Smuzhiyun #define STM32_QSPI_CCR_FMODE_SHIFT	(26)
98*4882a593Smuzhiyun #define STM32_QSPI_CCR_DMODE_SHIFT	(24)
99*4882a593Smuzhiyun #define STM32_QSPI_CCR_DCYC_SHIFT	(18)
100*4882a593Smuzhiyun #define STM32_QSPI_CCR_DCYC_MASK	GENMASK(4, 0)
101*4882a593Smuzhiyun #define STM32_QSPI_CCR_ABSIZE_SHIFT	(16)
102*4882a593Smuzhiyun #define STM32_QSPI_CCR_ABMODE_SHIFT	(14)
103*4882a593Smuzhiyun #define STM32_QSPI_CCR_ADSIZE_SHIFT	(12)
104*4882a593Smuzhiyun #define STM32_QSPI_CCR_ADMODE_SHIFT	(10)
105*4882a593Smuzhiyun #define STM32_QSPI_CCR_IMODE_SHIFT	(8)
106*4882a593Smuzhiyun #define STM32_QSPI_CCR_INSTRUCTION_MASK	GENMASK(7, 0)
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun enum STM32_QSPI_CCR_IMODE {
109*4882a593Smuzhiyun 	STM32_QSPI_CCR_IMODE_NONE = 0,
110*4882a593Smuzhiyun 	STM32_QSPI_CCR_IMODE_ONE_LINE = 1,
111*4882a593Smuzhiyun 	STM32_QSPI_CCR_IMODE_TWO_LINE = 2,
112*4882a593Smuzhiyun 	STM32_QSPI_CCR_IMODE_FOUR_LINE = 3,
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun enum STM32_QSPI_CCR_ADMODE {
116*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADMODE_NONE = 0,
117*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADMODE_ONE_LINE = 1,
118*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADMODE_TWO_LINE = 2,
119*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADMODE_FOUR_LINE = 3,
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun enum STM32_QSPI_CCR_ADSIZE {
123*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADSIZE_8BIT = 0,
124*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADSIZE_16BIT = 1,
125*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADSIZE_24BIT = 2,
126*4882a593Smuzhiyun 	STM32_QSPI_CCR_ADSIZE_32BIT = 3,
127*4882a593Smuzhiyun };
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun enum STM32_QSPI_CCR_ABMODE {
130*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABMODE_NONE = 0,
131*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABMODE_ONE_LINE = 1,
132*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABMODE_TWO_LINE = 2,
133*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABMODE_FOUR_LINE = 3,
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun enum STM32_QSPI_CCR_ABSIZE {
137*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABSIZE_8BIT = 0,
138*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABSIZE_16BIT = 1,
139*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABSIZE_24BIT = 2,
140*4882a593Smuzhiyun 	STM32_QSPI_CCR_ABSIZE_32BIT = 3,
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun enum STM32_QSPI_CCR_DMODE {
144*4882a593Smuzhiyun 	STM32_QSPI_CCR_DMODE_NONE = 0,
145*4882a593Smuzhiyun 	STM32_QSPI_CCR_DMODE_ONE_LINE = 1,
146*4882a593Smuzhiyun 	STM32_QSPI_CCR_DMODE_TWO_LINE = 2,
147*4882a593Smuzhiyun 	STM32_QSPI_CCR_DMODE_FOUR_LINE = 3,
148*4882a593Smuzhiyun };
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun enum STM32_QSPI_CCR_FMODE {
151*4882a593Smuzhiyun 	STM32_QSPI_CCR_IND_WRITE = 0,
152*4882a593Smuzhiyun 	STM32_QSPI_CCR_IND_READ = 1,
153*4882a593Smuzhiyun 	STM32_QSPI_CCR_AUTO_POLL = 2,
154*4882a593Smuzhiyun 	STM32_QSPI_CCR_MEM_MAP = 3,
155*4882a593Smuzhiyun };
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /* default SCK frequency, unit: HZ */
158*4882a593Smuzhiyun #define STM32_QSPI_DEFAULT_SCK_FREQ 108000000
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun struct stm32_qspi_platdata {
161*4882a593Smuzhiyun 	u32 base;
162*4882a593Smuzhiyun 	u32 memory_map;
163*4882a593Smuzhiyun 	u32 max_hz;
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun struct stm32_qspi_priv {
167*4882a593Smuzhiyun 	struct stm32_qspi_regs *regs;
168*4882a593Smuzhiyun 	ulong clock_rate;
169*4882a593Smuzhiyun 	u32 max_hz;
170*4882a593Smuzhiyun 	u32 mode;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	u32 command;
173*4882a593Smuzhiyun 	u32 address;
174*4882a593Smuzhiyun 	u32 dummycycles;
175*4882a593Smuzhiyun #define CMD_HAS_ADR	BIT(24)
176*4882a593Smuzhiyun #define CMD_HAS_DUMMY	BIT(25)
177*4882a593Smuzhiyun #define CMD_HAS_DATA	BIT(26)
178*4882a593Smuzhiyun };
179*4882a593Smuzhiyun 
_stm32_qspi_disable(struct stm32_qspi_priv * priv)180*4882a593Smuzhiyun static void _stm32_qspi_disable(struct stm32_qspi_priv *priv)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun 	clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun 
_stm32_qspi_enable(struct stm32_qspi_priv * priv)185*4882a593Smuzhiyun static void _stm32_qspi_enable(struct stm32_qspi_priv *priv)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun 
_stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv * priv)190*4882a593Smuzhiyun static void _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun 	while (readl(&priv->regs->sr) & STM32_QSPI_SR_BUSY)
193*4882a593Smuzhiyun 		;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
_stm32_qspi_wait_for_complete(struct stm32_qspi_priv * priv)196*4882a593Smuzhiyun static void _stm32_qspi_wait_for_complete(struct stm32_qspi_priv *priv)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_TCF))
199*4882a593Smuzhiyun 		;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
_stm32_qspi_wait_for_ftf(struct stm32_qspi_priv * priv)202*4882a593Smuzhiyun static void _stm32_qspi_wait_for_ftf(struct stm32_qspi_priv *priv)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_FTF))
205*4882a593Smuzhiyun 		;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
_stm32_qspi_set_flash_size(struct stm32_qspi_priv * priv,u32 size)208*4882a593Smuzhiyun static void _stm32_qspi_set_flash_size(struct stm32_qspi_priv *priv, u32 size)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	u32 fsize = fls(size) - 1;
211*4882a593Smuzhiyun 	clrsetbits_le32(&priv->regs->dcr,
212*4882a593Smuzhiyun 			STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT,
213*4882a593Smuzhiyun 			fsize << STM32_QSPI_DCR_FSIZE_SHIFT);
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun 
_stm32_qspi_gen_ccr(struct stm32_qspi_priv * priv)216*4882a593Smuzhiyun static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	unsigned int ccr_reg = 0;
219*4882a593Smuzhiyun 	u8 imode, admode, dmode;
220*4882a593Smuzhiyun 	u32 mode = priv->mode;
221*4882a593Smuzhiyun 	u32 cmd = (priv->command & STM32_QSPI_CCR_INSTRUCTION_MASK);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	imode = STM32_QSPI_CCR_IMODE_ONE_LINE;
224*4882a593Smuzhiyun 	admode = STM32_QSPI_CCR_ADMODE_ONE_LINE;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	if (mode & SPI_RX_QUAD) {
227*4882a593Smuzhiyun 		dmode = STM32_QSPI_CCR_DMODE_FOUR_LINE;
228*4882a593Smuzhiyun 		if (mode & SPI_TX_QUAD) {
229*4882a593Smuzhiyun 			imode = STM32_QSPI_CCR_IMODE_FOUR_LINE;
230*4882a593Smuzhiyun 			admode = STM32_QSPI_CCR_ADMODE_FOUR_LINE;
231*4882a593Smuzhiyun 		}
232*4882a593Smuzhiyun 	} else if (mode & SPI_RX_DUAL) {
233*4882a593Smuzhiyun 		dmode = STM32_QSPI_CCR_DMODE_TWO_LINE;
234*4882a593Smuzhiyun 		if (mode & SPI_TX_DUAL) {
235*4882a593Smuzhiyun 			imode = STM32_QSPI_CCR_IMODE_TWO_LINE;
236*4882a593Smuzhiyun 			admode = STM32_QSPI_CCR_ADMODE_TWO_LINE;
237*4882a593Smuzhiyun 		}
238*4882a593Smuzhiyun 	} else {
239*4882a593Smuzhiyun 		dmode = STM32_QSPI_CCR_DMODE_ONE_LINE;
240*4882a593Smuzhiyun 	}
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	if (priv->command & CMD_HAS_DATA)
243*4882a593Smuzhiyun 		ccr_reg |= (dmode << STM32_QSPI_CCR_DMODE_SHIFT);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	if (priv->command & CMD_HAS_DUMMY)
246*4882a593Smuzhiyun 		ccr_reg |= ((priv->dummycycles & STM32_QSPI_CCR_DCYC_MASK)
247*4882a593Smuzhiyun 				<< STM32_QSPI_CCR_DCYC_SHIFT);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	if (priv->command & CMD_HAS_ADR) {
250*4882a593Smuzhiyun 		ccr_reg |= (STM32_QSPI_CCR_ADSIZE_24BIT
251*4882a593Smuzhiyun 				<< STM32_QSPI_CCR_ADSIZE_SHIFT);
252*4882a593Smuzhiyun 		ccr_reg |= (admode << STM32_QSPI_CCR_ADMODE_SHIFT);
253*4882a593Smuzhiyun 	}
254*4882a593Smuzhiyun 	ccr_reg |= (imode << STM32_QSPI_CCR_IMODE_SHIFT);
255*4882a593Smuzhiyun 	ccr_reg |= cmd;
256*4882a593Smuzhiyun 	return ccr_reg;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun 
_stm32_qspi_enable_mmap(struct stm32_qspi_priv * priv,struct spi_flash * flash)259*4882a593Smuzhiyun static void _stm32_qspi_enable_mmap(struct stm32_qspi_priv *priv,
260*4882a593Smuzhiyun 		struct spi_flash *flash)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	unsigned int ccr_reg;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	priv->command = flash->read_opcode | CMD_HAS_ADR | CMD_HAS_DATA
265*4882a593Smuzhiyun 			| CMD_HAS_DUMMY;
266*4882a593Smuzhiyun 	priv->dummycycles = flash->read_dummy;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	unsigned int ccr_reg = _stm32_qspi_gen_ccr(priv);
269*4882a593Smuzhiyun 	ccr_reg |= (STM32_QSPI_CCR_MEM_MAP << STM32_QSPI_CCR_FMODE_SHIFT);
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	_stm32_qspi_wait_for_not_busy(priv);
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	writel(ccr_reg, &priv->regs->ccr);
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	priv->dummycycles = 0;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun 
_stm32_qspi_disable_mmap(struct stm32_qspi_priv * priv)278*4882a593Smuzhiyun static void _stm32_qspi_disable_mmap(struct stm32_qspi_priv *priv)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun 	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT);
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
_stm32_qspi_set_xfer_length(struct stm32_qspi_priv * priv,u32 length)283*4882a593Smuzhiyun static void _stm32_qspi_set_xfer_length(struct stm32_qspi_priv *priv,
284*4882a593Smuzhiyun 					u32 length)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun 	writel(length - 1, &priv->regs->dlr);
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
_stm32_qspi_start_xfer(struct stm32_qspi_priv * priv,u32 cr_reg)289*4882a593Smuzhiyun static void _stm32_qspi_start_xfer(struct stm32_qspi_priv *priv, u32 cr_reg)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	writel(cr_reg, &priv->regs->ccr);
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	if (priv->command & CMD_HAS_ADR)
294*4882a593Smuzhiyun 		writel(priv->address, &priv->regs->ar);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun 
_stm32_qspi_xfer(struct stm32_qspi_priv * priv,struct spi_flash * flash,unsigned int bitlen,const u8 * dout,u8 * din,unsigned long flags)297*4882a593Smuzhiyun static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,
298*4882a593Smuzhiyun 		struct spi_flash *flash, unsigned int bitlen,
299*4882a593Smuzhiyun 		const u8 *dout, u8 *din, unsigned long flags)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun 	unsigned int words = bitlen / 8;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	if (flags & SPI_XFER_MMAP) {
304*4882a593Smuzhiyun 		_stm32_qspi_enable_mmap(priv, flash);
305*4882a593Smuzhiyun 		return 0;
306*4882a593Smuzhiyun 	} else if (flags & SPI_XFER_MMAP_END) {
307*4882a593Smuzhiyun 		_stm32_qspi_disable_mmap(priv);
308*4882a593Smuzhiyun 		return 0;
309*4882a593Smuzhiyun 	}
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	if (bitlen == 0)
312*4882a593Smuzhiyun 		return -1;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	if (bitlen % 8) {
315*4882a593Smuzhiyun 		debug("spi_xfer: Non byte aligned SPI transfer\n");
316*4882a593Smuzhiyun 		return -1;
317*4882a593Smuzhiyun 	}
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	if (dout && din) {
320*4882a593Smuzhiyun 		debug("spi_xfer: QSPI cannot have data in and data out set\n");
321*4882a593Smuzhiyun 		return -1;
322*4882a593Smuzhiyun 	}
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	if (!dout && (flags & SPI_XFER_BEGIN)) {
325*4882a593Smuzhiyun 		debug("spi_xfer: QSPI transfer must begin with command\n");
326*4882a593Smuzhiyun 		return -1;
327*4882a593Smuzhiyun 	}
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	if (dout) {
330*4882a593Smuzhiyun 		if (flags & SPI_XFER_BEGIN) {
331*4882a593Smuzhiyun 			/* data is command */
332*4882a593Smuzhiyun 			priv->command = dout[0] | CMD_HAS_DATA;
333*4882a593Smuzhiyun 			if (words >= 4) {
334*4882a593Smuzhiyun 				/* address is here too */
335*4882a593Smuzhiyun 				priv->address = (dout[1] << 16) |
336*4882a593Smuzhiyun 						(dout[2] << 8) | dout[3];
337*4882a593Smuzhiyun 				priv->command |= CMD_HAS_ADR;
338*4882a593Smuzhiyun 			}
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 			if (words > 4) {
341*4882a593Smuzhiyun 				/* rest is dummy bytes */
342*4882a593Smuzhiyun 				priv->dummycycles = (words - 4) * 8;
343*4882a593Smuzhiyun 				priv->command |= CMD_HAS_DUMMY;
344*4882a593Smuzhiyun 			}
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 			if (flags & SPI_XFER_END) {
347*4882a593Smuzhiyun 				/* command without data */
348*4882a593Smuzhiyun 				priv->command &= ~(CMD_HAS_DATA);
349*4882a593Smuzhiyun 			}
350*4882a593Smuzhiyun 		}
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 		if (flags & SPI_XFER_END) {
353*4882a593Smuzhiyun 			u32 ccr_reg = _stm32_qspi_gen_ccr(priv);
354*4882a593Smuzhiyun 			ccr_reg |= STM32_QSPI_CCR_IND_WRITE
355*4882a593Smuzhiyun 					<< STM32_QSPI_CCR_FMODE_SHIFT;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 			_stm32_qspi_wait_for_not_busy(priv);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 			if (priv->command & CMD_HAS_DATA)
360*4882a593Smuzhiyun 				_stm32_qspi_set_xfer_length(priv, words);
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 			_stm32_qspi_start_xfer(priv, ccr_reg);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 			debug("%s: write: ccr:0x%08x adr:0x%08x\n",
365*4882a593Smuzhiyun 			      __func__, priv->regs->ccr, priv->regs->ar);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 			if (priv->command & CMD_HAS_DATA) {
368*4882a593Smuzhiyun 				_stm32_qspi_wait_for_ftf(priv);
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 				debug("%s: words:%d data:", __func__, words);
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 				int i = 0;
373*4882a593Smuzhiyun 				while (words > i) {
374*4882a593Smuzhiyun 					writeb(dout[i], &priv->regs->dr);
375*4882a593Smuzhiyun 					debug("%02x ", dout[i]);
376*4882a593Smuzhiyun 					i++;
377*4882a593Smuzhiyun 				}
378*4882a593Smuzhiyun 				debug("\n");
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 				_stm32_qspi_wait_for_complete(priv);
381*4882a593Smuzhiyun 			} else {
382*4882a593Smuzhiyun 				_stm32_qspi_wait_for_not_busy(priv);
383*4882a593Smuzhiyun 			}
384*4882a593Smuzhiyun 		}
385*4882a593Smuzhiyun 	} else if (din) {
386*4882a593Smuzhiyun 		u32 ccr_reg = _stm32_qspi_gen_ccr(priv);
387*4882a593Smuzhiyun 		ccr_reg |= STM32_QSPI_CCR_IND_READ
388*4882a593Smuzhiyun 				<< STM32_QSPI_CCR_FMODE_SHIFT;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 		_stm32_qspi_wait_for_not_busy(priv);
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 		_stm32_qspi_set_xfer_length(priv, words);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 		_stm32_qspi_start_xfer(priv, ccr_reg);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 		debug("%s: read: ccr:0x%08x adr:0x%08x len:%d\n", __func__,
397*4882a593Smuzhiyun 		      priv->regs->ccr, priv->regs->ar, priv->regs->dlr);
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 		debug("%s: data:", __func__);
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 		int i = 0;
402*4882a593Smuzhiyun 		while (words > i) {
403*4882a593Smuzhiyun 			din[i] = readb(&priv->regs->dr);
404*4882a593Smuzhiyun 			debug("%02x ", din[i]);
405*4882a593Smuzhiyun 			i++;
406*4882a593Smuzhiyun 		}
407*4882a593Smuzhiyun 		debug("\n");
408*4882a593Smuzhiyun 	}
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	return 0;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun 
stm32_qspi_ofdata_to_platdata(struct udevice * bus)413*4882a593Smuzhiyun static int stm32_qspi_ofdata_to_platdata(struct udevice *bus)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun 	struct fdt_resource res_regs, res_mem;
416*4882a593Smuzhiyun 	struct stm32_qspi_platdata *plat = bus->platdata;
417*4882a593Smuzhiyun 	const void *blob = gd->fdt_blob;
418*4882a593Smuzhiyun 	int node = dev_of_offset(bus);
419*4882a593Smuzhiyun 	int ret;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
422*4882a593Smuzhiyun 				     "QuadSPI", &res_regs);
423*4882a593Smuzhiyun 	if (ret) {
424*4882a593Smuzhiyun 		debug("Error: can't get regs base addresses(ret = %d)!\n", ret);
425*4882a593Smuzhiyun 		return -ENOMEM;
426*4882a593Smuzhiyun 	}
427*4882a593Smuzhiyun 	ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
428*4882a593Smuzhiyun 				     "QuadSPI-memory", &res_mem);
429*4882a593Smuzhiyun 	if (ret) {
430*4882a593Smuzhiyun 		debug("Error: can't get mmap base address(ret = %d)!\n", ret);
431*4882a593Smuzhiyun 		return -ENOMEM;
432*4882a593Smuzhiyun 	}
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
435*4882a593Smuzhiyun 					STM32_QSPI_DEFAULT_SCK_FREQ);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	plat->base = res_regs.start;
438*4882a593Smuzhiyun 	plat->memory_map = res_mem.start;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	debug("%s: regs=<0x%x> mapped=<0x%x>, max-frequency=%d\n",
441*4882a593Smuzhiyun 	      __func__,
442*4882a593Smuzhiyun 	      plat->base,
443*4882a593Smuzhiyun 	      plat->memory_map,
444*4882a593Smuzhiyun 	      plat->max_hz
445*4882a593Smuzhiyun 	      );
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	return 0;
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun 
stm32_qspi_probe(struct udevice * bus)450*4882a593Smuzhiyun static int stm32_qspi_probe(struct udevice *bus)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun 	struct stm32_qspi_platdata *plat = dev_get_platdata(bus);
453*4882a593Smuzhiyun 	struct stm32_qspi_priv *priv = dev_get_priv(bus);
454*4882a593Smuzhiyun 	struct dm_spi_bus *dm_spi_bus;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	dm_spi_bus = bus->uclass_priv;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	dm_spi_bus->max_hz = plat->max_hz;
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	priv->regs = (struct stm32_qspi_regs *)(uintptr_t)plat->base;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	priv->max_hz = plat->max_hz;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun #ifdef CONFIG_CLK
465*4882a593Smuzhiyun 	int ret;
466*4882a593Smuzhiyun 	struct clk clk;
467*4882a593Smuzhiyun 	ret = clk_get_by_index(bus, 0, &clk);
468*4882a593Smuzhiyun 	if (ret < 0)
469*4882a593Smuzhiyun 		return ret;
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	ret = clk_enable(&clk);
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	if (ret) {
474*4882a593Smuzhiyun 		dev_err(bus, "failed to enable clock\n");
475*4882a593Smuzhiyun 		return ret;
476*4882a593Smuzhiyun 	}
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	priv->clock_rate = clk_get_rate(&clk);
479*4882a593Smuzhiyun 	if (priv->clock_rate < 0) {
480*4882a593Smuzhiyun 		clk_disable(&clk);
481*4882a593Smuzhiyun 		return priv->clock_rate;
482*4882a593Smuzhiyun 	}
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun #endif
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	return 0;
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun 
stm32_qspi_remove(struct udevice * bus)491*4882a593Smuzhiyun static int stm32_qspi_remove(struct udevice *bus)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun 	return 0;
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun 
stm32_qspi_claim_bus(struct udevice * dev)496*4882a593Smuzhiyun static int stm32_qspi_claim_bus(struct udevice *dev)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	struct stm32_qspi_priv *priv;
499*4882a593Smuzhiyun 	struct udevice *bus;
500*4882a593Smuzhiyun 	struct spi_flash *flash;
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	bus = dev->parent;
503*4882a593Smuzhiyun 	priv = dev_get_priv(bus);
504*4882a593Smuzhiyun 	flash = dev_get_uclass_priv(dev);
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	_stm32_qspi_set_flash_size(priv, flash->size);
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	_stm32_qspi_enable(priv);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	return 0;
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun 
stm32_qspi_release_bus(struct udevice * dev)513*4882a593Smuzhiyun static int stm32_qspi_release_bus(struct udevice *dev)
514*4882a593Smuzhiyun {
515*4882a593Smuzhiyun 	struct stm32_qspi_priv *priv;
516*4882a593Smuzhiyun 	struct udevice *bus;
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	bus = dev->parent;
519*4882a593Smuzhiyun 	priv = dev_get_priv(bus);
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	_stm32_qspi_disable(priv);
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	return 0;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun 
stm32_qspi_xfer(struct udevice * dev,unsigned int bitlen,const void * dout,void * din,unsigned long flags)526*4882a593Smuzhiyun static int stm32_qspi_xfer(struct udevice *dev, unsigned int bitlen,
527*4882a593Smuzhiyun 		const void *dout, void *din, unsigned long flags)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun 	struct stm32_qspi_priv *priv;
530*4882a593Smuzhiyun 	struct udevice *bus;
531*4882a593Smuzhiyun 	struct spi_flash *flash;
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 	bus = dev->parent;
534*4882a593Smuzhiyun 	priv = dev_get_priv(bus);
535*4882a593Smuzhiyun 	flash = dev_get_uclass_priv(dev);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	return _stm32_qspi_xfer(priv, flash, bitlen, (const u8 *)dout,
538*4882a593Smuzhiyun 				(u8 *)din, flags);
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun 
stm32_qspi_set_speed(struct udevice * bus,uint speed)541*4882a593Smuzhiyun static int stm32_qspi_set_speed(struct udevice *bus, uint speed)
542*4882a593Smuzhiyun {
543*4882a593Smuzhiyun 	struct stm32_qspi_platdata *plat = bus->platdata;
544*4882a593Smuzhiyun 	struct stm32_qspi_priv *priv = dev_get_priv(bus);
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 	if (speed > plat->max_hz)
547*4882a593Smuzhiyun 		speed = plat->max_hz;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	u32 qspi_clk = priv->clock_rate;
550*4882a593Smuzhiyun 	u32 prescaler = 255;
551*4882a593Smuzhiyun 	if (speed > 0) {
552*4882a593Smuzhiyun 		prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1;
553*4882a593Smuzhiyun 		if (prescaler > 255)
554*4882a593Smuzhiyun 			prescaler = 255;
555*4882a593Smuzhiyun 		else if (prescaler < 0)
556*4882a593Smuzhiyun 			prescaler = 0;
557*4882a593Smuzhiyun 	}
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	u32 csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000);
560*4882a593Smuzhiyun 	csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	_stm32_qspi_wait_for_not_busy(priv);
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	clrsetbits_le32(&priv->regs->cr,
565*4882a593Smuzhiyun 			STM32_QSPI_CR_PRESCALER_MASK <<
566*4882a593Smuzhiyun 			STM32_QSPI_CR_PRESCALER_SHIFT,
567*4882a593Smuzhiyun 			prescaler << STM32_QSPI_CR_PRESCALER_SHIFT);
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	clrsetbits_le32(&priv->regs->dcr,
571*4882a593Smuzhiyun 			STM32_QSPI_DCR_CSHT_MASK << STM32_QSPI_DCR_CSHT_SHIFT,
572*4882a593Smuzhiyun 			csht << STM32_QSPI_DCR_CSHT_SHIFT);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 	debug("%s: regs=%p, speed=%d\n", __func__, priv->regs,
575*4882a593Smuzhiyun 	      (qspi_clk / (prescaler + 1)));
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	return 0;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun 
stm32_qspi_set_mode(struct udevice * bus,uint mode)580*4882a593Smuzhiyun static int stm32_qspi_set_mode(struct udevice *bus, uint mode)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun 	struct stm32_qspi_priv *priv = dev_get_priv(bus);
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	_stm32_qspi_wait_for_not_busy(priv);
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	if ((mode & SPI_CPHA) && (mode & SPI_CPOL))
587*4882a593Smuzhiyun 		setbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE);
588*4882a593Smuzhiyun 	else if (!(mode & SPI_CPHA) && !(mode & SPI_CPOL))
589*4882a593Smuzhiyun 		clrbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE);
590*4882a593Smuzhiyun 	else
591*4882a593Smuzhiyun 		return -ENODEV;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	if (mode & SPI_CS_HIGH)
594*4882a593Smuzhiyun 		return -ENODEV;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	if (mode & SPI_RX_QUAD)
597*4882a593Smuzhiyun 		priv->mode |= SPI_RX_QUAD;
598*4882a593Smuzhiyun 	else if (mode & SPI_RX_DUAL)
599*4882a593Smuzhiyun 		priv->mode |= SPI_RX_DUAL;
600*4882a593Smuzhiyun 	else
601*4882a593Smuzhiyun 		priv->mode &= ~(SPI_RX_QUAD | SPI_RX_DUAL);
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	if (mode & SPI_TX_QUAD)
604*4882a593Smuzhiyun 		priv->mode |= SPI_TX_QUAD;
605*4882a593Smuzhiyun 	else if (mode & SPI_TX_DUAL)
606*4882a593Smuzhiyun 		priv->mode |= SPI_TX_DUAL;
607*4882a593Smuzhiyun 	else
608*4882a593Smuzhiyun 		priv->mode &= ~(SPI_TX_QUAD | SPI_TX_DUAL);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	debug("%s: regs=%p, mode=%d rx: ", __func__, priv->regs, mode);
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	if (mode & SPI_RX_QUAD)
613*4882a593Smuzhiyun 		debug("quad, tx: ");
614*4882a593Smuzhiyun 	else if (mode & SPI_RX_DUAL)
615*4882a593Smuzhiyun 		debug("dual, tx: ");
616*4882a593Smuzhiyun 	else
617*4882a593Smuzhiyun 		debug("single, tx: ");
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	if (mode & SPI_TX_QUAD)
620*4882a593Smuzhiyun 		debug("quad\n");
621*4882a593Smuzhiyun 	else if (mode & SPI_TX_DUAL)
622*4882a593Smuzhiyun 		debug("dual\n");
623*4882a593Smuzhiyun 	else
624*4882a593Smuzhiyun 		debug("single\n");
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	return 0;
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun static const struct dm_spi_ops stm32_qspi_ops = {
630*4882a593Smuzhiyun 	.claim_bus	= stm32_qspi_claim_bus,
631*4882a593Smuzhiyun 	.release_bus	= stm32_qspi_release_bus,
632*4882a593Smuzhiyun 	.xfer		= stm32_qspi_xfer,
633*4882a593Smuzhiyun 	.set_speed	= stm32_qspi_set_speed,
634*4882a593Smuzhiyun 	.set_mode	= stm32_qspi_set_mode,
635*4882a593Smuzhiyun };
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun static const struct udevice_id stm32_qspi_ids[] = {
638*4882a593Smuzhiyun 	{ .compatible = "st,stm32-qspi" },
639*4882a593Smuzhiyun 	{ }
640*4882a593Smuzhiyun };
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun U_BOOT_DRIVER(stm32_qspi) = {
643*4882a593Smuzhiyun 	.name	= "stm32_qspi",
644*4882a593Smuzhiyun 	.id	= UCLASS_SPI,
645*4882a593Smuzhiyun 	.of_match = stm32_qspi_ids,
646*4882a593Smuzhiyun 	.ops	= &stm32_qspi_ops,
647*4882a593Smuzhiyun 	.ofdata_to_platdata = stm32_qspi_ofdata_to_platdata,
648*4882a593Smuzhiyun 	.platdata_auto_alloc_size = sizeof(struct stm32_qspi_platdata),
649*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct stm32_qspi_priv),
650*4882a593Smuzhiyun 	.probe	= stm32_qspi_probe,
651*4882a593Smuzhiyun 	.remove = stm32_qspi_remove,
652*4882a593Smuzhiyun };
653