xref: /rk3399_ARM-atf/drivers/arm/gic/common/gic_common.c (revision 3105f7ba9a3a9f6f0e78761e8bdd4da621254730)
1 /*
2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <assert.h>
32 #include <gic_common.h>
33 #include <mmio.h>
34 
35 /*******************************************************************************
36  * GIC Distributor interface accessors for reading entire registers
37  ******************************************************************************/
38 /*
39  * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt
40  * `id`, 32 interrupt ids at a time.
41  */
42 unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
43 {
44 	unsigned n = id >> IGROUPR_SHIFT;
45 	return mmio_read_32(base + GICD_IGROUPR + (n << 2));
46 }
47 
48 /*
49  * Accessor to read the GIC Distributor ISENABLER corresponding to the
50  * interrupt `id`, 32 interrupt ids at a time.
51  */
52 unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
53 {
54 	unsigned n = id >> ISENABLER_SHIFT;
55 	return mmio_read_32(base + GICD_ISENABLER + (n << 2));
56 }
57 
58 /*
59  * Accessor to read the GIC Distributor ICENABLER corresponding to the
60  * interrupt `id`, 32 interrupt IDs at a time.
61  */
62 unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
63 {
64 	unsigned n = id >> ICENABLER_SHIFT;
65 	return mmio_read_32(base + GICD_ICENABLER + (n << 2));
66 }
67 
68 /*
69  * Accessor to read the GIC Distributor ISPENDR corresponding to the
70  * interrupt `id`, 32 interrupt IDs at a time.
71  */
72 unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
73 {
74 	unsigned n = id >> ISPENDR_SHIFT;
75 	return mmio_read_32(base + GICD_ISPENDR + (n << 2));
76 }
77 
78 /*
79  * Accessor to read the GIC Distributor ICPENDR corresponding to the
80  * interrupt `id`, 32 interrupt IDs at a time.
81  */
82 unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
83 {
84 	unsigned n = id >> ICPENDR_SHIFT;
85 	return mmio_read_32(base + GICD_ICPENDR + (n << 2));
86 }
87 
88 /*
89  * Accessor to read the GIC Distributor ISACTIVER corresponding to the
90  * interrupt `id`, 32 interrupt IDs at a time.
91  */
92 unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
93 {
94 	unsigned n = id >> ISACTIVER_SHIFT;
95 	return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
96 }
97 
98 /*
99  * Accessor to read the GIC Distributor ICACTIVER corresponding to the
100  * interrupt `id`, 32 interrupt IDs at a time.
101  */
102 unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
103 {
104 	unsigned n = id >> ICACTIVER_SHIFT;
105 	return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
106 }
107 
108 /*
109  * Accessor to read the GIC Distributor IPRIORITYR corresponding to the
110  * interrupt `id`, 4 interrupt IDs at a time.
111  */
112 unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
113 {
114 	unsigned n = id >> IPRIORITYR_SHIFT;
115 	return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
116 }
117 
118 /*
119  * Accessor to read the GIC Distributor ICGFR corresponding to the
120  * interrupt `id`, 16 interrupt IDs at a time.
121  */
122 unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
123 {
124 	unsigned n = id >> ICFGR_SHIFT;
125 	return mmio_read_32(base + GICD_ICFGR + (n << 2));
126 }
127 
128 /*
129  * Accessor to read the GIC Distributor NSACR corresponding to the
130  * interrupt `id`, 16 interrupt IDs at a time.
131  */
132 unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
133 {
134 	unsigned n = id >> NSACR_SHIFT;
135 	return mmio_read_32(base + GICD_NSACR + (n << 2));
136 }
137 
138 /*******************************************************************************
139  * GIC Distributor interface accessors for writing entire registers
140  ******************************************************************************/
141 /*
142  * Accessor to write the GIC Distributor IGROUPR corresponding to the
143  * interrupt `id`, 32 interrupt IDs at a time.
144  */
145 void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
146 {
147 	unsigned n = id >> IGROUPR_SHIFT;
148 	mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
149 }
150 
151 /*
152  * Accessor to write the GIC Distributor ISENABLER corresponding to the
153  * interrupt `id`, 32 interrupt IDs at a time.
154  */
155 void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
156 {
157 	unsigned n = id >> ISENABLER_SHIFT;
158 	mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
159 }
160 
161 /*
162  * Accessor to write the GIC Distributor ICENABLER corresponding to the
163  * interrupt `id`, 32 interrupt IDs at a time.
164  */
165 void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
166 {
167 	unsigned n = id >> ICENABLER_SHIFT;
168 	mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
169 }
170 
171 /*
172  * Accessor to write the GIC Distributor ISPENDR corresponding to the
173  * interrupt `id`, 32 interrupt IDs at a time.
174  */
175 void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
176 {
177 	unsigned n = id >> ISPENDR_SHIFT;
178 	mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
179 }
180 
181 /*
182  * Accessor to write the GIC Distributor ICPENDR corresponding to the
183  * interrupt `id`, 32 interrupt IDs at a time.
184  */
185 void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
186 {
187 	unsigned n = id >> ICPENDR_SHIFT;
188 	mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
189 }
190 
191 /*
192  * Accessor to write the GIC Distributor ISACTIVER corresponding to the
193  * interrupt `id`, 32 interrupt IDs at a time.
194  */
195 void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
196 {
197 	unsigned n = id >> ISACTIVER_SHIFT;
198 	mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
199 }
200 
201 /*
202  * Accessor to write the GIC Distributor ICACTIVER corresponding to the
203  * interrupt `id`, 32 interrupt IDs at a time.
204  */
205 void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
206 {
207 	unsigned n = id >> ICACTIVER_SHIFT;
208 	mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
209 }
210 
211 /*
212  * Accessor to write the GIC Distributor IPRIORITYR corresponding to the
213  * interrupt `id`, 4 interrupt IDs at a time.
214  */
215 void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
216 {
217 	unsigned n = id >> IPRIORITYR_SHIFT;
218 	mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
219 }
220 
221 /*
222  * Accessor to write the GIC Distributor ICFGR corresponding to the
223  * interrupt `id`, 16 interrupt IDs at a time.
224  */
225 void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
226 {
227 	unsigned n = id >> ICFGR_SHIFT;
228 	mmio_write_32(base + GICD_ICFGR + (n << 2), val);
229 }
230 
231 /*
232  * Accessor to write the GIC Distributor NSACR corresponding to the
233  * interrupt `id`, 16 interrupt IDs at a time.
234  */
235 void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
236 {
237 	unsigned n = id >> NSACR_SHIFT;
238 	mmio_write_32(base + GICD_NSACR + (n << 2), val);
239 }
240 
241 /*******************************************************************************
242  * GIC Distributor interface accessors for individual interrupt manipulation
243  ******************************************************************************/
244 unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
245 {
246 	unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
247 	unsigned int reg_val = gicd_read_igroupr(base, id);
248 
249 	return (reg_val >> bit_num) & 0x1;
250 }
251 
252 void gicd_set_igroupr(uintptr_t base, unsigned int id)
253 {
254 	unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
255 	unsigned int reg_val = gicd_read_igroupr(base, id);
256 
257 	gicd_write_igroupr(base, id, reg_val | (1 << bit_num));
258 }
259 
260 void gicd_clr_igroupr(uintptr_t base, unsigned int id)
261 {
262 	unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
263 	unsigned int reg_val = gicd_read_igroupr(base, id);
264 
265 	gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num));
266 }
267 
268 void gicd_set_isenabler(uintptr_t base, unsigned int id)
269 {
270 	unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1);
271 
272 	gicd_write_isenabler(base, id, (1 << bit_num));
273 }
274 
275 void gicd_set_icenabler(uintptr_t base, unsigned int id)
276 {
277 	unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1);
278 
279 	gicd_write_icenabler(base, id, (1 << bit_num));
280 }
281 
282 void gicd_set_ispendr(uintptr_t base, unsigned int id)
283 {
284 	unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1);
285 
286 	gicd_write_ispendr(base, id, (1 << bit_num));
287 }
288 
289 void gicd_set_icpendr(uintptr_t base, unsigned int id)
290 {
291 	unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1);
292 
293 	gicd_write_icpendr(base, id, (1 << bit_num));
294 }
295 
296 void gicd_set_isactiver(uintptr_t base, unsigned int id)
297 {
298 	unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
299 
300 	gicd_write_isactiver(base, id, (1 << bit_num));
301 }
302 
303 void gicd_set_icactiver(uintptr_t base, unsigned int id)
304 {
305 	unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1);
306 
307 	gicd_write_icactiver(base, id, (1 << bit_num));
308 }
309