1 /*
2  * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Driver for ARM Generic Interrupt Controller
10  *
11  * The Generic Interrupt Controller (GIC) is the default interrupt controller
12  * for the ARM A and R profile cores.  This driver is used by the ARM arch
13  * implementation to handle interrupts.
14  */
15 
16 #ifndef ZEPHYR_INCLUDE_DRIVERS_GIC_H_
17 #define ZEPHYR_INCLUDE_DRIVERS_GIC_H_
18 
19 /*
20  * GIC Register Interface Base Addresses
21  */
22 
23 #define GIC_DIST_BASE	DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0)
24 #define GIC_CPU_BASE	DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1)
25 
26 /*
27  * GIC Distributor Interface
28  */
29 
30 /*
31  * 0x000  Distributor Control Register
32  * v1		ICDDCR
33  * v2/v3	GICD_CTLR
34  */
35 #define	GICD_CTLR		(GIC_DIST_BASE +   0x0)
36 
37 /*
38  * 0x004  Interrupt Controller Type Register
39  * v1		ICDICTR
40  * v2/v3	GICD_TYPER
41  */
42 #define	GICD_TYPER		(GIC_DIST_BASE +   0x4)
43 
44 /*
45  * 0x008  Distributor Implementer Identification Register
46  * v1		ICDIIDR
47  * v2/v3	GICD_IIDR
48  */
49 #define	GICD_IIDR		(GIC_DIST_BASE +   0x8)
50 
51 /*
52  * 0x080  Interrupt Group Registers
53  * v1		ICDISRn
54  * v2/v3	GICD_IGROUPRn
55  */
56 #define	GICD_IGROUPRn		(GIC_DIST_BASE +  0x80)
57 
58 /*
59  * 0x100  Interrupt Set-Enable Registers
60  * v1		ICDISERn
61  * v2/v3	GICD_ISENABLERn
62  */
63 #define	GICD_ISENABLERn		(GIC_DIST_BASE + 0x100)
64 
65 /*
66  * 0x180  Interrupt Clear-Enable Registers
67  * v1		ICDICERn
68  * v2/v3	GICD_ICENABLERn
69  */
70 #define	GICD_ICENABLERn		(GIC_DIST_BASE + 0x180)
71 
72 /*
73  * 0x200  Interrupt Set-Pending Registers
74  * v1		ICDISPRn
75  * v2/v3	GICD_ISPENDRn
76  */
77 #define	GICD_ISPENDRn		(GIC_DIST_BASE + 0x200)
78 
79 /*
80  * 0x280  Interrupt Clear-Pending Registers
81  * v1		ICDICPRn
82  * v2/v3	GICD_ICPENDRn
83  */
84 #define	GICD_ICPENDRn		(GIC_DIST_BASE + 0x280)
85 
86 /*
87  * 0x300  Interrupt Set-Active Registers
88  * v1		ICDABRn
89  * v2/v3	GICD_ISACTIVERn
90  */
91 #define	GICD_ISACTIVERn		(GIC_DIST_BASE + 0x300)
92 
93 #if CONFIG_GIC_VER >= 2
94 /*
95  * 0x380  Interrupt Clear-Active Registers
96  * v2/v3	GICD_ICACTIVERn
97  */
98 #define	GICD_ICACTIVERn		(GIC_DIST_BASE + 0x380)
99 #endif
100 
101 /*
102  * 0x400  Interrupt Priority Registers
103  * v1		ICDIPRn
104  * v2/v3	GICD_IPRIORITYRn
105  */
106 #define	GICD_IPRIORITYRn	(GIC_DIST_BASE + 0x400)
107 
108 /*
109  * 0x800  Interrupt Processor Targets Registers
110  * v1		ICDIPTRn
111  * v2/v3	GICD_ITARGETSRn
112  */
113 #define	GICD_ITARGETSRn		(GIC_DIST_BASE + 0x800)
114 
115 /*
116  * 0xC00  Interrupt Configuration Registers
117  * v1		ICDICRn
118  * v2/v3	GICD_ICFGRn
119  */
120 #define	GICD_ICFGRn		(GIC_DIST_BASE + 0xc00)
121 
122 /*
123  * 0xF00  Software Generated Interrupt Register
124  * v1		ICDSGIR
125  * v2/v3	GICD_SGIR
126  */
127 #define	GICD_SGIR		(GIC_DIST_BASE + 0xf00)
128 
129 /*
130  * GIC CPU Interface
131  */
132 
133 #if CONFIG_GIC_VER <= 2
134 
135 /*
136  * 0x0000  CPU Interface Control Register
137  * v1		ICCICR
138  * v2/v3	GICC_CTLR
139  */
140 #define GICC_CTLR		(GIC_CPU_BASE +    0x0)
141 
142 /*
143  * 0x0004  Interrupt Priority Mask Register
144  * v1		ICCPMR
145  * v2/v3	GICC_PMR
146  */
147 #define GICC_PMR		(GIC_CPU_BASE +    0x4)
148 
149 /*
150  * 0x0008  Binary Point Register
151  * v1		ICCBPR
152  * v2/v3	GICC_BPR
153  */
154 #define GICC_BPR		(GIC_CPU_BASE +    0x8)
155 
156 /*
157  * 0x000C  Interrupt Acknowledge Register
158  * v1		ICCIAR
159  * v2/v3	GICC_IAR
160  */
161 #define GICC_IAR		(GIC_CPU_BASE +    0xc)
162 
163 /*
164  * 0x0010  End of Interrupt Register
165  * v1		ICCEOIR
166  * v2/v3	GICC_EOIR
167  */
168 #define GICC_EOIR		(GIC_CPU_BASE +   0x10)
169 
170 
171 /*
172  * Helper Constants
173  */
174 
175 /* GICC_CTLR */
176 #define GICC_CTLR_ENABLEGRP0	BIT(0)
177 #define GICC_CTLR_ENABLEGRP1	BIT(1)
178 
179 #define GICC_CTLR_ENABLE_MASK	(GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1)
180 
181 #if defined(CONFIG_GIC_V2)
182 
183 #define GICC_CTLR_FIQBYPDISGRP0	BIT(5)
184 #define GICC_CTLR_IRQBYPDISGRP0	BIT(6)
185 #define GICC_CTLR_FIQBYPDISGRP1	BIT(7)
186 #define GICC_CTLR_IRQBYPDISGRP1	BIT(8)
187 
188 #define GICC_CTLR_BYPASS_MASK	(GICC_CTLR_FIQBYPDISGRP0 | \
189 				 GICC_CTLR_IRQBYPDISGRP1 | \
190 				 GICC_CTLR_FIQBYPDISGRP1 | \
191 				 GICC_CTLR_IRQBYPDISGRP1)
192 
193 #endif /* CONFIG_GIC_V2 */
194 
195 /* GICD_SGIR */
196 #define GICD_SGIR_TGTFILT(x)		((x) << 24)
197 #define GICD_SGIR_TGTFILT_CPULIST	GICD_SGIR_TGTFILT(0b00)
198 #define GICD_SGIR_TGTFILT_ALLBUTREQ	GICD_SGIR_TGTFILT(0b01)
199 #define GICD_SGIR_TGTFILT_REQONLY	GICD_SGIR_TGTFILT(0b10)
200 
201 #define GICD_SGIR_CPULIST(x)		((x) << 16)
202 #define GICD_SGIR_CPULIST_CPU(n)	GICD_SGIR_CPULIST(BIT(n))
203 #define GICD_SGIR_CPULIST_MASK		0xff
204 
205 #define GICD_SGIR_NSATT			BIT(15)
206 
207 #define GICD_SGIR_SGIINTID(x)		(x)
208 
209 #endif /* CONFIG_GIC_VER <= 2 */
210 
211 
212 /* GICD_ICFGR */
213 #define GICD_ICFGR_MASK			BIT_MASK(2)
214 #define GICD_ICFGR_TYPE			BIT(1)
215 
216 /* GICD_TYPER.ITLinesNumber 0:4 */
217 #define GICD_TYPER_ITLINESNUM_MASK	0x1f
218 
219 /* GICD_TYPER.IDbits */
220 #define GICD_TYPER_IDBITS(typer)	((((typer) >> 19) & 0x1f) + 1)
221 
222 /*
223  * Common Helper Constants
224  */
225 #define GIC_SGI_INT_BASE		0
226 #define GIC_PPI_INT_BASE		16
227 
228 #define GIC_IS_SGI(intid)		(((intid) >= GIC_SGI_INT_BASE) && \
229 					 ((intid) < GIC_PPI_INT_BASE))
230 
231 
232 #define GIC_SPI_INT_BASE		32
233 
234 #define GIC_SPI_MAX_INTID		1019
235 
236 #define GIC_IS_SPI(intid)		(((intid) >= GIC_SPI_INT_BASE) && \
237 					((intid) <= GIC_SPI_MAX_INTID))
238 
239 #define GIC_NUM_INTR_PER_REG		32
240 
241 #define GIC_NUM_CFG_PER_REG		16
242 
243 #define GIC_NUM_PRI_PER_REG		4
244 
245 /* GIC idle priority : value '0xff' will allow all interrupts */
246 #define GIC_IDLE_PRIO			0xff
247 
248 /* Priority levels 0:255 */
249 #define GIC_PRI_MASK			0xff
250 
251 /*
252  * '0xa0'is used to initialize each interrupt default priority.
253  * This is an arbitrary value in current context.
254  * Any value '0x80' to '0xff' will work for both NS and S state.
255  * The values of individual interrupt and default has to be chosen
256  * carefully if PMR and BPR based nesting and preemption has to be done.
257  */
258 #define GIC_INT_DEF_PRI_X4		0xa0a0a0a0
259 
260 /* GIC special interrupt id */
261 #define GIC_INTID_SPURIOUS		1023
262 
263 /* Fixme: update from platform specific define or dt */
264 #define GIC_NUM_CPU_IF			CONFIG_MP_MAX_NUM_CPUS
265 
266 #ifndef _ASMLANGUAGE
267 
268 #include <zephyr/types.h>
269 #include <zephyr/device.h>
270 
271 /*
272  * GIC Driver Interface Functions
273  */
274 
275 /**
276  * @brief Enable interrupt
277  *
278  * @param irq interrupt ID
279  */
280 void arm_gic_irq_enable(unsigned int irq);
281 
282 /**
283  * @brief Disable interrupt
284  *
285  * @param irq interrupt ID
286  */
287 void arm_gic_irq_disable(unsigned int irq);
288 
289 /**
290  * @brief Check if an interrupt is enabled
291  *
292  * @param irq interrupt ID
293  * @return Returns true if interrupt is enabled, false otherwise
294  */
295 bool arm_gic_irq_is_enabled(unsigned int irq);
296 
297 /**
298  * @brief Check if an interrupt is pending
299  *
300  * @param irq interrupt ID
301  * @return Returns true if interrupt is pending, false otherwise
302  */
303 bool arm_gic_irq_is_pending(unsigned int irq);
304 
305 /**
306  * @brief Clear the pending irq
307  *
308  * @param irq interrupt ID
309  */
310 void arm_gic_irq_clear_pending(unsigned int irq);
311 
312 /**
313  * @brief Set interrupt priority
314  *
315  * @param irq interrupt ID
316  * @param prio interrupt priority
317  * @param flags interrupt flags
318  */
319 void arm_gic_irq_set_priority(
320 	unsigned int irq, unsigned int prio, unsigned int flags);
321 
322 /**
323  * @brief Get active interrupt ID
324  *
325  * @return Returns the ID of an active interrupt
326  */
327 unsigned int arm_gic_get_active(void);
328 
329 /**
330  * @brief Signal end-of-interrupt
331  *
332  * @param irq interrupt ID
333  */
334 void arm_gic_eoi(unsigned int irq);
335 
336 #ifdef CONFIG_SMP
337 /**
338  * @brief Initialize GIC of secondary cores
339  */
340 void arm_gic_secondary_init(void);
341 #endif
342 
343 /**
344  * @brief raise SGI to target cores
345  *
346  * @param sgi_id      SGI ID 0 to 15
347  * @param target_aff  target affinity in mpidr form.
348  *                    Aff level 1 2 3 will be extracted by api.
349  * @param target_list bitmask of target cores
350  */
351 void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
352 		   uint16_t target_list);
353 
354 #endif /* !_ASMLANGUAGE */
355 
356 #endif /* ZEPHYR_INCLUDE_DRIVERS_GIC_H_ */
357