blob: 2882c62b0f4ecb77c55ffb57a717fe63908639a3 [file] [log] [blame]
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +08001/*
2 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#include <stdio.h>
bangzheng.liu4d71f922022-09-29 16:12:20 +08008#include "interrupt_control_eclic.h"
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +08009#include "common.h"
10#include "riscv_encoding.h"
11#include "register.h"
12
bangzheng.liu68c01152022-09-29 16:57:22 +080013static uint8_t CLICINTCTLBITS;
14
xiaohu.huang38262102022-05-06 22:21:48 +080015// Configure PMP to make all the address space accesable and executable
16void eclic_init(uint32_t num_irq)
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080017{
xiaohu.huang38262102022-05-06 22:21:48 +080018 typedef volatile uint32_t vuint32_t;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080019
xiaohu.huang38262102022-05-06 22:21:48 +080020 //clear cfg register
21 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080022
xiaohu.huang38262102022-05-06 22:21:48 +080023 //clear minthresh register
24 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080025
xiaohu.huang38262102022-05-06 22:21:48 +080026 //clear all IP/IE/ATTR/CTRL bits for all interrupt sources
27 vuint32_t *ptr;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080028
xiaohu.huang38262102022-05-06 22:21:48 +080029 vuint32_t *base = (vuint32_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET);
30 vuint32_t *upper = (vuint32_t *)(base + num_irq * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080031
xiaohu.huang38262102022-05-06 22:21:48 +080032 for (ptr = base; ptr < upper; ptr = ptr + 4)
33 *ptr = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080034
xiaohu.huang38262102022-05-06 22:21:48 +080035 clean_int_src();
bangzheng.liu68c01152022-09-29 16:57:22 +080036
37 CLICINTCTLBITS = eclic_get_clicintctlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080038}
39
40void print_eclic(void)
41{
42 typedef volatile uint32_t vuint32_t;
43
xiaohu.huang38262102022-05-06 22:21:48 +080044 vuint32_t *ptr = (vuint32_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + 7 * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080045
xiaohu.huang38262102022-05-06 22:21:48 +080046 printf("\nTIME=0x%lx\n", *ptr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080047}
48
xiaohu.huang38262102022-05-06 22:21:48 +080049void eclic_enable_interrupt(uint32_t source)
50{
51 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = 1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080052}
53
xiaohu.huang38262102022-05-06 22:21:48 +080054void eclic_disable_interrupt(uint32_t source)
55{
56 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080057}
58
xiaohu.huang38262102022-05-06 22:21:48 +080059void eclic_set_pending(uint32_t source)
60{
61 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = 1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080062}
63
xiaohu.huang38262102022-05-06 22:21:48 +080064void eclic_clear_pending(uint32_t source)
65{
66 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = 0;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080067}
68
xiaohu.huang38262102022-05-06 22:21:48 +080069void eclic_set_intctrl(uint32_t source, uint8_t intctrl)
70{
71 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + source * 4) = intctrl;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080072}
73
xiaohu.huang38262102022-05-06 22:21:48 +080074uint8_t eclic_get_intctrl(uint32_t source)
75{
76 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + source * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080077}
78
xiaohu.huang38262102022-05-06 22:21:48 +080079void eclic_set_intattr(uint32_t source, uint8_t intattr)
80{
81 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + source * 4) = intattr;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080082}
83
xiaohu.huang38262102022-05-06 22:21:48 +080084uint8_t eclic_get_intattr(uint32_t source)
85{
86 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + source * 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080087}
88
xiaohu.huang38262102022-05-06 22:21:48 +080089void eclic_set_cliccfg(uint8_t cliccfg)
90{
91 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = cliccfg;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080092}
93
xiaohu.huang38262102022-05-06 22:21:48 +080094uint8_t eclic_get_cliccfg(void)
95{
96 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080097}
98
bangzheng.liu68c01152022-09-29 16:57:22 +080099uint32_t eclic_get_clicinfo(void)
100{
101 return *(volatile uint32_t *)(ECLIC_ADDR_BASE + ECLIC_INFO_OFFSET);
102}
103
104//get clicintctlbits
105uint8_t eclic_get_clicintctlbits(void)
106{
107 //extract clicintctlbits
108 uint32_t clicinfo = eclic_get_clicinfo();
109 uint8_t clicintctlbits = (clicinfo & ECLIC_INFO_CLICINTCTLBITS_MASK)
110 >> ECLIC_INFO_CLICINTCTLBITS_LSB;
111 return clicintctlbits;
112}
113
xiaohu.huang38262102022-05-06 22:21:48 +0800114void eclic_set_mth(uint8_t mth)
115{
116 *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = mth;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800117}
118
xiaohu.huang38262102022-05-06 22:21:48 +0800119uint8_t eclic_get_mth(void)
120{
121 return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800122}
123
124//sets nlbits
xiaohu.huang38262102022-05-06 22:21:48 +0800125void eclic_set_nlbits(uint8_t nlbits)
126{
127 //shift nlbits to correct position
128 uint8_t nlbits_shifted = nlbits << ECLIC_CFG_NLBITS_LSB;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800129
xiaohu.huang38262102022-05-06 22:21:48 +0800130 //read the current cliccfg
131 uint8_t old_cliccfg = eclic_get_cliccfg();
132 uint8_t new_cliccfg =
133 (old_cliccfg & (~ECLIC_CFG_NLBITS_MASK)) | (ECLIC_CFG_NLBITS_MASK & nlbits_shifted);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800134
xiaohu.huang38262102022-05-06 22:21:48 +0800135 eclic_set_cliccfg(new_cliccfg);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800136}
137
138//get nlbits
xiaohu.huang38262102022-05-06 22:21:48 +0800139uint8_t eclic_get_nlbits(void)
140{
141 //extract nlbits
142 uint8_t nlbits = eclic_get_cliccfg();
143
144 nlbits = (nlbits & ECLIC_CFG_NLBITS_MASK) >> ECLIC_CFG_NLBITS_LSB;
145 return nlbits;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800146}
147
148//sets an interrupt level based encoding of nlbits and CLICINTCTLBITS
xiaohu.huang38262102022-05-06 22:21:48 +0800149void eclic_set_irq_lvl(uint32_t source, uint8_t lvl)
150{
151 //extract nlbits
152 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800153
xiaohu.huang38262102022-05-06 22:21:48 +0800154 if (nlbits > CLICINTCTLBITS)
155 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800156
xiaohu.huang38262102022-05-06 22:21:48 +0800157 //shift lvl right to mask off unused bits
158 lvl = lvl >> (8 - nlbits);
159 //shift lvl into correct bit position
160 lvl = lvl << (8 - nlbits);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800161
xiaohu.huang38262102022-05-06 22:21:48 +0800162 //write to clicintctrl
163 uint8_t current_intctrl = eclic_get_intctrl(source);
164 //shift intctrl left to mask off unused bits
165 current_intctrl = current_intctrl << nlbits;
166 //shift intctrl into correct bit position
167 current_intctrl = current_intctrl >> nlbits;
168
169 eclic_set_intctrl(source, (current_intctrl | lvl));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800170}
171
172//gets an interrupt level based encoding of nlbits
xiaohu.huang38262102022-05-06 22:21:48 +0800173uint8_t eclic_get_irq_lvl(uint32_t source)
174{
175 //extract nlbits
176 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800177
xiaohu.huang38262102022-05-06 22:21:48 +0800178 if (nlbits > CLICINTCTLBITS)
179 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800180
xiaohu.huang38262102022-05-06 22:21:48 +0800181 uint8_t intctrl = eclic_get_intctrl(source);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800182
xiaohu.huang38262102022-05-06 22:21:48 +0800183 //shift intctrl
184 intctrl = intctrl >> (8 - nlbits);
185 //shift intctrl
186 uint8_t lvl = intctrl << (8 - nlbits);
187
188 return lvl;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800189}
190
xiaohu.huang38262102022-05-06 22:21:48 +0800191void eclic_set_irq_lvl_abs(uint32_t source, uint8_t lvl_abs)
192{
193 //extract nlbits
194 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800195
xiaohu.huang38262102022-05-06 22:21:48 +0800196 if (nlbits > CLICINTCTLBITS)
197 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800198
xiaohu.huang38262102022-05-06 22:21:48 +0800199 //shift lvl_abs into correct bit position
200 uint8_t lvl = lvl_abs << (8 - nlbits);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800201
xiaohu.huang38262102022-05-06 22:21:48 +0800202 //write to clicintctrl
203 uint8_t current_intctrl = eclic_get_intctrl(source);
204 //shift intctrl left to mask off unused bits
205 current_intctrl = current_intctrl << nlbits;
206 //shift intctrl into correct bit position
207 current_intctrl = current_intctrl >> nlbits;
208
209 eclic_set_intctrl(source, (current_intctrl | lvl));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800210}
211
xiaohu.huang38262102022-05-06 22:21:48 +0800212uint8_t eclic_get_irq_lvl_abs(uint32_t source)
213{
214 //extract nlbits
215 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800216
xiaohu.huang38262102022-05-06 22:21:48 +0800217 if (nlbits > CLICINTCTLBITS)
218 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800219
xiaohu.huang38262102022-05-06 22:21:48 +0800220 uint8_t intctrl = eclic_get_intctrl(source);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800221
xiaohu.huang38262102022-05-06 22:21:48 +0800222 //shift intctrl
223 intctrl = intctrl >> (8 - nlbits);
224 //shift intctrl
225 uint8_t lvl_abs = intctrl;
226
227 return lvl_abs;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800228}
229
xiaohu.huang38262102022-05-06 22:21:48 +0800230void eclic_set_irq_pri(uint32_t source, uint8_t pri)
231{
232 //extract nlbits
233 uint8_t nlbits = eclic_get_nlbits();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800234
xiaohu.huang38262102022-05-06 22:21:48 +0800235 if (nlbits > CLICINTCTLBITS)
236 nlbits = CLICINTCTLBITS;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800237
xiaohu.huang38262102022-05-06 22:21:48 +0800238 //write to clicintctrl
239 uint8_t current_intctrl = eclic_get_intctrl(source);
240 //shift intctrl left to mask off unused bits
241 current_intctrl = current_intctrl >> (8 - nlbits);
242 //shift intctrl into correct bit position
243 current_intctrl = current_intctrl << (8 - nlbits);
244
bangzheng.liu68c01152022-09-29 16:57:22 +0800245 pri = (pri << (8 - CLICINTCTLBITS + nlbits)) >> nlbits;
xiaohu.huang38262102022-05-06 22:21:48 +0800246 eclic_set_intctrl(source, (current_intctrl | pri));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800247}
248
xiaohu.huang38262102022-05-06 22:21:48 +0800249void eclic_mode_enable(void)
250{
251 uint32_t mtvec_value = read_csr(mtvec);
252
253 mtvec_value = mtvec_value & 0xFFFFFFC0;
254 mtvec_value = mtvec_value | 0x00000003;
255 write_csr(mtvec, mtvec_value);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800256}
257
258//sets vector-mode or non-vector mode
xiaohu.huang38262102022-05-06 22:21:48 +0800259void eclic_set_vmode(uint32_t source)
260{
261 //read the current attr
262 uint8_t old_intattr = eclic_get_intattr(source);
263 // Keep other bits unchanged and only set the LSB bit
264 uint8_t new_intattr = (old_intattr | 0x1);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800265
xiaohu.huang38262102022-05-06 22:21:48 +0800266 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800267}
268
xiaohu.huang38262102022-05-06 22:21:48 +0800269void eclic_set_nonvmode(uint32_t source)
270{
271 //read the current attr
272 uint8_t old_intattr = eclic_get_intattr(source);
273 // Keep other bits unchanged and only clear the LSB bit
274 uint8_t new_intattr = (old_intattr & (~0x1));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800275
xiaohu.huang38262102022-05-06 22:21:48 +0800276 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800277}
278
279//sets interrupt as level sensitive
280//Bit 1, trig[0], is defined as "edge-triggered" (0: level-triggered, 1: edge-triggered);
281//Bit 2, trig[1], is defined as "negative-edge" (0: positive-edge, 1: negative-edge).
282
xiaohu.huang38262102022-05-06 22:21:48 +0800283void eclic_set_level_trig(uint32_t source)
284{
285 //read the current attr
286 uint8_t old_intattr = eclic_get_intattr(source);
287 // Keep other bits unchanged and only clear the bit 1
288 uint8_t new_intattr = (old_intattr & (~0x2));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800289
xiaohu.huang38262102022-05-06 22:21:48 +0800290 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800291}
292
xiaohu.huang38262102022-05-06 22:21:48 +0800293void eclic_set_posedge_trig(uint32_t source)
294{
295 //read the current attr
296 uint8_t old_intattr = eclic_get_intattr(source);
297 // Keep other bits unchanged and only set the bit 1
298 uint8_t new_intattr = (old_intattr | 0x2);
299 // Keep other bits unchanged and only clear the bit 2
300 new_intattr = (new_intattr & (~0x4));
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800301
xiaohu.huang38262102022-05-06 22:21:48 +0800302 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800303}
304
xiaohu.huang38262102022-05-06 22:21:48 +0800305void eclic_set_negedge_trig(uint32_t source)
306{
307 //read the current attr
308 uint8_t old_intattr = eclic_get_intattr(source);
309 // Keep other bits unchanged and only set the bit 1
310 uint8_t new_intattr = (old_intattr | 0x2);
311 // Keep other bits unchanged and only set the bit 2
312 new_intattr = (new_intattr | 0x4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800313
xiaohu.huang38262102022-05-06 22:21:48 +0800314 eclic_set_intattr(source, new_intattr);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800315}
316
317extern void core_wfe(void);
xiaohu.huang38262102022-05-06 22:21:48 +0800318void wfe(void)
319{
320 core_wfe();
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800321}
322
323void clean_int_src(void)
324{
xiaohu.huang38262102022-05-06 22:21:48 +0800325 for (uint32_t i = 0; i < 8; i++)
326 REG32(AOCPU_IRQ_SEL0 + i * 4) = 0;
bangzheng.liu4d71f922022-09-29 16:12:20 +0800327#ifdef AOCPU_IRQ_REG_NONCONTINUOUS
328 for (uint32_t i = 0; i < 8; i++)
329 REG32(AOCPU_IRQ_SEL8 + i * 4) = 0;
330#endif
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800331}
332
333int int_src_sel(uint32_t ulIrq, uint32_t src)
334{
335 uint32_t index;
336
bangzheng.liu68c01152022-09-29 16:57:22 +0800337 if (ulIrq < ECLIC_INTERNAL_NUM_INTERRUPTS || ulIrq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800338 printf("Error ulIrq!\n");
339 return -1;
340 }
341
bangzheng.liu4d71f922022-09-29 16:12:20 +0800342 if (src > IRQ_NUM_MAX) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800343 printf("Error src!\n");
344 return -2;
345 }
346
347 ulIrq -= ECLIC_INTERNAL_NUM_INTERRUPTS;
348
bangzheng.liu4d71f922022-09-29 16:12:20 +0800349#ifdef AOCPU_IRQ_REG_NONCONTINUOUS
350 index = ulIrq / 2;
351
352 if (ulIrq < 16) {
353 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
354 REG32(AOCPU_IRQ_SEL0 + index * 4) |= src << (ulIrq % 2) * 16;
355 } else {
bangzheng.liudfec97d2023-03-08 15:15:48 +0800356 index -= 8;
bangzheng.liu4d71f922022-09-29 16:12:20 +0800357 REG32(AOCPU_IRQ_SEL8 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
358 REG32(AOCPU_IRQ_SEL8 + index * 4) |= src << (ulIrq % 2)*16;
359 }
360#else
xiaohu.huang38262102022-05-06 22:21:48 +0800361 index = ulIrq / 4;
362 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0xff << (ulIrq % 4) * 8);
363 REG32(AOCPU_IRQ_SEL0 + index * 4) |= src << (ulIrq % 4) * 8;
bangzheng.liu4d71f922022-09-29 16:12:20 +0800364#endif
365
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800366 return 0;
367}
368
369int int_src_clean(uint32_t ulIrq)
370{
371 uint32_t index;
372
bangzheng.liu68c01152022-09-29 16:57:22 +0800373 if (ulIrq < ECLIC_INTERNAL_NUM_INTERRUPTS || ulIrq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800374 printf("Error ulIrq!\n");
375 return -1;
376 }
377
378 ulIrq -= ECLIC_INTERNAL_NUM_INTERRUPTS;
379
bangzheng.liu4d71f922022-09-29 16:12:20 +0800380#ifdef AOCPU_IRQ_REG_NONCONTINUOUS
381 index = ulIrq / 2;
382
383 if (ulIrq < 16)
384 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
385 else
bangzheng.liudfec97d2023-03-08 15:15:48 +0800386 REG32(AOCPU_IRQ_SEL8 + (index - 8) * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
bangzheng.liu4d71f922022-09-29 16:12:20 +0800387#else
xiaohu.huang38262102022-05-06 22:21:48 +0800388 index = ulIrq / 4;
389 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0xff << (ulIrq % 4) * 8);
bangzheng.liu4d71f922022-09-29 16:12:20 +0800390#endif
391
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800392 return 0;
393}
394
395/*Just for external interrupt source.
396 *Because int_src_sel() just support external select
397 */
398int eclic_map_interrupt(uint32_t ulIrq, uint32_t src)
399{
400 uint8_t val;
401
402 if (int_src_sel(ulIrq, src)) {
403 printf("Enable %ld irq, %ld src fail!\n", ulIrq, src);
404 return -1;
405 }
406
xiaohu.huang38262102022-05-06 22:21:48 +0800407 val = eclic_get_intattr(ulIrq);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800408 val |= ECLIC_INT_ATTR_MACH_MODE;
409 /*Use edge trig interrupt default*/
410 val |= ECLIC_INT_ATTR_TRIG_EDGE;
411 eclic_set_intattr(ulIrq, val);
412 //eclic_enable_interrupt(ulIrq);
413 return 0;
414}
415
xiaohu.huang38262102022-05-06 22:21:48 +0800416uint32_t eclic_interrupt_inner[SOC_ECLIC_NUM_INTERRUPTS] = { 0 };
417int RegisterIrq(uint32_t int_num, uint32_t int_priority, function_ptr_t handler)
418{
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800419 int irq = 0;
420
bangzheng.liu68c01152022-09-29 16:57:22 +0800421 /* Prevent duplicate registration with the same interrupt. */
422 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
423 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == int_num) {
424 printf("Warning: the irq %ld has already been registered!\n", int_num);
425 return 0;
426 }
427 }
428
429 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800430 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == 0)
431 break;
432 }
433 if (eclic_map_interrupt(irq, int_num) < 0) {
434 printf("eclic map error.\n");
435 return -1;
436 }
437 eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] = int_num;
438
439 *(&vector_base + irq) = (uint32_t)handler;
440 eclic_set_irq_pri(irq, int_priority);
441
442 return 0;
443}
444
445int UnRegisterIrq(uint32_t ulIrq)
446{
447 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800448
bangzheng.liu68c01152022-09-29 16:57:22 +0800449 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800450 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
451 break;
452 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800453 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800454 printf("Error ulIrq!\n");
455 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800456 }
xiaohu.huang38262102022-05-06 22:21:48 +0800457
458 if (int_src_clean(irq)) {
459 printf("unregister %ld irq, %ld src fail!\n", ulIrq, irq);
460 return -1;
461 }
462 eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] = 0;
463 *(&vector_base + irq) = 0;
464
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800465 return 0;
466}
467
468int EnableIrq(uint32_t ulIrq)
469{
470 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800471
bangzheng.liu68c01152022-09-29 16:57:22 +0800472 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800473 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
474 break;
475 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800476 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800477 printf("Error ulIrq!\n");
478 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800479 }
xiaohu.huang38262102022-05-06 22:21:48 +0800480
481 eclic_enable_interrupt(irq);
482
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800483 return 0;
484}
485
486int DisableIrq(uint32_t ulIrq)
487{
488 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800489
bangzheng.liu68c01152022-09-29 16:57:22 +0800490 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800491 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
492 break;
493 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800494 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800495 printf("Error ulIrq!\n");
496 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800497 }
xiaohu.huang38262102022-05-06 22:21:48 +0800498
499 eclic_disable_interrupt(irq);
500
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800501 return 0;
502}
503
504int SetIrqPriority(uint32_t ulIrq, uint32_t ulProi)
505{
506 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800507
bangzheng.liu68c01152022-09-29 16:57:22 +0800508 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800509 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
510 break;
511 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800512 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800513 printf("Error ulIrq!\n");
514 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800515 }
xiaohu.huang38262102022-05-06 22:21:48 +0800516
517 eclic_set_irq_pri(irq, ulProi);
518
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800519 return 0;
520}
521
522int ClearPendingIrq(uint32_t ulIrq)
523{
524 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800525
bangzheng.liu68c01152022-09-29 16:57:22 +0800526 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800527 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
528 break;
529 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800530 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800531 printf("Error ulIrq!\n");
532 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800533 }
xiaohu.huang38262102022-05-06 22:21:48 +0800534
535 eclic_clear_pending(irq);
536
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800537 return 0;
538}