1 /*
2  * Copyright (c) 2018 Marvell
3  * Copyright (c) 2018 Lexmark International, Inc.
4  * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 /*
10  * NOTE: This driver implements the GICv1 and GICv2 interfaces.
11  */
12 
13 #include <devicetree.h>
14 #include <sw_isr_table.h>
15 #include <dt-bindings/interrupt-controller/arm-gic.h>
16 #include <drivers/interrupt_controller/gic.h>
17 
18 #define CPU_REG_ID(cpu_node_id) DT_REG_ADDR(cpu_node_id),
19 static const uint64_t cpu_mpid_list[] = {
20 	DT_FOREACH_CHILD_STATUS_OKAY(DT_PATH(cpus), CPU_REG_ID)
21 };
22 
23 BUILD_ASSERT(ARRAY_SIZE(cpu_mpid_list) >= CONFIG_MP_NUM_CPUS,
24 		"The count of CPU Cores nodes in dts is less than CONFIG_MP_NUM_CPUS\n");
25 
arm_gic_irq_enable(unsigned int irq)26 void arm_gic_irq_enable(unsigned int irq)
27 {
28 	int int_grp, int_off;
29 
30 	int_grp = irq / 32;
31 	int_off = irq % 32;
32 
33 	sys_write32((1 << int_off), (GICD_ISENABLERn + int_grp * 4));
34 }
35 
arm_gic_irq_disable(unsigned int irq)36 void arm_gic_irq_disable(unsigned int irq)
37 {
38 	int int_grp, int_off;
39 
40 	int_grp = irq / 32;
41 	int_off = irq % 32;
42 
43 	sys_write32((1 << int_off), (GICD_ICENABLERn + int_grp * 4));
44 }
45 
arm_gic_irq_is_enabled(unsigned int irq)46 bool arm_gic_irq_is_enabled(unsigned int irq)
47 {
48 	int int_grp, int_off;
49 	unsigned int enabler;
50 
51 	int_grp = irq / 32;
52 	int_off = irq % 32;
53 
54 	enabler = sys_read32(GICD_ISENABLERn + int_grp * 4);
55 
56 	return (enabler & (1 << int_off)) != 0;
57 }
58 
arm_gic_irq_set_priority(unsigned int irq,unsigned int prio,uint32_t flags)59 void arm_gic_irq_set_priority(
60 	unsigned int irq, unsigned int prio, uint32_t flags)
61 {
62 	int int_grp, int_off;
63 	uint32_t val;
64 
65 	/* Set priority */
66 	sys_write8(prio & 0xff, GICD_IPRIORITYRn + irq);
67 
68 	/* Set interrupt type */
69 	int_grp = (irq / 16) * 4;
70 	int_off = (irq % 16) * 2;
71 
72 	val = sys_read32(GICD_ICFGRn + int_grp);
73 	val &= ~(GICD_ICFGR_MASK << int_off);
74 	if (flags & IRQ_TYPE_EDGE) {
75 		val |= (GICD_ICFGR_TYPE << int_off);
76 	}
77 
78 	sys_write32(val, GICD_ICFGRn + int_grp);
79 }
80 
arm_gic_get_active(void)81 unsigned int arm_gic_get_active(void)
82 {
83 	int irq;
84 
85 	irq = sys_read32(GICC_IAR) & 0x3ff;
86 	return irq;
87 }
88 
arm_gic_eoi(unsigned int irq)89 void arm_gic_eoi(unsigned int irq)
90 {
91 	/*
92 	 * Ensure the write to peripheral registers are *complete* before the write
93 	 * to GIC_EOIR.
94 	 *
95 	 * Note: The completion gurantee depends on various factors of system design
96 	 * and the barrier is the best core can do by which execution of further
97 	 * instructions waits till the barrier is alive.
98 	 */
99 	__DSB();
100 
101 	/* set to inactive */
102 	sys_write32(irq, GICC_EOIR);
103 }
104 
gic_raise_sgi(unsigned int sgi_id,uint64_t target_aff,uint16_t target_list)105 void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
106 		uint16_t target_list)
107 {
108 	uint32_t sgi_val;
109 
110 	ARG_UNUSED(target_aff);
111 
112 	sgi_val = GICD_SGIR_TGTFILT_CPULIST |
113 		GICD_SGIR_CPULIST(target_list & GICD_SGIR_CPULIST_MASK) |
114 		sgi_id;
115 
116 	__DSB();
117 	sys_write32(sgi_val, GICD_SGIR);
118 	__ISB();
119 }
120 
gic_dist_init(void)121 static void gic_dist_init(void)
122 {
123 	unsigned int gic_irqs, i;
124 	uint8_t cpu_mask = 0;
125 	uint32_t reg_val;
126 
127 	gic_irqs = sys_read32(GICD_TYPER) & 0x1f;
128 	gic_irqs = (gic_irqs + 1) * 32;
129 	if (gic_irqs > 1020) {
130 		gic_irqs = 1020;
131 	}
132 
133 	/*
134 	 * Disable the forwarding of pending interrupts
135 	 * from the Distributor to the CPU interfaces
136 	 */
137 	sys_write32(0, GICD_CTLR);
138 
139 	/*
140 	 * Enable all global interrupts distributing to CPUs listed
141 	 * in dts with the count of CONFIG_MP_NUM_CPUS.
142 	 */
143 	for (i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
144 		cpu_mask |= BIT(cpu_mpid_list[i]);
145 	}
146 	reg_val = cpu_mask | (cpu_mask << 8) | (cpu_mask << 16)
147 		| (cpu_mask << 24);
148 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 4) {
149 		sys_write32(reg_val, GICD_ITARGETSRn + i);
150 	}
151 
152 	/*
153 	 * Set all global interrupts to be level triggered, active low.
154 	 */
155 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 16) {
156 		sys_write32(0, GICD_ICFGRn + i / 4);
157 	}
158 
159 	/*  Set priority on all global interrupts.   */
160 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 4) {
161 		sys_write32(0, GICD_IPRIORITYRn + i);
162 	}
163 
164 	/* Set all interrupts to group 0 */
165 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 32) {
166 		sys_write32(0, GICD_IGROUPRn + i / 8);
167 	}
168 
169 	/*
170 	 * Disable all interrupts.  Leave the PPI and SGIs alone
171 	 * as these enables are banked registers.
172 	 */
173 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 32) {
174 #ifndef CONFIG_GIC_V1
175 		sys_write32(0xffffffff, GICD_ICACTIVERn + i / 8);
176 #endif
177 		sys_write32(0xffffffff, GICD_ICENABLERn + i / 8);
178 	}
179 
180 	/*
181 	 * Enable the forwarding of pending interrupts
182 	 * from the Distributor to the CPU interfaces
183 	 */
184 	sys_write32(1, GICD_CTLR);
185 }
186 
gic_cpu_init(void)187 static void gic_cpu_init(void)
188 {
189 	int i;
190 	uint32_t val;
191 
192 	/*
193 	 * Deal with the banked PPI and SGI interrupts - disable all
194 	 * PPI interrupts, ensure all SGI interrupts are enabled.
195 	 */
196 #ifndef CONFIG_GIC_V1
197 	sys_write32(0xffffffff, GICD_ICACTIVERn);
198 #endif
199 	sys_write32(0xffff0000, GICD_ICENABLERn);
200 	sys_write32(0x0000ffff, GICD_ISENABLERn);
201 
202 	/*
203 	 * Set priority on PPI and SGI interrupts
204 	 */
205 	for (i = 0; i < 32; i += 4) {
206 		sys_write32(0xa0a0a0a0, GICD_IPRIORITYRn + i);
207 	}
208 
209 	sys_write32(0xf0, GICC_PMR);
210 
211 	/*
212 	 * Enable interrupts and signal them using the IRQ signal.
213 	 */
214 	val = sys_read32(GICC_CTLR);
215 #ifndef CONFIG_GIC_V1
216 	val &= ~GICC_CTLR_BYPASS_MASK;
217 #endif
218 	val |= GICC_CTLR_ENABLE_MASK;
219 	sys_write32(val, GICC_CTLR);
220 }
221 
222 /**
223  *
224  * @brief Initialize the GIC device driver
225  *
226  *
227  * @return N/A
228  */
229 #define GIC_PARENT_IRQ 0
230 #define GIC_PARENT_IRQ_PRI 0
231 #define GIC_PARENT_IRQ_FLAGS 0
arm_gic_init(const struct device * unused)232 int arm_gic_init(const struct device *unused)
233 {
234 	ARG_UNUSED(unused);
235 
236 	/* Init of Distributor interface registers */
237 	gic_dist_init();
238 
239 	/* Init CPU interface registers */
240 	gic_cpu_init();
241 
242 	return 0;
243 }
244 
245 SYS_INIT(arm_gic_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
246 
247 #ifdef CONFIG_SMP
arm_gic_secondary_init(void)248 void arm_gic_secondary_init(void)
249 {
250 	/* Init CPU interface registers for each secondary core */
251 	gic_cpu_init();
252 }
253 #endif
254