blob: 4b1a0296cb9ab97108def6fb78d8fc083339106a [file] [log] [blame]
Lionel Debieve923e4d32019-09-24 17:44:28 +02001/*
Yann Gautierebb7e692020-03-11 17:09:21 +01002 * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
Lionel Debieve923e4d32019-09-24 17:44:28 +02003 *
4 * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
5 */
6
Manish Pandey9b384b32021-11-12 12:59:09 +00007#include <inttypes.h>
Lionel Debieve923e4d32019-09-24 17:44:28 +02008#include <libfdt.h>
9
10#include <platform_def.h>
11
12#include <common/debug.h>
Andre Przywara4a1c8742020-03-26 12:11:34 +000013#include <common/fdt_wrappers.h>
Lionel Debieve923e4d32019-09-24 17:44:28 +020014#include <drivers/delay_timer.h>
15#include <drivers/spi_mem.h>
16#include <drivers/st/stm32_gpio.h>
Yann Gautierebb7e692020-03-11 17:09:21 +010017#include <drivers/st/stm32_qspi.h>
Lionel Debieve923e4d32019-09-24 17:44:28 +020018#include <drivers/st/stm32mp_reset.h>
19#include <lib/mmio.h>
20#include <lib/utils_def.h>
21
Etienne Carrieref02647a2019-12-08 08:14:40 +010022/* Timeout for device interface reset */
23#define TIMEOUT_US_1_MS 1000U
24
Lionel Debieve923e4d32019-09-24 17:44:28 +020025/* QUADSPI registers */
26#define QSPI_CR 0x00U
27#define QSPI_DCR 0x04U
28#define QSPI_SR 0x08U
29#define QSPI_FCR 0x0CU
30#define QSPI_DLR 0x10U
31#define QSPI_CCR 0x14U
32#define QSPI_AR 0x18U
33#define QSPI_ABR 0x1CU
34#define QSPI_DR 0x20U
35#define QSPI_PSMKR 0x24U
36#define QSPI_PSMAR 0x28U
37#define QSPI_PIR 0x2CU
38#define QSPI_LPTR 0x30U
39
40/* QUADSPI control register */
41#define QSPI_CR_EN BIT(0)
42#define QSPI_CR_ABORT BIT(1)
43#define QSPI_CR_DMAEN BIT(2)
44#define QSPI_CR_TCEN BIT(3)
45#define QSPI_CR_SSHIFT BIT(4)
46#define QSPI_CR_DFM BIT(6)
47#define QSPI_CR_FSEL BIT(7)
48#define QSPI_CR_FTHRES_SHIFT 8U
49#define QSPI_CR_TEIE BIT(16)
50#define QSPI_CR_TCIE BIT(17)
51#define QSPI_CR_FTIE BIT(18)
52#define QSPI_CR_SMIE BIT(19)
53#define QSPI_CR_TOIE BIT(20)
54#define QSPI_CR_APMS BIT(22)
55#define QSPI_CR_PMM BIT(23)
56#define QSPI_CR_PRESCALER_MASK GENMASK_32(31, 24)
57#define QSPI_CR_PRESCALER_SHIFT 24U
58
59/* QUADSPI device configuration register */
60#define QSPI_DCR_CKMODE BIT(0)
61#define QSPI_DCR_CSHT_MASK GENMASK_32(10, 8)
62#define QSPI_DCR_CSHT_SHIFT 8U
63#define QSPI_DCR_FSIZE_MASK GENMASK_32(20, 16)
64#define QSPI_DCR_FSIZE_SHIFT 16U
65
66/* QUADSPI status register */
67#define QSPI_SR_TEF BIT(0)
68#define QSPI_SR_TCF BIT(1)
69#define QSPI_SR_FTF BIT(2)
70#define QSPI_SR_SMF BIT(3)
71#define QSPI_SR_TOF BIT(4)
72#define QSPI_SR_BUSY BIT(5)
73
74/* QUADSPI flag clear register */
75#define QSPI_FCR_CTEF BIT(0)
76#define QSPI_FCR_CTCF BIT(1)
77#define QSPI_FCR_CSMF BIT(3)
78#define QSPI_FCR_CTOF BIT(4)
79
80/* QUADSPI communication configuration register */
81#define QSPI_CCR_DDRM BIT(31)
82#define QSPI_CCR_DHHC BIT(30)
83#define QSPI_CCR_SIOO BIT(28)
84#define QSPI_CCR_FMODE_SHIFT 26U
85#define QSPI_CCR_DMODE_SHIFT 24U
86#define QSPI_CCR_DCYC_SHIFT 18U
87#define QSPI_CCR_ABSIZE_SHIFT 16U
88#define QSPI_CCR_ABMODE_SHIFT 14U
89#define QSPI_CCR_ADSIZE_SHIFT 12U
90#define QSPI_CCR_ADMODE_SHIFT 10U
91#define QSPI_CCR_IMODE_SHIFT 8U
92#define QSPI_CCR_IND_WRITE 0U
93#define QSPI_CCR_IND_READ 1U
94#define QSPI_CCR_MEM_MAP 3U
95
96#define QSPI_MAX_CHIP 2U
97
98#define QSPI_FIFO_TIMEOUT_US 30U
99#define QSPI_CMD_TIMEOUT_US 1000U
100#define QSPI_BUSY_TIMEOUT_US 100U
101#define QSPI_ABT_TIMEOUT_US 100U
102
103#define DT_QSPI_COMPAT "st,stm32f469-qspi"
104
105#define FREQ_100MHZ 100000000U
106
107struct stm32_qspi_ctrl {
108 uintptr_t reg_base;
109 uintptr_t mm_base;
110 size_t mm_size;
111 unsigned long clock_id;
112 unsigned int reset_id;
113};
114
115static struct stm32_qspi_ctrl stm32_qspi;
116
117static uintptr_t qspi_base(void)
118{
119 return stm32_qspi.reg_base;
120}
121
122static int stm32_qspi_wait_for_not_busy(void)
123{
124 uint64_t timeout = timeout_init_us(QSPI_BUSY_TIMEOUT_US);
125
126 while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_BUSY) != 0U) {
127 if (timeout_elapsed(timeout)) {
128 ERROR("%s: busy timeout\n", __func__);
129 return -ETIMEDOUT;
130 }
131 }
132
133 return 0;
134}
135
136static int stm32_qspi_wait_cmd(const struct spi_mem_op *op)
137{
138 int ret = 0;
139 uint64_t timeout;
140
141 if (op->data.nbytes == 0U) {
142 return stm32_qspi_wait_for_not_busy();
143 }
144
145 timeout = timeout_init_us(QSPI_CMD_TIMEOUT_US);
146 while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TCF) == 0U) {
147 if (timeout_elapsed(timeout)) {
148 ret = -ETIMEDOUT;
149 break;
150 }
151 }
152
153 if (ret == 0) {
154 if ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TEF) != 0U) {
155 ERROR("%s: transfer error\n", __func__);
156 ret = -EIO;
157 }
158 } else {
159 ERROR("%s: cmd timeout\n", __func__);
160 }
161
162 /* Clear flags */
163 mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF | QSPI_FCR_CTEF);
164
165 return ret;
166}
167
168static void stm32_qspi_read_fifo(uint8_t *val, uintptr_t addr)
169{
170 *val = mmio_read_8(addr);
171}
172
173static void stm32_qspi_write_fifo(uint8_t *val, uintptr_t addr)
174{
175 mmio_write_8(addr, *val);
176}
177
178static int stm32_qspi_poll(const struct spi_mem_op *op)
179{
180 void (*fifo)(uint8_t *val, uintptr_t addr);
Yann Gautierebb7e692020-03-11 17:09:21 +0100181 uint32_t len;
Lionel Debieve923e4d32019-09-24 17:44:28 +0200182 uint8_t *buf;
Lionel Debieve923e4d32019-09-24 17:44:28 +0200183
184 if (op->data.dir == SPI_MEM_DATA_IN) {
185 fifo = stm32_qspi_read_fifo;
186 } else {
187 fifo = stm32_qspi_write_fifo;
188 }
189
190 buf = (uint8_t *)op->data.buf;
191
192 for (len = op->data.nbytes; len != 0U; len--) {
Yann Gautierebb7e692020-03-11 17:09:21 +0100193 uint64_t timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US);
194
Lionel Debieve923e4d32019-09-24 17:44:28 +0200195 while ((mmio_read_32(qspi_base() + QSPI_SR) &
196 QSPI_SR_FTF) == 0U) {
197 if (timeout_elapsed(timeout)) {
198 ERROR("%s: fifo timeout\n", __func__);
199 return -ETIMEDOUT;
200 }
201 }
202
203 fifo(buf++, qspi_base() + QSPI_DR);
204 }
205
206 return 0;
207}
208
209static int stm32_qspi_mm(const struct spi_mem_op *op)
210{
211 memcpy(op->data.buf,
212 (void *)(stm32_qspi.mm_base + (size_t)op->addr.val),
213 op->data.nbytes);
214
215 return 0;
216}
217
218static int stm32_qspi_tx(const struct spi_mem_op *op, uint8_t mode)
219{
220 if (op->data.nbytes == 0U) {
221 return 0;
222 }
223
224 if (mode == QSPI_CCR_MEM_MAP) {
225 return stm32_qspi_mm(op);
226 }
227
228 return stm32_qspi_poll(op);
229}
230
231static unsigned int stm32_qspi_get_mode(uint8_t buswidth)
232{
233 if (buswidth == 4U) {
234 return 3U;
235 }
236
237 return buswidth;
238}
239
240static int stm32_qspi_exec_op(const struct spi_mem_op *op)
241{
242 uint64_t timeout;
243 uint32_t ccr;
244 size_t addr_max;
245 uint8_t mode = QSPI_CCR_IND_WRITE;
246 int ret;
247
Manish Pandey9b384b32021-11-12 12:59:09 +0000248 VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%" PRIx64 " len:%x\n",
Lionel Debieve923e4d32019-09-24 17:44:28 +0200249 __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
250 op->dummy.buswidth, op->data.buswidth,
251 op->addr.val, op->data.nbytes);
252
253 ret = stm32_qspi_wait_for_not_busy();
254 if (ret != 0) {
255 return ret;
256 }
257
258 addr_max = op->addr.val + op->data.nbytes + 1U;
259
260 if ((op->data.dir == SPI_MEM_DATA_IN) && (op->data.nbytes != 0U)) {
261 if ((addr_max < stm32_qspi.mm_size) &&
262 (op->addr.buswidth != 0U)) {
263 mode = QSPI_CCR_MEM_MAP;
264 } else {
265 mode = QSPI_CCR_IND_READ;
266 }
267 }
268
269 if (op->data.nbytes != 0U) {
270 mmio_write_32(qspi_base() + QSPI_DLR, op->data.nbytes - 1U);
271 }
272
273 ccr = mode << QSPI_CCR_FMODE_SHIFT;
274 ccr |= op->cmd.opcode;
275 ccr |= stm32_qspi_get_mode(op->cmd.buswidth) << QSPI_CCR_IMODE_SHIFT;
276
277 if (op->addr.nbytes != 0U) {
278 ccr |= (op->addr.nbytes - 1U) << QSPI_CCR_ADSIZE_SHIFT;
279 ccr |= stm32_qspi_get_mode(op->addr.buswidth) <<
280 QSPI_CCR_ADMODE_SHIFT;
281 }
282
283 if ((op->dummy.buswidth != 0U) && (op->dummy.nbytes != 0U)) {
284 ccr |= (op->dummy.nbytes * 8U / op->dummy.buswidth) <<
285 QSPI_CCR_DCYC_SHIFT;
286 }
287
288 if (op->data.nbytes != 0U) {
289 ccr |= stm32_qspi_get_mode(op->data.buswidth) <<
290 QSPI_CCR_DMODE_SHIFT;
291 }
292
293 mmio_write_32(qspi_base() + QSPI_CCR, ccr);
294
295 if ((op->addr.nbytes != 0U) && (mode != QSPI_CCR_MEM_MAP)) {
296 mmio_write_32(qspi_base() + QSPI_AR, op->addr.val);
297 }
298
299 ret = stm32_qspi_tx(op, mode);
300
301 /*
302 * Abort in:
303 * - Error case.
304 * - Memory mapped read: prefetching must be stopped if we read the last
305 * byte of device (device size - fifo size). If device size is not
306 * known then prefetching is always stopped.
307 */
308 if ((ret != 0) || (mode == QSPI_CCR_MEM_MAP)) {
309 goto abort;
310 }
311
312 /* Wait end of TX in indirect mode */
313 ret = stm32_qspi_wait_cmd(op);
314 if (ret != 0) {
315 goto abort;
316 }
317
318 return 0;
319
320abort:
321 mmio_setbits_32(qspi_base() + QSPI_CR, QSPI_CR_ABORT);
322
323 /* Wait clear of abort bit by hardware */
324 timeout = timeout_init_us(QSPI_ABT_TIMEOUT_US);
325 while ((mmio_read_32(qspi_base() + QSPI_CR) & QSPI_CR_ABORT) != 0U) {
326 if (timeout_elapsed(timeout)) {
327 ret = -ETIMEDOUT;
328 break;
329 }
330 }
331
332 mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF);
333
334 if (ret != 0) {
335 ERROR("%s: exec op error\n", __func__);
336 }
337
338 return ret;
339}
340
341static int stm32_qspi_claim_bus(unsigned int cs)
342{
343 uint32_t cr;
344
345 if (cs >= QSPI_MAX_CHIP) {
346 return -ENODEV;
347 }
348
349 /* Set chip select and enable the controller */
350 cr = QSPI_CR_EN;
351 if (cs == 1U) {
352 cr |= QSPI_CR_FSEL;
353 }
354
355 mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_FSEL, cr);
356
357 return 0;
358}
359
360static void stm32_qspi_release_bus(void)
361{
362 mmio_clrbits_32(qspi_base() + QSPI_CR, QSPI_CR_EN);
363}
364
365static int stm32_qspi_set_speed(unsigned int hz)
366{
367 unsigned long qspi_clk = stm32mp_clk_get_rate(stm32_qspi.clock_id);
368 uint32_t prescaler = UINT8_MAX;
369 uint32_t csht;
370 int ret;
371
372 if (qspi_clk == 0U) {
373 return -EINVAL;
374 }
375
376 if (hz > 0U) {
377 prescaler = div_round_up(qspi_clk, hz) - 1U;
378 if (prescaler > UINT8_MAX) {
379 prescaler = UINT8_MAX;
380 }
381 }
382
383 csht = div_round_up((5U * qspi_clk) / (prescaler + 1U), FREQ_100MHZ);
384 csht = ((csht - 1U) << QSPI_DCR_CSHT_SHIFT) & QSPI_DCR_CSHT_MASK;
385
386 ret = stm32_qspi_wait_for_not_busy();
387 if (ret != 0) {
388 return ret;
389 }
390
391 mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_PRESCALER_MASK,
392 prescaler << QSPI_CR_PRESCALER_SHIFT);
393
394 mmio_clrsetbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CSHT_MASK, csht);
395
396 VERBOSE("%s: speed=%lu\n", __func__, qspi_clk / (prescaler + 1U));
397
398 return 0;
399}
400
401static int stm32_qspi_set_mode(unsigned int mode)
402{
403 int ret;
404
405 ret = stm32_qspi_wait_for_not_busy();
406 if (ret != 0) {
407 return ret;
408 }
409
410 if ((mode & SPI_CS_HIGH) != 0U) {
411 return -ENODEV;
412 }
413
414 if (((mode & SPI_CPHA) != 0U) && ((mode & SPI_CPOL) != 0U)) {
415 mmio_setbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE);
416 } else if (((mode & SPI_CPHA) == 0U) && ((mode & SPI_CPOL) == 0U)) {
417 mmio_clrbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE);
418 } else {
419 return -ENODEV;
420 }
421
422 VERBOSE("%s: mode=0x%x\n", __func__, mode);
423
424 if ((mode & SPI_RX_QUAD) != 0U) {
425 VERBOSE("rx: quad\n");
426 } else if ((mode & SPI_RX_DUAL) != 0U) {
427 VERBOSE("rx: dual\n");
428 } else {
429 VERBOSE("rx: single\n");
430 }
431
432 if ((mode & SPI_TX_QUAD) != 0U) {
433 VERBOSE("tx: quad\n");
434 } else if ((mode & SPI_TX_DUAL) != 0U) {
435 VERBOSE("tx: dual\n");
436 } else {
437 VERBOSE("tx: single\n");
438 }
439
440 return 0;
441}
442
443static const struct spi_bus_ops stm32_qspi_bus_ops = {
444 .claim_bus = stm32_qspi_claim_bus,
445 .release_bus = stm32_qspi_release_bus,
446 .set_speed = stm32_qspi_set_speed,
447 .set_mode = stm32_qspi_set_mode,
448 .exec_op = stm32_qspi_exec_op,
449};
450
451int stm32_qspi_init(void)
452{
453 size_t size;
454 int qspi_node;
455 struct dt_node_info info;
456 void *fdt = NULL;
457 int ret;
458
459 if (fdt_get_address(&fdt) == 0) {
460 return -FDT_ERR_NOTFOUND;
461 }
462
463 qspi_node = dt_get_node(&info, -1, DT_QSPI_COMPAT);
464 if (qspi_node < 0) {
465 ERROR("No QSPI ctrl found\n");
466 return -FDT_ERR_NOTFOUND;
467 }
468
469 if (info.status == DT_DISABLED) {
470 return -FDT_ERR_NOTFOUND;
471 }
472
Andre Przywara4a1c8742020-03-26 12:11:34 +0000473 ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi",
Lionel Debieve923e4d32019-09-24 17:44:28 +0200474 &stm32_qspi.reg_base, &size);
475 if (ret != 0) {
476 return ret;
477 }
478
Andre Przywara4a1c8742020-03-26 12:11:34 +0000479 ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi_mm",
Lionel Debieve923e4d32019-09-24 17:44:28 +0200480 &stm32_qspi.mm_base,
481 &stm32_qspi.mm_size);
482 if (ret != 0) {
483 return ret;
484 }
485
486 if (dt_set_pinctrl_config(qspi_node) != 0) {
487 return -FDT_ERR_BADVALUE;
488 }
489
490 if ((info.clock < 0) || (info.reset < 0)) {
491 return -FDT_ERR_BADVALUE;
492 }
493
494 stm32_qspi.clock_id = (unsigned long)info.clock;
495 stm32_qspi.reset_id = (unsigned int)info.reset;
496
497 stm32mp_clk_enable(stm32_qspi.clock_id);
498
Etienne Carrieref02647a2019-12-08 08:14:40 +0100499 ret = stm32mp_reset_assert(stm32_qspi.reset_id, TIMEOUT_US_1_MS);
500 if (ret != 0) {
501 panic();
502 }
503 ret = stm32mp_reset_deassert(stm32_qspi.reset_id, TIMEOUT_US_1_MS);
504 if (ret != 0) {
505 panic();
506 }
Lionel Debieve923e4d32019-09-24 17:44:28 +0200507
508 mmio_write_32(qspi_base() + QSPI_CR, QSPI_CR_SSHIFT);
509 mmio_write_32(qspi_base() + QSPI_DCR, QSPI_DCR_FSIZE_MASK);
510
511 return spi_mem_init_slave(fdt, qspi_node, &stm32_qspi_bus_ops);
512};