1 #include "bflb_irq.h"
2 #include "bflb_core.h"
3 #if defined(BL602) || defined(BL702) || defined(BL702L)
4 #include <risc-v/e24/clic.h>
5 #else
6 #include <csi_core.h>
7 #endif
8
9 extern struct bflb_irq_info_s g_irqvector[];
10
irq_unexpected_isr(int irq,void * arg)11 static void irq_unexpected_isr(int irq, void *arg)
12 {
13 printf("irq :%d unregistered\r\n", irq);
14 }
15
bflb_irq_initialize(void)16 void bflb_irq_initialize(void)
17 {
18 int i;
19
20 /* Point all interrupt vectors to the unexpected interrupt */
21 for (i = 0; i < CONFIG_IRQ_NUM; i++) {
22 g_irqvector[i].handler = irq_unexpected_isr;
23 g_irqvector[i].arg = NULL;
24 }
25 }
26
bflb_irq_save(void)27 ATTR_TCM_SECTION uintptr_t bflb_irq_save(void)
28 {
29 uintptr_t oldstat;
30
31 /* Read mstatus & clear machine interrupt enable (MIE) in mstatus */
32
33 asm volatile("csrrc %0, mstatus, %1"
34 : "=r"(oldstat)
35 : "r"(MSTATUS_MIE));
36 return oldstat;
37 }
38
bflb_irq_restore(uintptr_t flags)39 ATTR_TCM_SECTION void bflb_irq_restore(uintptr_t flags)
40 {
41 /* Write flags to mstatus */
42
43 asm volatile("csrw mstatus, %0"
44 : /* no output */
45 : "r"(flags));
46 }
47
bflb_irq_attach(int irq,irq_callback isr,void * arg)48 int bflb_irq_attach(int irq, irq_callback isr, void *arg)
49 {
50 if (irq > CONFIG_IRQ_NUM) {
51 return -EINVAL;
52 }
53 g_irqvector[irq].handler = isr;
54 g_irqvector[irq].arg = arg;
55 return 0;
56 }
57
bflb_irq_detach(int irq)58 int bflb_irq_detach(int irq)
59 {
60 if (irq > CONFIG_IRQ_NUM) {
61 return -EINVAL;
62 }
63 g_irqvector[irq].handler = irq_unexpected_isr;
64 g_irqvector[irq].arg = NULL;
65 return 0;
66 }
67
bflb_irq_enable(int irq)68 void bflb_irq_enable(int irq)
69 {
70 #if defined(BL702) || defined(BL602) || defined(BL702L)
71 putreg8(1, CLIC_HART0_BASE + CLIC_INTIE_OFFSET + irq);
72 #else
73 #if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
74 if (csi_vic_get_prio(irq) == 0) {
75 csi_vic_set_prio(irq, 1);
76 }
77 #endif
78 csi_vic_enable_irq(irq);
79 #endif
80 }
81
bflb_irq_disable(int irq)82 void bflb_irq_disable(int irq)
83 {
84 #if defined(BL702) || defined(BL602) || defined(BL702L)
85 putreg8(0, CLIC_HART0_BASE + CLIC_INTIE_OFFSET + irq);
86 #else
87 csi_vic_disable_irq(irq);
88 #endif
89 }
90
bflb_irq_set_pending(int irq)91 void bflb_irq_set_pending(int irq)
92 {
93 #if defined(BL702) || defined(BL602) || defined(BL702L)
94 putreg8(1, CLIC_HART0_BASE + CLIC_INTIP_OFFSET + irq);
95 #else
96 csi_vic_set_pending_irq(irq);
97 #endif
98 }
99
bflb_irq_clear_pending(int irq)100 void bflb_irq_clear_pending(int irq)
101 {
102 #if defined(BL702) || defined(BL602) || defined(BL702L)
103 putreg8(0, CLIC_HART0_BASE + CLIC_INTIP_OFFSET + irq);
104 #else
105 csi_vic_clear_pending_irq(irq);
106 #endif
107 }
108
bflb_irq_set_nlbits(uint8_t nlbits)109 void bflb_irq_set_nlbits(uint8_t nlbits)
110 {
111 #if defined(BL702) || defined(BL602) || defined(BL702L)
112 uint8_t clicCfg = getreg8(CLIC_HART0_BASE + CLIC_CFG_OFFSET);
113 putreg8((clicCfg & 0xe1) | ((nlbits & 0xf) << 1), CLIC_HART0_BASE + CLIC_CFG_OFFSET);
114 #else
115 #if !defined(CPU_D0)
116 CLIC->CLICCFG = ((nlbits & 0xf) << 1) | 1;
117 #endif
118 #endif
119 }
120
bflb_irq_set_priority(int irq,uint8_t preemptprio,uint8_t subprio)121 void bflb_irq_set_priority(int irq, uint8_t preemptprio, uint8_t subprio)
122 {
123 #if defined(BL702) || defined(BL602) || defined(BL702L)
124 uint8_t nlbits = getreg8(CLIC_HART0_BASE + CLIC_CFG_OFFSET) >> 1 & 0xf;
125 uint8_t clicIntCfg = getreg8(CLIC_HART0_BASE + CLIC_INTCFG_OFFSET + irq);
126 putreg8((clicIntCfg & 0xf) | (preemptprio << (8 - nlbits)) | ((subprio & (0xf >> nlbits)) << 4), CLIC_HART0_BASE + CLIC_INTCFG_OFFSET + irq);
127 #else
128 csi_vic_set_prio(irq, preemptprio);
129 #endif
130 }
131