blob: 1c22bdc4e18270bb9343d2215c6cb55e2c52ec30 [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 {
356 REG32(AOCPU_IRQ_SEL8 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
357 REG32(AOCPU_IRQ_SEL8 + index * 4) |= src << (ulIrq % 2)*16;
358 }
359#else
xiaohu.huang38262102022-05-06 22:21:48 +0800360 index = ulIrq / 4;
361 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0xff << (ulIrq % 4) * 8);
362 REG32(AOCPU_IRQ_SEL0 + index * 4) |= src << (ulIrq % 4) * 8;
bangzheng.liu4d71f922022-09-29 16:12:20 +0800363#endif
364
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800365 return 0;
366}
367
368int int_src_clean(uint32_t ulIrq)
369{
370 uint32_t index;
371
bangzheng.liu68c01152022-09-29 16:57:22 +0800372 if (ulIrq < ECLIC_INTERNAL_NUM_INTERRUPTS || ulIrq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800373 printf("Error ulIrq!\n");
374 return -1;
375 }
376
377 ulIrq -= ECLIC_INTERNAL_NUM_INTERRUPTS;
378
bangzheng.liu4d71f922022-09-29 16:12:20 +0800379#ifdef AOCPU_IRQ_REG_NONCONTINUOUS
380 index = ulIrq / 2;
381
382 if (ulIrq < 16)
383 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
384 else
385 REG32(AOCPU_IRQ_SEL8 + index * 4) &= ~(0x1ff << (ulIrq % 2) * 16);
386#else
xiaohu.huang38262102022-05-06 22:21:48 +0800387 index = ulIrq / 4;
388 REG32(AOCPU_IRQ_SEL0 + index * 4) &= ~(0xff << (ulIrq % 4) * 8);
bangzheng.liu4d71f922022-09-29 16:12:20 +0800389#endif
390
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800391 return 0;
392}
393
394/*Just for external interrupt source.
395 *Because int_src_sel() just support external select
396 */
397int eclic_map_interrupt(uint32_t ulIrq, uint32_t src)
398{
399 uint8_t val;
400
401 if (int_src_sel(ulIrq, src)) {
402 printf("Enable %ld irq, %ld src fail!\n", ulIrq, src);
403 return -1;
404 }
405
xiaohu.huang38262102022-05-06 22:21:48 +0800406 val = eclic_get_intattr(ulIrq);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800407 val |= ECLIC_INT_ATTR_MACH_MODE;
408 /*Use edge trig interrupt default*/
409 val |= ECLIC_INT_ATTR_TRIG_EDGE;
410 eclic_set_intattr(ulIrq, val);
411 //eclic_enable_interrupt(ulIrq);
412 return 0;
413}
414
xiaohu.huang38262102022-05-06 22:21:48 +0800415uint32_t eclic_interrupt_inner[SOC_ECLIC_NUM_INTERRUPTS] = { 0 };
416int RegisterIrq(uint32_t int_num, uint32_t int_priority, function_ptr_t handler)
417{
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800418 int irq = 0;
419
bangzheng.liu68c01152022-09-29 16:57:22 +0800420 /* Prevent duplicate registration with the same interrupt. */
421 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
422 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == int_num) {
423 printf("Warning: the irq %ld has already been registered!\n", int_num);
424 return 0;
425 }
426 }
427
428 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800429 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == 0)
430 break;
431 }
432 if (eclic_map_interrupt(irq, int_num) < 0) {
433 printf("eclic map error.\n");
434 return -1;
435 }
436 eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] = int_num;
437
438 *(&vector_base + irq) = (uint32_t)handler;
439 eclic_set_irq_pri(irq, int_priority);
440
441 return 0;
442}
443
444int UnRegisterIrq(uint32_t ulIrq)
445{
446 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800447
bangzheng.liu68c01152022-09-29 16:57:22 +0800448 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800449 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
450 break;
451 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800452 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800453 printf("Error ulIrq!\n");
454 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800455 }
xiaohu.huang38262102022-05-06 22:21:48 +0800456
457 if (int_src_clean(irq)) {
458 printf("unregister %ld irq, %ld src fail!\n", ulIrq, irq);
459 return -1;
460 }
461 eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] = 0;
462 *(&vector_base + irq) = 0;
463
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800464 return 0;
465}
466
467int EnableIrq(uint32_t ulIrq)
468{
469 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800470
bangzheng.liu68c01152022-09-29 16:57:22 +0800471 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800472 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
473 break;
474 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800475 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800476 printf("Error ulIrq!\n");
477 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800478 }
xiaohu.huang38262102022-05-06 22:21:48 +0800479
480 eclic_enable_interrupt(irq);
481
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800482 return 0;
483}
484
485int DisableIrq(uint32_t ulIrq)
486{
487 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800488
bangzheng.liu68c01152022-09-29 16:57:22 +0800489 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800490 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
491 break;
492 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800493 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800494 printf("Error ulIrq!\n");
495 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800496 }
xiaohu.huang38262102022-05-06 22:21:48 +0800497
498 eclic_disable_interrupt(irq);
499
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800500 return 0;
501}
502
503int SetIrqPriority(uint32_t ulIrq, uint32_t ulProi)
504{
505 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800506
bangzheng.liu68c01152022-09-29 16:57:22 +0800507 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800508 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
509 break;
510 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800511 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800512 printf("Error ulIrq!\n");
513 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800514 }
xiaohu.huang38262102022-05-06 22:21:48 +0800515
516 eclic_set_irq_pri(irq, ulProi);
517
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800518 return 0;
519}
520
521int ClearPendingIrq(uint32_t ulIrq)
522{
523 int irq = 0;
xiaohu.huang38262102022-05-06 22:21:48 +0800524
bangzheng.liu68c01152022-09-29 16:57:22 +0800525 for (irq = ECLIC_INTERNAL_NUM_INTERRUPTS; irq < ECLIC_NUM_INTERRUPTS; irq++) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800526 if (eclic_interrupt_inner[irq - ECLIC_INTERNAL_NUM_INTERRUPTS] == ulIrq)
527 break;
528 }
bangzheng.liu68c01152022-09-29 16:57:22 +0800529 if (irq > ECLIC_NUM_INTERRUPTS - 1) {
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800530 printf("Error ulIrq!\n");
531 return -1;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800532 }
xiaohu.huang38262102022-05-06 22:21:48 +0800533
534 eclic_clear_pending(irq);
535
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +0800536 return 0;
537}