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 *)&regs->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 *)&regs->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 = &regs->TX_LDMA_CHAN[chantx - 1u];
1157     } else if ((ldflags & MEC5_QSPI_DCFG1_FLAG_DIR_RX) && chanrx) {
1158         ldma_regs = &regs->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)&regs->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