xref: /rk3399_ARM-atf/drivers/arm/gic/v3/gicrv3_helpers.c (revision 0a0a7a9ac82cb79af91f098cedc69cc67bca3978)
1 /*
2  * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch.h>
8 #include <arch_helpers.h>
9 #include <common/debug.h>
10 #include <common/interrupt_props.h>
11 #include <drivers/arm/gicv3.h>
12 #include "gicv3_private.h"
13 
14 /*******************************************************************************
15  * GIC Redistributor functions
16  * Note: The raw register values correspond to multiple interrupt IDs and
17  * the number of interrupt IDs involved depends on the register accessed.
18  ******************************************************************************/
19 
20 /*
21  * Accessor to read the GIC Redistributor IPRIORITYR corresponding to the
22  * interrupt `id`, 4 interrupts IDs at a time.
23  */
24 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
25 {
26 	unsigned int n = id >> IPRIORITYR_SHIFT;
27 
28 	return mmio_read_32(base + GICR_IPRIORITYR + (n << 2));
29 }
30 
31 /*
32  * Accessor to write the GIC Redistributor IPRIORITYR corresponding to the
33  * interrupt `id`, 4 interrupts IDs at a time.
34  */
35 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
36 {
37 	unsigned int n = id >> IPRIORITYR_SHIFT;
38 
39 	mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val);
40 }
41 
42 /*
43  * Accessor to set the byte corresponding to interrupt ID
44  * in GIC Redistributor IPRIORITYR.
45  */
46 void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
47 {
48 	GICR_WRITE_8(IPRIORITYR, base, id, pri & GIC_PRI_MASK);
49 }
50 
51 /*
52  * Accessor to get the bit corresponding to interrupt ID
53  * from GIC Redistributor IGROUPR0.
54  */
55 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id)
56 {
57 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
58 	unsigned int reg_val = gicr_read_igroupr0(base);
59 
60 	return (reg_val >> bit_num) & 0x1U;
61 }
62 
63 /*
64  * Accessor to set the bit corresponding to interrupt ID
65  * in GIC Redistributor IGROUPR0.
66  */
67 void gicr_set_igroupr0(uintptr_t base, unsigned int id)
68 {
69 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
70 	unsigned int reg_val = gicr_read_igroupr0(base);
71 
72 	gicr_write_igroupr0(base, reg_val | (1U << bit_num));
73 }
74 
75 /*
76  * Accessor to clear the bit corresponding to interrupt ID
77  * in GIC Redistributor IGROUPR0.
78  */
79 void gicr_clr_igroupr0(uintptr_t base, unsigned int id)
80 {
81 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
82 	unsigned int reg_val = gicr_read_igroupr0(base);
83 
84 	gicr_write_igroupr0(base, reg_val & ~(1U << bit_num));
85 }
86 
87 /*
88  * Accessor to get the bit corresponding to interrupt ID
89  * from GIC Redistributor IGRPMODR0.
90  */
91 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id)
92 {
93 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
94 	unsigned int reg_val = gicr_read_igrpmodr0(base);
95 
96 	return (reg_val >> bit_num) & 0x1U;
97 }
98 
99 /*
100  * Accessor to set the bit corresponding to interrupt ID
101  * in GIC Redistributor IGRPMODR0.
102  */
103 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id)
104 {
105 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
106 	unsigned int reg_val = gicr_read_igrpmodr0(base);
107 
108 	gicr_write_igrpmodr0(base, reg_val | (1U << bit_num));
109 }
110 
111 /*
112  * Accessor to clear the bit corresponding to interrupt ID
113  * in GIC Redistributor IGRPMODR0.
114  */
115 void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id)
116 {
117 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
118 	unsigned int reg_val = gicr_read_igrpmodr0(base);
119 
120 	gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num));
121 }
122 
123 /*
124  * Accessor to set the bit corresponding to interrupt ID
125  * in GIC Redistributor ISENABLER0.
126  */
127 void gicr_set_isenabler0(uintptr_t base, unsigned int id)
128 {
129 	unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
130 
131 	gicr_write_isenabler0(base, (1U << bit_num));
132 }
133 
134 /*
135  * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
136  * ICENABLER0.
137  */
138 void gicr_set_icenabler0(uintptr_t base, unsigned int id)
139 {
140 	unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
141 
142 	gicr_write_icenabler0(base, (1U << bit_num));
143 }
144 
145 /*
146  * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
147  * ISACTIVER0.
148  */
149 unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
150 {
151 	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
152 	unsigned int reg_val = gicr_read_isactiver0(base);
153 
154 	return (reg_val >> bit_num) & 0x1U;
155 }
156 
157 /*
158  * Accessor to clear the bit corresponding to interrupt ID in GIC Redistributor
159  * ICPENDRR0.
160  */
161 void gicr_set_icpendr0(uintptr_t base, unsigned int id)
162 {
163 	unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
164 
165 	gicr_write_icpendr0(base, (1U << bit_num));
166 }
167 
168 /*
169  * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
170  * ISPENDR0.
171  */
172 void gicr_set_ispendr0(uintptr_t base, unsigned int id)
173 {
174 	unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
175 
176 	gicr_write_ispendr0(base, (1U << bit_num));
177 }
178 
179 /*
180  * Accessor to set the bit fields corresponding to interrupt ID
181  * in GIC Redistributor ICFGR0.
182  */
183 void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
184 {
185 	/* Interrupt configuration is a 2-bit field */
186 	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
187 	unsigned int bit_shift = bit_num << 1U;
188 
189 	uint32_t reg_val = gicr_read_icfgr0(base);
190 
191 	/* Clear the field, and insert required configuration */
192 	reg_val &= ~(GIC_CFG_MASK << bit_shift);
193 	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
194 
195 	gicr_write_icfgr0(base, reg_val);
196 }
197 
198 /*
199  * Accessor to set the bit fields corresponding to interrupt ID
200  * in GIC Redistributor ICFGR1.
201  */
202 void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg)
203 {
204 	/* Interrupt configuration is a 2-bit field */
205 	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
206 	unsigned int bit_shift = bit_num << 1U;
207 
208 	uint32_t reg_val = gicr_read_icfgr1(base);
209 
210 	/* Clear the field, and insert required configuration */
211 	reg_val &= ~(GIC_CFG_MASK << bit_shift);
212 	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
213 
214 	gicr_write_icfgr1(base, reg_val);
215 }
216