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