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_espi_taf.h"
15 #include "mec_qspi_api.h"
16 #include "mec_pcr_api.h"
17 #include "mec_retval.h"
18 
19 /* ---- eSPI Target-Attached-Flash (TAF) ----
20  * eSPI target controller responds to flash read/erase/program/rpmc requests
21  * from the Host eSPI controller.
22  * Version 1.5 TAF hardware supports up to two SPI flash devices.
23  * TAF hardware makes use of the QSPI controller for SPI access. When TAF is
24  * activated the QSPI controller registers disappear from AHB memory space and
25  * are owned by TAF. The Host application must configure the QSPI controller and
26  * its pins before TAF is activated.
27  */
28 #define MEC_ESPI_TAF_GIRQ           19
29 #define MEC_ESPI_TAF_GIRQ_AGGR_NVIC 11
30 #define MEC_ESPI_TAF_DONE_NVIC      166
31 #define MEC_ESPI_TAF_ERR_NVIC       167
32 #define MEC_ESPI_TAF_ECP_GIRQ_POS   9
33 #define MEC_ESPI_TAF_HWMON_GIRQ_POS 10
34 #define MEC_ESPI_TAF_DONE_ECIA_INFO \
35     MEC5_ECIA_INFO(MEC_ESPI_TAF_GIRQ, MEC_ESPI_TAF_DONE_GIRQ_POS, MEC_ESPI_TAF_GIRQ_AGGR_NVIC,\
36                    MEC_ESPI_TAF_DONE_NVIC)
37 #define MEC_ESPI_TAF_ERR_ECIA_INFO  \
38     MEC5_ECIA_INFO(MEC_ESPI_TAF_GIRQ, MEC_ESPI_TAF_ERR_GIRQ_POS, MEC_ESPI_TAF_GIRQ_AGGR_NVIC,\
39                    MEC_ESPI_TAF_ERR_NVIC)
40 
41 /* Flash channel status errors */
42 #define MEC_ESPI_TAF_ERR_ALL \
43   (BIT(MEC_ESPI_TAF_MON_STS_TMOUT_ERR_Pos) | BIT(MEC_ESPI_TAF_MON_STS_OOR_ERR_Pos) \
44    | BIT(MEC_ESPI_TAF_MON_STS_ACCV_ERR_Pos) | BIT(MEC_ESPI_TAF_MON_STS_4KB_ERR_Pos) \
45    | BIT(MEC_ESPI_TAF_MON_STS_ERSZ_ERR_Pos))
46 
47 
48 #define MEC_TAF_DFLT_FREQ_HZ 24000000u
49 
50 /* Protection region register address and limit are in 4KB units */
51 #define MEC_TAF_PR_UNIT_SHIFT     12
52 #define MEC_TAF_PR_UNIT_SIZE      0x1000
53 #define MEC_TAF_PR_UNIT_MASK      0xfffu
54 #define MEC_TAF_PR_START_LIM_MASK 0xfffffu /* b[19:0] */
55 #define MEC_TAF_PR_START_DFLT     0x7fffu
56 #define MEC_TAF_PR_LIMIT_DFLT     0
57 
58 #ifdef MEC_ESPI_TAF_CHECK_REG_ADDR
taf_regs_valid(struct mec_espi_taf_regs * regs)59 static inline bool taf_regs_valid(struct mec_espi_taf_regs *regs)
60 {
61     if (((uintptr_t)regs != (uintptr_t)MEC_ESPI_TAF_BASE)) {
62         return false;
63     }
64     return true;
65 }
66 #else
taf_regs_valid(struct mec_espi_taf_regs * regs)67 static inline bool taf_regs_valid(struct mec_espi_taf_regs *regs) { return true; }
68 #endif
69 
iflags_to_bitmap(uint32_t flags)70 static inline uint32_t iflags_to_bitmap(uint32_t flags)
71 {
72     uint32_t bitmap = 0;
73 
74     if (flags & MEC_BIT(MEC_ESPI_TAF_INTR_ECP_DONE_POS)) {
75         bitmap |= MEC_BIT(MEC_ESPI_TAF_ECP_GIRQ_POS);
76     }
77     if (flags & MEC_BIT(MEC_ESPI_TAF_INTR_HWMON_ERR_POS)) {
78         bitmap |= MEC_BIT(MEC_ESPI_TAF_HWMON_GIRQ_POS);
79     }
80     return bitmap;
81 }
82 
pr_is_dirty(struct mec_espi_taf_regs * regs,uint8_t pridx)83 static bool pr_is_dirty(struct mec_espi_taf_regs *regs, uint8_t pridx)
84 {
85    if (regs->PR_DIRTY & MEC_BIT(pridx)) {
86        return true;
87     }
88     return false;
89 }
90 
taf_disable_clear_intr(struct mec_espi_taf_regs * regs)91 static void taf_disable_clear_intr(struct mec_espi_taf_regs *regs)
92 {
93     uint32_t girq_bm = MEC_BIT(MEC_ESPI_TAF_ECP_GIRQ_POS) | MEC_BIT(MEC_ESPI_TAF_HWMON_GIRQ_POS);
94     regs->FC_MISC = 0u;
95     regs->ECP_IEN = 0;
96     regs->MON_IEN = 0;
97 
98     mec_hal_girq_bm_en(MEC_ESPI_TAF_GIRQ, girq_bm, 0);
99 
100     regs->ECP_STS = UINT32_MAX;
101     regs->MON_STS = UINT32_MAX;
102     regs->PR_DIRTY = UINT32_MAX;
103 
104     mec_hal_girq_bm_clr_src(MEC_ESPI_TAF_GIRQ, girq_bm);
105     NVIC_ClearPendingIRQ(MEC_ESPI_TAF_DONE_NVIC);
106     NVIC_ClearPendingIRQ(MEC_ESPI_TAF_ERR_NVIC);
107 }
108 
109 /* ---- Public API ---- */
110 
mec_hal_espi_taf_girq_ctrl(uint8_t enable,uint32_t flags)111 void mec_hal_espi_taf_girq_ctrl(uint8_t enable, uint32_t flags)
112 {
113     uint32_t bitmap = iflags_to_bitmap(flags);
114 
115     if (bitmap) {
116         mec_hal_girq_bm_en(MEC_ESPI_TAF_GIRQ, bitmap, enable);
117     }
118 }
119 
mec_hal_espi_taf_girq_status_clr(uint32_t flags)120 void mec_hal_espi_taf_girq_status_clr(uint32_t flags)
121 {
122     uint32_t bitmap = iflags_to_bitmap(flags);
123 
124     if (bitmap) {
125         mec_hal_girq_bm_clr_src(MEC_ESPI_TAF_GIRQ, bitmap);
126     }
127 }
128 
mec_hal_espi_taf_girq_status(void)129 uint32_t mec_hal_espi_taf_girq_status(void)
130 {
131     uint32_t bitmap = 0;
132     uint32_t src = mec_hal_girq_source_get(MEC_ESPI_TAF_GIRQ);
133 
134     if (src & MEC_BIT(MEC_ESPI_TAF_ECP_GIRQ_POS)) {
135         bitmap |= MEC_BIT(MEC_ESPI_TAF_INTR_ECP_DONE_POS);
136     }
137     if (src & MEC_BIT(MEC_ESPI_TAF_HWMON_GIRQ_POS)) {
138         bitmap |= MEC_BIT(MEC_ESPI_TAF_INTR_HWMON_ERR_POS);
139     }
140 
141     return bitmap;
142 }
143 
mec_hal_espi_taf_girq_result(void)144 uint32_t mec_hal_espi_taf_girq_result(void)
145 {
146     uint32_t bitmap = 0;
147     uint32_t src = mec_hal_girq_result_get(MEC_ESPI_TAF_GIRQ);
148 
149     if (src & MEC_BIT(MEC_ESPI_TAF_ECP_GIRQ_POS)) {
150         bitmap |= MEC_BIT(MEC_ESPI_TAF_INTR_ECP_DONE_POS);
151     }
152     if (src & MEC_BIT(MEC_ESPI_TAF_HWMON_GIRQ_POS)) {
153         bitmap |= MEC_BIT(MEC_ESPI_TAF_INTR_HWMON_ERR_POS);
154     }
155 
156     return bitmap;
157 }
158 
159 /* returns 0 if eSPI TAF is not activated meaning QSPI controller is accessible else
160  * returns non-zero if eSPI TAF is activated and QSPI is not accessible.
161  */
mec_hal_espi_taf_is_activated(void)162 bool mec_hal_espi_taf_is_activated(void)
163 {
164     struct mec_espi_taf_regs *regs = (struct mec_espi_taf_regs *)(MEC_ESPI_TAF_BASE);
165 
166     if (regs->FC_MISC & MEC_BIT(MEC_ESPI_TAF_FC_MISC_TAF_EN_Pos)) {
167         return true;
168     }
169 
170     return false;
171 }
172 
173 /* Activate eSPI TAF hardware. Once activated the QSPI0 controller used by TAF is no longer
174  * accessible.
175  */
mec_hal_espi_taf_activate(uint8_t enable)176 void mec_hal_espi_taf_activate(uint8_t enable)
177 {
178     struct mec_espi_taf_regs *regs = (struct mec_espi_taf_regs *)(MEC_ESPI_TAF_BASE);
179 
180     if (enable) {
181         regs->FC_MISC |= MEC_BIT(MEC_ESPI_TAF_FC_MISC_TAF_EN_Pos);
182     } else {
183         regs->FC_MISC &= (uint32_t)~MEC_BIT(MEC_ESPI_TAF_FC_MISC_TAF_EN_Pos);
184     }
185 }
186 
mec_hal_espi_taf_init(struct mec_espi_taf_regs * regs,uint32_t initflags)187 int mec_hal_espi_taf_init(struct mec_espi_taf_regs *regs, uint32_t initflags)
188 {
189     struct mec_espi_io_regs *ioregs = (struct mec_espi_io_regs *)(MEC_ESPI_IO_BASE);
190     uint8_t capfc = ioregs->CAPFC;
191 
192     if (!taf_regs_valid(regs)) {
193         return MEC_RET_ERR_INVAL;
194     }
195 
196     mec_hal_pcr_clr_blk_slp_en(MEC_PCR_ESPI_TAF);
197     if (initflags & MEC_BIT(MEC_ESPI_TAF_INIT_RESET_POS)) {
198         mec_hal_pcr_blk_reset(MEC_PCR_ESPI_TAF);
199     }
200 
201     taf_disable_clear_intr(regs);
202 
203     if (!(ioregs->CAP0 & MEC_BIT(MEC_ESPI_IO_CAP0_FC_SUPP_Pos))) {
204         return MEC_RET_ERR_HW_NOT_SUPP;
205     }
206 
207     capfc &= (uint8_t)~MEC_ESPI_IO_CAPFC_SHARING_SUPP_Msk;
208     if (initflags & MEC_BIT(MEC_ESPI_TAF_CAF_SHARE_POS)) {
209         capfc |= (MEC_ESPI_IO_CAPFC_SHARING_SUPP_CAF_TAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
210     } else {
211         capfc |= (MEC_ESPI_IO_CAPFC_SHARING_SUPP_TAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
212     }
213     ioregs->CAPFC = capfc;
214 
215     return MEC_RET_OK;
216 }
217 
218 /* qfreq = MHZ(24)
219  * qcpha = 0
220  *
221  * if cfg freq flag
222  *   qfreq = thwcfg->qspi_freq_mhz * MHZ(1)
223  * else if qspi enabled
224  *   qfreq = read from QSPI
225  *
226  * if cfg cpha flag
227  *   qcpha = thwcfg->qspi_cpha
228  * else if qspi enabled
229  *   qcpha = read from QSPI
230  *
231  */
taf_qspi_freq_timing(struct mec_qspi_regs * qregs,const struct espi_taf_hw_cfg * thwcfg)232 static void taf_qspi_freq_timing(struct mec_qspi_regs *qregs,
233                                  const struct espi_taf_hw_cfg *thwcfg)
234 {
235     uint32_t qfreq = MEC_TAF_DFLT_FREQ_HZ;
236     uint8_t clk_tap = 0, ctrl_tap = 0;
237 
238     if (mec_hal_qspi_is_enabled(qregs)) {
239         qfreq = mec_hal_qspi_get_freq(qregs);
240     }
241 
242     if (thwcfg->flags & MEC_BIT(MEC_ESPI_TAF_HW_CFG_FLAG_FREQ_POS)) {
243         qfreq = (uint32_t)thwcfg->qspi_freq_mhz * 1000u * 1000u;
244     }
245 
246     /* save and restore signalling mode, cs timing and timing taps */
247     mec_hal_qspi_reset_sr(qregs);
248     mec_hal_qspi_set_freq(qregs, qfreq);
249 
250     if (thwcfg->flags & MEC_BIT(MEC_ESPI_TAF_HW_CFG_FLAG_CPHA_POS)) {
251         mec_hal_qspi_sampling_phase_pol(qregs, thwcfg->qspi_cpha);
252     }
253 
254     if (thwcfg->flags & MEC_BIT(MEC_ESPI_TAF_HW_CFG_FLAG_CSTM_POS)) {
255         mec_hal_qspi_cs_timing(qregs, thwcfg->qspi_cs_timing);
256     }
257 
258     if (thwcfg->flags & MEC_BIT(MEC_ESPI_TAF_HW_CFG_FLAG_TAPS_POS)) {
259         clk_tap = (uint8_t)(thwcfg->qtaps_sel & 0xffu);
260         ctrl_tap = (uint8_t)((thwcfg->qtaps_sel >> 8) & 0xffu);
261         mec_hal_qspi_tap_select(qregs, clk_tap, ctrl_tap);
262     }
263 }
264 
mec_hal_espi_taf_qspi_init(struct mec_espi_taf_regs * tregs,struct mec_qspi_regs * qregs,const struct espi_taf_hw_cfg * thwcfg)265 int mec_hal_espi_taf_qspi_init(struct mec_espi_taf_regs *tregs, struct mec_qspi_regs *qregs,
266                                const struct espi_taf_hw_cfg *thwcfg)
267 {
268     int ret = 0;
269     uint32_t flags = 0;
270     uint32_t qfdiv = 0;
271 
272     if (!taf_regs_valid(tregs) || ((uintptr_t)qregs != (uintptr_t)(MEC_QSPI0_BASE))
273         || !thwcfg) {
274         return MEC_RET_ERR_INVAL;
275     }
276 
277     taf_qspi_freq_timing(qregs, thwcfg);
278 
279     /* copy raw QSPI frequency divider field into TAF CS0/CS1 freq divider regs */
280     qfdiv = mec_hal_qspi_freq_div_raw(qregs);
281     qfdiv = qfdiv | (qfdiv << 16);
282     tregs->CLKDIV_CS0 = qfdiv;
283     tregs->CLKDIV_CS1 = qfdiv;
284 
285     /* load continous mode enter/exit and status polling descriptors */
286     ret = mec_hal_qspi_load_descrs_at(qregs, thwcfg->generic_descr,
287                                       MEC_ESPI_TAF_GENERIC_DESCR_MAX,
288                                       MCHP_TAF_CM_EXIT_START_DESCR);
289     if (ret != MEC_RET_OK) {
290         return ret;
291     }
292 
293     /* TODO: MEC172x do we need to set QSPI.TX_LDMA[0].CTRL enable, restart-enable, and
294      * access size = 4?
295      */
296 
297     mec_hal_qspi_intr_ctrl_msk(qregs, 1, MEC_QSPI_IEN_XFR_DONE);
298     flags = MEC_BIT(MEC_QSPI_OPT_ACTV_EN_POS) | MEC_BIT(MEC_QSPI_OPT_TAF_DMA_EN_POS)
299             | MEC_BIT(MEC_QSPI_OPT_RX_LDMA_EN_POS) | MEC_BIT(MEC_QSPI_OPT_TX_LDMA_EN_POS);
300     mec_hal_qspi_options(qregs, 1, flags);
301 
302     return MEC_RET_OK;
303 }
304 
mec_hal_espi_taf_pr_is_dirty(struct mec_espi_taf_regs * regs,uint8_t pr_idx)305 bool mec_hal_espi_taf_pr_is_dirty(struct mec_espi_taf_regs *regs, uint8_t pr_idx)
306 {
307     if (!taf_regs_valid(regs) || (pr_idx >= MEC_ESPI_TAF_PROT_REG_MAX)) {
308         return false;
309     }
310 
311     return pr_is_dirty(regs, pr_idx);
312 }
313 
mec_hal_espi_taf_pr_dirty_clr(struct mec_espi_taf_regs * regs,uint8_t pr_idx)314 int mec_hal_espi_taf_pr_dirty_clr(struct mec_espi_taf_regs *regs, uint8_t pr_idx)
315 {
316     if (!taf_regs_valid(regs) || (pr_idx >= MEC_ESPI_TAF_PROT_REG_MAX)) {
317         return MEC_RET_ERR_INVAL;
318     }
319 
320     regs->PR_DIRTY = MEC_BIT(pr_idx);
321 
322     return MEC_RET_OK;
323 }
324 
325 
mec_hal_espi_taf_pr_dirty_clr_mask(struct mec_espi_taf_regs * regs,uint32_t mask)326 int mec_hal_espi_taf_pr_dirty_clr_mask(struct mec_espi_taf_regs *regs, uint32_t mask)
327 {
328     if (!taf_regs_valid(regs)) {
329         return MEC_RET_ERR_INVAL;
330     }
331 
332     regs->PR_DIRTY = mask;
333 
334     return MEC_RET_OK;
335 }
336 
mec_hal_espi_taf_pr_lock_get(struct mec_espi_taf_regs * regs)337 uint32_t mec_hal_espi_taf_pr_lock_get(struct mec_espi_taf_regs *regs)
338 {
339     if (!taf_regs_valid(regs)) {
340         return 0;
341     }
342 
343     return regs->PR_LOCK;
344 }
345 
346 /* TAF protection region lock bits are read/write-once.
347  * Lock bits are only cleared on RESET_SYS therefore we aren't required
348  * to perform a read-modify-write.
349  */
mec_hal_espi_taf_pr_lock(struct mec_espi_taf_regs * regs,uint32_t lockmap)350 int mec_hal_espi_taf_pr_lock(struct mec_espi_taf_regs *regs, uint32_t lockmap)
351 {
352     if (!taf_regs_valid(regs)) {
353         return MEC_RET_ERR_INVAL;
354     }
355 
356     regs->PR_LOCK = lockmap;
357 
358     return MEC_RET_OK;
359 }
360 
361 /* TAF has 17 protection regions:
362  * Each region must be aligned on >= 4KB boundary.
363  * Region size must be a multiple of 4KB.
364  * Read and write permissions for each of eight requester IDs.
365  * If protection region is to be enabled program registers if start
366  * is aligned >= 4KB and size is a multiple of 4KB.
367  * If PR not enabled program with disable defaults.
368  *
369  */
mec_hal_espi_taf_pr_set(struct mec_espi_taf_regs * regs,struct espi_taf_pr * pr)370 int mec_hal_espi_taf_pr_set(struct mec_espi_taf_regs *regs, struct espi_taf_pr *pr)
371 {
372     if (!taf_regs_valid(regs) || !pr || (pr->pr_num >= MEC_ESPI_TAF_PROT_REG_MAX)) {
373         return MEC_RET_ERR_INVAL;
374     }
375 
376     if (!MEC_IS_PTR_ALIGNED4K(pr->start) || !MEC_IS_PTR_ALIGNED4K(pr->size)) {
377         return MEC_RET_ERR_DATA_ALIGN;
378     }
379 
380     volatile struct mec_espi_taf_pr_regs *pregs = &regs->PR[pr->pr_num];
381 
382     if (pr->flags & MEC_BIT(MCHP_TAF_PR_FLAG_ENABLE)) {
383         pregs->START =  (pr->start >> MEC_TAF_PR_UNIT_SHIFT) & MEC_TAF_PR_START_LIM_MASK;
384         pregs->LIMIT = (((pr->start + pr->size - 1u) >> MEC_TAF_PR_UNIT_SHIFT)
385                     & MEC_TAF_PR_START_LIM_MASK);
386         pregs->WRBM = pr->req_bm_we;
387         pregs->RDBM = pr->req_bm_rd;
388 
389         regs->PR_DIRTY = MEC_BIT(pr->pr_num);
390 
391         if (pr->flags & MEC_BIT(MCHP_TAF_PR_FLAG_LOCK)) {
392             regs->PR_LOCK |= MEC_BIT(pr->pr_num);
393         }
394     } else {
395         pregs->START = MEC_TAF_PR_START_DFLT;
396         pregs->LIMIT = MEC_TAF_PR_LIMIT_DFLT;
397         pregs->WRBM = 0;
398         pregs->RDBM = 0;
399         regs->PR_DIRTY = MEC_BIT(pr->pr_num);
400     }
401 
402     return MEC_RET_OK;
403 }
404 /* end mec_espi_taf.c */
405