xref: /rk3399_ARM-atf/drivers/arm/gic/common/gic_common.c (revision c3cf06f1a3a9b9ee8ac7a0ae505f95c45f7dca84)
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 }
339