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     mec_hal_girq_clr_src(MEC_QSPI0_ECIA_INFO);
265 }
266 
mec_hal_qspi_girq_ctrl(struct mec_qspi_regs * base,uint8_t enable)267 void mec_hal_qspi_girq_ctrl(struct mec_qspi_regs *base, uint8_t enable)
268 {
269     mec_hal_girq_ctrl(MEC_QSPI0_ECIA_INFO, enable);
270 }
271 
272 /* Returns non-zero if QSPI0 GIRQ result bit is set else 0 */
mec_hal_qspi_girq_is_result(struct mec_qspi_regs * base)273 uint32_t mec_hal_qspi_girq_is_result(struct mec_qspi_regs *base)
274 {
275     return mec_hal_girq_result(MEC_QSPI0_ECIA_INFO);
276 }
277 
mec_hal_qspi_reset(struct mec_qspi_regs * base)278 int mec_hal_qspi_reset(struct mec_qspi_regs *base)
279 {
280     if (!base) {
281         return MEC_RET_ERR_INVAL;
282     }
283 
284     qspi_reset(base);
285 
286     return MEC_RET_OK;
287 }
288 
mec_hal_qspi_reset_sr(struct mec_qspi_regs * base)289 int mec_hal_qspi_reset_sr(struct mec_qspi_regs *base)
290 {
291     uint32_t saved[5];
292 
293     if (!base) {
294         return MEC_RET_ERR_INVAL;
295     }
296 
297     mec_hal_girq_ctrl(MEC_QSPI0_ECIA_INFO, 0);
298 
299     saved[0] = base->MODE & (MEC_QSPI_MODE_CPOL_Msk | MEC_QSPI_MODE_CPHA_MOSI_Msk
300                              | MEC_QSPI_MODE_CPHA_MISO_Msk | MEC_QSPI_MODE_CLKDIV_Msk);
301     saved[1] = base->CSTM;
302     saved[2] = base->TAPSS;
303     saved[3] = base->TAPSA;
304     saved[4] = base->TAPSC;
305 
306     qspi_reset(base);
307     mec_hal_girq_clr_src(MEC_QSPI0_ECIA_INFO);
308 
309     base->MODE = saved[0];
310     base->CSTM = saved[1];
311     base->TAPSS = saved[2];
312     base->TAPSA = saved[3];
313     base->TAPSC = saved[4];
314 
315     return MEC_RET_OK;
316 }
317 
318 /* Set frequency for chip select 1.
319  * param regs = QSPI instance register base address
320  * param freq = frequency use for CS1. Zero indicates use same as CS0.
321  */
qspi_cs1_freq(struct mec_qspi_regs * base,uint32_t freq)322 static void qspi_cs1_freq(struct mec_qspi_regs *base, uint32_t freq)
323 {
324     uint32_t fdiv;
325 
326     if (freq) {
327         fdiv = compute_freq_divisor(freq);
328         base->ALT1_MODE = (fdiv << MEC_QSPI_MODE_CLKDIV_Pos) & MEC_QSPI_MODE_CLKDIV_Msk;
329         base->ALT1_MODE |= MEC_BIT(MEC_QSPI_ALT1_MODE_CS1_ALTEN_Pos);
330     } else {
331         base->ALT1_MODE = 0u;
332     }
333 }
334 
mec_hal_qspi_cs1_freq(struct mec_qspi_regs * base,uint32_t freq)335 int mec_hal_qspi_cs1_freq(struct mec_qspi_regs *base, uint32_t freq)
336 {
337     if (!base) {
338         return MEC_RET_ERR_INVAL;
339     }
340 
341     qspi_cs1_freq(base, freq);
342 
343     return MEC_RET_OK;
344 }
345 
qspi_compute_byte_time_ns(struct mec_qspi_regs * base)346 static uint32_t qspi_compute_byte_time_ns(struct mec_qspi_regs *base)
347 {
348     uint32_t freq = qspi_max_spi_clock();
349     uint32_t fdiv = (base->MODE & MEC_QSPI_MODE_CLKDIV_Msk) >> MEC_QSPI_MODE_CLKDIV_Pos;
350     uint32_t btime_ns;
351 
352     /* Not CS0 and alternate frequency divider enabled */
353     if ((base->MODE & MEC_QSPI_MODE_CS_Msk) &&
354         (base->ALT1_MODE & MEC_BIT(MEC_QSPI_ALT1_MODE_CS1_ALTEN_Pos))) {
355         fdiv = ((base->ALT1_MODE & MEC_QSPI_ALT1_MODE_CS1_ALT_CLKDIV_Msk)
356                 >> MEC_QSPI_ALT1_MODE_CS1_ALT_CLKDIV_Pos);
357     }
358 
359     if (!fdiv) { /* divider reg field = 0 is maximum divider */
360         fdiv = MEC_QSPI_M_FDIV_MAX;
361     }
362 
363     freq /= fdiv;
364 
365     /* Pad to two byte times */
366     btime_ns = (uint32_t)(16000000000ULL / freq);
367 
368     return btime_ns;
369 }
370 
qspi_cs_select(struct mec_qspi_regs * base,enum mec_qspi_cs cs)371 static void qspi_cs_select(struct mec_qspi_regs *base, enum mec_qspi_cs cs)
372 {
373     uint32_t mode = base->MODE & (uint32_t)~MEC_QSPI_MODE_CS_Msk;
374 
375     mode |= (((uint32_t)cs << MEC_QSPI_MODE_CS_Pos) & MEC_QSPI_MODE_CS_Msk);
376     base->MODE = mode;
377 }
378 
mec_hal_qspi_cs_select(struct mec_qspi_regs * base,enum mec_qspi_cs cs)379 int mec_hal_qspi_cs_select(struct mec_qspi_regs *base, enum mec_qspi_cs cs)
380 {
381     if (!base || (cs >= MEC_QSPI_CS_MAX)) {
382         return MEC_RET_ERR_INVAL;
383     }
384 
385     qspi_cs_select(base, cs);
386 
387     return MEC_RET_OK;
388 }
389 
390 static const uint8_t qspi_smode[MEC_SPI_SIGNAL_MODE_MAX] = { 0x0, 0x6, 0x1, 0x7, };
391 static const uint8_t qspi_smode_hi[MEC_SPI_SIGNAL_MODE_MAX] = { 0x4, 0x2, 0x5, 0x3, };
392 
qspi_spi_signal_mode(struct mec_qspi_regs * base,enum mec_qspi_signal_mode spi_mode)393 static void qspi_spi_signal_mode(struct mec_qspi_regs *base, enum mec_qspi_signal_mode spi_mode)
394 {
395     uint32_t freq = qspi_get_freq(base);
396     uint32_t hwsm = 0;
397 
398     if (freq > MEC_QSPI_SIGNAL_NORM_FREQ) {
399         hwsm = (uint32_t)qspi_smode_hi[spi_mode];
400     } else {
401         hwsm = (uint32_t)qspi_smode[spi_mode];
402     }
403 
404     base->MODE = (base->MODE & ~0x700u) | (hwsm << MEC_QSPI_MODE_CPOL_Pos);
405 }
406 
407 /* Requires frequency programmed first */
mec_hal_qspi_spi_signal_mode(struct mec_qspi_regs * base,enum mec_qspi_signal_mode spi_mode)408 int mec_hal_qspi_spi_signal_mode(struct mec_qspi_regs *base, enum mec_qspi_signal_mode spi_mode)
409 {
410     if ((base == NULL) || (spi_mode >= MEC_SPI_SIGNAL_MODE_MAX)) {
411         return MEC_RET_ERR_INVAL;
412     }
413 
414     qspi_spi_signal_mode(base, spi_mode);
415 
416     return MEC_RET_OK;
417 }
418 
mec_hal_qspi_sampling_phase_pol(struct mec_qspi_regs * base,uint8_t phpol)419 int mec_hal_qspi_sampling_phase_pol(struct mec_qspi_regs *base, uint8_t phpol)
420 {
421     if (!base) {
422         return MEC_RET_ERR_INVAL;
423     }
424 
425     base->MODE = (base->MODE & ~0x700u) | ((uint32_t)(phpol & 0x7u) << 8);
426 
427     return MEC_RET_OK;
428 }
429 
qspi_ifm(enum mec_qspi_io iom)430 static uint32_t qspi_ifm(enum mec_qspi_io iom)
431 {
432     uint32_t ifm;
433 
434     if (iom == MEC_QSPI_IO_QUAD) {
435         ifm = (uint32_t)MEC_QSPI_CTRL_IFM_QUAD;
436     } else if (iom == MEC_QSPI_IO_DUAL) {
437         ifm = (uint32_t)MEC_QSPI_CTRL_IFM_DUAL;
438     } else {
439         ifm = (uint32_t)MEC_QSPI_CTRL_IFM_FD;
440     }
441 
442     return (ifm << MEC_QSPI_CTRL_IFM_Pos);
443 }
444 
qspi_io(struct mec_qspi_regs * base,enum mec_qspi_io io)445 static void qspi_io(struct mec_qspi_regs *base, enum mec_qspi_io io)
446 {
447     base->CTRL = (base->CTRL & (uint32_t)~MEC_QSPI_CTRL_IFM_Msk) | qspi_ifm(io);
448 }
449 
mec_hal_qspi_io(struct mec_qspi_regs * base,enum mec_qspi_io io)450 int mec_hal_qspi_io(struct mec_qspi_regs *base, enum mec_qspi_io io)
451 {
452     if (!base || (io >= MEC_QSPI_IO_MAX)) {
453         return MEC_RET_ERR_INVAL;
454     }
455 
456     qspi_io(base, io);
457 
458     return MEC_RET_OK;
459 }
460 
461 struct qspi_cstm_info {
462     uint8_t pos;
463     uint8_t msk0;
464 };
465 
466 const struct qspi_cstm_info cstm_tbl[MEC_QSPI_CSTM_MAX] = {
467     {0, 0xfu},
468     {8, 0xfu},
469     {16, 0xfu},
470     {24, 0xffu},
471 };
472 
mec_hal_qspi_cs_timing_adjust(struct mec_qspi_regs * base,enum mec_qspi_cstm field,uint8_t val)473 int mec_hal_qspi_cs_timing_adjust(struct mec_qspi_regs *base, enum mec_qspi_cstm field,
474                                   uint8_t val)
475 {
476     if ((!base) || (field >= MEC_QSPI_CSTM_MAX)) {
477         return MEC_RET_ERR_INVAL;
478     }
479 
480     uint32_t pos = cstm_tbl[field].pos;
481     uint32_t msk0 = cstm_tbl[field].msk0;
482 
483     base->CSTM = (base->CSTM & ~(msk0 << pos)) | ((val & msk0) << pos);
484 
485     return MEC_RET_OK;
486 }
487 
mec_hal_qspi_cs_timing(struct mec_qspi_regs * base,uint32_t cs_timing)488 int mec_hal_qspi_cs_timing(struct mec_qspi_regs *base, uint32_t cs_timing)
489 {
490     if (!base) {
491         return MEC_RET_ERR_INVAL;
492     }
493 
494     base->CSTM = cs_timing;
495 
496     return MEC_RET_OK;
497 }
498 
mec_hal_qspi_tap_select(struct mec_qspi_regs * base,uint8_t sel_sck_tap,uint8_t sel_ctrl_tap)499 int mec_hal_qspi_tap_select(struct mec_qspi_regs *base, uint8_t sel_sck_tap, uint8_t sel_ctrl_tap)
500 {
501     uint32_t tapss = sel_sck_tap | ((uint32_t)sel_ctrl_tap << 8);
502 
503     if (!base) {
504         return MEC_RET_ERR_INVAL;
505     }
506 
507     tapss = ((uint32_t)sel_sck_tap << MEC_QSPI_TAPSS_TSCK_Pos) & MEC_QSPI_TAPSS_TSCK_Msk;
508     tapss |= (((uint32_t)sel_ctrl_tap << MEC_QSPI_TAPSS_TCTRL_Pos) & MEC_QSPI_TAPSS_TCTRL_Msk);
509     base->TAPSS = (base->TAPSS & (uint32_t)~(MEC_QSPI_TAPSS_TSCK_Msk | MEC_QSPI_TAPSS_TSCK_Msk)) | tapss;
510 
511     return MEC_RET_OK;
512 }
513 
514 /* 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)515 int mec_hal_qspi_init(struct mec_qspi_regs *base,
516                       uint32_t freq_hz,
517                       enum mec_qspi_signal_mode spi_signal_mode,
518                       enum mec_qspi_io iom,
519                       enum mec_qspi_cs chip_sel)
520 {
521     const struct mec_qspi_info *info = qspi_get_info(base);
522 
523     if (!info) {
524         return MEC_RET_ERR_INVAL;
525     }
526 
527     mec_hal_pcr_clr_blk_slp_en(info->pcr_id); /* clocks gated ON */
528     mec_hal_qspi_reset_sr(base);
529     qspi_set_freq(base, freq_hz);
530     qspi_spi_signal_mode(base, spi_signal_mode);
531     qspi_io(base, iom);
532     qspi_cs_select(base, chip_sel);
533 
534     base->MODE |= MEC_BIT(MEC_QSPI_MODE_ACTV_Pos);
535 
536     /* Enable QSPI interrupt signal to propagate to NVIC */
537     mec_hal_girq_ctrl(info->devi, 1);
538 
539     return MEC_RET_OK;
540 }
541 
mec_hal_qspi_options(struct mec_qspi_regs * regs,uint8_t en,uint32_t options)542 int mec_hal_qspi_options(struct mec_qspi_regs *regs, uint8_t en, uint32_t options)
543 {
544     uint32_t val = 0, msk = 0;
545 
546     if (!regs) {
547         return MEC_RET_ERR_INVAL;
548     }
549 
550     if (options & MEC_BIT(MEC_QSPI_OPT_ACTV_EN_POS)) {
551         msk |= MEC_BIT(MEC_QSPI_MODE_ACTV_Pos);
552         if (en) {
553             val |= MEC_BIT(MEC_QSPI_MODE_ACTV_Pos);
554         }
555     }
556     if (options & MEC_BIT(MEC_QSPI_OPT_TAF_DMA_EN_POS)) {
557         msk |= MEC_BIT(MEC_QSPI_MODE_TAFDMA_Pos);
558         if (en) {
559             val |= MEC_BIT(MEC_QSPI_MODE_TAFDMA_Pos);
560         }
561     }
562     if (options & MEC_BIT(MEC_QSPI_OPT_RX_LDMA_EN_POS)) {
563         msk |= MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos);
564         if (en) {
565             val |= MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos);
566         }
567     }
568     if (options & MEC_BIT(MEC_QSPI_OPT_TX_LDMA_EN_POS)) {
569         msk |= MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos);
570         if (en) {
571             val |= MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos);
572         }
573     }
574 
575     regs->MODE = (regs->MODE & ~msk) | (val & msk);
576 
577     return MEC_RET_OK;
578 }
579 
580 /* Force QSPI to stop an on-going transaction.
581  * If QSPI is generating clocks, it will stop at the next byte boundary
582  * and de-assert chip select.
583  */
mec_hal_qspi_force_stop(struct mec_qspi_regs * base)584 int mec_hal_qspi_force_stop(struct mec_qspi_regs *base)
585 {
586     uint32_t btime_ns;
587 
588     if (!base) {
589         return MEC_RET_ERR_INVAL;
590     }
591 
592     base->EXE = MEC_BIT(MEC_QSPI_EXE_STOP_Pos);
593 
594     /* computation uses up some of the time */
595     btime_ns = qspi_compute_byte_time_ns(base);
596 
597     /* Timeout period, doesn't have to be accurate.
598      * EC running at 96MHz (~10 ns) or slower.
599      */
600     while (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_ACTIVE_Pos)) {
601         if (!btime_ns) {
602             return MEC_RET_ERR_TIMEOUT;
603         }
604         btime_ns--;
605     }
606 
607     return MEC_RET_OK;
608 }
609 
mec_hal_qspi_done(struct mec_qspi_regs * base)610 int mec_hal_qspi_done(struct mec_qspi_regs *base)
611 {
612     uint32_t qsts;
613 
614     if (!base) {
615         return MEC_RET_ERR_INVAL;
616     }
617 
618     qsts = base->STATUS;
619 
620     if (qsts & MEC_QSPI_STATUS_ERRORS) {
621         return MEC_RET_ERR_HW;
622     }
623 
624     if (qsts & MEC_BIT(MEC_QSPI_STATUS_DONE_Pos)) {
625         return MEC_RET_OK;
626     }
627 
628     return MEC_RET_ERR_BUSY;
629 }
630 
mec_hal_qspi_hw_status(struct mec_qspi_regs * base)631 uint32_t mec_hal_qspi_hw_status(struct mec_qspi_regs *base)
632 {
633     if (!base) {
634         return 0;
635     }
636 
637     return base->STATUS;
638 }
639 
mec_hal_qspi_hw_status_clr(struct mec_qspi_regs * base,uint32_t msk)640 int mec_hal_qspi_hw_status_clr(struct mec_qspi_regs *base, uint32_t msk)
641 {
642     if (!base) {
643         return MEC_RET_ERR_INVAL;
644     }
645 
646     base->STATUS = msk;
647 
648     return MEC_RET_OK;
649 }
650 
qspi_intr_ctrl(struct mec_qspi_regs * base,int enable)651 static void qspi_intr_ctrl(struct mec_qspi_regs *base, int enable)
652 {
653     uint32_t qien = 0u;
654 
655     if (enable) {
656         qien = (MEC_BIT(MEC_QSPI_INTR_CTRL_DONE_Pos)
657                 | MEC_BIT(MEC_QSPI_INTR_CTRL_TXBERR_Pos)
658                 | MEC_BIT(MEC_QSPI_INTR_CTRL_PROGERR_Pos)
659                 | MEC_BIT(MEC_QSPI_INTR_CTRL_LDRXERR_Pos)
660                 | MEC_BIT(MEC_QSPI_INTR_CTRL_LDTXERR_Pos));
661     }
662 
663     base->INTR_CTRL = qien;
664 }
665 
mec_hal_qspi_intr_ctrl(struct mec_qspi_regs * base,int enable)666 int mec_hal_qspi_intr_ctrl(struct mec_qspi_regs *base, int enable)
667 {
668     if (!base) {
669         return MEC_RET_ERR_INVAL;
670     }
671 
672     qspi_intr_ctrl(base, enable);
673 
674     return MEC_RET_OK;
675 }
676 
mec_hal_qspi_intr_ctrl_msk(struct mec_qspi_regs * base,int enable,uint32_t msk)677 int mec_hal_qspi_intr_ctrl_msk(struct mec_qspi_regs *base, int enable, uint32_t msk)
678 {
679     if (!base) {
680         return MEC_RET_ERR_INVAL;
681     }
682 
683     if (enable) {
684         base->INTR_CTRL |= msk;
685     } else {
686         base->INTR_CTRL &= (uint32_t)~msk;
687     }
688 
689     return MEC_RET_OK;
690 }
691 
mec_hal_qspi_tx_fifo_is_empty(struct mec_qspi_regs * base)692 int mec_hal_qspi_tx_fifo_is_empty(struct mec_qspi_regs *base)
693 {
694     if (base) {
695         if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_TXBE_Pos)) {
696             return 1;
697         }
698     }
699 
700     return 0;
701 }
702 
mec_hal_qspi_tx_fifo_is_full(struct mec_qspi_regs * base)703 int mec_hal_qspi_tx_fifo_is_full(struct mec_qspi_regs *base)
704 {
705     if (base) {
706         if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_TXBF_Pos)) {
707             return 1;
708         }
709     }
710 
711     return 0;
712 }
713 
mec_hal_qspi_rx_fifo_is_empty(struct mec_qspi_regs * base)714 int mec_hal_qspi_rx_fifo_is_empty(struct mec_qspi_regs *base)
715 {
716     if (base) {
717         if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_RXBE_Pos)) {
718             return 1;
719         }
720     }
721 
722     return 0;
723 }
724 
mec_hal_qspi_rx_fifo_is_full(struct mec_qspi_regs * base)725 int mec_hal_qspi_rx_fifo_is_full(struct mec_qspi_regs *base)
726 {
727     if (base) {
728         if (base->STATUS & MEC_BIT(MEC_QSPI_STATUS_RXBF_Pos)) {
729             return 1;
730         }
731     }
732 
733     return 0;
734 }
735 
mec_hal_qspi_start(struct mec_qspi_regs * base,uint32_t ien_mask)736 int mec_hal_qspi_start(struct mec_qspi_regs *base, uint32_t ien_mask)
737 {
738     if (!base) {
739         return MEC_RET_ERR_INVAL;
740     }
741 
742     base->STATUS = UINT32_MAX;
743     base->INTR_CTRL = ien_mask;
744     base->EXE = MEC_BIT(MEC_QSPI_EXE_START_Pos);
745 
746     return MEC_RET_OK;
747 }
748 
749 /* Write up to smaller of bufsz or space available in TX FIFO bytes.
750  * If pointer nloaded not NULL set to number of bytes written to TX FIFO.
751  */
mec_hal_qspi_wr_tx_fifo(struct mec_qspi_regs * regs,const uint8_t * buf,uint32_t bufsz,uint32_t * nwr)752 int mec_hal_qspi_wr_tx_fifo(struct mec_qspi_regs *regs, const uint8_t *buf, uint32_t bufsz,
753                             uint32_t *nwr)
754 {
755     uint32_t loaded = 0;
756     volatile uint8_t *tx_fifo = (volatile uint8_t *)&regs->TX_FIFO;
757 
758     if (!regs || (!buf && bufsz)) {
759         return MEC_RET_ERR_INVAL;
760     }
761 
762     while (bufsz--) {
763         if (regs->STATUS & MEC_BIT(MEC_QSPI_STATUS_TXBF_Pos)) {
764             break;
765         }
766         *tx_fifo = *buf++;
767         loaded++;
768     }
769 
770     if (nwr) {
771         *nwr = loaded;
772     }
773 
774     return MEC_RET_OK;
775 }
776 
777 /* If data is available in QSPI RX FIFO read it and store into buffer data unless
778  * buf is NULL then discard the data.
779  * Stops reading when RX FIFO becomes empty.
780  * Stores number of bytes read in nrd if not NULL.
781  */
mec_hal_qspi_rd_rx_fifo(struct mec_qspi_regs * regs,uint8_t * buf,uint32_t bufsz,uint32_t * nrd)782 int mec_hal_qspi_rd_rx_fifo(struct mec_qspi_regs *regs, uint8_t *buf, uint32_t bufsz,
783                             uint32_t *nrd)
784 {
785     volatile uint8_t *rx_fifo = (volatile uint8_t *)&regs->RX_FIFO;
786     uint32_t nr = 0;
787     uint8_t db = 0;
788 
789     if (!regs) {
790         return MEC_RET_ERR_INVAL;
791     }
792 
793     while (bufsz--) {
794         if (regs->STATUS & MEC_BIT(MEC_QSPI_STATUS_RXBE_Pos)) {
795             break;
796         }
797         db = *rx_fifo;
798         if (buf) {
799             *buf++ = db;
800         }
801         nr++;
802     }
803 
804     if (nrd) {
805         *nrd = nr;
806     }
807 
808     return MEC_RET_OK;
809 }
810 
qspi_ldma_init(struct mec_qspi_regs * base)811 static void qspi_ldma_init(struct mec_qspi_regs *base)
812 {
813     base->MODE &= ~(MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos) | MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos));
814     base->LDMA_RXEN = 0u;
815     base->LDMA_TXEN = 0u;
816     base->RX_LDMA_CHAN[0].CTRL = 0;
817     base->RX_LDMA_CHAN[1].CTRL = 0;
818     base->RX_LDMA_CHAN[2].CTRL = 0;
819     base->TX_LDMA_CHAN[0].CTRL = 0;
820     base->TX_LDMA_CHAN[1].CTRL = 0;
821     base->TX_LDMA_CHAN[2].CTRL = 0;
822 }
823 
824 /* Configure QSPI LDMA RX channel 0 and LDMA TX channel 0 for rx/tx of lenb
825  * bytes. If RX buffer is NULL use read-only QSPI buffer count register
826  * as the target destination and do not set address increment.
827  * If TX buffer is NULL read the write-only QSPI Execute register as
828  * the data source to be written.
829  */
qspi_ldma_cfg1(struct mec_qspi_regs * base,const uint8_t * txb,uint8_t * rxb,size_t lenb)830 static void qspi_ldma_cfg1(struct mec_qspi_regs *base, const uint8_t *txb,
831                            uint8_t *rxb, size_t lenb)
832 {
833     uint32_t rctrl = MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_EN_Pos);
834     uint32_t wctrl = MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_EN_Pos);
835     uint32_t temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_1B;
836 
837     if ((((uintptr_t)rxb | (uintptr_t)lenb) & 0x03u) == 0u) {
838         temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_4B;
839     }
840     rctrl |= (temp << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
841 
842     temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_1B;
843     if ((((uintptr_t)txb | (uintptr_t)lenb) & 0x03u) == 0u) {
844         temp = (uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_4B;
845     }
846     wctrl |= (temp << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
847 
848     base->RX_LDMA_CHAN[0].LEN = lenb;
849     if (rxb) {
850         base->RX_LDMA_CHAN[0].MEM_START = (uintptr_t)rxb;
851         rctrl |= MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_INCRA_Pos);
852     } else {
853         base->RX_LDMA_CHAN[0].MEM_START = (uintptr_t)&base->BCNT_STS;
854     }
855     base->RX_LDMA_CHAN[0].CTRL = rctrl;
856 
857     if (txb) {
858         base->TX_LDMA_CHAN[0].LEN = lenb;
859         base->TX_LDMA_CHAN[0].MEM_START = (uintptr_t)txb;
860         base->TX_LDMA_CHAN[0].CTRL = wctrl | MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_INCRA_Pos);
861     }
862 }
863 
864 /* Build the intitial value used for all descriptors.
865  * param txb pointer to transmit buffer
866  * param interface mode field value (full-duplex, dual, or quad)
867  * return initial/constant descriptor field values.
868  * note Use RX LDMA channel 0 and TX LDMA channel 0.
869  * If transmit buffer is NULL make use of QSPI HW feature to
870  * transmit all 0's.
871  */
descr_ldma_init(const uint8_t * txb,uint32_t ifm)872 static uint32_t descr_ldma_init(const uint8_t *txb, uint32_t ifm)
873 {
874     uint32_t d = ifm;
875 
876     if (txb) {
877         d |= (((uint32_t)MEC_QSPI_DESCR_TXEN_EN << MEC_QSPI_DESCR_TXEN_Pos)
878              | ((uint32_t)MEC_QSPI_DESCR_TXDMA_1B_LDMA_CH0 << MEC_QSPI_DESCR_TXDMA_Pos));
879     }
880 
881     /* always enable receive LDMA for full duplex */
882     d |= (((uint32_t)MEC_QSPI_DESCR_RXEN_EN << MEC_QSPI_DESCR_RXEN_Pos)
883           | ((uint32_t)MEC_QSPI_DESCR_RXDMA_1B_LDMA_CH0 << MEC_QSPI_DESCR_RXDMA_Pos));
884 
885     return d;
886 }
887 
888 #ifdef MEC5_QSPI_LDMA_TX_NULL_LEN_ARE_CLOCKS
889 /*
890  * FD 1 bit = 1 clock
891  * Dual 2 bits = 1 clock
892  * Quad 4 bits = 1 clock
893  */
qspi_clocks_to_bits(uint32_t ctrl,uint32_t nclocks)894 static uint32_t qspi_clocks_to_bits(uint32_t ctrl, uint32_t nclocks)
895 {
896     uint32_t ifm = (ctrl & MEC_QSPI_CTRL_IFM_Msk) >> MEC_QSPI_CTRL_IFM_Pos;
897 
898     if (ifm == MEC_QSPI_CTRL_IFM_QUAD) {
899         return (nclocks * 4u);
900     } else if (ifm == MEC_QSPI_CTRL_IFM_DUAL) {
901         return (nclocks * 2u);
902     } else {
903         return nclocks;
904     }
905 }
906 
qspi_gen_ts_clocks(struct mec_qspi_regs * base,uint32_t nclocks,uint32_t flags)907 static int qspi_gen_ts_clocks(struct mec_qspi_regs *base, uint32_t nclocks, uint32_t flags)
908 {
909     uint32_t descr = qspi_clocks_to_bits(base->CTRL, nclocks);
910     int ien = 0;
911 
912     descr <<= MEC_QSPI_DESCR_QNUNITS_Pos;
913     descr &= MEC_QSPI_DESCR_QNUNITS_Msk;
914     descr |= (base->CTRL & MEC_QSPI_CTRL_IFM_Msk);
915     descr |= (1u << MEC_QSPI_DESCR_NEXT_Pos);
916     descr |= MEC_BIT(MEC_QSPI_DESCR_LAST_Pos);
917 
918     if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_CLOSE_POS)) {
919         descr |= MEC_BIT(MEC_QSPI_DESCR_CLOSE_Pos);
920     }
921     base->DESCR[0] = descr;
922 
923     if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_IEN_POS)) {
924         ien = 1;
925     }
926 
927     qspi_intr_ctrl(base, ien);
928 
929     /* start HW */
930     if (flags & MEC_QSPI_XFR_FLAG_START_POS) {
931         base->EXE = MEC_BIT(MEC_QSPI_EXE_START_Pos);
932     }
933 
934     return MEC_RET_OK;
935 }
936 #endif
937 
938 /* Configure and start/continue a SPI transaction
939  * base is a pointer to the QSPI control instance hardware registers.
940  * txb is a pointer to a constant buffer containing bytes to transmit.
941  * rxb is a pointer to a r/w buffer to hold data received as each byte is
942  * transmitted. If rxb is NULL the received data is discarded. lenb is the size
943  * in bytes of each buffer. flags contains bits to enable interrupts before the
944  * transfer starts.
945  */
mec_hal_qspi_ldma(struct mec_qspi_regs * base,const uint8_t * txb,uint8_t * rxb,size_t lenb,uint32_t flags)946 int mec_hal_qspi_ldma(struct mec_qspi_regs *base, const uint8_t *txb,
947                       uint8_t *rxb, size_t lenb, uint32_t flags)
948 {
949     uint32_t nbytes = lenb;
950     uint32_t shift = 0, nu = 0, descr = 0, descr_init = 0, didx = 0;
951     int ien = 0;
952 
953     if (!base) {
954         return MEC_RET_ERR_INVAL;
955     }
956 
957     if (!lenb) {
958         return 0;
959     }
960 
961     qspi_ldma_init(base);
962 
963     if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_CLR_FIFOS_POS)) {
964         base->EXE = MEC_BIT(MEC_QSPI_EXE_CLRF_Pos);
965     } else if (base->BCNT_STS) { /* data left in TX and/or RX FIFO */
966         return MEC_RET_ERR_HW;
967     }
968 
969     base->STATUS = UINT32_MAX;
970     /* descriptor mode starting at descriptor 0 */
971     base->CTRL |= MEC_BIT(MEC_QSPI_CTRL_DESCR_MODE_Pos);
972 
973 #ifdef MEC5_QSPI_LDMA_TX_NULL_LEN_ARE_CLOCKS
974     if (!txb && !rxb && lenb) {
975         return qspi_gen_ts_clocks(base, lenb, flags);
976     } else {
977         descr_init = descr_ldma_init(txb, base->CTRL & MEC_QSPI_CTRL_IFM_Msk);
978     }
979 #else
980     descr_init = descr_ldma_init(txb, base->CTRL & MEC_QSPI_CTRL_IFM_Msk);
981 #endif
982 
983     while (nbytes && (didx < MEC5_QSPI_NUM_DESCRS)) {
984         descr = descr_init;
985         nu = nbytes;
986         shift = 0;
987         if (nu > MEC_QSPI_DESCR_NU_MAX) {
988             shift = 4;
989             nu >>= 4;
990             descr |= ((uint32_t)MEC_QSPI_DESCR_QUNITS_16B << MEC_QSPI_DESCR_QUNITS_Pos);
991         } else {
992             descr |= ((uint32_t)MEC_QSPI_DESCR_QUNITS_1B << MEC_QSPI_DESCR_QUNITS_Pos);
993         }
994 
995         descr |= (nu << MEC_QSPI_DESCR_QNUNITS_Pos);
996         descr |= (((didx + 1u) << MEC_QSPI_DESCR_NEXT_Pos) & MEC_QSPI_DESCR_NEXT_Msk);
997         base->DESCR[didx] = descr;
998         base->LDMA_RXEN |= MEC_BIT(didx);
999         if (txb) {
1000             base->LDMA_TXEN |= MEC_BIT(didx);
1001         }
1002         nbytes -= (nu << shift);
1003         didx++;
1004     }
1005 
1006     descr = base->DESCR[didx - 1u] | MEC_BIT(MEC_QSPI_DESCR_LAST_Pos);
1007     if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_CLOSE_POS)) {
1008         descr |= MEC_BIT(MEC_QSPI_DESCR_CLOSE_Pos);
1009     }
1010     base->DESCR[didx - 1u] = descr;
1011 
1012     if (nbytes) {
1013         return MEC_RET_ERR_DATA_LEN;
1014     }
1015 
1016     qspi_ldma_cfg1(base, txb, rxb, lenb);
1017 
1018     base->MODE |= (MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos) | MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos));
1019 
1020     if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_IEN_POS)) {
1021         ien = 1;
1022     }
1023 
1024     qspi_intr_ctrl(base, ien);
1025 
1026     /* start HW */
1027     if (flags & MEC_BIT(MEC_QSPI_XFR_FLAG_START_POS)) {
1028         base->EXE = MEC_BIT(MEC_QSPI_EXE_START_Pos);
1029     }
1030 
1031     return 0;
1032 }
1033 
1034 /* -------- 2024-02-24 -------- */
1035 
mec_hal_qspi_context_init(struct mec_qspi_context * ctx)1036 void mec_hal_qspi_context_init(struct mec_qspi_context *ctx)
1037 {
1038     ctx->ndescrs = 0;
1039     ctx->ntxdma = 0;
1040     ctx->nrxdma = 0;
1041     ctx->xflags = 0;
1042     for (size_t n = 0; n < MEC5_QSPI_NUM_DESCRS; n++) {
1043         ctx->descrs[n] = 0;
1044     }
1045 }
1046 
mec_hal_qspi_ctx_alloc_ldma_chan(struct mec_qspi_context * ctx,uint8_t is_tx)1047 uint8_t mec_hal_qspi_ctx_alloc_ldma_chan(struct mec_qspi_context *ctx, uint8_t is_tx)
1048 {
1049     if (!ctx) {
1050         return 0;
1051     }
1052 
1053     if (is_tx) {
1054         if (ctx->ntxdma < MEC5_QSPI_LDMA_CHANNELS) {
1055             return ++ctx->ntxdma;
1056         }
1057     } else {
1058         if (ctx->nrxdma < MEC5_QSPI_LDMA_CHANNELS) {
1059             return ++ctx->nrxdma;
1060         }
1061     }
1062 
1063     return 0;
1064 }
1065 
qspi_nio_pins_to_ifm(uint8_t nio_pins)1066 static uint32_t qspi_nio_pins_to_ifm(uint8_t nio_pins)
1067 {
1068     uint8_t ifm_val;
1069 
1070     if (nio_pins == 4) {
1071         ifm_val = MEC_QSPI_DESCR_IFM_QUAD;
1072     } else if (nio_pins == 2) {
1073         ifm_val = MEC_QSPI_DESCR_IFM_DUAL;
1074     } else {
1075         ifm_val = MEC_QSPI_DESCR_IFM_FD;
1076     }
1077 
1078     return ((uint32_t)ifm_val << MEC_QSPI_DESCR_IFM_Pos);
1079 }
1080 
mec_hal_qspi_cfg_gen_ts_clocks(struct mec_qspi_context * ctx,uint32_t nclocks,uint8_t nio_pins)1081 int mec_hal_qspi_cfg_gen_ts_clocks(struct mec_qspi_context *ctx, uint32_t nclocks,
1082                                    uint8_t nio_pins)
1083 {
1084     uint32_t didx = 0, descr = 0;
1085 
1086     if (!((nio_pins == 1) || (nio_pins == 2) || (nio_pins == 4))) {
1087         return MEC_RET_ERR_INVAL;
1088     }
1089 
1090     if (!nclocks) {
1091         return MEC_RET_ERR_NOP;
1092     }
1093 
1094     didx = ctx->ndescrs;
1095     if (didx >= MEC5_QSPI_NUM_DESCRS) {
1096         return MEC_RET_ERR_NO_RES;
1097     }
1098 
1099     descr |= qspi_nio_pins_to_ifm(nio_pins);
1100     if (!(nclocks & 0x7u)) { /* multiple of 8 bits? */
1101         descr |= (MEC_QSPI_DESCR_QUNITS_1B << MEC_QSPI_DESCR_QUNITS_Pos);
1102         descr |= ((((nclocks >> 3) * nio_pins) << MEC_QSPI_DESCR_QNUNITS_Pos)
1103                   & MEC_QSPI_DESCR_QNUNITS_Msk);
1104     } else {
1105         descr |= (MEC_QSPI_DESCR_QUNITS_BITS << MEC_QSPI_DESCR_QUNITS_Pos);
1106         descr |= (((nclocks * nio_pins) << MEC_QSPI_DESCR_QNUNITS_Pos) & MEC_QSPI_DESCR_QNUNITS_Msk);
1107     }
1108     ctx->descrs[didx] = descr;
1109     ctx->ndescrs++;
1110 
1111     return MEC_RET_OK;
1112 }
1113 
1114 /* Configure the specified QSPI Local-DMA channel.
1115  * regs - pointer to QSPI hardware registers
1116  * buf_addr - address of source or destination buffer in memory
1117  * nbytes - requested number of bytes to transfer
1118  * chan_dir
1119  *    b[3:0] = 1-based channel (1, 2, or 3)
1120  *    b[4] = direction: 0(RX), 1(TX)
1121  * return 0 success
1122  *        < 0 error
1123  *
1124  * Program the specified QSPI RX or TX LDMA channel with memory address
1125  * of source/destination buffer and transfer length in bytes.
1126  * If buffer address is 0 then source/destination memory address is set
1127  * to the QSPI buffer status count read-only register and LDMA channel
1128  * increment address is disabled.
1129  */
mec_hal_qspi_ldma_cfg1(struct mec_qspi_regs * regs,uintptr_t buf_addr,uint32_t nbytes,uint32_t ldflags)1130 int mec_hal_qspi_ldma_cfg1(struct mec_qspi_regs *regs, uintptr_t buf_addr, uint32_t nbytes,
1131                            uint32_t ldflags)
1132 {
1133     volatile struct mec_qspi_ldma_chan_regs *ldma_regs = NULL;
1134     uint32_t ctrl = 0;
1135     uint8_t chanrx = 0, chantx = 0;
1136 
1137     if (!regs) {
1138         return MEC_RET_ERR_INVAL;
1139     }
1140 
1141     if (!nbytes) {
1142         return MEC_RET_OK;
1143     }
1144 
1145     ctrl = ((uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_1B << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
1146     chanrx = (ldflags >> MEC5_QSPI_DCFG1_FLAG_DMA_RX_POS) & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0;
1147     chantx = (ldflags >> MEC5_QSPI_DCFG1_FLAG_DMA_TX_POS) & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0;
1148 
1149     if ((ldflags & MEC5_QSPI_DCFG1_FLAG_DIR_TX) && chantx) {
1150         ldma_regs = &regs->TX_LDMA_CHAN[chantx - 1u];
1151     } else if ((ldflags & MEC5_QSPI_DCFG1_FLAG_DIR_RX) && chanrx) {
1152         ldma_regs = &regs->RX_LDMA_CHAN[chanrx - 1u];
1153     } else {
1154         return MEC_RET_ERR_INVAL;
1155     }
1156 
1157     ldma_regs->CTRL = 0;
1158     ldma_regs->MEM_START = (uint32_t)buf_addr;
1159     ldma_regs->LEN = nbytes;
1160 
1161     if (buf_addr) {
1162         ctrl |= MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_INCRA_Pos);
1163     } else {
1164         ldma_regs->MEM_START = (uint32_t)((uintptr_t)&regs->BCNT_STS & UINT32_MAX);
1165     }
1166 
1167     if (!((buf_addr | nbytes) & 0x3u)) {
1168         ctrl &= (uint32_t)~MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Msk;
1169         ctrl |= ((uint32_t)MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_4B << MEC_QSPI_LDMA_CHAN_CTRL_ACCSZ_Pos);
1170     }
1171 
1172     ldma_regs->CTRL = ctrl | MEC_BIT(MEC_QSPI_LDMA_CHAN_CTRL_EN_Pos);
1173 
1174     return 0;
1175 }
1176 
1177 /* Configures descriptor(s):
1178  *   IFM (full-duplex, dual, or quad)
1179  *   xfr count unit size
1180  *   number of units
1181  *   TX enable (TX-Data only)
1182  *   TX-LDMA channel select (disable or channel id)
1183  *   RX enable
1184  *   RX-LDMA channel select (disable or channel id)
1185  */
mec_hal_qspi_descrs_cfg1(struct mec_qspi_context * ctx,uint32_t nbytes,uint32_t flags)1186 uint32_t mec_hal_qspi_descrs_cfg1(struct mec_qspi_context *ctx, uint32_t nbytes, uint32_t flags)
1187 {
1188     uint32_t dbase;
1189     uint32_t nb;
1190     uint32_t nu;
1191     uint8_t didx;
1192 
1193     if (!ctx) {
1194         return UINT32_MAX;
1195     }
1196 
1197     dbase = qspi_nio_pins_to_ifm(flags & MEC5_QSPI_DCFG1_FLAG_IFM_MSK);
1198 
1199     if (flags & MEC5_QSPI_DCFG1_FLAG_DIR_TX) {
1200         dbase |= (MEC_QSPI_DESCR_TXEN_EN << MEC_QSPI_DESCR_TXEN_Pos);
1201         /* b[5:4] = TX-DMA: 0=disabled, 1-2 specify LDMA channel */
1202         dbase |= ((flags >> MEC5_QSPI_DCFG1_FLAG_DMA_TX_POS)
1203                   & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0) << MEC_QSPI_DESCR_TXDMA_Pos;
1204     }
1205     if (flags & MEC5_QSPI_DCFG1_FLAG_DIR_RX) {
1206         dbase |= MEC_BIT(MEC_QSPI_DESCR_RXEN_Pos);
1207         /* b[8:7] = RX-DMA: 0=disabled, 1-2 specify LDMA channel */
1208         dbase |= ((flags >> MEC5_QSPI_DCFG1_FLAG_DMA_RX_POS)
1209                   & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0) << MEC_QSPI_DESCR_RXDMA_Pos;
1210     }
1211 
1212     didx = ctx->ndescrs;
1213     nb = nbytes;
1214     while (nb) {
1215         if (didx >= MEC5_QSPI_NUM_DESCRS) {
1216             break;
1217         }
1218 
1219         /* b[11:10] = 01b 1-byte units
1220          *            11b 16-byte units
1221          * b[31:17] = number of units
1222          */
1223         if (nb > MEC_QSPI_DESCR_NU_MAX) {
1224             nu = (nb >> 4);
1225             if (nu > MEC_QSPI_DESCR_NU_MAX) {
1226                 nu = MEC_QSPI_DESCR_NU_MAX;
1227             }
1228             ctx->descrs[didx] = (((nu << MEC_QSPI_DESCR_QNUNITS_Pos) & MEC_QSPI_DESCR_QNUNITS_Msk)
1229                                  | (MEC_QSPI_DESCR_QUNITS_16B << MEC_QSPI_DESCR_QUNITS_Pos)
1230                                  | dbase);
1231             nb -= (nu << 4);
1232         } else {
1233             ctx->descrs[didx] = (((nb << MEC_QSPI_DESCR_QNUNITS_Pos) & MEC_QSPI_DESCR_QNUNITS_Msk)
1234                                  | (MEC_QSPI_DESCR_QUNITS_1B << MEC_QSPI_DESCR_QUNITS_Pos)
1235                                  | dbase);
1236             nb = 0;
1237         }
1238         didx++;
1239     }
1240 
1241     ctx->ndescrs = didx;
1242 
1243     return nb;
1244 }
1245 
mec_hal_qspi_load_descrs(struct mec_qspi_regs * regs,struct mec_qspi_context * ctx,uint32_t flags)1246 int mec_hal_qspi_load_descrs(struct mec_qspi_regs *regs, struct mec_qspi_context *ctx,
1247                              uint32_t flags)
1248 {
1249     size_t didx, max_ndescr;
1250     uint32_t descr, ldchan, mode;
1251 
1252     if (!regs || !ctx) {
1253         return MEC_RET_ERR_INVAL;
1254     }
1255 
1256     if (!ctx->ndescrs) {
1257         return MEC_RET_ERR_NOP;
1258     }
1259 
1260     mode = 0;
1261     max_ndescr = (size_t)ctx->ndescrs;
1262 
1263     if (max_ndescr > MEC5_QSPI_NUM_DESCRS) {
1264         max_ndescr = MEC5_QSPI_NUM_DESCRS;
1265     }
1266 
1267     for (didx = 0; didx < max_ndescr; didx++) {
1268         descr = ctx->descrs[didx];
1269         descr &= (uint32_t)~(MEC_QSPI_DESCR_NEXT_Msk);
1270         descr |= ((((uint32_t)didx + 1u) << MEC_QSPI_DESCR_NEXT_Pos) & MEC_QSPI_DESCR_NEXT_Msk);
1271         regs->DESCR[didx] = descr;
1272 
1273         if ((descr & MEC_QSPI_DESCR_TXEN_Msk) == (MEC_QSPI_DESCR_TXEN_EN << MEC_QSPI_DESCR_TXEN_Pos)) {
1274             /* TX-Data enabled? */
1275             ldchan = (descr & MEC_QSPI_DESCR_TXDMA_Msk) >> MEC_QSPI_DESCR_TXDMA_Pos;
1276             if (ldchan) {
1277                 regs->LDMA_TXEN |= MEC_BIT(didx);
1278                 mode |= MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos);
1279             } else {
1280                 regs->LDMA_TXEN &= (uint32_t)~MEC_BIT(didx);
1281             }
1282         }
1283 
1284         if (descr & MEC_BIT(MEC_QSPI_DESCR_RXEN_Pos)) {
1285             ldchan = (descr & MEC_QSPI_DESCR_RXDMA_Msk) >> MEC_QSPI_DESCR_RXDMA_Pos;
1286             if (ldchan) {
1287                 regs->LDMA_RXEN |= MEC_BIT(didx);
1288                 mode |= MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos);
1289             } else {
1290                 regs->LDMA_RXEN &= (uint32_t)~MEC_BIT(didx);
1291             }
1292         }
1293     }
1294 
1295     regs->MODE = (regs->MODE & ~(MEC_BIT(MEC_QSPI_MODE_TX_LDMA_Pos)
1296                                  | MEC_BIT(MEC_QSPI_MODE_RX_LDMA_Pos))) | mode;
1297 
1298     didx = max_ndescr - 1u;
1299     if (flags & MEC_BIT(MEC5_QSPI_LD_FLAGS_LAST_POS)) {
1300         regs->DESCR[didx] |= MEC_BIT(MEC_QSPI_DESCR_LAST_Pos);
1301     }
1302 
1303     if (flags & MEC_BIT(MEC5_QSPI_LD_FLAGS_CLOSE_ON_LAST_POS)) {
1304         regs->DESCR[didx] |= MEC_BIT(MEC_QSPI_DESCR_CLOSE_Pos);
1305     }
1306 
1307     /* Enable descriptor mode with start descriptor = Descr[0] */
1308     regs->CTRL = MEC_BIT(MEC_QSPI_CTRL_DESCR_MODE_Pos);
1309 
1310     return 0;
1311 }
1312 
1313 /* 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)1314 int mec_hal_qspi_load_descrs_at(struct mec_qspi_regs *regs, const uint32_t *descrs, uint8_t ndescr,
1315                                 uint8_t start_descr_idx)
1316 {
1317     uint32_t didx, didx_lim, n;
1318 
1319     if (!regs || !descrs || !ndescr || (start_descr_idx >= MEC5_QSPI_NUM_DESCRS)) {
1320         return MEC_RET_ERR_INVAL;
1321     }
1322 
1323     if (mec_hal_qspi_done(regs) == MEC_RET_ERR_BUSY) {
1324         return MEC_RET_ERR_BUSY;
1325     }
1326 
1327     didx = start_descr_idx;
1328     didx_lim = didx + ndescr;
1329     if (didx_lim > MEC5_QSPI_NUM_DESCRS) {
1330         didx_lim = MEC5_QSPI_NUM_DESCRS;
1331     }
1332 
1333     n = 0;
1334     while (didx < didx_lim) {
1335         regs->DESCR[didx++] = descrs[n++];
1336     }
1337 
1338     return MEC_RET_OK;
1339 }
1340 
1341 /* end mec_qspi.c */
1342