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