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