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