589de5da40b50e89914dfee6a2f4ca38ababf596
[project/bcm63xx/atf.git] / drivers / arm / gic / common / gic_common.c
1 /*
2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <assert.h>
8 #include <gic_common.h>
9 #include <mmio.h>
10 #include "gic_common_private.h"
11
12 /*******************************************************************************
13 * GIC Distributor interface accessors for reading entire registers
14 ******************************************************************************/
15 /*
16 * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt
17 * `id`, 32 interrupt ids at a time.
18 */
19 unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
20 {
21 unsigned int n = id >> IGROUPR_SHIFT;
22
23 return mmio_read_32(base + GICD_IGROUPR + (n << 2));
24 }
25
26 /*
27 * Accessor to read the GIC Distributor ISENABLER corresponding to the
28 * interrupt `id`, 32 interrupt ids at a time.
29 */
30 unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
31 {
32 unsigned int n = id >> ISENABLER_SHIFT;
33
34 return mmio_read_32(base + GICD_ISENABLER + (n << 2));
35 }
36
37 /*
38 * Accessor to read the GIC Distributor ICENABLER corresponding to the
39 * interrupt `id`, 32 interrupt IDs at a time.
40 */
41 unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
42 {
43 unsigned int n = id >> ICENABLER_SHIFT;
44
45 return mmio_read_32(base + GICD_ICENABLER + (n << 2));
46 }
47
48 /*
49 * Accessor to read the GIC Distributor ISPENDR corresponding to the
50 * interrupt `id`, 32 interrupt IDs at a time.
51 */
52 unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
53 {
54 unsigned int n = id >> ISPENDR_SHIFT;
55
56 return mmio_read_32(base + GICD_ISPENDR + (n << 2));
57 }
58
59 /*
60 * Accessor to read the GIC Distributor ICPENDR corresponding to the
61 * interrupt `id`, 32 interrupt IDs at a time.
62 */
63 unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
64 {
65 unsigned int n = id >> ICPENDR_SHIFT;
66
67 return mmio_read_32(base + GICD_ICPENDR + (n << 2));
68 }
69
70 /*
71 * Accessor to read the GIC Distributor ISACTIVER corresponding to the
72 * interrupt `id`, 32 interrupt IDs at a time.
73 */
74 unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
75 {
76 unsigned int n = id >> ISACTIVER_SHIFT;
77
78 return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
79 }
80
81 /*
82 * Accessor to read the GIC Distributor ICACTIVER corresponding to the
83 * interrupt `id`, 32 interrupt IDs at a time.
84 */
85 unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
86 {
87 unsigned int n = id >> ICACTIVER_SHIFT;
88
89 return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
90 }
91
92 /*
93 * Accessor to read the GIC Distributor IPRIORITYR corresponding to the
94 * interrupt `id`, 4 interrupt IDs at a time.
95 */
96 unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
97 {
98 unsigned int n = id >> IPRIORITYR_SHIFT;
99
100 return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
101 }
102
103 /*
104 * Accessor to read the GIC Distributor ICGFR corresponding to the
105 * interrupt `id`, 16 interrupt IDs at a time.
106 */
107 unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
108 {
109 unsigned int n = id >> ICFGR_SHIFT;
110
111 return mmio_read_32(base + GICD_ICFGR + (n << 2));
112 }
113
114 /*
115 * Accessor to read the GIC Distributor NSACR corresponding to the
116 * interrupt `id`, 16 interrupt IDs at a time.
117 */
118 unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
119 {
120 unsigned int n = id >> NSACR_SHIFT;
121
122 return mmio_read_32(base + GICD_NSACR + (n << 2));
123 }
124
125 /*******************************************************************************
126 * GIC Distributor interface accessors for writing entire registers
127 ******************************************************************************/
128 /*
129 * Accessor to write the GIC Distributor IGROUPR corresponding to the
130 * interrupt `id`, 32 interrupt IDs at a time.
131 */
132 void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
133 {
134 unsigned int n = id >> IGROUPR_SHIFT;
135
136 mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
137 }
138
139 /*
140 * Accessor to write the GIC Distributor ISENABLER corresponding to the
141 * interrupt `id`, 32 interrupt IDs at a time.
142 */
143 void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
144 {
145 unsigned int n = id >> ISENABLER_SHIFT;
146
147 mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
148 }
149
150 /*
151 * Accessor to write the GIC Distributor ICENABLER corresponding to the
152 * interrupt `id`, 32 interrupt IDs at a time.
153 */
154 void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
155 {
156 unsigned int n = id >> ICENABLER_SHIFT;
157
158 mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
159 }
160
161 /*
162 * Accessor to write the GIC Distributor ISPENDR corresponding to the
163 * interrupt `id`, 32 interrupt IDs at a time.
164 */
165 void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
166 {
167 unsigned int n = id >> ISPENDR_SHIFT;
168
169 mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
170 }
171
172 /*
173 * Accessor to write the GIC Distributor ICPENDR corresponding to the
174 * interrupt `id`, 32 interrupt IDs at a time.
175 */
176 void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
177 {
178 unsigned int n = id >> ICPENDR_SHIFT;
179
180 mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
181 }
182
183 /*
184 * Accessor to write the GIC Distributor ISACTIVER corresponding to the
185 * interrupt `id`, 32 interrupt IDs at a time.
186 */
187 void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
188 {
189 unsigned int n = id >> ISACTIVER_SHIFT;
190
191 mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
192 }
193
194 /*
195 * Accessor to write the GIC Distributor ICACTIVER corresponding to the
196 * interrupt `id`, 32 interrupt IDs at a time.
197 */
198 void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
199 {
200 unsigned int n = id >> ICACTIVER_SHIFT;
201
202 mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
203 }
204
205 /*
206 * Accessor to write the GIC Distributor IPRIORITYR corresponding to the
207 * interrupt `id`, 4 interrupt IDs at a time.
208 */
209 void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
210 {
211 unsigned int n = id >> IPRIORITYR_SHIFT;
212
213 mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
214 }
215
216 /*
217 * Accessor to write the GIC Distributor ICFGR corresponding to the
218 * interrupt `id`, 16 interrupt IDs at a time.
219 */
220 void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
221 {
222 unsigned int n = id >> ICFGR_SHIFT;
223
224 mmio_write_32(base + GICD_ICFGR + (n << 2), val);
225 }
226
227 /*
228 * Accessor to write the GIC Distributor NSACR corresponding to the
229 * interrupt `id`, 16 interrupt IDs at a time.
230 */
231 void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
232 {
233 unsigned int n = id >> NSACR_SHIFT;
234
235 mmio_write_32(base + GICD_NSACR + (n << 2), val);
236 }
237
238 /*******************************************************************************
239 * GIC Distributor functions for accessing the GIC registers
240 * corresponding to a single interrupt ID. These functions use bitwise
241 * operations or appropriate register accesses to modify or return
242 * the bit-field corresponding the single interrupt ID.
243 ******************************************************************************/
244 unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
245 {
246 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
247 unsigned int reg_val = gicd_read_igroupr(base, id);
248
249 return (reg_val >> bit_num) & 0x1U;
250 }
251
252 void gicd_set_igroupr(uintptr_t base, unsigned int id)
253 {
254 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
255 unsigned int reg_val = gicd_read_igroupr(base, id);
256
257 gicd_write_igroupr(base, id, reg_val | (1U << bit_num));
258 }
259
260 void gicd_clr_igroupr(uintptr_t base, unsigned int id)
261 {
262 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
263 unsigned int reg_val = gicd_read_igroupr(base, id);
264
265 gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num));
266 }
267
268 void gicd_set_isenabler(uintptr_t base, unsigned int id)
269 {
270 unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
271
272 gicd_write_isenabler(base, id, (1U << bit_num));
273 }
274
275 void gicd_set_icenabler(uintptr_t base, unsigned int id)
276 {
277 unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
278
279 gicd_write_icenabler(base, id, (1U << bit_num));
280 }
281
282 void gicd_set_ispendr(uintptr_t base, unsigned int id)
283 {
284 unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
285
286 gicd_write_ispendr(base, id, (1U << bit_num));
287 }
288
289 void gicd_set_icpendr(uintptr_t base, unsigned int id)
290 {
291 unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
292
293 gicd_write_icpendr(base, id, (1U << bit_num));
294 }
295
296 unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
297 {
298 unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
299 unsigned int reg_val = gicd_read_isactiver(base, id);
300
301 return (reg_val >> bit_num) & 0x1U;
302 }
303
304 void gicd_set_isactiver(uintptr_t base, unsigned int id)
305 {
306 unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
307
308 gicd_write_isactiver(base, id, (1U << bit_num));
309 }
310
311 void gicd_set_icactiver(uintptr_t base, unsigned int id)
312 {
313 unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U);
314
315 gicd_write_icactiver(base, id, (1U << bit_num));
316 }
317
318 void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
319 {
320 uint8_t val = pri & GIC_PRI_MASK;
321
322 mmio_write_8(base + GICD_IPRIORITYR + id, val);
323 }
324
325 void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
326 {
327 /* Interrupt configuration is a 2-bit field */
328 unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
329 unsigned int bit_shift = bit_num << 1;
330
331 uint32_t reg_val = gicd_read_icfgr(base, id);
332
333 /* Clear the field, and insert required configuration */
334 reg_val &= ~(GIC_CFG_MASK << bit_shift);
335 reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
336
337 gicd_write_icfgr(base, id, reg_val);
338 }