xref: /OK3568_Linux_fs/u-boot/arch/arm/lib/gic_64.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/*
2*4882a593Smuzhiyun * GIC Initialization Routines.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * (C) Copyright 2013
5*4882a593Smuzhiyun * David Feng <fenghua@phytium.com.cn>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun#include <asm-offsets.h>
11*4882a593Smuzhiyun#include <config.h>
12*4882a593Smuzhiyun#include <linux/linkage.h>
13*4882a593Smuzhiyun#include <asm/gic.h>
14*4882a593Smuzhiyun#include <asm/macro.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun/*************************************************************************
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * void gic_init_secure(DistributorBase);
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * Initialize secure copy of GIC at EL3.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun *************************************************************************/
24*4882a593SmuzhiyunENTRY(gic_init_secure)
25*4882a593Smuzhiyun	/*
26*4882a593Smuzhiyun	 * Initialize Distributor
27*4882a593Smuzhiyun	 * x0: Distributor Base
28*4882a593Smuzhiyun	 */
29*4882a593Smuzhiyun#if defined(CONFIG_GICV3)
30*4882a593Smuzhiyun	mov	w9, #0x37		/* EnableGrp0 | EnableGrp1NS */
31*4882a593Smuzhiyun					/* EnableGrp1S | ARE_S | ARE_NS */
32*4882a593Smuzhiyun	str	w9, [x0, GICD_CTLR]	/* Secure GICD_CTLR */
33*4882a593Smuzhiyun	ldr	w9, [x0, GICD_TYPER]
34*4882a593Smuzhiyun	and	w10, w9, #0x1f		/* ITLinesNumber */
35*4882a593Smuzhiyun	cbz	w10, 1f			/* No SPIs */
36*4882a593Smuzhiyun	add	x11, x0, (GICD_IGROUPRn + 4)
37*4882a593Smuzhiyun	add	x12, x0, (GICD_IGROUPMODRn + 4)
38*4882a593Smuzhiyun	mov	w9, #~0
39*4882a593Smuzhiyun0:	str	w9, [x11], #0x4
40*4882a593Smuzhiyun	str	wzr, [x12], #0x4	/* Config SPIs as Group1NS */
41*4882a593Smuzhiyun	sub	w10, w10, #0x1
42*4882a593Smuzhiyun	cbnz	w10, 0b
43*4882a593Smuzhiyun#elif defined(CONFIG_GICV2)
44*4882a593Smuzhiyun	mov	w9, #0x3		/* EnableGrp0 | EnableGrp1 */
45*4882a593Smuzhiyun	str	w9, [x0, GICD_CTLR]	/* Secure GICD_CTLR */
46*4882a593Smuzhiyun	ldr	w9, [x0, GICD_TYPER]
47*4882a593Smuzhiyun	and	w10, w9, #0x1f		/* ITLinesNumber */
48*4882a593Smuzhiyun	cbz	w10, 1f			/* No SPIs */
49*4882a593Smuzhiyun	add	x11, x0, GICD_IGROUPRn
50*4882a593Smuzhiyun	mov	w9, #~0			/* Config SPIs as Grp1 */
51*4882a593Smuzhiyun	str	w9, [x11], #0x4
52*4882a593Smuzhiyun0:	str	w9, [x11], #0x4
53*4882a593Smuzhiyun	sub	w10, w10, #0x1
54*4882a593Smuzhiyun	cbnz	w10, 0b
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun	ldr	x1, =GICC_BASE		/* GICC_CTLR */
57*4882a593Smuzhiyun	mov	w0, #3			/* EnableGrp0 | EnableGrp1 */
58*4882a593Smuzhiyun	str	w0, [x1]
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun	mov	w0, #1 << 7		/* allow NS access to GICC_PMR */
61*4882a593Smuzhiyun	str	w0, [x1, #4]		/* GICC_PMR */
62*4882a593Smuzhiyun#endif
63*4882a593Smuzhiyun1:
64*4882a593Smuzhiyun	ret
65*4882a593SmuzhiyunENDPROC(gic_init_secure)
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun/*************************************************************************
69*4882a593Smuzhiyun * For Gicv2:
70*4882a593Smuzhiyun * void gic_init_secure_percpu(DistributorBase, CpuInterfaceBase);
71*4882a593Smuzhiyun * For Gicv3:
72*4882a593Smuzhiyun * void gic_init_secure_percpu(ReDistributorBase);
73*4882a593Smuzhiyun *
74*4882a593Smuzhiyun * Initialize secure copy of GIC at EL3.
75*4882a593Smuzhiyun *
76*4882a593Smuzhiyun *************************************************************************/
77*4882a593SmuzhiyunENTRY(gic_init_secure_percpu)
78*4882a593Smuzhiyun#if defined(CONFIG_GICV3)
79*4882a593Smuzhiyun	/*
80*4882a593Smuzhiyun	 * Initialize ReDistributor
81*4882a593Smuzhiyun	 * x0: ReDistributor Base
82*4882a593Smuzhiyun	 */
83*4882a593Smuzhiyun	mrs	x10, mpidr_el1
84*4882a593Smuzhiyun	lsr	x9, x10, #32
85*4882a593Smuzhiyun	bfi	x10, x9, #24, #8	/* w10 is aff3:aff2:aff1:aff0 */
86*4882a593Smuzhiyun	mov	x9, x0
87*4882a593Smuzhiyun1:	ldr	x11, [x9, GICR_TYPER]
88*4882a593Smuzhiyun	lsr	x11, x11, #32		/* w11 is aff3:aff2:aff1:aff0 */
89*4882a593Smuzhiyun	cmp	w10, w11
90*4882a593Smuzhiyun	b.eq	2f
91*4882a593Smuzhiyun	add	x9, x9, #(2 << 16)
92*4882a593Smuzhiyun	b	1b
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun	/* x9: ReDistributor Base Address of Current CPU */
95*4882a593Smuzhiyun2:	mov	w10, #~0x2
96*4882a593Smuzhiyun	ldr	w11, [x9, GICR_WAKER]
97*4882a593Smuzhiyun	and	w11, w11, w10		/* Clear ProcessorSleep */
98*4882a593Smuzhiyun	str	w11, [x9, GICR_WAKER]
99*4882a593Smuzhiyun	dsb	st
100*4882a593Smuzhiyun	isb
101*4882a593Smuzhiyun3:	ldr	w10, [x9, GICR_WAKER]
102*4882a593Smuzhiyun	tbnz	w10, #2, 3b		/* Wait Children be Alive */
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun	add	x10, x9, #(1 << 16)	/* SGI_Base */
105*4882a593Smuzhiyun	mov	w11, #~0
106*4882a593Smuzhiyun	str	w11, [x10, GICR_IGROUPRn]
107*4882a593Smuzhiyun	str	wzr, [x10, GICR_IGROUPMODRn]	/* SGIs|PPIs Group1NS */
108*4882a593Smuzhiyun	mov	w11, #0x1		/* Enable SGI 0 */
109*4882a593Smuzhiyun	str	w11, [x10, GICR_ISENABLERn]
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun#if CONFIG_IS_ENABLED(IRQ)
112*4882a593Smuzhiyun	/* Rockchip: check elx */
113*4882a593Smuzhiyun	switch_el x0, el3_sre, el2_sre, el1_sre
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun	/* Initialize Cpu Interface */
116*4882a593Smuzhiyunel3_sre:
117*4882a593Smuzhiyun	mrs	x10, ICC_SRE_EL3
118*4882a593Smuzhiyun	orr	x10, x10, #0xf		/* SRE & Disable IRQ/FIQ Bypass & */
119*4882a593Smuzhiyun					/* Allow EL2 access to ICC_SRE_EL2 */
120*4882a593Smuzhiyun	msr	ICC_SRE_EL3, x10
121*4882a593Smuzhiyun	isb
122*4882a593Smuzhiyun
123*4882a593Smuzhiyunel2_sre:
124*4882a593Smuzhiyun	mrs	x10, ICC_SRE_EL2
125*4882a593Smuzhiyun	orr	x10, x10, #0xf		/* SRE & Disable IRQ/FIQ Bypass & */
126*4882a593Smuzhiyun					/* Allow EL1 access to ICC_SRE_EL1 */
127*4882a593Smuzhiyun	msr	ICC_SRE_EL2, x10
128*4882a593Smuzhiyun	isb
129*4882a593Smuzhiyun
130*4882a593Smuzhiyunel1_sre:
131*4882a593Smuzhiyun	mrs	x0, CurrentEL		/* check currentEL */
132*4882a593Smuzhiyun	cmp	x0, 0xC
133*4882a593Smuzhiyun	b.ne	el1_ctlr		/* currentEL != EL3 */
134*4882a593Smuzhiyun
135*4882a593Smuzhiyunel3_ctlr:
136*4882a593Smuzhiyun	mov	x10, #0x3		/* EnableGrp1NS | EnableGrp1S */
137*4882a593Smuzhiyun	msr	ICC_IGRPEN1_EL3, x10
138*4882a593Smuzhiyun	isb
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun	msr	ICC_CTLR_EL3, xzr
141*4882a593Smuzhiyun	isb
142*4882a593Smuzhiyun
143*4882a593Smuzhiyunel1_ctlr:
144*4882a593Smuzhiyun	mov	x10, #0x3		/* EnableGrp1NS | EnableGrp1S */
145*4882a593Smuzhiyun	msr	ICC_IGRPEN1_EL1, x10
146*4882a593Smuzhiyun	isb
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun	msr	ICC_CTLR_EL1, xzr	/* NonSecure ICC_CTLR_EL1 */
149*4882a593Smuzhiyun	isb
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun	mov	x10, #0xf0		/* Non-Secure access to ICC_PMR_EL1 */
152*4882a593Smuzhiyun	msr	ICC_PMR_EL1, x10
153*4882a593Smuzhiyun	isb
154*4882a593Smuzhiyun#else
155*4882a593Smuzhiyun	/* Initialize Cpu Interface */
156*4882a593Smuzhiyun	mrs	x10, ICC_SRE_EL3
157*4882a593Smuzhiyun	orr	x10, x10, #0xf		/* SRE & Disable IRQ/FIQ Bypass & */
158*4882a593Smuzhiyun					/* Allow EL2 access to ICC_SRE_EL2 */
159*4882a593Smuzhiyun	msr	ICC_SRE_EL3, x10
160*4882a593Smuzhiyun	isb
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun	mrs	x10, ICC_SRE_EL2
163*4882a593Smuzhiyun	orr	x10, x10, #0xf		/* SRE & Disable IRQ/FIQ Bypass & */
164*4882a593Smuzhiyun					/* Allow EL1 access to ICC_SRE_EL1 */
165*4882a593Smuzhiyun	msr	ICC_SRE_EL2, x10
166*4882a593Smuzhiyun	isb
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun	mov	x10, #0x3		/* EnableGrp1NS | EnableGrp1S */
169*4882a593Smuzhiyun	msr	ICC_IGRPEN1_EL3, x10
170*4882a593Smuzhiyun	isb
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun	msr	ICC_CTLR_EL3, xzr
173*4882a593Smuzhiyun	isb
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun	msr	ICC_CTLR_EL1, xzr	/* NonSecure ICC_CTLR_EL1 */
176*4882a593Smuzhiyun	isb
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun	mov	x10, #0x1 << 7		/* Non-Secure access to ICC_PMR_EL1 */
179*4882a593Smuzhiyun	msr	ICC_PMR_EL1, x10
180*4882a593Smuzhiyun	isb
181*4882a593Smuzhiyun#endif
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun#elif defined(CONFIG_GICV2)
184*4882a593Smuzhiyun	/*
185*4882a593Smuzhiyun	 * Initialize SGIs and PPIs
186*4882a593Smuzhiyun	 * x0: Distributor Base
187*4882a593Smuzhiyun	 * x1: Cpu Interface Base
188*4882a593Smuzhiyun	 */
189*4882a593Smuzhiyun	mov	w9, #~0			/* Config SGIs and PPIs as Grp1 */
190*4882a593Smuzhiyun	str	w9, [x0, GICD_IGROUPRn]	/* GICD_IGROUPR0 */
191*4882a593Smuzhiyun	mov	w9, #0x1		/* Enable SGI 0 */
192*4882a593Smuzhiyun	str	w9, [x0, GICD_ISENABLERn]
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun	/* Initialize Cpu Interface */
195*4882a593Smuzhiyun	mov	w9, #0x1e7		/* Disable IRQ/FIQ Bypass & */
196*4882a593Smuzhiyun					/* Enable Ack Group1 Interrupt & */
197*4882a593Smuzhiyun					/* EnableGrp0 & EnableGrp1 */
198*4882a593Smuzhiyun	str	w9, [x1, GICC_CTLR]	/* Secure GICC_CTLR */
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun	mov	w9, #0x1 << 7		/* Non-Secure access to GICC_PMR */
201*4882a593Smuzhiyun	str	w9, [x1, GICC_PMR]
202*4882a593Smuzhiyun#endif
203*4882a593Smuzhiyun	ret
204*4882a593SmuzhiyunENDPROC(gic_init_secure_percpu)
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun/*************************************************************************
208*4882a593Smuzhiyun * For Gicv2:
209*4882a593Smuzhiyun * void gic_kick_secondary_cpus(DistributorBase);
210*4882a593Smuzhiyun * For Gicv3:
211*4882a593Smuzhiyun * void gic_kick_secondary_cpus(void);
212*4882a593Smuzhiyun *
213*4882a593Smuzhiyun *************************************************************************/
214*4882a593SmuzhiyunENTRY(gic_kick_secondary_cpus)
215*4882a593Smuzhiyun#if defined(CONFIG_GICV3)
216*4882a593Smuzhiyun	mov	x9, #(1 << 40)
217*4882a593Smuzhiyun	msr	ICC_ASGI1R_EL1, x9
218*4882a593Smuzhiyun	isb
219*4882a593Smuzhiyun#elif defined(CONFIG_GICV2)
220*4882a593Smuzhiyun	mov	w9, #0x8000
221*4882a593Smuzhiyun	movk	w9, #0x100, lsl #16
222*4882a593Smuzhiyun	str	w9, [x0, GICD_SGIR]
223*4882a593Smuzhiyun#endif
224*4882a593Smuzhiyun	ret
225*4882a593SmuzhiyunENDPROC(gic_kick_secondary_cpus)
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun/*************************************************************************
229*4882a593Smuzhiyun * For Gicv2:
230*4882a593Smuzhiyun * void gic_wait_for_interrupt(CpuInterfaceBase);
231*4882a593Smuzhiyun * For Gicv3:
232*4882a593Smuzhiyun * void gic_wait_for_interrupt(void);
233*4882a593Smuzhiyun *
234*4882a593Smuzhiyun * Wait for SGI 0 from master.
235*4882a593Smuzhiyun *
236*4882a593Smuzhiyun *************************************************************************/
237*4882a593SmuzhiyunENTRY(gic_wait_for_interrupt)
238*4882a593Smuzhiyun#if defined(CONFIG_GICV3)
239*4882a593Smuzhiyun	gic_wait_for_interrupt_m x9
240*4882a593Smuzhiyun#elif defined(CONFIG_GICV2)
241*4882a593Smuzhiyun	gic_wait_for_interrupt_m x0, w9
242*4882a593Smuzhiyun#endif
243*4882a593Smuzhiyun	ret
244*4882a593SmuzhiyunENDPROC(gic_wait_for_interrupt)
245