1 /*
2 *********************************************************************************************************
3 *                                                AR100 SYSTEM
4 *                                     AR100 Software System Develop Kits
5 *                                              interrupt  module
6 *
7 *                                    (c) Copyright 2012-2016, Sunny China
8 *                                             All Rights Reserved
9 *
10 * File    : intc.c
11 * By      : Sunny
12 * Version : v1.0
13 * Date    : 2012-5-3
14 * Descript: interrupt controller module.
15 * Update  : date                auther      ver     notes
16 *           2012-5-3 13:25:40   Sunny       1.0     Create this file.
17 *********************************************************************************************************
18 */
19 
20 #include "intc_i.h"
21 #include "platform-intc.h"
22 
23 struct intc_regs *pintc_regs;
24 
25 /*
26 *********************************************************************************************************
27 *                                           INTERRUPT INIT
28 *
29 * Description:  initialize interrupt.
30 *
31 * Arguments  :  none.
32 *
33 * Returns    :  OK if initialize succeeded, others if failed.
34 *
35 * Note       :
36 *********************************************************************************************************
37 */
intc_init(void)38 s32 intc_init(void)
39 {
40     pintc_regs = (struct intc_regs *)(SUNXI_R_INTC_PBASE);
41 
42     /*initialize interrupt controller */
43     pintc_regs->enable = 0x0;
44     pintc_regs->mask = 0x0;
45     pintc_regs->pending = 0xffffffff;
46 
47     pintc_regs->enable1 = 0x0;
48     pintc_regs->mask1 = 0x0;
49     pintc_regs->pending1 = 0xffffffff;
50 
51     pintc_regs->enable2 = 0x0;
52     pintc_regs->mask2 = 0x0;
53     pintc_regs->pending2 = 0xffffffff;
54     return OK;
55 }
56 
57 /*
58 *********************************************************************************************************
59 *                                         INTERRUPT EXIT
60 *
61 * Description:  exit interrupt.
62 *
63 * Arguments  :  none.
64 *
65 * Returns    :  OK if exit succeeded, others if failed.
66 *
67 * Note       :
68 *********************************************************************************************************
69 */
intc_exit(void)70 s32 intc_exit(void)
71 {
72     pintc_regs = NULL;
73 
74     return OK;
75 }
76 
77 /*
78 *********************************************************************************************************
79 *                                           ENABLE INTERRUPT
80 *
81 * Description:  enable a specific interrupt.
82 *
83 * Arguments  :  intno   : the source number of interrupt to which we want to enable.
84 *
85 * Returns    :  OK if enable interrupt succeeded, others if failed.
86 *
87 * Note       :
88 *********************************************************************************************************
89 */
intc_enable_interrupt(u32 intno)90 s32 intc_enable_interrupt(u32 intno)
91 {
92     /*intno can't beyond then IRQ_SOURCE_MAX */
93     /* ASSERT(intno < IRQ_SOUCE_MAX); */
94 
95     /*
96      * NMI interrupt should clear before enable.
97      * by sunny at 2012-6-12 19:30:22.
98      */
99     if (intno == SUNXI_RINTC_IRQ_NMI) {
100         pintc_regs->pending = (1 << intno);
101     }
102 
103     /*enable interrupt which number is intno */
104     if (intno <= 31)
105         pintc_regs->enable |= (1 << intno);
106     else if (intno > 31 && intno <= 63)
107         pintc_regs->enable1 |= (1 << (intno - 32));
108     else
109         pintc_regs->enable2 |= (1 << (intno - 64));
110 
111     return OK;
112 }
113 
114 /*
115 *********************************************************************************************************
116 *                                           DISABLE INTERRUPT
117 *
118 * Description:  disable a specific interrupt.
119 *
120 * Arguments  :  intno  : the source number of interrupt which we want to disable.
121 *
122 * Returns    :  OK if disable interrupt succeeded, others if failed.
123 *
124 * Note       :
125 *********************************************************************************************************
126 */
intc_disable_interrupt(u32 intno)127 s32 intc_disable_interrupt(u32 intno)
128 {
129     /*intno can't beyond then IRQ_SOURCE_MAX */
130     /* ASSERT(intno < IRQ_SOUCE_MAX); */
131 
132     /*enable interrupt which number is intno */
133     if (intno <= 31)
134         pintc_regs->enable &= ~(1 << intno);
135     else if (intno > 31 && intno <= 63)
136         pintc_regs->enable1 &= ~(1 << (intno - 32));
137     else
138         pintc_regs->enable2 &= ~(1 << (intno - 64));
139 
140     return OK;
141 }
142 
143 /*
144 *********************************************************************************************************
145 *                                   GET CURRENT INTERRUPT
146 *
147 * Description: get the source number of current interrupt.
148 *
149 * Arguments  : none.
150 *
151 * Returns    : the source number of current interrupt.
152 *
153 * Note       :
154 *********************************************************************************************************
155 */
intc_get_current_interrupt(void)156 u32 intc_get_current_interrupt(void)
157 {
158     volatile u32 interrupt;
159 
160     interrupt = (u32) ((pintc_regs->vector) >> 2);
161 
162     return interrupt;
163 }
164 
intc_set_mask(u32 intno,u32 mask)165 s32 intc_set_mask(u32 intno, u32 mask)
166 {
167     /* intno can't beyond then IRQ_SOURCE_MAX */
168     /* ASSERT(intno < IRQ_SOUCE_MAX); */
169 
170     /* enable interrupt which number is intno */
171     if (intno <= 31) {
172         pintc_regs->mask &= ~(1 << intno);
173         pintc_regs->mask |= (mask << intno);
174     } else if (intno > 31 && intno <= 63) {
175         pintc_regs->mask1 &= ~(1 << (intno - 32));
176         pintc_regs->mask1 |= (mask << intno);
177     } else {
178         pintc_regs->mask2 &= ~(1 << (intno - 64));
179         pintc_regs->mask2 |= (mask << intno);
180     }
181 
182     return OK;
183 }
184 
intc_set_group_config(u32 grp_irq_num,u32 mask)185 s32 intc_set_group_config(u32 grp_irq_num, u32 mask)
186 {
187     if (grp_irq_num <= 31) {
188         pintc_regs->group_config0 &= ~(1 << grp_irq_num);
189         pintc_regs->group_config0 |= (mask << grp_irq_num);
190     } else if (grp_irq_num > 31 && grp_irq_num <= 63) {
191         pintc_regs->group_config1 &= ~(1 << (grp_irq_num - 32));
192         pintc_regs->group_config1 |= (mask << grp_irq_num);
193     } else if (grp_irq_num > 63 && grp_irq_num <= 95) {
194         pintc_regs->group_config2 &= ~(1 << (grp_irq_num - 64));
195         pintc_regs->group_config2 |= (mask << grp_irq_num);
196     } else {
197         pintc_regs->group_config3 &= ~(1 << (grp_irq_num - 64));
198         pintc_regs->group_config3 |= (mask << grp_irq_num);
199     }
200 
201     return OK;
202 }
203