xref: /rk3399_ARM-atf/drivers/arm/gic/common/gic_common.c (revision 09d40e0e08283a249e7dce0e106c07c5141f9b7e)
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>
8*09d40e0eSAntonio Nino Diaz 
9*09d40e0eSAntonio Nino Diaz #include <drivers/arm/gic_common.h>
10*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
11*09d40e0eSAntonio Nino Diaz 
12e9ec3cecSSoby Mathew #include "gic_common_private.h"
13df373737SAchin Gupta 
14df373737SAchin Gupta /*******************************************************************************
15df373737SAchin Gupta  * GIC Distributor interface accessors for reading entire registers
16df373737SAchin Gupta  ******************************************************************************/
17df373737SAchin Gupta /*
18df373737SAchin Gupta  * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt
19df373737SAchin Gupta  * `id`, 32 interrupt ids at a time.
20df373737SAchin Gupta  */
21df373737SAchin Gupta unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
22df373737SAchin Gupta {
233fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> IGROUPR_SHIFT;
243fea9c8bSAntonio Nino Diaz 
25df373737SAchin Gupta 	return mmio_read_32(base + GICD_IGROUPR + (n << 2));
26df373737SAchin Gupta }
27df373737SAchin Gupta 
28df373737SAchin Gupta /*
29df373737SAchin Gupta  * Accessor to read the GIC Distributor ISENABLER corresponding to the
30df373737SAchin Gupta  * interrupt `id`, 32 interrupt ids at a time.
31df373737SAchin Gupta  */
32df373737SAchin Gupta unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
33df373737SAchin Gupta {
343fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ISENABLER_SHIFT;
353fea9c8bSAntonio Nino Diaz 
36df373737SAchin Gupta 	return mmio_read_32(base + GICD_ISENABLER + (n << 2));
37df373737SAchin Gupta }
38df373737SAchin Gupta 
39df373737SAchin Gupta /*
40df373737SAchin Gupta  * Accessor to read the GIC Distributor ICENABLER corresponding to the
41df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
42df373737SAchin Gupta  */
43df373737SAchin Gupta unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
44df373737SAchin Gupta {
453fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICENABLER_SHIFT;
463fea9c8bSAntonio Nino Diaz 
47df373737SAchin Gupta 	return mmio_read_32(base + GICD_ICENABLER + (n << 2));
48df373737SAchin Gupta }
49df373737SAchin Gupta 
50df373737SAchin Gupta /*
51df373737SAchin Gupta  * Accessor to read the GIC Distributor ISPENDR corresponding to the
52df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
53df373737SAchin Gupta  */
54df373737SAchin Gupta unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
55df373737SAchin Gupta {
563fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ISPENDR_SHIFT;
573fea9c8bSAntonio Nino Diaz 
58df373737SAchin Gupta 	return mmio_read_32(base + GICD_ISPENDR + (n << 2));
59df373737SAchin Gupta }
60df373737SAchin Gupta 
61df373737SAchin Gupta /*
62df373737SAchin Gupta  * Accessor to read the GIC Distributor ICPENDR corresponding to the
63df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
64df373737SAchin Gupta  */
65df373737SAchin Gupta unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
66df373737SAchin Gupta {
673fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICPENDR_SHIFT;
683fea9c8bSAntonio Nino Diaz 
69df373737SAchin Gupta 	return mmio_read_32(base + GICD_ICPENDR + (n << 2));
70df373737SAchin Gupta }
71df373737SAchin Gupta 
72df373737SAchin Gupta /*
73df373737SAchin Gupta  * Accessor to read the GIC Distributor ISACTIVER corresponding to the
74df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
75df373737SAchin Gupta  */
76df373737SAchin Gupta unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
77df373737SAchin Gupta {
783fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ISACTIVER_SHIFT;
793fea9c8bSAntonio Nino Diaz 
80df373737SAchin Gupta 	return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
81df373737SAchin Gupta }
82df373737SAchin Gupta 
83df373737SAchin Gupta /*
84df373737SAchin Gupta  * Accessor to read the GIC Distributor ICACTIVER corresponding to the
85df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
86df373737SAchin Gupta  */
87df373737SAchin Gupta unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
88df373737SAchin Gupta {
893fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICACTIVER_SHIFT;
903fea9c8bSAntonio Nino Diaz 
91df373737SAchin Gupta 	return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
92df373737SAchin Gupta }
93df373737SAchin Gupta 
94df373737SAchin Gupta /*
95df373737SAchin Gupta  * Accessor to read the GIC Distributor IPRIORITYR corresponding to the
96df373737SAchin Gupta  * interrupt `id`, 4 interrupt IDs at a time.
97df373737SAchin Gupta  */
98df373737SAchin Gupta unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
99df373737SAchin Gupta {
1003fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> IPRIORITYR_SHIFT;
1013fea9c8bSAntonio Nino Diaz 
102df373737SAchin Gupta 	return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
103df373737SAchin Gupta }
104df373737SAchin Gupta 
105df373737SAchin Gupta /*
106df373737SAchin Gupta  * Accessor to read the GIC Distributor ICGFR corresponding to the
107df373737SAchin Gupta  * interrupt `id`, 16 interrupt IDs at a time.
108df373737SAchin Gupta  */
109df373737SAchin Gupta unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
110df373737SAchin Gupta {
1113fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICFGR_SHIFT;
1123fea9c8bSAntonio Nino Diaz 
113df373737SAchin Gupta 	return mmio_read_32(base + GICD_ICFGR + (n << 2));
114df373737SAchin Gupta }
115df373737SAchin Gupta 
116df373737SAchin Gupta /*
117df373737SAchin Gupta  * Accessor to read the GIC Distributor NSACR corresponding to the
118df373737SAchin Gupta  * interrupt `id`, 16 interrupt IDs at a time.
119df373737SAchin Gupta  */
120df373737SAchin Gupta unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
121df373737SAchin Gupta {
1223fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> NSACR_SHIFT;
1233fea9c8bSAntonio Nino Diaz 
124df373737SAchin Gupta 	return mmio_read_32(base + GICD_NSACR + (n << 2));
125df373737SAchin Gupta }
126df373737SAchin Gupta 
127df373737SAchin Gupta /*******************************************************************************
128df373737SAchin Gupta  * GIC Distributor interface accessors for writing entire registers
129df373737SAchin Gupta  ******************************************************************************/
130df373737SAchin Gupta /*
131df373737SAchin Gupta  * Accessor to write the GIC Distributor IGROUPR corresponding to the
132df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
133df373737SAchin Gupta  */
134df373737SAchin Gupta void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
135df373737SAchin Gupta {
1363fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> IGROUPR_SHIFT;
1373fea9c8bSAntonio Nino Diaz 
138df373737SAchin Gupta 	mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
139df373737SAchin Gupta }
140df373737SAchin Gupta 
141df373737SAchin Gupta /*
142df373737SAchin Gupta  * Accessor to write the GIC Distributor ISENABLER corresponding to the
143df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
144df373737SAchin Gupta  */
145df373737SAchin Gupta void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
146df373737SAchin Gupta {
1473fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ISENABLER_SHIFT;
1483fea9c8bSAntonio Nino Diaz 
149df373737SAchin Gupta 	mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
150df373737SAchin Gupta }
151df373737SAchin Gupta 
152df373737SAchin Gupta /*
153df373737SAchin Gupta  * Accessor to write the GIC Distributor ICENABLER corresponding to the
154df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
155df373737SAchin Gupta  */
156df373737SAchin Gupta void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
157df373737SAchin Gupta {
1583fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICENABLER_SHIFT;
1593fea9c8bSAntonio Nino Diaz 
160df373737SAchin Gupta 	mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
161df373737SAchin Gupta }
162df373737SAchin Gupta 
163df373737SAchin Gupta /*
164df373737SAchin Gupta  * Accessor to write the GIC Distributor ISPENDR corresponding to the
165df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
166df373737SAchin Gupta  */
167df373737SAchin Gupta void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
168df373737SAchin Gupta {
1693fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ISPENDR_SHIFT;
1703fea9c8bSAntonio Nino Diaz 
171df373737SAchin Gupta 	mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
172df373737SAchin Gupta }
173df373737SAchin Gupta 
174df373737SAchin Gupta /*
175df373737SAchin Gupta  * Accessor to write the GIC Distributor ICPENDR corresponding to the
176df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
177df373737SAchin Gupta  */
178df373737SAchin Gupta void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
179df373737SAchin Gupta {
1803fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICPENDR_SHIFT;
1813fea9c8bSAntonio Nino Diaz 
182df373737SAchin Gupta 	mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
183df373737SAchin Gupta }
184df373737SAchin Gupta 
185df373737SAchin Gupta /*
186df373737SAchin Gupta  * Accessor to write the GIC Distributor ISACTIVER corresponding to the
187df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
188df373737SAchin Gupta  */
189df373737SAchin Gupta void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
190df373737SAchin Gupta {
1913fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ISACTIVER_SHIFT;
1923fea9c8bSAntonio Nino Diaz 
193df373737SAchin Gupta 	mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
194df373737SAchin Gupta }
195df373737SAchin Gupta 
196df373737SAchin Gupta /*
197df373737SAchin Gupta  * Accessor to write the GIC Distributor ICACTIVER corresponding to the
198df373737SAchin Gupta  * interrupt `id`, 32 interrupt IDs at a time.
199df373737SAchin Gupta  */
200df373737SAchin Gupta void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
201df373737SAchin Gupta {
2023fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICACTIVER_SHIFT;
2033fea9c8bSAntonio Nino Diaz 
204df373737SAchin Gupta 	mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
205df373737SAchin Gupta }
206df373737SAchin Gupta 
207df373737SAchin Gupta /*
208df373737SAchin Gupta  * Accessor to write the GIC Distributor IPRIORITYR corresponding to the
209df373737SAchin Gupta  * interrupt `id`, 4 interrupt IDs at a time.
210df373737SAchin Gupta  */
211df373737SAchin Gupta void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
212df373737SAchin Gupta {
2133fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> IPRIORITYR_SHIFT;
2143fea9c8bSAntonio Nino Diaz 
215df373737SAchin Gupta 	mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
216df373737SAchin Gupta }
217df373737SAchin Gupta 
218df373737SAchin Gupta /*
219df373737SAchin Gupta  * Accessor to write the GIC Distributor ICFGR corresponding to the
220df373737SAchin Gupta  * interrupt `id`, 16 interrupt IDs at a time.
221df373737SAchin Gupta  */
222df373737SAchin Gupta void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
223df373737SAchin Gupta {
2243fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> ICFGR_SHIFT;
2253fea9c8bSAntonio Nino Diaz 
226df373737SAchin Gupta 	mmio_write_32(base + GICD_ICFGR + (n << 2), val);
227df373737SAchin Gupta }
228df373737SAchin Gupta 
229df373737SAchin Gupta /*
230df373737SAchin Gupta  * Accessor to write the GIC Distributor NSACR corresponding to the
231df373737SAchin Gupta  * interrupt `id`, 16 interrupt IDs at a time.
232df373737SAchin Gupta  */
233df373737SAchin Gupta void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
234df373737SAchin Gupta {
2353fea9c8bSAntonio Nino Diaz 	unsigned int n = id >> NSACR_SHIFT;
2363fea9c8bSAntonio Nino Diaz 
237df373737SAchin Gupta 	mmio_write_32(base + GICD_NSACR + (n << 2), val);
238df373737SAchin Gupta }
239df373737SAchin Gupta 
240df373737SAchin Gupta /*******************************************************************************
241e9ec3cecSSoby Mathew  * GIC Distributor functions for accessing the GIC registers
242e9ec3cecSSoby Mathew  * corresponding to a single interrupt ID. These functions use bitwise
243e9ec3cecSSoby Mathew  * operations or appropriate register accesses to modify or return
244e9ec3cecSSoby Mathew  * the bit-field corresponding the single interrupt ID.
245df373737SAchin Gupta  ******************************************************************************/
246df373737SAchin Gupta unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
247df373737SAchin Gupta {
2483fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
249df373737SAchin Gupta 	unsigned int reg_val = gicd_read_igroupr(base, id);
250df373737SAchin Gupta 
2513fea9c8bSAntonio Nino Diaz 	return (reg_val >> bit_num) & 0x1U;
252df373737SAchin Gupta }
253df373737SAchin Gupta 
254df373737SAchin Gupta void gicd_set_igroupr(uintptr_t base, unsigned int id)
255df373737SAchin Gupta {
2563fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
257df373737SAchin Gupta 	unsigned int reg_val = gicd_read_igroupr(base, id);
258df373737SAchin Gupta 
2593fea9c8bSAntonio Nino Diaz 	gicd_write_igroupr(base, id, reg_val | (1U << bit_num));
260df373737SAchin Gupta }
261df373737SAchin Gupta 
262df373737SAchin Gupta void gicd_clr_igroupr(uintptr_t base, unsigned int id)
263df373737SAchin Gupta {
2643fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
265df373737SAchin Gupta 	unsigned int reg_val = gicd_read_igroupr(base, id);
266df373737SAchin Gupta 
2673fea9c8bSAntonio Nino Diaz 	gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num));
268df373737SAchin Gupta }
269df373737SAchin Gupta 
270df373737SAchin Gupta void gicd_set_isenabler(uintptr_t base, unsigned int id)
271df373737SAchin Gupta {
2723fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
273df373737SAchin Gupta 
2743fea9c8bSAntonio Nino Diaz 	gicd_write_isenabler(base, id, (1U << bit_num));
275df373737SAchin Gupta }
276df373737SAchin Gupta 
277df373737SAchin Gupta void gicd_set_icenabler(uintptr_t base, unsigned int id)
278df373737SAchin Gupta {
2793fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
280df373737SAchin Gupta 
2813fea9c8bSAntonio Nino Diaz 	gicd_write_icenabler(base, id, (1U << bit_num));
282df373737SAchin Gupta }
283df373737SAchin Gupta 
284df373737SAchin Gupta void gicd_set_ispendr(uintptr_t base, unsigned int id)
285df373737SAchin Gupta {
2863fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
287df373737SAchin Gupta 
2883fea9c8bSAntonio Nino Diaz 	gicd_write_ispendr(base, id, (1U << bit_num));
289df373737SAchin Gupta }
290df373737SAchin Gupta 
291df373737SAchin Gupta void gicd_set_icpendr(uintptr_t base, unsigned int id)
292df373737SAchin Gupta {
2933fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
294df373737SAchin Gupta 
2953fea9c8bSAntonio Nino Diaz 	gicd_write_icpendr(base, id, (1U << bit_num));
296df373737SAchin Gupta }
297df373737SAchin Gupta 
298cbd3f370SJeenu Viswambharan unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
299cbd3f370SJeenu Viswambharan {
3003fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
301cbd3f370SJeenu Viswambharan 	unsigned int reg_val = gicd_read_isactiver(base, id);
302cbd3f370SJeenu Viswambharan 
3033fea9c8bSAntonio Nino Diaz 	return (reg_val >> bit_num) & 0x1U;
304cbd3f370SJeenu Viswambharan }
305cbd3f370SJeenu Viswambharan 
306df373737SAchin Gupta void gicd_set_isactiver(uintptr_t base, unsigned int id)
307df373737SAchin Gupta {
3083fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
309df373737SAchin Gupta 
3103fea9c8bSAntonio Nino Diaz 	gicd_write_isactiver(base, id, (1U << bit_num));
311df373737SAchin Gupta }
312df373737SAchin Gupta 
313df373737SAchin Gupta void gicd_set_icactiver(uintptr_t base, unsigned int id)
314df373737SAchin Gupta {
3153fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U);
316df373737SAchin Gupta 
3173fea9c8bSAntonio Nino Diaz 	gicd_write_icactiver(base, id, (1U << bit_num));
318df373737SAchin Gupta }
31938a78614SSoby Mathew 
32038a78614SSoby Mathew void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
32138a78614SSoby Mathew {
3223fea9c8bSAntonio Nino Diaz 	uint8_t val = pri & GIC_PRI_MASK;
3233fea9c8bSAntonio Nino Diaz 
3243fea9c8bSAntonio Nino Diaz 	mmio_write_8(base + GICD_IPRIORITYR + id, val);
32538a78614SSoby Mathew }
32622966106SJeenu Viswambharan 
32722966106SJeenu Viswambharan void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
32822966106SJeenu Viswambharan {
32917e84eedSJeenu Viswambharan 	/* Interrupt configuration is a 2-bit field */
3303fea9c8bSAntonio Nino Diaz 	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
33117e84eedSJeenu Viswambharan 	unsigned int bit_shift = bit_num << 1;
33217e84eedSJeenu Viswambharan 
33322966106SJeenu Viswambharan 	uint32_t reg_val = gicd_read_icfgr(base, id);
33422966106SJeenu Viswambharan 
33522966106SJeenu Viswambharan 	/* Clear the field, and insert required configuration */
33617e84eedSJeenu Viswambharan 	reg_val &= ~(GIC_CFG_MASK << bit_shift);
33717e84eedSJeenu Viswambharan 	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
33822966106SJeenu Viswambharan 
33922966106SJeenu Viswambharan 	gicd_write_icfgr(base, id, reg_val);
34022966106SJeenu Viswambharan }
341