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