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