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 Reigsters
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 /*
220  * Common Helper Constants
221  */
222 #define GIC_SGI_INT_BASE		0
223 #define GIC_PPI_INT_BASE		16
224 
225 #define GIC_IS_SGI(intid)		(((intid) >= GIC_SGI_INT_BASE) && \
226 					 ((intid) < GIC_PPI_INT_BASE))
227 
228 
229 #define GIC_SPI_INT_BASE		32
230 
231 #define GIC_SPI_MAX_INTID		1019
232 
233 #define GIC_IS_SPI(intid)		(((intid) >= GIC_SPI_INT_BASE) && \
234 					((intid) <= GIC_SPI_MAX_INTID))
235 
236 #define GIC_NUM_INTR_PER_REG		32
237 
238 #define GIC_NUM_CFG_PER_REG		16
239 
240 #define GIC_NUM_PRI_PER_REG		4
241 
242 /* GIC idle priority : value '0xff' will allow all interrupts */
243 #define GIC_IDLE_PRIO			0xff
244 
245 /* Priority levels 0:255 */
246 #define GIC_PRI_MASK			0xff
247 
248 /*
249  * '0xa0'is used to initialize each interrtupt default priority.
250  * This is an arbitrary value in current context.
251  * Any value '0x80' to '0xff' will work for both NS and S state.
252  * The values of individual interrupt and default has to be chosen
253  * carefully if PMR and BPR based nesting and preemption has to be done.
254  */
255 #define GIC_INT_DEF_PRI_X4		0xa0a0a0a0
256 
257 /* GIC special interrupt id */
258 #define GIC_INTID_SPURIOUS		1023
259 
260 /* Fixme: update from platform specific define or dt */
261 #define GIC_NUM_CPU_IF			CONFIG_MP_NUM_CPUS
262 
263 #ifndef _ASMLANGUAGE
264 
265 #include <zephyr/types.h>
266 #include <device.h>
267 
268 /*
269  * GIC Driver Interface Functions
270  */
271 
272 /**
273  * @brief Enable interrupt
274  *
275  * @param irq interrupt ID
276  */
277 void arm_gic_irq_enable(unsigned int irq);
278 
279 /**
280  * @brief Disable interrupt
281  *
282  * @param irq interrupt ID
283  */
284 void arm_gic_irq_disable(unsigned int irq);
285 
286 /**
287  * @brief Check if an interrupt is enabled
288  *
289  * @param irq interrupt ID
290  * @return Returns true if interrupt is enabled, false otherwise
291  */
292 bool arm_gic_irq_is_enabled(unsigned int irq);
293 
294 /**
295  * @brief Set interrupt priority
296  *
297  * @param irq interrupt ID
298  * @param prio interrupt priority
299  * @param flags interrupt flags
300  */
301 void arm_gic_irq_set_priority(
302 	unsigned int irq, unsigned int prio, unsigned int flags);
303 
304 /**
305  * @brief Get active interrupt ID
306  *
307  * @return Returns the ID of an active interrupt
308  */
309 unsigned int arm_gic_get_active(void);
310 
311 /**
312  * @brief Signal end-of-interrupt
313  *
314  * @param irq interrupt ID
315  */
316 void arm_gic_eoi(unsigned int irq);
317 
318 #ifdef CONFIG_SMP
319 /**
320  * @brief Initialize GIC of secondary cores
321  */
322 void arm_gic_secondary_init(void);
323 #endif
324 
325 /**
326  * @brief raise SGI to target cores
327  *
328  * @param sgi_id      SGI ID 0 to 15
329  * @param target_aff  target affinity in mpidr form.
330  *                    Aff level 1 2 3 will be extracted by api.
331  * @param target_list bitmask of target cores
332  */
333 void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
334 		   uint16_t target_list);
335 
336 #endif /* !_ASMLANGUAGE */
337 
338 #endif /* ZEPHYR_INCLUDE_DRIVERS_GIC_H_ */
339