1 /*
2 * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <device_mec5.h>
11 #include "mec_pcfg.h"
12 #include "mec_defs.h"
13 #include "mec_ecia_api.h"
14 #include "mec_pcr_api.h"
15 #include "mec_qspi_api.h"
16 #include "mec_retval.h"
17
18 #define MEC_QSPI_GIRQ 18
19 #define MEC_QSPI0_GIRQ_POS 1
20 #define MEC_QSPI0_AGGR_NVIC 10
21 #define MEC_QSPI0_NVIC 91
22
23 #define MEC_QSPI0_ECIA_INFO \
24 MEC5_ECIA_INFO(MEC_QSPI_GIRQ, MEC_QSPI0_GIRQ_POS, MEC_QSPI0_AGGR_NVIC, MEC_QSPI0_NVIC)
25
26 #define MEC_QSPI_M_FDIV_MAX 0x10000
27 #define MEC_QSPI_SOFT_RESET_WAIT_LOOPS 16
28 #define MEC_QSPI_CLR_FIFOS_WAIT_LOOPS 16
29 #define MEC_QSPI_FORCE_STOP_WAIT_LOOPS 1000
30 #define MEC_QSPI_DESCR_NU_MAX 0x7fffu
31
32 #define MEC_QSPI_STATUS_ERRORS (MEC_BIT(MEC_QSPI_STATUS_TXBERR_Pos) \
33 | MEC_BIT(MEC_QSPI_STATUS_RXBERR_Pos) \
34 | MEC_BIT(MEC_QSPI_STATUS_PROGERR_Pos) \
35 | MEC_BIT(MEC_QSPI_STATUS_LDRXERR_Pos) \
36 | MEC_BIT(MEC_QSPI_STATUS_LDTXERR_Pos))
37
38 #define MEC_QSPI_SIG_MODE_POS MEC_QSPI_MODE_CPOL_Pos
39 #define MEC_QSPI_SIG_MODE_MSK \
40 (MEC_QSPI_MODE_CPOL_Msk | MEC_QSPI_MODE_CPHA_MOSI_Msk | MEC_QSPI_MODE_CPHA_MISO_Msk)
41
42 #define MEC5_QSPI_START_DESCR_MSK0 ((uint32_t)MEC_QSPI_CTRL_DPTR_Msk >> MEC_QSPI_CTRL_DPTR_Pos)
43 #define MEC5_QSPI_NEXT_DESCR_MSK0 ((uint32_t)MEC_QSPI_DESCR_NEXT_Msk >> MEC_QSPI_DESCR_NEXT_Pos)
44
45 /* QSPI SPI frequencies less than or equal to this value use
46 * normal CPHA and CPOL settings. For frequencies above this
47 * value we must transmit and sample on the same edge.
48 */
49 #define MEC_QSPI_SIGNAL_NORM_FREQ 24000000u
50
51 struct mec_qspi_info {
52 uintptr_t base_addr;
53 uint32_t devi;
54 uint16_t pcr_id;
55 };
56
57 const struct mec_qspi_info qspi_instances[MEC5_QSPI_INSTANCES] = {
58 {MEC_QSPI0_BASE, MEC_QSPI0_ECIA_INFO, MEC_PCR_QSPI0},
59 };
60
qspi_get_info(struct mec_qspi_regs * base)61 static struct mec_qspi_info const *qspi_get_info(struct mec_qspi_regs *base)
62 {
63 for (size_t n = 0u; n < MEC5_QSPI_INSTANCES; n++) {
64 const struct mec_qspi_info *p = &qspi_instances[n];
65
66 if (p->base_addr == (uintptr_t)base) {
67 return p;
68 }
69 }
70
71 return NULL;
72 }
73
74 /* Return the QSPI controller clock source frequency in Hz. */
qspi_max_spi_clock(void)75 static uint32_t qspi_max_spi_clock(void)
76 {
77 /* QMSPI uses the same PLL output clock as the CPU domain */
78 return mec_hal_pcr_cpu_max_freq();
79 }
80
qspi_get_freq(struct mec_qspi_regs * base)81 static uint32_t qspi_get_freq(struct mec_qspi_regs *base)
82 {
83 uint32_t srcfreq = qspi_max_spi_clock();
84 uint32_t fdiv = (base->MODE & MEC_QSPI_MODE_CLKDIV_Msk) >> MEC_QSPI_MODE_CLKDIV_Pos;
85
86 if (fdiv == 0u) { /* zero is maximum clock divider */
87 fdiv = MEC_QSPI_M_FDIV_MAX;
88 }
89
90 return (srcfreq / fdiv);
91 }
92
mec_hal_qspi_get_freq(struct mec_qspi_regs * base)93 uint32_t mec_hal_qspi_get_freq(struct mec_qspi_regs *base)
94 {
95 if (!base) {
96 return MEC_RET_ERR_INVAL;
97 }
98
99 return qspi_get_freq(base);
100 }
101
mec_hal_qspi_freq_div(struct mec_qspi_regs * base)102 uint32_t mec_hal_qspi_freq_div(struct mec_qspi_regs *base)
103 {
104 uint32_t fdiv = 0;
105
106 if ((uintptr_t)base == (uintptr_t)(MEC_QSPI0_BASE)) {
107 fdiv = (base->MODE & MEC_QSPI_MODE_CLKDIV_Msk) >> MEC_QSPI_MODE_CLKDIV_Pos;
108 }
109
110 if (fdiv == 0) {
111 fdiv = 0x10000u;
112 }
113
114 return fdiv;
115 }
116
117 /* Return the raw 16-bit clock divider field from QSPI Mode register.
118 * 0 = divide by maximum (0x10000)
119 * 1 - 0xffff is divide by this value
120 */
mec_hal_qspi_freq_div_raw(struct mec_qspi_regs * base)121 uint16_t mec_hal_qspi_freq_div_raw(struct mec_qspi_regs *base)
122 {
123 if ((uintptr_t)base != (uintptr_t)(MEC_QSPI0_BASE)) {
124 return 0;
125 }
126
127 return (uint16_t)((base->MODE & MEC_QSPI_MODE_CLKDIV_Msk) >> MEC_QSPI_MODE_CLKDIV_Pos);
128 }
129
mec_hal_qspi_is_enabled(struct mec_qspi_regs * regs)130 bool mec_hal_qspi_is_enabled(struct mec_qspi_regs *regs)
131 {
132 if ((uintptr_t)regs != (uintptr_t)MEC_QSPI0_BASE) {
133 return false;
134 }
135
136 return (regs->MODE & MEC_BIT(MEC_QSPI_MODE_ACTV_Pos)) ? true : false;
137 }
138
139 /* Compute an estimate of time in nanoseconds to clock in/out one byte.
140 * Maximum: F = 96 MHz, T = 10.42 ns
141 * Single: 83.3 ns
142 * Dual = 41.7 ns
143 * Quad = 20.8 ns
144 * Minimum: F = 48 MHz / 65536 = 732.4 Hz, T = 1.365 ms
145 * Single: 10922667 (0x00a6_aaab) ns
146 * Dual: 5461333 ns
147 * Quad = 2730666 ns
148 *
149 * Maximum clock divider Fin = 96MHz
150 * Tsingle = 1e9 * ((65536 / 96,000,000) * 8) = 5461333.33333 ns
151 * Tdual = 1e9 * ((65536 / 96,000,000) * 4) = 2730666.66666 ns
152 * Tquad = 1e9 * ((65536 / 96,000,000) * 2) = 1365333.33333 ns
153 *
154 * Fin = 48MHz
155 * Tsingle = 1e9 * ((65536 / 48,000,000) * 8) = 10922666.66666
156 *
157 */
qspi_byte_time_ns(struct mec_qspi_regs * base)158 static uint32_t qspi_byte_time_ns(struct mec_qspi_regs *base)
159 {
160 uint32_t clkdiv = (base->MODE & MEC_QSPI_MODE_CLKDIV_Msk) >> MEC_QSPI_MODE_CLKDIV_Pos;
161 uint32_t iom = (base->CTRL & MEC_QSPI_CTRL_IFM_Msk) >> MEC_QSPI_CTRL_IFM_Pos;
162 uint32_t byte_time_ns = 10922667u; /* 8-bits full duplex 48MHz clock source, max clock divider */
163
164 if (mec_hal_pcr_is_turbo_clock()) { /* 96MHz clock source? */
165 byte_time_ns = 5461333u; /* max clock divider */
166 }
167
168 /* adjust for IO mode */
169 if (iom == MEC_QSPI_CTRL_IFM_QUAD) {
170 byte_time_ns >>= 2u;
171 } else if (iom == MEC_QSPI_CTRL_IFM_DUAL) {
172 byte_time_ns >>= 1u;
173 }
174
175 /* HW clkdiv == 0 special value is maximum divider = 65536 */
176 if (!clkdiv) {
177 clkdiv = 65536u;
178 }
179
180 /* adjust for clock divider */
181 byte_time_ns = byte_time_ns / (65536u / clkdiv);
182
183 return byte_time_ns;
184 }
185
mec_hal_qspi_byte_time_ns(struct mec_qspi_regs * base,uint32_t * btime_ns)186 int mec_hal_qspi_byte_time_ns(struct mec_qspi_regs *base, uint32_t *btime_ns)
187 {
188 if ((!base) || (!btime_ns)) {
189 return MEC_RET_ERR_INVAL;
190 }
191
192 *btime_ns = qspi_byte_time_ns(base);
193
194 return MEC_RET_OK;
195 }
196
197 /* Computer QSPI frequency divider given desired SPI clock in Hz.
198 * Hardware fdiv = 1 to pow(2, fdiv_field_bit_length) - 1 is Source_Freq / n
199 * Hardware fdiv = 0 is Source_Freq / pow(2, fdiv_field_bit_length)
200 * fdiv_field_bit_length = 8 for MEC152x and 16 for MEC172x
201 * NOTE: Truncation from integer division may result in an actual frequency
202 * lower than requested.
203 */
compute_freq_divisor(uint32_t freq_hz)204 static uint32_t compute_freq_divisor(uint32_t freq_hz)
205 {
206 uint32_t src_freq = qspi_max_spi_clock();
207 uint32_t fdiv;
208
209 if (freq_hz < (src_freq / MEC_QSPI_M_FDIV_MAX)) {
210 fdiv = 0u; /* HW divider of 0 is divide by MEC_QSPI_M_FDIV_MAX */
211 } else if (freq_hz > src_freq) {
212 fdiv = 1u;
213 } else {
214 fdiv = src_freq / freq_hz;
215 }
216
217 return fdiv;
218 }
219
qspi_set_freq(struct mec_qspi_regs * base,uint32_t freqhz)220 static void qspi_set_freq(struct mec_qspi_regs *base, uint32_t freqhz)
221 {
222 uint32_t fdiv = compute_freq_divisor(freqhz);
223
224 base->MODE = ((base->MODE & (uint32_t)~MEC_QSPI_MODE_CLKDIV_Msk)
225 | (fdiv << MEC_QSPI_MODE_CLKDIV_Pos));
226 }
227
mec_hal_qspi_set_freq(struct mec_qspi_regs * base,uint32_t freqhz)228 int mec_hal_qspi_set_freq(struct mec_qspi_regs *base, uint32_t freqhz)
229 {
230 if (!base) {
231 return MEC_RET_ERR_INVAL;
232 }
233
234 qspi_set_freq(base, freqhz);
235
236 return MEC_RET_OK;
237 }
238
qspi_intr_clr_dis(struct mec_qspi_regs * base)239 static void qspi_intr_clr_dis(struct mec_qspi_regs *base)
240 {
241 const struct mec_qspi_info *info = qspi_get_info(base);
242
243 if (!info) {
244 return;
245 }
246
247 base->INTR_CTRL = 0;
248 base->STATUS = UINT32_MAX;
249 mec_hal_girq_ctrl(info->devi, 0);
250 mec_hal_girq_clr_src(info->devi);
251 }
252
qspi_reset(struct mec_qspi_regs * base)253 static void qspi_reset(struct mec_qspi_regs *base)
254 {
255 /* Self clearing soft reset bit (write-only) */
256 base->MODE |= MEC_BIT(MEC_QSPI_MODE_SRST_Pos);
257
258 qspi_intr_clr_dis(base);
259 }
260
261 /* Clear GIRQ source status. Current SoC's have one QSPI instance */
mec_hal_qspi_girq_clr(struct mec_qspi_regs * base)262 void mec_hal_qspi_girq_clr(struct mec_qspi_regs *base)
263 {
264 (void)base;
265
266 mec_hal_girq_clr_src(MEC_QSPI0_ECIA_INFO);
267 }
268
mec_hal_qspi_girq_ctrl(struct mec_qspi_regs * base,uint8_t enable)269 void mec_hal_qspi_girq_ctrl(struct mec_qspi_regs *base, uint8_t enable)
270 {
271 (void)base;
272
273 mec_hal_girq_ctrl(MEC_QSPI0_ECIA_INFO, enable);
274 }
275
276 /* Returns non-zero if QSPI0 GIRQ result bit is set else 0 */
mec_hal_qspi_girq_is_result(struct mec_qspi_regs * base)277 uint32_t mec_hal_qspi_girq_is_result(struct mec_qspi_regs *base)
278 {
279 (void)base;
280
281 return mec_hal_girq_result(MEC_QSPI0_ECIA_INFO);
282 }
283
mec_hal_qspi_reset(struct mec_qspi_regs * base)284 int mec_hal_qspi_reset(struct mec_qspi_regs *base)
285 {
286 if (!base) {
287 return MEC_RET_ERR_INVAL;
288 }
289
290 qspi_reset(base);
291
292 return MEC_RET_OK;
293 }
294
mec_hal_qspi_reset_sr(struct mec_qspi_regs * base)295 int mec_hal_qspi_reset_sr(struct mec_qspi_regs *base)
296 {
297 uint32_t saved[5];
298
299 if (!base) {
300 return MEC_RET_ERR_INVAL;
301 }
302
303 mec_hal_girq_ctrl(MEC_QSPI0_ECIA_INFO, 0);
304
305 saved[0] = base->MODE & (MEC_QSPI_MODE_CPOL_Msk | MEC_QSPI_MODE_CPHA_MOSI_Msk
306 | MEC_QSPI_MODE_CPHA_MISO_Msk | MEC_QSPI_MODE_CLKDIV_Msk);
307 saved[1] = base->CSTM;
308 saved[2] = base->TAPSS;
309 saved[3] = base->TAPSA;
310 saved[4] = base->TAPSC;
311
312 qspi_reset(base);
313 mec_hal_girq_clr_src(MEC_QSPI0_ECIA_INFO);
314
315 base->MODE = saved[0];
316 base->CSTM = saved[1];
317 base->TAPSS = saved[2];
318 base->TAPSA = saved[3];
319 base->TAPSC = saved[4];
320
321 return MEC_RET_OK;
322 }
323
324 /* Set frequency for chip select 1.
325 * param regs = QSPI instance register base address
326 * param freq = frequency use for CS1. Zero indicates use same as CS0.
327 */
qspi_cs1_freq(struct mec_qspi_regs * base,uint32_t freq)328 static void qspi_cs1_freq(struct mec_qspi_regs *base, uint32_t freq)
329 {
330 uint32_t fdiv;
331
332 if (freq) {
333 fdiv = compute_freq_divisor(freq);
334 base->ALT1_MODE = (fdiv << MEC_QSPI_MODE_CLKDIV_Pos) & MEC_QSPI_MODE_CLKDIV_Msk;
335 base->ALT1_MODE |= MEC_BIT(MEC_QSPI_ALT1_MODE_CS1_ALTEN_Pos);
336 } else {
337 base->ALT1_MODE = 0u;
338 }
339 }
340
mec_hal_qspi_cs1_freq(struct mec_qspi_regs * base,uint32_t freq)341 int mec_hal_qspi_cs1_freq(struct mec_qspi_regs *base, uint32_t freq)
342 {
343 if (!base) {
344 return MEC_RET_ERR_INVAL;
345 }
346
347 qspi_cs1_freq(base, freq);
348
349 return MEC_RET_OK;
350 }
351
qspi_compute_byte_time_ns(struct mec_qspi_regs * base)352 static uint32_t qspi_compute_byte_time_ns(struct mec_qspi_regs *base)
353 {
354 uint32_t freq = qspi_max_spi_clock();
355 uint32_t fdiv = (base->MODE & MEC_QSPI_MODE_CLKDIV_Msk) >> MEC_QSPI_MODE_CLKDIV_Pos;
356 uint32_t btime_ns;
357
358 /* Not CS0 and alternate frequency divider enabled */
359 if ((base->MODE & MEC_QSPI_MODE_CS_Msk) &&
360 (base->ALT1_MODE & MEC_BIT(MEC_QSPI_ALT1_MODE_CS1_ALTEN_Pos))) {
361 fdiv = ((base->ALT1_MODE & MEC_QSPI_ALT1_MODE_CS1_ALT_CLKDIV_Msk)
362 >> MEC_QSPI_ALT1_MODE_CS1_ALT_CLKDIV_Pos);
363 }
364
365 if (!fdiv) { /* divider reg field = 0 is maximum divider */
366 fdiv = MEC_QSPI_M_FDIV_MAX;
367 }
368
369 freq /= fdiv;
370
371 /* Pad to two byte times */
372 btime_ns = (uint32_t)(16000000000ULL / freq);
373
374 return btime_ns;
375 }
376
qspi_cs_select(struct mec_qspi_regs * base,enum mec_qspi_cs cs)377 static void qspi_cs_select(struct mec_qspi_regs *base, enum mec_qspi_cs cs)
378 {
379 uint32_t mode = base->MODE & (uint32_t)~MEC_QSPI_MODE_CS_Msk;
380
381 mode |= (((uint32_t)cs << MEC_QSPI_MODE_CS_Pos) & MEC_QSPI_MODE_CS_Msk);
382 base->MODE = mode;
383 }
384
mec_hal_qspi_cs_select(struct mec_qspi_regs * base,enum mec_qspi_cs cs)385 int mec_hal_qspi_cs_select(struct mec_qspi_regs *base, enum mec_qspi_cs cs)
386 {
387 if (!base || (cs >= MEC_QSPI_CS_MAX)) {
388 return MEC_RET_ERR_INVAL;
389 }
390
391 qspi_cs_select(base, cs);
392
393 return MEC_RET_OK;
394 }
395
396 static const uint8_t qspi_smode[MEC_SPI_SIGNAL_MODE_MAX] = { 0x0, 0x6, 0x1, 0x7, };
397 static const uint8_t qspi_smode_hi[MEC_SPI_SIGNAL_MODE_MAX] = { 0x4, 0x2, 0x5, 0x3, };
398
qspi_spi_signal_mode(struct mec_qspi_regs * base,enum mec_qspi_signal_mode spi_mode)399 static void qspi_spi_signal_mode(struct mec_qspi_regs *base, enum mec_qspi_signal_mode spi_mode)
400 {
401 uint32_t freq = qspi_get_freq(base);
402 uint32_t hwsm = 0;
403
404 if (freq > MEC_QSPI_SIGNAL_NORM_FREQ) {
405 hwsm = (uint32_t)qspi_smode_hi[spi_mode];
406 } else {
407 hwsm = (uint32_t)qspi_smode[spi_mode];
408 }
409
410 base->MODE = (base->MODE & ~0x700u) | (hwsm << MEC_QSPI_MODE_CPOL_Pos);
411 }
412
413 /* Requires frequency programmed first */
mec_hal_qspi_spi_signal_mode(struct mec_qspi_regs * base,enum mec_qspi_signal_mode spi_mode)414 int mec_hal_qspi_spi_signal_mode(struct mec_qspi_regs *base, enum mec_qspi_signal_mode spi_mode)
415 {
416 if ((base == NULL) || (spi_mode >= MEC_SPI_SIGNAL_MODE_MAX)) {
417 return MEC_RET_ERR_INVAL;
418 }
419
420 qspi_spi_signal_mode(base, spi_mode);
421
422 return MEC_RET_OK;
423 }
424
mec_hal_qspi_sampling_phase_pol(struct mec_qspi_regs * base,uint8_t phpol)425 int mec_hal_qspi_sampling_phase_pol(struct mec_qspi_regs *base, uint8_t phpol)
426 {
427 if (!base) {
428 return MEC_RET_ERR_INVAL;
429 }
430
431 base->MODE = (base->MODE & ~0x700u) | ((uint32_t)(phpol & 0x7u) << 8);
432
433 return MEC_RET_OK;
434 }
435
qspi_ifm(enum mec_qspi_io iom)436 static uint32_t qspi_ifm(enum mec_qspi_io iom)
437 {
438 uint32_t ifm;
439
440 if (iom == MEC_QSPI_IO_QUAD) {
441 ifm = (uint32_t)MEC_QSPI_CTRL_IFM_QUAD;
442 } else if (iom == MEC_QSPI_IO_DUAL) {
443 ifm = (uint32_t)MEC_QSPI_CTRL_IFM_DUAL;
444 } else {
445 ifm = (uint32_t)MEC_QSPI_CTRL_IFM_FD;
446 }
447
448 return (ifm << MEC_QSPI_CTRL_IFM_Pos);
449 }
450
qspi_io(struct mec_qspi_regs * base,enum mec_qspi_io io)451 static void qspi_io(struct mec_qspi_regs *base, enum mec_qspi_io io)
452 {
453 base->CTRL = (base->CTRL & (uint32_t)~MEC_QSPI_CTRL_IFM_Msk) | qspi_ifm(io);
454 }
455
mec_hal_qspi_io(struct mec_qspi_regs * base,enum mec_qspi_io io)456 int mec_hal_qspi_io(struct mec_qspi_regs *base, enum mec_qspi_io io)
457 {
458 if (!base || (io >= MEC_QSPI_IO_MAX)) {
459 return MEC_RET_ERR_INVAL;
460 }
461
462 qspi_io(base, io);
463
464 return MEC_RET_OK;
465 }
466
467 struct qspi_cstm_info {
468 uint8_t pos;
469 uint8_t msk0;
470 };
471
472 const struct qspi_cstm_info cstm_tbl[MEC_QSPI_CSTM_MAX] = {
473 {0, 0xfu},
474 {8, 0xfu},
475 {16, 0xfu},
476 {24, 0xffu},
477 };
478
mec_hal_qspi_cs_timing_adjust(struct mec_qspi_regs * base,enum mec_qspi_cstm field,uint8_t val)479 int mec_hal_qspi_cs_timing_adjust(struct mec_qspi_regs *base, enum mec_qspi_cstm field,
480 uint8_t val)
481 {
482 if ((!base) || (field >= MEC_QSPI_CSTM_MAX)) {
483 return MEC_RET_ERR_INVAL;
484 }
485
486 uint32_t pos = cstm_tbl[field].pos;
487 uint32_t msk0 = cstm_tbl[field].msk0;
488
489 base->CSTM = (base->CSTM & ~(msk0 << pos)) | ((val & msk0) << pos);
490
491 return MEC_RET_OK;
492 }
493
mec_hal_qspi_cs_timing(struct mec_qspi_regs * base,uint32_t cs_timing)494 int mec_hal_qspi_cs_timing(struct mec_qspi_regs *base, uint32_t cs_timing)
495 {
496 if (!base) {
497 return MEC_RET_ERR_INVAL;
498 }
499
500 base->CSTM = cs_timing;
501
502 return MEC_RET_OK;
503 }
504
mec_hal_qspi_tap_select(struct mec_qspi_regs * base,uint8_t sel_sck_tap,uint8_t sel_ctrl_tap)505 int mec_hal_qspi_tap_select(struct mec_qspi_regs *base, uint8_t sel_sck_tap, uint8_t sel_ctrl_tap)
506 {
507 uint32_t tapss = sel_sck_tap | ((uint32_t)sel_ctrl_tap << 8);
508
509 if (!base) {
510 return MEC_RET_ERR_INVAL;
511 }
512
513 tapss = ((uint32_t)sel_sck_tap << MEC_QSPI_TAPSS_TSCK_Pos) & MEC_QSPI_TAPSS_TSCK_Msk;
514 tapss |= (((uint32_t)sel_ctrl_tap << MEC_QSPI_TAPSS_TCTRL_Pos) & MEC_QSPI_TAPSS_TCTRL_Msk);
515 base->TAPSS = (base->TAPSS & (uint32_t)~(MEC_QSPI_TAPSS_TSCK_Msk | MEC_QSPI_TAPSS_TSCK_Msk)) | tapss;
516
517 return MEC_RET_OK;
518 }
519
520 /* Initialize QMSPI controller using local DMA. */
mec_hal_qspi_init(struct mec_qspi_regs * base,uint32_t freq_hz,enum mec_qspi_signal_mode spi_signal_mode,enum mec_qspi_io iom,enum mec_qspi_cs chip_sel)521 int mec_hal_qspi_init(struct mec_qspi_regs *base,
522 uint32_t freq_hz,
523 enum mec_qspi_signal_mode spi_signal_mode,
524 enum mec_qspi_io iom,
525 enum mec_qspi_cs chip_sel)
526 {
527 const struct mec_qspi_info *info = qspi_get_info(base);
528
529 if (!info) {
530 return MEC_RET_ERR_INVAL;
531 }
532
533 mec_hal_pcr_clr_blk_slp_en(info->pcr_id); /* clocks gated ON */
534 mec_hal_qspi_reset_sr(base);
535 qspi_set_freq(base, freq_hz);
536 qspi_spi_signal_mode(base, spi_signal_mode);
537 qspi_io(base, iom);
538 qspi_cs_select(base, chip_sel);
539
540 base->MODE |= MEC_BIT(MEC_QSPI_MODE_ACTV_Pos);
541
542 /* Enable QSPI interrupt signal to propagate to NVIC */
543 mec_hal_girq_ctrl(info->devi, 1);
544
545 return MEC_RET_OK;
546 }
547
mec_hal_qspi_options(struct mec_qspi_regs * regs,uint8_t en,uint32_t options)548 int mec_hal_qspi_options(struct mec_qspi_regs *regs, uint8_t en, uint32_t options)
549 {
550 uint32_t val = 0, msk = 0;
551
552 if (!regs) {
553 return MEC_RET_ERR_INVAL;
554 }
555
556 if (options & MEC_BIT(MEC_QSPI_OPT_ACTV_EN_POS)) {
557 msk |= MEC_BIT(MEC_QSPI_MODE_ACTV_Pos);
558 if (en) {
559 val |= MEC_BIT(MEC_QSPI_MODE_ACTV_Pos);
560 }
561 }
562 if (options & MEC_BIT(MEC_QSPI_OPT_TAF_DMA_EN_POS)) {
563 msk |= MEC_BIT(MEC_QSPI_MODE_TAFDMA_Pos);
564 if (en) {
565 val |= MEC_BIT(MEC_QSPI_MODE_TAFDMA_Pos);
566 }
567 }
568 if (options & MEC_BIT(MEC_QSPI_OPT_RX_LDMA_EN_POS)) {
569 msk |= MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos);
570 if (en) {
571 val |= MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos);
572 }
573 }
574 if (options & MEC_BIT(MEC_QSPI_OPT_TX_LDMA_EN_POS)) {
575 msk |= MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos);
576 if (en) {
577 val |= MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos);
578 }
579 }
580
581 regs->MODE = (regs->MODE & ~msk) | (val & msk);
582
583 return MEC_RET_OK;
584 }
585
586 /* Force QSPI to stop an on-going transaction.
587 * If QSPI is generating clocks, it will stop at the next byte boundary
588 * and de-assert chip select.
589 */
mec_hal_qspi_force_stop(struct mec_qspi_regs * base)590 int mec_hal_qspi_force_stop(struct mec_qspi_regs *base)
591 {
592 uint32_t btime_ns;
593
594 if (!base) {
595 return MEC_RET_ERR_INVAL;
596 }
597
598 base->EXE = MEC_BIT(MEC_QSPI_EXE_STOP_Pos);
599
600 /* computation uses up some of the time */
601 btime_ns = qspi_compute_byte_time_ns(base);
602
603 /* Timeout period, doesn't have to be accurate.
604 * EC running at 96MHz (~10 ns) or slower.
605 */
606 while (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_ACTIVE_Pos)) {
607 if (!btime_ns) {
608 return MEC_RET_ERR_TIMEOUT;
609 }
610 btime_ns--;
611 }
612
613 return MEC_RET_OK;
614 }
615
mec_hal_qspi_done(struct mec_qspi_regs * base)616 int mec_hal_qspi_done(struct mec_qspi_regs *base)
617 {
618 uint32_t qsts;
619
620 if (!base) {
621 return MEC_RET_ERR_INVAL;
622 }
623
624 qsts = base->STATUS;
625
626 if (qsts & MEC_QSPI_STATUS_ERRORS) {
627 return MEC_RET_ERR_HW;
628 }
629
630 if (qsts & MEC_BIT(MEC_QSPI_STATUS_DONE_Pos)) {
631 return MEC_RET_OK;
632 }
633
634 return MEC_RET_ERR_BUSY;
635 }
636
mec_hal_qspi_hw_status(struct mec_qspi_regs * base)637 uint32_t mec_hal_qspi_hw_status(struct mec_qspi_regs *base)
638 {
639 if (!base) {
640 return 0;
641 }
642
643 return base->STATUS;
644 }
645
mec_hal_qspi_hw_status_clr(struct mec_qspi_regs * base,uint32_t msk)646 int mec_hal_qspi_hw_status_clr(struct mec_qspi_regs *base, uint32_t msk)
647 {
648 if (!base) {
649 return MEC_RET_ERR_INVAL;
650 }
651
652 base->STATUS = msk;
653
654 return MEC_RET_OK;
655 }
656
qspi_intr_ctrl(struct mec_qspi_regs * base,int enable)657 static void qspi_intr_ctrl(struct mec_qspi_regs *base, int enable)
658 {
659 uint32_t qien = 0u;
660
661 if (enable) {
662 qien = (MEC_BIT(MEC_QSPI_INTR_CTRL_DONE_Pos)
663 | MEC_BIT(MEC_QSPI_INTR_CTRL_TXBERR_Pos)
664 | MEC_BIT(MEC_QSPI_INTR_CTRL_PROGERR_Pos)
665 | MEC_BIT(MEC_QSPI_INTR_CTRL_LDRXERR_Pos)
666 | MEC_BIT(MEC_QSPI_INTR_CTRL_LDTXERR_Pos));
667 }
668
669 base->INTR_CTRL = qien;
670 }
671
mec_hal_qspi_intr_ctrl(struct mec_qspi_regs * base,int enable)672 int mec_hal_qspi_intr_ctrl(struct mec_qspi_regs *base, int enable)
673 {
674 if (!base) {
675 return MEC_RET_ERR_INVAL;
676 }
677
678 qspi_intr_ctrl(base, enable);
679
680 return MEC_RET_OK;
681 }
682
mec_hal_qspi_intr_ctrl_msk(struct mec_qspi_regs * base,int enable,uint32_t msk)683 int mec_hal_qspi_intr_ctrl_msk(struct mec_qspi_regs *base, int enable, uint32_t msk)
684 {
685 if (!base) {
686 return MEC_RET_ERR_INVAL;
687 }
688
689 if (enable) {
690 base->INTR_CTRL |= msk;
691 } else {
692 base->INTR_CTRL &= (uint32_t)~msk;
693 }
694
695 return MEC_RET_OK;
696 }
697
mec_hal_qspi_tx_fifo_is_empty(struct mec_qspi_regs * base)698 int mec_hal_qspi_tx_fifo_is_empty(struct mec_qspi_regs *base)
699 {
700 if (base) {
701 if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_TXBE_Pos)) {
702 return 1;
703 }
704 }
705
706 return 0;
707 }
708
mec_hal_qspi_tx_fifo_is_full(struct mec_qspi_regs * base)709 int mec_hal_qspi_tx_fifo_is_full(struct mec_qspi_regs *base)
710 {
711 if (base) {
712 if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_TXBF_Pos)) {
713 return 1;
714 }
715 }
716
717 return 0;
718 }
719
mec_hal_qspi_rx_fifo_is_empty(struct mec_qspi_regs * base)720 int mec_hal_qspi_rx_fifo_is_empty(struct mec_qspi_regs *base)
721 {
722 if (base) {
723 if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_RXBE_Pos)) {
724 return 1;
725 }
726 }
727
728 return 0;
729 }
730
mec_hal_qspi_rx_fifo_is_full(struct mec_qspi_regs * base)731 int mec_hal_qspi_rx_fifo_is_full(struct mec_qspi_regs *base)
732 {
733 if (base) {
734 if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_RXBF_Pos)) {
735 return 1;
736 }
737 }
738
739 return 0;
740 }
741
mec_hal_qspi_start(struct mec_qspi_regs * base,uint32_t ien_mask)742 int mec_hal_qspi_start(struct mec_qspi_regs *base, uint32_t ien_mask)
743 {
744 if (!base) {
745 return MEC_RET_ERR_INVAL;
746 }
747
748 base->STATUS = UINT32_MAX;
749 base->INTR_CTRL = ien_mask;
750 base->EXE = MEC_BIT(MEC_QSPI_EXE_START_Pos);
751
752 return MEC_RET_OK;
753 }
754
755 /* Write up to smaller of bufsz or space available in TX FIFO bytes.
756 * If pointer nloaded not NULL set to number of bytes written to TX FIFO.
757 */
mec_hal_qspi_wr_tx_fifo(struct mec_qspi_regs * regs,const uint8_t * buf,uint32_t bufsz,uint32_t * nwr)758 int mec_hal_qspi_wr_tx_fifo(struct mec_qspi_regs *regs, const uint8_t *buf, uint32_t bufsz,
759 uint32_t *nwr)
760 {
761 uint32_t loaded = 0;
762 volatile uint8_t *tx_fifo = (volatile uint8_t *)®s->TX_FIFO;
763
764 if (!regs || (!buf && bufsz)) {
765 return MEC_RET_ERR_INVAL;
766 }
767
768 while (bufsz--) {
769 if (regs->STATUS & MEC_BIT(MEC_QSPI_STATUS_TXBF_Pos)) {
770 break;
771 }
772 *tx_fifo = *buf++;
773 loaded++;
774 }
775
776 if (nwr) {
777 *nwr = loaded;
778 }
779
780 return MEC_RET_OK;
781 }
782
783 /* If data is available in QSPI RX FIFO read it and store into buffer data unless
784 * buf is NULL then discard the data.
785 * Stops reading when RX FIFO becomes empty.
786 * Stores number of bytes read in nrd if not NULL.
787 */
mec_hal_qspi_rd_rx_fifo(struct mec_qspi_regs * regs,uint8_t * buf,uint32_t bufsz,uint32_t * nrd)788 int mec_hal_qspi_rd_rx_fifo(struct mec_qspi_regs *regs, uint8_t *buf, uint32_t bufsz,
789 uint32_t *nrd)
790 {
791 volatile uint8_t *rx_fifo = (volatile uint8_t *)®s->RX_FIFO;
792 uint32_t nr = 0;
793 uint8_t db = 0;
794
795 if (!regs) {
796 return MEC_RET_ERR_INVAL;
797 }
798
799 while (bufsz--) {
800 if (regs->STATUS & MEC_BIT(MEC_QSPI_STATUS_RXBE_Pos)) {
801 break;
802 }
803 db = *rx_fifo;
804 if (buf) {
805 *buf++ = db;
806 }
807 nr++;
808 }
809
810 if (nrd) {
811 *nrd = nr;
812 }
813
814 return MEC_RET_OK;
815 }
816
qspi_ldma_init(struct mec_qspi_regs * base)817 static void qspi_ldma_init(struct mec_qspi_regs *base)
818 {
819 base->MODE &= ~(MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos) | MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos));
820 base->LDMA_RXEN = 0u;
821 base->LDMA_TXEN = 0u;
822 base->RX_LDMA_CHAN[0].CTRL = 0;
823 base->RX_LDMA_CHAN[1].CTRL = 0;
824 base->RX_LDMA_CHAN[2].CTRL = 0;
825 base->TX_LDMA_CHAN[0].CTRL = 0;
826 base->TX_LDMA_CHAN[1].CTRL = 0;
827 base->TX_LDMA_CHAN[2].CTRL = 0;
828 }
829
830 /* Configure QSPI LDMA RX channel 0 and LDMA TX channel 0 for rx/tx of lenb
831 * bytes. If RX buffer is NULL use read-only QSPI buffer count register
832 * as the target destination and do not set address increment.
833 * If TX buffer is NULL read the write-only QSPI Execute register as
834 * the data source to be written.
835 */
qspi_ldma_cfg1(struct mec_qspi_regs * base,const uint8_t * txb,uint8_t * rxb,size_t lenb)836 static void qspi_ldma_cfg1(struct mec_qspi_regs *base, const uint8_t *txb,
837 uint8_t *rxb, size_t lenb)
838 {
839 uint32_t rctrl = MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_EN_Pos);
840 uint32_t wctrl = MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_EN_Pos);
841 uint32_t temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_1B;
842
843 if ((((uintptr_t)rxb | (uintptr_t)lenb) & 0x03u) == 0u) {
844 temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_4B;
845 }
846 rctrl |= (temp << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
847
848 temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_1B;
849 if ((((uintptr_t)txb | (uintptr_t)lenb) & 0x03u) == 0u) {
850 temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_4B;
851 }
852 wctrl |= (temp << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
853
854 base->RX_LDMA_CHAN[0].LEN = lenb;
855 if (rxb) {
856 base->RX_LDMA_CHAN[0].MEM_START = (uintptr_t)rxb;
857 rctrl |= MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_INCRA_Pos);
858 } else {
859 base->RX_LDMA_CHAN[0].MEM_START = (uintptr_t)&base->BCNT_STS;
860 }
861 base->RX_LDMA_CHAN[0].CTRL = rctrl;
862
863 if (txb) {
864 base->TX_LDMA_CHAN[0].LEN = lenb;
865 base->TX_LDMA_CHAN[0].MEM_START = (uintptr_t)txb;
866 base->TX_LDMA_CHAN[0].CTRL = wctrl | MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_INCRA_Pos);
867 }
868 }
869
870 /* Build the intitial value used for all descriptors.
871 * param txb pointer to transmit buffer
872 * param interface mode field value (full-duplex, dual, or quad)
873 * return initial/constant descriptor field values.
874 * note Use RX LDMA channel 0 and TX LDMA channel 0.
875 * If transmit buffer is NULL make use of QSPI HW feature to
876 * transmit all 0's.
877 */
descr_ldma_init(const uint8_t * txb,uint32_t ifm)878 static uint32_t descr_ldma_init(const uint8_t *txb, uint32_t ifm)
879 {
880 uint32_t d = ifm;
881
882 if (txb) {
883 d |= (((uint32_t)MEC_QSPI_DESCR_TXEN_EN << MEC_QSPI_DESCR_TXEN_Pos)
884 | ((uint32_t)MEC_QSPI_DESCR_TXDMA_1B_LDMA_CH0 << MEC_QSPI_DESCR_TXDMA_Pos));
885 }
886
887 /* always enable receive LDMA for full duplex */
888 d |= (((uint32_t)MEC_QSPI_DESCR_RXEN_EN << MEC_QSPI_DESCR_RXEN_Pos)
889 | ((uint32_t)MEC_QSPI_DESCR_RXDMA_1B_LDMA_CH0 << MEC_QSPI_DESCR_RXDMA_Pos));
890
891 return d;
892 }
893
894 #ifdef MEC5_QSPI_LDMA_TX_NULL_LEN_ARE_CLOCKS
895 /*
896 * FD 1 bit = 1 clock
897 * Dual 2 bits = 1 clock
898 * Quad 4 bits = 1 clock
899 */
qspi_clocks_to_bits(uint32_t ctrl,uint32_t nclocks)900 static uint32_t qspi_clocks_to_bits(uint32_t ctrl, uint32_t nclocks)
901 {
902 uint32_t ifm = (ctrl & MEC_QSPI_CTRL_IFM_Msk) >> MEC_QSPI_CTRL_IFM_Pos;
903
904 if (ifm == MEC_QSPI_CTRL_IFM_QUAD) {
905 return (nclocks * 4u);
906 } else if (ifm == MEC_QSPI_CTRL_IFM_DUAL) {
907 return (nclocks * 2u);
908 } else {
909 return nclocks;
910 }
911 }
912
qspi_gen_ts_clocks(struct mec_qspi_regs * base,uint32_t nclocks,uint32_t flags)913 static int qspi_gen_ts_clocks(struct mec_qspi_regs *base, uint32_t nclocks, uint32_t flags)
914 {
915 uint32_t descr = qspi_clocks_to_bits(base->CTRL, nclocks);
916 int ien = 0;
917
918 descr <<= MEC_QSPI_DESCR_QNUNITS_Pos;
919 descr &= MEC_QSPI_DESCR_QNUNITS_Msk;
920 descr |= (base->CTRL & MEC_QSPI_CTRL_IFM_Msk);
921 descr |= (1u << MEC_QSPI_DESCR_NEXT_Pos);
922 descr |= MEC_BIT(MEC_QSPI_DESCR_LAST_Pos);
923
924 if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_CLOSE_POS)) {
925 descr |= MEC_BIT(MEC_QSPI_DESCR_CLOSE_Pos);
926 }
927 base->DESCR[0] = descr;
928
929 if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_IEN_POS)) {
930 ien = 1;
931 }
932
933 qspi_intr_ctrl(base, ien);
934
935 /* start HW */
936 if (flags & MEC_QSPI_XFR_FLAG_START_POS) {
937 base->EXE = MEC_BIT(MEC_QSPI_EXE_START_Pos);
938 }
939
940 return MEC_RET_OK;
941 }
942 #endif
943
944 /* Configure and start/continue a SPI transaction
945 * base is a pointer to the QSPI control instance hardware registers.
946 * txb is a pointer to a constant buffer containing bytes to transmit.
947 * rxb is a pointer to a r/w buffer to hold data received as each byte is
948 * transmitted. If rxb is NULL the received data is discarded. lenb is the size
949 * in bytes of each buffer. flags contains bits to enable interrupts before the
950 * transfer starts.
951 */
mec_hal_qspi_ldma(struct mec_qspi_regs * base,const uint8_t * txb,uint8_t * rxb,size_t lenb,uint32_t flags)952 int mec_hal_qspi_ldma(struct mec_qspi_regs *base, const uint8_t *txb,
953 uint8_t *rxb, size_t lenb, uint32_t flags)
954 {
955 uint32_t nbytes = lenb;
956 uint32_t shift = 0, nu = 0, descr = 0, descr_init = 0, didx = 0;
957 int ien = 0;
958
959 if (!base) {
960 return MEC_RET_ERR_INVAL;
961 }
962
963 if (!lenb) {
964 return 0;
965 }
966
967 qspi_ldma_init(base);
968
969 if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_CLR_FIFOS_POS)) {
970 base->EXE = MEC_BIT(MEC_QSPI_EXE_CLRF_Pos);
971 } else if (base->BCNT_STS) { /* data left in TX and/or RX FIFO */
972 return MEC_RET_ERR_HW;
973 }
974
975 base->STATUS = UINT32_MAX;
976 /* descriptor mode starting at descriptor 0 */
977 base->CTRL |= MEC_BIT(MEC_QSPI_CTRL_DESCR_MODE_Pos);
978
979 #ifdef MEC5_QSPI_LDMA_TX_NULL_LEN_ARE_CLOCKS
980 if (!txb && !rxb && lenb) {
981 return qspi_gen_ts_clocks(base, lenb, flags);
982 } else {
983 descr_init = descr_ldma_init(txb, base->CTRL & MEC_QSPI_CTRL_IFM_Msk);
984 }
985 #else
986 descr_init = descr_ldma_init(txb, base->CTRL & MEC_QSPI_CTRL_IFM_Msk);
987 #endif
988
989 while (nbytes && (didx < MEC5_QSPI_NUM_DESCRS)) {
990 descr = descr_init;
991 nu = nbytes;
992 shift = 0;
993 if (nu > MEC_QSPI_DESCR_NU_MAX) {
994 shift = 4;
995 nu >>= 4;
996 descr |= ((uint32_t)MEC_QSPI_DESCR_QUNITS_16B << MEC_QSPI_DESCR_QUNITS_Pos);
997 } else {
998 descr |= ((uint32_t)MEC_QSPI_DESCR_QUNITS_1B << MEC_QSPI_DESCR_QUNITS_Pos);
999 }
1000
1001 descr |= (nu << MEC_QSPI_DESCR_QNUNITS_Pos);
1002 descr |= (((didx + 1u) << MEC_QSPI_DESCR_NEXT_Pos) & MEC_QSPI_DESCR_NEXT_Msk);
1003 base->DESCR[didx] = descr;
1004 base->LDMA_RXEN |= MEC_BIT(didx);
1005 if (txb) {
1006 base->LDMA_TXEN |= MEC_BIT(didx);
1007 }
1008 nbytes -= (nu << shift);
1009 didx++;
1010 }
1011
1012 descr = base->DESCR[didx - 1u] | MEC_BIT(MEC_QSPI_DESCR_LAST_Pos);
1013 if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_CLOSE_POS)) {
1014 descr |= MEC_BIT(MEC_QSPI_DESCR_CLOSE_Pos);
1015 }
1016 base->DESCR[didx - 1u] = descr;
1017
1018 if (nbytes) {
1019 return MEC_RET_ERR_DATA_LEN;
1020 }
1021
1022 qspi_ldma_cfg1(base, txb, rxb, lenb);
1023
1024 base->MODE |= (MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos) | MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos));
1025
1026 if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_IEN_POS)) {
1027 ien = 1;
1028 }
1029
1030 qspi_intr_ctrl(base, ien);
1031
1032 /* start HW */
1033 if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_START_POS)) {
1034 base->EXE = MEC_BIT(MEC_QSPI_EXE_START_Pos);
1035 }
1036
1037 return 0;
1038 }
1039
1040 /* -------- 2024-02-24 -------- */
1041
mec_hal_qspi_context_init(struct mec_qspi_context * ctx)1042 void mec_hal_qspi_context_init(struct mec_qspi_context *ctx)
1043 {
1044 ctx->ndescrs = 0;
1045 ctx->ntxdma = 0;
1046 ctx->nrxdma = 0;
1047 ctx->xflags = 0;
1048 for (size_t n = 0; n < MEC5_QSPI_NUM_DESCRS; n++) {
1049 ctx->descrs[n] = 0;
1050 }
1051 }
1052
mec_hal_qspi_ctx_alloc_ldma_chan(struct mec_qspi_context * ctx,uint8_t is_tx)1053 uint8_t mec_hal_qspi_ctx_alloc_ldma_chan(struct mec_qspi_context *ctx, uint8_t is_tx)
1054 {
1055 if (!ctx) {
1056 return 0;
1057 }
1058
1059 if (is_tx) {
1060 if (ctx->ntxdma < MEC5_QSPI_LDMA_CHANNELS) {
1061 return ++ctx->ntxdma;
1062 }
1063 } else {
1064 if (ctx->nrxdma < MEC5_QSPI_LDMA_CHANNELS) {
1065 return ++ctx->nrxdma;
1066 }
1067 }
1068
1069 return 0;
1070 }
1071
qspi_nio_pins_to_ifm(uint8_t nio_pins)1072 static uint32_t qspi_nio_pins_to_ifm(uint8_t nio_pins)
1073 {
1074 uint8_t ifm_val;
1075
1076 if (nio_pins == 4) {
1077 ifm_val = MEC_QSPI_DESCR_IFM_QUAD;
1078 } else if (nio_pins == 2) {
1079 ifm_val = MEC_QSPI_DESCR_IFM_DUAL;
1080 } else {
1081 ifm_val = MEC_QSPI_DESCR_IFM_FD;
1082 }
1083
1084 return ((uint32_t)ifm_val << MEC_QSPI_DESCR_IFM_Pos);
1085 }
1086
mec_hal_qspi_cfg_gen_ts_clocks(struct mec_qspi_context * ctx,uint32_t nclocks,uint8_t nio_pins)1087 int mec_hal_qspi_cfg_gen_ts_clocks(struct mec_qspi_context *ctx, uint32_t nclocks,
1088 uint8_t nio_pins)
1089 {
1090 uint32_t didx = 0, descr = 0;
1091
1092 if (!((nio_pins == 1) || (nio_pins == 2) || (nio_pins == 4))) {
1093 return MEC_RET_ERR_INVAL;
1094 }
1095
1096 if (!nclocks) {
1097 return MEC_RET_ERR_NOP;
1098 }
1099
1100 didx = ctx->ndescrs;
1101 if (didx >= MEC5_QSPI_NUM_DESCRS) {
1102 return MEC_RET_ERR_NO_RES;
1103 }
1104
1105 descr |= qspi_nio_pins_to_ifm(nio_pins);
1106 if (!(nclocks & 0x7u)) { /* multiple of 8 bits? */
1107 descr |= (MEC_QSPI_DESCR_QUNITS_1B << MEC_QSPI_DESCR_QUNITS_Pos);
1108 descr |= ((((nclocks >> 3) * nio_pins) << MEC_QSPI_DESCR_QNUNITS_Pos)
1109 & MEC_QSPI_DESCR_QNUNITS_Msk);
1110 } else {
1111 descr |= (MEC_QSPI_DESCR_QUNITS_BITS << MEC_QSPI_DESCR_QUNITS_Pos);
1112 descr |= (((nclocks * nio_pins) << MEC_QSPI_DESCR_QNUNITS_Pos) & MEC_QSPI_DESCR_QNUNITS_Msk);
1113 }
1114 ctx->descrs[didx] = descr;
1115 ctx->ndescrs++;
1116
1117 return MEC_RET_OK;
1118 }
1119
1120 /* Configure the specified QSPI Local-DMA channel.
1121 * regs - pointer to QSPI hardware registers
1122 * buf_addr - address of source or destination buffer in memory
1123 * nbytes - requested number of bytes to transfer
1124 * chan_dir
1125 * b[3:0] = 1-based channel (1, 2, or 3)
1126 * b[4] = direction: 0(RX), 1(TX)
1127 * return 0 success
1128 * < 0 error
1129 *
1130 * Program the specified QSPI RX or TX LDMA channel with memory address
1131 * of source/destination buffer and transfer length in bytes.
1132 * If buffer address is 0 then source/destination memory address is set
1133 * to the QSPI buffer status count read-only register and LDMA channel
1134 * increment address is disabled.
1135 */
mec_hal_qspi_ldma_cfg1(struct mec_qspi_regs * regs,uintptr_t buf_addr,uint32_t nbytes,uint32_t ldflags)1136 int mec_hal_qspi_ldma_cfg1(struct mec_qspi_regs *regs, uintptr_t buf_addr, uint32_t nbytes,
1137 uint32_t ldflags)
1138 {
1139 volatile struct mec_qspi_ldma_chan_regs *ldma_regs = NULL;
1140 uint32_t ctrl = 0;
1141 uint8_t chanrx = 0, chantx = 0;
1142
1143 if (!regs) {
1144 return MEC_RET_ERR_INVAL;
1145 }
1146
1147 if (!nbytes) {
1148 return MEC_RET_OK;
1149 }
1150
1151 ctrl = ((uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_1B << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
1152 chanrx = (ldflags >> MEC5_QSPI_DCFG1_FLAG_DMA_RX_POS) & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0;
1153 chantx = (ldflags >> MEC5_QSPI_DCFG1_FLAG_DMA_TX_POS) & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0;
1154
1155 if ((ldflags & MEC5_QSPI_DCFG1_FLAG_DIR_TX) && chantx) {
1156 ldma_regs = ®s->TX_LDMA_CHAN[chantx - 1u];
1157 } else if ((ldflags & MEC5_QSPI_DCFG1_FLAG_DIR_RX) && chanrx) {
1158 ldma_regs = ®s->RX_LDMA_CHAN[chanrx - 1u];
1159 } else {
1160 return MEC_RET_ERR_INVAL;
1161 }
1162
1163 ldma_regs->CTRL = 0;
1164 ldma_regs->MEM_START = (uint32_t)buf_addr;
1165 ldma_regs->LEN = nbytes;
1166
1167 if (buf_addr) {
1168 ctrl |= MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_INCRA_Pos);
1169 } else {
1170 ldma_regs->MEM_START = (uint32_t)((uintptr_t)®s->BCNT_STS & UINT32_MAX);
1171 }
1172
1173 if (!((buf_addr | nbytes) & 0x3u)) {
1174 ctrl &= (uint32_t)~MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Msk;
1175 ctrl |= ((uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_4B << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
1176 }
1177
1178 ldma_regs->CTRL = ctrl | MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_EN_Pos);
1179
1180 return 0;
1181 }
1182
1183 /* Configures descriptor(s):
1184 * IFM (full-duplex, dual, or quad)
1185 * xfr count unit size
1186 * number of units
1187 * TX enable (TX-Data only)
1188 * TX-LDMA channel select (disable or channel id)
1189 * RX enable
1190 * RX-LDMA channel select (disable or channel id)
1191 */
mec_hal_qspi_descrs_cfg1(struct mec_qspi_context * ctx,uint32_t nbytes,uint32_t flags)1192 uint32_t mec_hal_qspi_descrs_cfg1(struct mec_qspi_context *ctx, uint32_t nbytes, uint32_t flags)
1193 {
1194 uint32_t dbase;
1195 uint32_t nb;
1196 uint32_t nu;
1197 uint8_t didx;
1198
1199 if (!ctx) {
1200 return UINT32_MAX;
1201 }
1202
1203 dbase = qspi_nio_pins_to_ifm(flags & MEC5_QSPI_DCFG1_FLAG_IFM_MSK);
1204
1205 if (flags & MEC5_QSPI_DCFG1_FLAG_DIR_TX) {
1206 dbase |= (MEC_QSPI_DESCR_TXEN_EN << MEC_QSPI_DESCR_TXEN_Pos);
1207 /* b[5:4] = TX-DMA: 0=disabled, 1-2 specify LDMA channel */
1208 dbase |= ((flags >> MEC5_QSPI_DCFG1_FLAG_DMA_TX_POS)
1209 & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0) << MEC_QSPI_DESCR_TXDMA_Pos;
1210 }
1211 if (flags & MEC5_QSPI_DCFG1_FLAG_DIR_RX) {
1212 dbase |= MEC_BIT(MEC_QSPI_DESCR_RXEN_Pos);
1213 /* b[8:7] = RX-DMA: 0=disabled, 1-2 specify LDMA channel */
1214 dbase |= ((flags >> MEC5_QSPI_DCFG1_FLAG_DMA_RX_POS)
1215 & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0) << MEC_QSPI_DESCR_RXDMA_Pos;
1216 }
1217
1218 didx = ctx->ndescrs;
1219 nb = nbytes;
1220 while (nb) {
1221 if (didx >= MEC5_QSPI_NUM_DESCRS) {
1222 break;
1223 }
1224
1225 /* b[11:10] = 01b 1-byte units
1226 * 11b 16-byte units
1227 * b[31:17] = number of units
1228 */
1229 if (nb > MEC_QSPI_DESCR_NU_MAX) {
1230 nu = (nb >> 4);
1231 if (nu > MEC_QSPI_DESCR_NU_MAX) {
1232 nu = MEC_QSPI_DESCR_NU_MAX;
1233 }
1234 ctx->descrs[didx] = (((nu << MEC_QSPI_DESCR_QNUNITS_Pos) & MEC_QSPI_DESCR_QNUNITS_Msk)
1235 | (MEC_QSPI_DESCR_QUNITS_16B << MEC_QSPI_DESCR_QUNITS_Pos)
1236 | dbase);
1237 nb -= (nu << 4);
1238 } else {
1239 ctx->descrs[didx] = (((nb << MEC_QSPI_DESCR_QNUNITS_Pos) & MEC_QSPI_DESCR_QNUNITS_Msk)
1240 | (MEC_QSPI_DESCR_QUNITS_1B << MEC_QSPI_DESCR_QUNITS_Pos)
1241 | dbase);
1242 nb = 0;
1243 }
1244 didx++;
1245 }
1246
1247 ctx->ndescrs = didx;
1248
1249 return nb;
1250 }
1251
mec_hal_qspi_load_descrs(struct mec_qspi_regs * regs,struct mec_qspi_context * ctx,uint32_t flags)1252 int mec_hal_qspi_load_descrs(struct mec_qspi_regs *regs, struct mec_qspi_context *ctx,
1253 uint32_t flags)
1254 {
1255 size_t didx, max_ndescr;
1256 uint32_t descr, ldchan, mode;
1257
1258 if (!regs || !ctx) {
1259 return MEC_RET_ERR_INVAL;
1260 }
1261
1262 if (!ctx->ndescrs) {
1263 return MEC_RET_ERR_NOP;
1264 }
1265
1266 mode = 0;
1267 max_ndescr = (size_t)ctx->ndescrs;
1268
1269 if (max_ndescr > MEC5_QSPI_NUM_DESCRS) {
1270 max_ndescr = MEC5_QSPI_NUM_DESCRS;
1271 }
1272
1273 for (didx = 0; didx < max_ndescr; didx++) {
1274 descr = ctx->descrs[didx];
1275 descr &= (uint32_t)~(MEC_QSPI_DESCR_NEXT_Msk);
1276 descr |= ((((uint32_t)didx + 1u) << MEC_QSPI_DESCR_NEXT_Pos) & MEC_QSPI_DESCR_NEXT_Msk);
1277 regs->DESCR[didx] = descr;
1278
1279 if ((descr & MEC_QSPI_DESCR_TXEN_Msk) == (MEC_QSPI_DESCR_TXEN_EN << MEC_QSPI_DESCR_TXEN_Pos)) {
1280 /* TX-Data enabled? */
1281 ldchan = (descr & MEC_QSPI_DESCR_TXDMA_Msk) >> MEC_QSPI_DESCR_TXDMA_Pos;
1282 if (ldchan) {
1283 regs->LDMA_TXEN |= MEC_BIT(didx);
1284 mode |= MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos);
1285 } else {
1286 regs->LDMA_TXEN &= (uint32_t)~MEC_BIT(didx);
1287 }
1288 }
1289
1290 if (descr & MEC_BIT(MEC_QSPI_DESCR_RXEN_Pos)) {
1291 ldchan = (descr & MEC_QSPI_DESCR_RXDMA_Msk) >> MEC_QSPI_DESCR_RXDMA_Pos;
1292 if (ldchan) {
1293 regs->LDMA_RXEN |= MEC_BIT(didx);
1294 mode |= MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos);
1295 } else {
1296 regs->LDMA_RXEN &= (uint32_t)~MEC_BIT(didx);
1297 }
1298 }
1299 }
1300
1301 regs->MODE = (regs->MODE & ~(MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos)
1302 | MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos))) | mode;
1303
1304 didx = max_ndescr - 1u;
1305 if (flags & MEC_BIT(MEC5_QSPI_LD_FLAGS_LAST_POS)) {
1306 regs->DESCR[didx] |= MEC_BIT(MEC_QSPI_DESCR_LAST_Pos);
1307 }
1308
1309 if (flags & MEC_BIT(MEC5_QSPI_LD_FLAGS_CLOSE_ON_LAST_POS)) {
1310 regs->DESCR[didx] |= MEC_BIT(MEC_QSPI_DESCR_CLOSE_Pos);
1311 }
1312
1313 /* Enable descriptor mode with start descriptor = Descr[0] */
1314 regs->CTRL = MEC_BIT(MEC_QSPI_CTRL_DESCR_MODE_Pos);
1315
1316 return 0;
1317 }
1318
1319 /* Load descriptors register only. Does not touch other QSPI registers */
mec_hal_qspi_load_descrs_at(struct mec_qspi_regs * regs,const uint32_t * descrs,uint8_t ndescr,uint8_t start_descr_idx)1320 int mec_hal_qspi_load_descrs_at(struct mec_qspi_regs *regs, const uint32_t *descrs, uint8_t ndescr,
1321 uint8_t start_descr_idx)
1322 {
1323 uint32_t didx, didx_lim, n;
1324
1325 if (!regs || !descrs || !ndescr || (start_descr_idx >= MEC5_QSPI_NUM_DESCRS)) {
1326 return MEC_RET_ERR_INVAL;
1327 }
1328
1329 if (mec_hal_qspi_done(regs) == MEC_RET_ERR_BUSY) {
1330 return MEC_RET_ERR_BUSY;
1331 }
1332
1333 didx = start_descr_idx;
1334 didx_lim = didx + ndescr;
1335 if (didx_lim > MEC5_QSPI_NUM_DESCRS) {
1336 didx_lim = MEC5_QSPI_NUM_DESCRS;
1337 }
1338
1339 n = 0;
1340 while (didx < didx_lim) {
1341 regs->DESCR[didx++] = descrs[n++];
1342 }
1343
1344 return MEC_RET_OK;
1345 }
1346
1347 /* end mec_qspi.c */
1348