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