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 = ®s->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