1 /*
2 * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stddef.h>
7 #include <stdint.h>
8
9 #include <device_mec5.h>
10 #include "mec_pcfg.h"
11 #include "mec_defs.h"
12 #include "mec_ecia_api.h"
13 #include "mec_retval.h"
14 #include "mec_ecia_api.h"
15
16 /* #define MEC_ECIA_ENABLE_CHECKS */
17 #ifdef MEC_ECIA_ENABLE_CHECKS
18 #include <assert.h>
19 #endif
20
21 /*
22 * EC Interrupt Aggregator and NVIC configuration.
23 * Implementation:
24 * All NVIC enables and priorities will be set at initialization based
25 * upon the supplied direct bitmap and NVIC priority.
26 * Peripheral level code will use the ECIA GIRQ and any peripheral interrupt
27 * enable/status registers.
28 * Reason:
29 * NVIC interrupt registers may only be accessed when the Cortex-M4 is in
30 * privileged mode.
31 */
32
33 /* b[4:0] = number of interrupt lines in groups of 32.
34 * 0 = 32
35 * 1 = 64
36 * 2 = 96
37 * ...
38 * 7 = 256
39 */
40
41 struct mec_nvic_map {
42 uint8_t girq_bitpos;
43 uint8_t nvic_direct;
44 };
45
46 struct mec_girq_route {
47 uint8_t nvic_aggr;
48 uint8_t num_direct;
49 const struct mec_nvic_map *nmap;
50 };
51
52 static const struct mec_nvic_map girq13_nvic_map[] = {
53 { 0U, 20U }, { 1U, 21U }, { 2U, 22U }, { 3U, 23U }, { 4U, 158U },
54 #if defined(MEC5_I3C_HOST_CTRL_INSTANCES)
55 { 8U, 181U },
56 #endif
57 #if defined(MEC5_I3C_SEC_CTRL_INSTANCES)
58 { 9U, 182U },
59 #endif
60 #if defined(MEC5_HAS_USB_OTG_0)
61 { 10U, 192U },
62 #endif
63 };
64 #define GIRQ13_NUM_DIRECT (sizeof(girq13_nvic_map) / sizeof(struct mec_nvic_map))
65
66 static const struct mec_nvic_map girq14_nvic_map[] = {
67 { 0U, 24U }, { 1U, 25U }, { 2U, 26U }, { 3U, 27U }, { 4U, 28U },
68 { 5U, 29U }, { 6U, 30U }, { 7U, 31U }, { 8U, 32U }, { 9U, 33U },
69 { 10U, 34U }, { 11U, 35U }, { 12U, 36U }, { 13U, 37U }, { 14U, 38U },
70 { 15U, 39U },
71 #if MEC5_DMAC_NUM_CHANNELS == 20
72 { 16U, 194U }, { 17U, 195U }, { 18U, 196U }, { 19U, 197U },
73 #endif
74 };
75 #define GIRQ14_NUM_DIRECT (sizeof(girq14_nvic_map) / sizeof(struct mec_nvic_map))
76
77 static const struct mec_nvic_map girq15_nvic_map[] = {
78 { 0U, 40U }, { 1U, 41U }, { 2U, 42U }, { 3U, 43U }, { 4U, 44U },
79 { 5U, 45U }, { 6U, 46U }, { 7U, 47U }, { 8U, 48U }, { 9U, 49U },
80 { 10U, 50U }, { 11U, 51U }, { 12U, 52U }, { 13U, 53U }, { 14U, 54U },
81 { 15U, 55U }, { 16U, 56U }, { 17U, 57U }, { 18U, 58U }, { 19U, 59U },
82 { 20U, 60U }, { 22U, 62U },
83 #if MEC5_UART_INSTANCES > 2
84 { 25U, 183U },
85 #endif
86 #if MEC5_UART_INSTANCES > 3
87 { 26U, 184 },
88 #endif
89 };
90 #define GIRQ15_NUM_DIRECT (sizeof(girq15_nvic_map) / sizeof(struct mec_nvic_map))
91
92 static const struct mec_nvic_map girq16_nvic_map[] = {
93 { 0U, 65U }, { 2U, 67U }, { 3U, 68U }
94 };
95 #define GIRQ16_NUM_DIRECT (sizeof(girq16_nvic_map) / sizeof(struct mec_nvic_map))
96
97 static const struct mec_nvic_map girq17_nvic_map[] = {
98 { 0U, 70U }, { 1U, 71U }, { 2U, 72U }, { 3U, 73U }, { 4U, 159U },
99 { 8U, 78U }, { 9U, 79U }, { 10U, 80U }, { 11U, 81U }, { 12U, 82U },
100 { 13U, 83U }, { 14U, 84U }, { 15U, 85U }, { 16U, 86U }, { 17U, 87U },
101 { 18U, 88U }, { 19U, 89U }, { 20U, 74U }, { 21U, 75U }, { 22U, 76U },
102 { 23U, 77U }
103 };
104 #define GIRQ17_NUM_DIRECT (sizeof(girq17_nvic_map) / sizeof(struct mec_nvic_map))
105
106 static const struct mec_nvic_map girq18_nvic_map[] = {
107 { 1U, 91U },
108 { 2U, 92U },
109 #if MEC5_GPSPI_CTRL_VERSION == 1
110 { 3U, 93U},
111 #endif
112 { 4U, 94U },
113 #if MEC5_GPSPI_CTRL_VERSION == 1
114 { 5U, 95U},
115 #endif
116 { 6U, 97U }, { 7U, 96U },
117 { 10U, 100U },
118 #if MEC5_P2S_INSTANCES == 2
119 { 11U, 101U },
120 #endif
121 { 20U, 146U }, { 21U, 147U }, { 22U, 148U }, { 23U, 149U }, { 24U, 150U },
122 { 25U, 151U }, { 26U, 152U }, { 27U, 153U }, { 28U, 154U },
123 };
124 #define GIRQ18_NUM_DIRECT (sizeof(girq18_nvic_map) / sizeof(struct mec_nvic_map))
125
126 static const struct mec_nvic_map girq19_nvic_map[] = {
127 { 0U, 103U }, { 1U, 104U }, { 2U, 105U }, { 3U, 106U }, { 4U, 107U },
128 { 5U, 108U }, { 6U, 109U }, { 7U, 110U }, { 8U, 156U }, { 9U, 166U },
129 { 10U, 167U },
130 };
131 #define GIRQ19_NUM_DIRECT (sizeof(girq19_nvic_map) / sizeof(struct mec_nvic_map))
132
133 static const struct mec_nvic_map girq20_nvic_map[] = {
134 { 3U, 173U }, { 9U, 174U }
135 };
136 #define GIRQ20_NUM_DIRECT (sizeof(girq20_nvic_map) / sizeof(struct mec_nvic_map))
137
138 static const struct mec_nvic_map girq21_nvic_map[] = {
139 { 2U, 171U }, { 3U, 114U }, { 4U, 115U }, { 5U, 116U }, { 6U, 117U },
140 { 7U, 118U }, { 8U, 119U }, { 9U, 120U }, { 10U, 121U }, { 11U, 122U },
141 { 12U, 123U }, { 13U, 124U }, { 14U, 125U }, { 18U, 129U }, { 19U, 130U },
142 #if MEC5_P2S_INSTANCES == 2
143 { 21U, 132U },
144 #endif
145 { 24U, 134U }, { 26U, 172U },
146 #ifdef MEC5_HAS_ROM_TIMER
147 { 27U, 193U }
148 #endif
149 };
150 #define GIRQ21_NUM_DIRECT (sizeof(girq21_nvic_map) / sizeof(struct mec_nvic_map))
151
152 /* NOTE: GIRQ22 aggregated output and individual source interrupt signals
153 * are not connected to the NVIC. GIRQ22's purpose is to signal MEC's power
154 * managemente HW to turn on the PLL to process incoming signal/data from
155 * an external device. HW determins if the event requires EC notification.
156 * If EC notification required the respective peripheral interrupt signal
157 * will assert otherwise HW will turn off the PLL and re-enter full deep sleep.
158 */
159 static const struct mec_nvic_map girq22_nvic_map[] = {
160 { 0U, 255U }, /* Process event received on SPI Target */
161 { 1U, 255U }, /* Process event received on I2C Controller 0 */
162 { 2U, 255U },
163 { 3U, 255U },
164 { 4U, 255U },
165 { 5U, 255U }, /* Process event received on I2C Controller 4 */
166 { 9U, 255U }, /* Process event received on eSPI interface */
167 #if defined(MEC5_I3C_HOST_CTRL_INSTANCES)
168 { 16U, 255U }, /* Process event received on I3C Primary Controller */
169 #endif
170 #if defined(MEC5_I3C_SEC_CTRL_INSTANCES)
171 { 17U, 255U }, /* Process event received on I3C Secondary Controller */
172 #endif
173 };
174 #define GIRQ22_NUM_DIRECT 0
175
176 static const struct mec_nvic_map girq23_nvic_map[] = {
177 { 0U, 136U }, { 1U, 137U }, { 2U, 138U }, { 3U, 139U }, { 4U, 140U },
178 { 5U, 141U }, { 6U, 142U }, { 7U, 143U }, { 8U, 144U }, { 9U, 145U },
179 { 10U, 111U }, { 16U, 112U }, { 17U, 113U },
180 };
181 #define GIRQ23_NUM_DIRECT (sizeof(girq23_nvic_map) / sizeof(struct mec_nvic_map))
182
183 static const struct mec_girq_route girq_routing_tbl[MEC5_ECIA_NUM_GIRQS] = {
184 { 0U, 0U, NULL }, /* GIRQ08 - GIRQ12 aggregated only */
185 { 1U, 0U, NULL },
186 { 2U, 0U, NULL },
187 { 3U, 0U, NULL },
188 { 4U, 0U, NULL },
189 { 5U, GIRQ13_NUM_DIRECT, girq13_nvic_map },
190 { 6U, GIRQ14_NUM_DIRECT, girq14_nvic_map },
191 { 7U, GIRQ15_NUM_DIRECT, girq15_nvic_map },
192 { 8U, GIRQ16_NUM_DIRECT, girq16_nvic_map },
193 { 9U, GIRQ17_NUM_DIRECT, girq17_nvic_map },
194 { 10U, GIRQ18_NUM_DIRECT, girq18_nvic_map },
195 { 11U, GIRQ19_NUM_DIRECT, girq19_nvic_map },
196 { 12U, GIRQ20_NUM_DIRECT, girq20_nvic_map },
197 { 13U, GIRQ21_NUM_DIRECT, girq21_nvic_map },
198 { 255U, GIRQ22_NUM_DIRECT, girq22_nvic_map }, /* GIRQ22 clock wake only */
199 { 14U, GIRQ23_NUM_DIRECT, girq23_nvic_map },
200 { 15U, 0U, NULL }, /* GIRQ24 - GIRQ26 aggregated only */
201 { 16U, 0U, NULL },
202 { 17U, 0U, NULL }
203 };
204
nvic_extirq_enable(uint32_t extn)205 static void nvic_extirq_enable(uint32_t extn)
206 {
207 if (extn >= MEC5_MAX_NVIC_EXT_INPUTS) {
208 return;
209 }
210
211 NVIC_EnableIRQ(extn);
212 }
213
nvic_extirq_disable(uint32_t extn)214 static void nvic_extirq_disable(uint32_t extn)
215 {
216 if (extn >= MEC5_MAX_NVIC_EXT_INPUTS) {
217 return;
218 }
219
220 NVIC_DisableIRQ(extn);
221 }
222
nvic_extirq_pend_clear(uint32_t extn)223 static void nvic_extirq_pend_clear(uint32_t extn)
224 {
225 if (extn >= MEC5_MAX_NVIC_EXT_INPUTS) {
226 return;
227 }
228
229 NVIC_ClearPendingIRQ(extn);
230 }
231
nvic_extirq_pend_get(uint32_t extn)232 static uint32_t nvic_extirq_pend_get(uint32_t extn)
233 {
234 if (extn >= MEC5_MAX_NVIC_EXT_INPUTS) {
235 return 0;
236 }
237
238 return NVIC_GetPendingIRQ(extn);
239 }
240
241 /* priority = Cortex-M4 NVIC for this SoC. 3-bits where 0 = highest and 7 is
242 * lowest priority. Each external interrupt priority is an 8-bit register
243 * where the priority is stored in the upper 3 bits.
244 */
nvic_extirq_priority_set(uint32_t extn,uint8_t priority)245 static void nvic_extirq_priority_set(uint32_t extn, uint8_t priority)
246 {
247 if (extn >= MEC5_MAX_NVIC_EXT_INPUTS) {
248 return;
249 }
250
251 NVIC_SetPriority(extn, priority);
252 }
253
nvic_extirq_priority_get(uint32_t extn)254 static uint32_t nvic_extirq_priority_get(uint32_t extn)
255 {
256 if (extn >= MEC5_MAX_NVIC_EXT_INPUTS) {
257 return 0; /* NVIC POR default priority */
258 }
259
260 return NVIC_GetPriority(extn);
261 }
262
enable_nvic_aggregated(uint32_t aggr_bitmap)263 static void enable_nvic_aggregated(uint32_t aggr_bitmap)
264 {
265 uint32_t abm = aggr_bitmap & MEC5_ECIA_ALL_BITMAP;
266
267 for (uint32_t n = MEC5_ECIA_FIRST_GIRQ_NOS; n < MEC5_ECIA_LAST_GIRQ_NOS; n++) {
268 if (!abm) {
269 break;
270 }
271
272 if (abm & MEC_BIT(n)) {
273 const struct mec_girq_route *pgr = &girq_routing_tbl[n - MEC5_ECIA_FIRST_GIRQ_NOS];
274
275 NVIC_EnableIRQ(pgr->nvic_aggr);
276 abm &= (uint32_t)~MEC_BIT(n);
277 }
278 }
279 }
280
enable_nvic_directs(uint32_t girq_bitmap)281 static void enable_nvic_directs(uint32_t girq_bitmap)
282 {
283 for (size_t n = 0; n < MEC5_ECIA_NUM_GIRQS; n++) {
284 const struct mec_girq_route *gr = &girq_routing_tbl[n];
285
286 if ((gr->nvic_aggr == 0xffu) || (gr->num_direct == 0u)) {
287 continue;
288 }
289
290 if (!(girq_bitmap & MEC_BIT(n + 8u))) {
291 continue;
292 }
293
294 const struct mec_nvic_map *map = gr->nmap;
295
296 for (uint8_t m = 0; m < gr->num_direct; m++) {
297 NVIC_EnableIRQ(map[m].nvic_direct);
298 }
299 }
300 }
301
302 /* Set all GIRQ enables for specified direct GIRQ's */
enable_girq_direct_bitmap(uint32_t bitmap)303 static void enable_girq_direct_bitmap(uint32_t bitmap)
304 {
305 uint32_t dbm = bitmap & MEC5_ECIA_DIRECT_BITMAP;
306 uint32_t bpos = 0;
307 uint8_t msb = 0;
308
309 while (dbm) {
310 /* returns 32 if no bits are set */
311 msb = __CLZ(dbm);
312 if (msb == 32U) {
313 break;
314 }
315
316 bpos = 31u - msb; /* convert number of leading zeros to bit position */
317 if ((bpos >= MEC5_ECIA_FIRST_GIRQ_NOS) && (bpos <= MEC5_ECIA_LAST_GIRQ_NOS)) {
318 const struct mec_girq_route *pgr =
319 &girq_routing_tbl[bpos - MEC5_ECIA_FIRST_GIRQ_NOS];
320
321 if (pgr->nmap && !(MEC_ECIA0->BLK_EN_SET & MEC_BIT(bpos))) {
322 MEC_ECIA0->GIRQ[0].EN_SET = UINT32_MAX;
323 }
324 }
325
326 dbm &= (uint32_t)~MEC_BIT(bpos);
327 }
328 }
329
330 /* !!! Touches NVIC registers. Caller must be Privileged !!!
331 * NOTE: Cortex-M4 NVIC encodes priority where 0 = highest and lowests
332 * is equal to all bits set. The number of bits implemented is set at
333 * hardware design time (MEC_NVIC_NUM_PRI_BITS).
334 */
set_all_pri(uint8_t dflt_priority)335 static void set_all_pri(uint8_t dflt_priority)
336 {
337 uint32_t pri32 = ((uint32_t)(dflt_priority & 0x7U) << (8U - __NVIC_PRIO_BITS)) & 0xffu;
338 uintptr_t nvic_ip_addr = (uintptr_t)&NVIC->IP[0];
339
340 pri32 |= (pri32 << 8);
341 pri32 |= (pri32 << 16);
342
343 for (uint32_t n = 0; n < MEC5_NVIC_NUM_IP_REGS; n++) {
344 MEC_MMCR32(nvic_ip_addr) = pri32;
345 nvic_ip_addr += 4U;
346 }
347 }
348
is_direct_allowed(void)349 static inline int is_direct_allowed(void)
350 {
351 if (MEC_ECS->INTR_CTRL & MEC_BIT(MEC_ECS_INTR_CTRL_DIRECT_Pos)) {
352 return 1;
353 }
354 return 0;
355 }
356
357 /**
358 * mec_ecia_init - Initial EC Interrupt Aggregator and NVIC
359 * external interrupt registers.
360 *
361 * @param direct_bitmap Bit map of GIRQ's caller wants to use direct NVIC
362 * connection.
363 *
364 * @param dflt_priority - Priority 0=highest to 7=lowest to set all
365 * external peripheral NVIC priority to.
366 *
367 * @note - Touches NVIC registers. Caller must be Privileged.
368 * Restrictions on GIRQ's:
369 * Aggregated only: 8-12 and 24-26
370 * Direct or Aggregated: 13-21 and 23
371 * No connection to NVIC: GIRQ22 used to wake AHB fabric only.
372 * The function parameters will be masked with allowed bitmaps.
373 *
374 * Sets all NVIC enables for direct and aggregated interrupt
375 * sources.
376 * TODO - change to set all GIRQ enables for direct. Do not
377 * set any NVIC enables. Drivers will handle NVIC enables.
378 * How to handle Aggregated only GIRQ's?
379 * GIRQ's 8 - 12, and 26 are GPIO's. The GPIO control registers
380 * have interrupt enable fields but ROM enable some. Enabling
381 * the aggregated GIRQ's may cause an issue.
382 * GIRQ's 24 and 25 are for eSPI Controller to Target virtual wires.
383 * Each C2T VWire has an interrupt enable field. We should be able
384 * to enable these.
385 */
mec_hal_ecia_init(uint32_t direct_bitmap,uint8_t dflt_priority,uint32_t flags)386 void mec_hal_ecia_init(uint32_t direct_bitmap, uint8_t dflt_priority, uint32_t flags)
387 {
388 uint32_t aggr_bitmap = 0, i = 0;
389
390 /* Clear ECIA PCR sleep enable */
391 /* TODO mec_pcr_clr_blk_slp_en(MEC_PCR_ECIA); */
392
393 /* Disconnect all direct capable GIRQ sources from the NVIC
394 * allowing us to clear direct NVIC pending bits
395 */
396 MEC_ECS->INTR_CTRL &= ~(MEC_ECS_INTR_CTRL_DIRECT_Msk);
397
398 /* disconnect all GIRQ aggregated block outputs from NVIC */
399 MEC_ECIA0->BLK_EN_CLR = UINT32_MAX;
400
401 /* clear all ECIA GIRQ individual enables and status(source) bits */
402 for (i = 0; i < MEC5_ECIA_NUM_GIRQS; i++) {
403 MEC_ECIA0->GIRQ[i].EN_CLR = UINT32_MAX;
404 MEC_ECIA0->GIRQ[i].SOURCE = UINT32_MAX;
405 }
406
407 /* clear all NVIC enables and pending status */
408 for (i = 0; i < MEC5_NVIC_NUM_REGS; i++) {
409 NVIC->ICER[i] = UINT32_MAX;
410 NVIC->ICPR[i] = UINT32_MAX;
411 }
412
413 set_all_pri(dflt_priority);
414
415 /* mask out GIRQ's that cannot do direct */
416 direct_bitmap &= MEC5_ECIA_DIRECT_BITMAP;
417 aggr_bitmap = MEC5_ECIA_ALL_BITMAP & ~(direct_bitmap);
418
419 /* Route all aggregated GIRQn outputs to NVIC */
420 MEC_ECIA0->BLK_EN_SET = aggr_bitmap;
421 if (flags & MEC_ECIA_INIT_FLAG_ALL_AGGR_GIRQ) {
422 enable_nvic_aggregated(aggr_bitmap);
423 }
424
425 /* enable any direct connections? */
426 if (direct_bitmap) {
427 /* Disconnect aggregated GIRQ output for direct mapped */
428 MEC_ECIA0->BLK_EN_CLR = direct_bitmap;
429 MEC_ECS->INTR_CTRL |= MEC_BIT(MEC_ECS_INTR_CTRL_DIRECT_Pos);
430 if (flags & MEC_ECIA_INIT_FLAG_ALL_DIRECT_GIRQ) {
431 enable_girq_direct_bitmap(direct_bitmap);
432 }
433 if (flags & MEC_ECIA_INIT_FLAG_ALL_DIRECT_NVIC) {
434 enable_nvic_directs(direct_bitmap);
435 }
436 }
437 }
438
439 /* Enable/disable multiple GIRQ sources */
mec_hal_girq_bm_en(uint32_t girq_num,uint32_t bitmap,uint8_t enable)440 int mec_hal_girq_bm_en(uint32_t girq_num, uint32_t bitmap, uint8_t enable)
441 {
442 if ((girq_num < MEC5_ECIA_FIRST_GIRQ_NOS) || (girq_num > MEC5_ECIA_LAST_GIRQ_NOS)) {
443 return MEC_RET_ERR_INVAL;
444 }
445
446 if (!bitmap) {
447 return MEC_RET_OK;
448 }
449
450 uint32_t gidx = girq_num - MEC5_ECIA_FIRST_GIRQ_NOS;
451
452 if (enable) {
453 MEC_ECIA0->GIRQ[gidx].EN_SET = bitmap;
454 } else {
455 MEC_ECIA0->GIRQ[gidx].EN_CLR = bitmap;
456 }
457
458 return MEC_RET_OK;
459 }
460
461 /* Clear multiple GIRQ source(status) bits */
mec_hal_girq_bm_clr_src(uint32_t girq_num,uint32_t bitmap)462 int mec_hal_girq_bm_clr_src(uint32_t girq_num, uint32_t bitmap)
463 {
464 if ((girq_num < MEC5_ECIA_FIRST_GIRQ_NOS) || (girq_num > MEC5_ECIA_LAST_GIRQ_NOS)) {
465 return MEC_RET_ERR_INVAL;
466 }
467
468 if (!bitmap) {
469 return MEC_RET_OK;
470 }
471
472 uint32_t gidx = girq_num - MEC5_ECIA_FIRST_GIRQ_NOS;
473
474 MEC_ECIA0->GIRQ[gidx].SOURCE = bitmap;
475
476 return MEC_RET_OK;
477 }
478
mec_hal_girq_source_get(uint32_t girq_num)479 uint32_t mec_hal_girq_source_get(uint32_t girq_num)
480 {
481 if ((girq_num < MEC5_ECIA_FIRST_GIRQ_NOS) || (girq_num > MEC5_ECIA_LAST_GIRQ_NOS)) {
482 return 0u;
483 }
484
485 uint32_t gidx = girq_num - MEC5_ECIA_FIRST_GIRQ_NOS;
486
487 return MEC_ECIA0->GIRQ[gidx].SOURCE;
488 }
489
mec_hal_girq_result_get(uint32_t girq_num)490 uint32_t mec_hal_girq_result_get(uint32_t girq_num)
491 {
492 if ((girq_num < MEC5_ECIA_FIRST_GIRQ_NOS) || (girq_num > MEC5_ECIA_LAST_GIRQ_NOS)) {
493 return 0u;
494 }
495
496 uint32_t gidx = girq_num - MEC5_ECIA_FIRST_GIRQ_NOS;
497
498 return MEC_ECIA0->GIRQ[gidx].RESULT;
499 }
500
mec_hal_girq_result_test(uint32_t girq_num,uint32_t bitpos)501 uint32_t mec_hal_girq_result_test(uint32_t girq_num, uint32_t bitpos)
502 {
503 uint32_t result = mec_hal_girq_result_get(girq_num);
504
505 return (result & MEC_BIT(bitpos));
506 }
507
508 /* Set or clear GIRQ enable for a peripheral source. */
mec_hal_girq_ctrl(uint32_t devi,int enable)509 void mec_hal_girq_ctrl(uint32_t devi, int enable)
510 {
511 uint32_t gidx = MEC5_ECIA_INFO_GIRQZ(devi);
512 uint32_t gpos = MEC5_ECIA_INFO_GIRQ_POS(devi);
513
514 if (gidx >= MEC5_ECIA_NUM_GIRQS) {
515 return;
516 }
517
518 if (enable) { /* write 1 to set register */
519 MEC_ECIA0->GIRQ[gidx].EN_SET = MEC_BIT(gpos);
520 } else { /* write 1 to clear register */
521 MEC_ECIA0->GIRQ[gidx].EN_CLR = MEC_BIT(gpos);
522 }
523 }
524
525 /*
526 * Return 0 if source not set else non-zero
527 * (single bit should be set in word)
528 */
mec_hal_girq_src(uint32_t devi)529 uint32_t mec_hal_girq_src(uint32_t devi)
530 {
531 uint32_t gidx = MEC5_ECIA_INFO_GIRQZ(devi);
532 uint32_t gpos = MEC5_ECIA_INFO_GIRQ_POS(devi);
533
534 if (gidx >= MEC5_ECIA_NUM_GIRQS) {
535 return 0;
536 }
537
538 return MEC_ECIA0->GIRQ[gidx].SOURCE & MEC_BIT(gpos);
539 }
540
mec_hal_girq_result(uint32_t devi)541 uint32_t mec_hal_girq_result(uint32_t devi)
542 {
543 uint32_t gidx = MEC5_ECIA_INFO_GIRQZ(devi);
544 uint32_t gpos = MEC5_ECIA_INFO_GIRQ_POS(devi);
545
546 if (gidx >= MEC5_ECIA_NUM_GIRQS) {
547 return 0;
548 }
549
550 return MEC_ECIA0->GIRQ[gidx].RESULT & MEC_BIT(gpos);
551 }
552
553 /* Clear GIRQ source(status) for a peripheral source. */
mec_hal_girq_clr_src(uint32_t devi)554 void mec_hal_girq_clr_src(uint32_t devi)
555 {
556 uint32_t gidx = MEC5_ECIA_INFO_GIRQZ(devi);
557 uint32_t gpos = MEC5_ECIA_INFO_GIRQ_POS(devi);
558
559 if (gidx >= MEC5_ECIA_NUM_GIRQS) {
560 return;
561 }
562
563 /* register is write 1 to clear bit(s) */
564 MEC_ECIA0->GIRQ[gidx].SOURCE = MEC_BIT(gpos);
565 }
566
mec_hal_ecia_girq_aggr_enable(uint32_t girq_num,uint8_t enable)567 int mec_hal_ecia_girq_aggr_enable(uint32_t girq_num, uint8_t enable)
568 {
569 uint8_t gid = (uint8_t)(girq_num & 0xffu);
570
571 if ((gid < MEC5_ECIA_FIRST_GIRQ_NOS) || (girq_num > MEC5_ECIA_LAST_GIRQ_NOS)) {
572 return MEC_RET_ERR_INVAL;
573 }
574
575 if (enable) {
576 MEC_ECIA0->BLK_EN_SET = MEC_BIT(gid);
577 } else {
578 MEC_ECIA0->BLK_EN_CLR = MEC_BIT(gid);
579 }
580
581 return MEC_RET_OK;
582 }
583
584 /*
585 * This is not a simple question.
586 * This routine only works if Method 1 initialization
587 * is implemented in mec_ecia_init() and the application
588 * developer calls mec_ecia_init() or duplicates its
589 * functionality.
590 */
mec_hal_ecia_is_direct(uint32_t devi)591 int mec_hal_ecia_is_direct(uint32_t devi)
592 {
593 /* Is direct mode disabled? */
594 if (!is_direct_allowed()) {
595 return 0;
596 }
597
598 uint32_t girq_num = MEC5_ECIA_INFO_GIRQZ(devi) + MEC5_ECIA_FIRST_GIRQ_NOS;
599
600 if (!(MEC_BIT(girq_num) & MEC5_ECIA_DIRECT_BITMAP)) {
601 return 0;
602 }
603
604 /* Is aggregated GIRQ routed to NVIC? */
605 if (MEC_ECIA0->BLK_EN_SET & MEC_BIT(girq_num)) {
606 return 0; /* Yes, don't use direct */
607 }
608
609 return 1;
610 }
611
612 /* !!! Touches NVIC register(s). Caller must be Privileged !!! */
613
mec_hal_ecia_nvic_enable(uint32_t devi)614 void mec_hal_ecia_nvic_enable(uint32_t devi)
615 {
616 uint32_t nvic_extn = MEC5_ECIA_INFO_NVIC_AGGR(devi);
617
618 if (mec_hal_ecia_is_direct(devi)) {
619 nvic_extn = MEC5_ECIA_INFO_NVIC_DIRECT(devi);
620 }
621
622 nvic_extirq_enable(nvic_extn);
623 }
624
mec_hal_ecia_nvic_disable(uint32_t devi)625 void mec_hal_ecia_nvic_disable(uint32_t devi)
626 {
627 uint32_t nvic_extn = MEC5_ECIA_INFO_NVIC_AGGR(devi);
628
629 if (mec_hal_ecia_is_direct(devi)) {
630 nvic_extn = MEC5_ECIA_INFO_NVIC_DIRECT(devi);
631 }
632
633 nvic_extirq_disable(nvic_extn);
634 }
635
mec_hal_ecia_nvic_clr_pend(uint32_t devi)636 void mec_hal_ecia_nvic_clr_pend(uint32_t devi)
637 {
638 uint32_t nvic_extn = MEC5_ECIA_INFO_NVIC_AGGR(devi);
639
640 if (mec_hal_ecia_is_direct(devi)) {
641 nvic_extn = MEC5_ECIA_INFO_NVIC_DIRECT(devi);
642 }
643
644 nvic_extirq_pend_clear(nvic_extn);
645 }
646
mec_hal_ecia_nvic_get_pending(uint32_t devi)647 uint32_t mec_hal_ecia_nvic_get_pending(uint32_t devi)
648 {
649 uint32_t extn = MEC5_ECIA_INFO_NVIC_AGGR(devi);
650
651 if (mec_hal_ecia_is_direct(devi)) {
652 extn = MEC5_ECIA_INFO_NVIC_DIRECT(devi);
653 }
654
655 return nvic_extirq_pend_get(extn);
656 }
657
mec_hal_ecia_nvic_get_pri(uint32_t devi)658 uint8_t mec_hal_ecia_nvic_get_pri(uint32_t devi)
659 {
660 uint32_t extn = MEC5_ECIA_INFO_NVIC_AGGR(devi);
661
662 if (mec_hal_ecia_is_direct(devi)) {
663 extn = MEC5_ECIA_INFO_NVIC_DIRECT(devi);
664 }
665
666 return (uint8_t)(nvic_extirq_priority_get(extn));
667 }
668
mec_hal_ecia_nvic_set_pri(uint32_t devi,uint8_t priority)669 void mec_hal_ecia_nvic_set_pri(uint32_t devi, uint8_t priority)
670 {
671 uint32_t extn = MEC5_ECIA_INFO_NVIC_AGGR(devi);
672
673 if (mec_hal_ecia_is_direct(devi)) {
674 extn = MEC5_ECIA_INFO_NVIC_DIRECT(devi);
675 }
676
677 if (priority > MEC5_NVIC_PRI_LO_VAL) {
678 priority = MEC5_NVIC_PRI_LO_VAL;
679 }
680
681 nvic_extirq_priority_set(extn, priority);
682 }
683
684 /* end mec_ecia.c */
685