xref: /rk3399_ARM-atf/plat/nxp/soc-ls1046a/aarch64/ls1046a.S (revision 1b33b58b665e5ab5e179b8ee1b71f5412b721e42)
1*cc708597SJiafei Pan/*
2*cc708597SJiafei Pan * Copyright 2020-2022 NXP
3*cc708597SJiafei Pan *
4*cc708597SJiafei Pan * SPDX-License-Identifier: BSD-3-Clause
5*cc708597SJiafei Pan *
6*cc708597SJiafei Pan */
7*cc708597SJiafei Pan
8*cc708597SJiafei Pan#include <asm_macros.S>
9*cc708597SJiafei Pan#include <dcfg_lsch2.h>
10*cc708597SJiafei Pan#include <nxp_timer.h>
11*cc708597SJiafei Pan#include <plat_gic.h>
12*cc708597SJiafei Pan#include <scfg.h>
13*cc708597SJiafei Pan
14*cc708597SJiafei Pan#include <bl31_data.h>
15*cc708597SJiafei Pan#include <plat_psci.h>
16*cc708597SJiafei Pan#include <platform_def.h>
17*cc708597SJiafei Pan
18*cc708597SJiafei Pan#define DAIF_DATA		AUX_01_DATA
19*cc708597SJiafei Pan#define TIMER_CNTRL_DATA	AUX_02_DATA
20*cc708597SJiafei Pan
21*cc708597SJiafei Pan.global soc_init_lowlevel
22*cc708597SJiafei Pan.global soc_init_percpu
23*cc708597SJiafei Pan.global _soc_core_release
24*cc708597SJiafei Pan.global _soc_core_restart
25*cc708597SJiafei Pan.global _soc_ck_disabled
26*cc708597SJiafei Pan.global _soc_sys_reset
27*cc708597SJiafei Pan.global _soc_sys_off
28*cc708597SJiafei Pan.global _soc_set_start_addr
29*cc708597SJiafei Pan.global _getGICC_BaseAddr
30*cc708597SJiafei Pan.global _getGICD_BaseAddr
31*cc708597SJiafei Pan.global _soc_core_prep_off
32*cc708597SJiafei Pan.global _soc_core_entr_off
33*cc708597SJiafei Pan.global _soc_core_exit_off
34*cc708597SJiafei Pan.global _soc_core_prep_stdby
35*cc708597SJiafei Pan.global _soc_core_entr_stdby
36*cc708597SJiafei Pan.global _soc_core_exit_stdby
37*cc708597SJiafei Pan.global _soc_core_prep_pwrdn
38*cc708597SJiafei Pan.global _soc_core_entr_pwrdn
39*cc708597SJiafei Pan.global _soc_core_exit_pwrdn
40*cc708597SJiafei Pan.global _soc_clstr_prep_stdby
41*cc708597SJiafei Pan.global _soc_clstr_exit_stdby
42*cc708597SJiafei Pan.global _soc_clstr_prep_pwrdn
43*cc708597SJiafei Pan.global _soc_clstr_exit_pwrdn
44*cc708597SJiafei Pan.global _soc_sys_prep_stdby
45*cc708597SJiafei Pan.global _soc_sys_exit_stdby
46*cc708597SJiafei Pan.global _soc_sys_prep_pwrdn
47*cc708597SJiafei Pan.global _soc_sys_pwrdn_wfi
48*cc708597SJiafei Pan.global _soc_sys_exit_pwrdn
49*cc708597SJiafei Pan
50*cc708597SJiafei Pan
51*cc708597SJiafei Pan/* This function initialize the soc
52*cc708597SJiafei Pan * in: void
53*cc708597SJiafei Pan * out: void
54*cc708597SJiafei Pan */
55*cc708597SJiafei Panfunc soc_init_lowlevel
56*cc708597SJiafei Pan    ret
57*cc708597SJiafei Panendfunc soc_init_lowlevel
58*cc708597SJiafei Pan
59*cc708597SJiafei Pan
60*cc708597SJiafei Pan/* void soc_init_percpu(void)
61*cc708597SJiafei Pan * this function performs any soc-specific initialization that is needed on
62*cc708597SJiafei Pan * a per-core basis
63*cc708597SJiafei Pan * in:  none
64*cc708597SJiafei Pan * out: none
65*cc708597SJiafei Pan * uses x0, x1, x2, x3
66*cc708597SJiafei Pan */
67*cc708597SJiafei Panfunc soc_init_percpu
68*cc708597SJiafei Pan	mov	x3, x30
69*cc708597SJiafei Pan
70*cc708597SJiafei Pan	bl	plat_my_core_mask
71*cc708597SJiafei Pan	mov	x2, x0
72*cc708597SJiafei Pan
73*cc708597SJiafei Pan	/* see if this core is marked for prefetch disable */
74*cc708597SJiafei Pan	mov	x0, #PREFETCH_DIS_OFFSET
75*cc708597SJiafei Pan	bl	_get_global_data  /* 0-1 */
76*cc708597SJiafei Pan	tst	x0, x2
77*cc708597SJiafei Pan	b.eq	1f
78*cc708597SJiafei Pan	bl	_disable_ldstr_pfetch_A72  /* 0 */
79*cc708597SJiafei Pan1:
80*cc708597SJiafei Pan	mov	x30, x3
81*cc708597SJiafei Pan	ret
82*cc708597SJiafei Panendfunc soc_init_percpu
83*cc708597SJiafei Pan
84*cc708597SJiafei Pan/* part of CPU_ON
85*cc708597SJiafei Pan * this function releases a secondary core from reset
86*cc708597SJiafei Pan * in:   x0 = core_mask_lsb
87*cc708597SJiafei Pan * out:  none
88*cc708597SJiafei Pan * uses: x0, x1, x2, x3
89*cc708597SJiafei Pan */
90*cc708597SJiafei Panfunc _soc_core_release
91*cc708597SJiafei Pan
92*cc708597SJiafei Pan#if (TEST_BL31)
93*cc708597SJiafei Pan	rbit	w2, w0
94*cc708597SJiafei Pan	/* x2 = core mask msb */
95*cc708597SJiafei Pan#else
96*cc708597SJiafei Pan	mov	x2, x0
97*cc708597SJiafei Pan#endif
98*cc708597SJiafei Pan	/* write COREBCR */
99*cc708597SJiafei Pan	mov	x1, #NXP_SCFG_ADDR
100*cc708597SJiafei Pan	rev	w3, w2
101*cc708597SJiafei Pan	str	w3, [x1, #SCFG_COREBCR_OFFSET]
102*cc708597SJiafei Pan	isb
103*cc708597SJiafei Pan
104*cc708597SJiafei Pan	/* read-modify-write BRR */
105*cc708597SJiafei Pan	mov	x1, #NXP_DCFG_ADDR
106*cc708597SJiafei Pan	ldr	w2, [x1, #DCFG_BRR_OFFSET]
107*cc708597SJiafei Pan	rev	w3, w2
108*cc708597SJiafei Pan	orr	w3, w3, w0
109*cc708597SJiafei Pan	rev	w2, w3
110*cc708597SJiafei Pan	str	w2, [x1, #DCFG_BRR_OFFSET]
111*cc708597SJiafei Pan	isb
112*cc708597SJiafei Pan
113*cc708597SJiafei Pan	/* send event */
114*cc708597SJiafei Pan	sev
115*cc708597SJiafei Pan	isb
116*cc708597SJiafei Pan	ret
117*cc708597SJiafei Panendfunc _soc_core_release
118*cc708597SJiafei Pan
119*cc708597SJiafei Pan
120*cc708597SJiafei Pan/* part of CPU_ON
121*cc708597SJiafei Pan * this function restarts a core shutdown via _soc_core_entr_off
122*cc708597SJiafei Pan * in:  x0 = core mask lsb (of the target cpu)
123*cc708597SJiafei Pan * out: x0 == 0, on success
124*cc708597SJiafei Pan *      x0 != 0, on failure
125*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5
126*cc708597SJiafei Pan */
127*cc708597SJiafei Panfunc _soc_core_restart
128*cc708597SJiafei Pan	mov	x5, x30
129*cc708597SJiafei Pan	mov	x3, x0
130*cc708597SJiafei Pan
131*cc708597SJiafei Pan	/*
132*cc708597SJiafei Pan	 * unset ph20 request in RCPM_PCPH20CLEARR
133*cc708597SJiafei Pan	 * this is an lsb-0 register
134*cc708597SJiafei Pan	 */
135*cc708597SJiafei Pan	ldr	x1, =NXP_RCPM_ADDR
136*cc708597SJiafei Pan	rev	w2, w3
137*cc708597SJiafei Pan	str	w2, [x1, #RCPM_PCPH20CLRR_OFFSET]
138*cc708597SJiafei Pan	dsb	sy
139*cc708597SJiafei Pan	isb
140*cc708597SJiafei Pan
141*cc708597SJiafei Pan	bl	_getGICD_BaseAddr
142*cc708597SJiafei Pan	mov	x4, x0
143*cc708597SJiafei Pan
144*cc708597SJiafei Pan	/* enable forwarding of group 0 interrupts by setting GICD_CTLR[0] = 1 */
145*cc708597SJiafei Pan	ldr	w1, [x4, #GICD_CTLR_OFFSET]
146*cc708597SJiafei Pan	orr	w1, w1, #GICD_CTLR_EN_GRP0
147*cc708597SJiafei Pan	str	w1, [x4, #GICD_CTLR_OFFSET]
148*cc708597SJiafei Pan	dsb	sy
149*cc708597SJiafei Pan	isb
150*cc708597SJiafei Pan
151*cc708597SJiafei Pan
152*cc708597SJiafei Pan	/*
153*cc708597SJiafei Pan	 * fire SGI by writing to GICD_SGIR the following values:
154*cc708597SJiafei Pan	 * [25:24] = 0x0 (forward interrupt to the CPU interfaces
155*cc708597SJiafei Pan	 *           specified in CPUTargetList field)
156*cc708597SJiafei Pan	 * [23:16] = core mask lsb[7:0] (forward interrupt to target cpu)
157*cc708597SJiafei Pan	 * [15]    = 0 (forward SGI only if it is configured as group 0 interrupt)
158*cc708597SJiafei Pan	 * [3:0]   = 0xF (interrupt ID = 15)
159*cc708597SJiafei Pan	 */
160*cc708597SJiafei Pan	lsl	w1, w3, #16
161*cc708597SJiafei Pan	orr	w1, w1, #0xF
162*cc708597SJiafei Pan	str	w1, [x4, #GICD_SGIR_OFFSET]
163*cc708597SJiafei Pan	dsb	sy
164*cc708597SJiafei Pan	isb
165*cc708597SJiafei Pan
166*cc708597SJiafei Pan	/* load '0' on success */
167*cc708597SJiafei Pan	mov	x0, xzr
168*cc708597SJiafei Pan
169*cc708597SJiafei Pan	mov	x30, x5
170*cc708597SJiafei Pan	ret
171*cc708597SJiafei Panendfunc _soc_core_restart
172*cc708597SJiafei Pan
173*cc708597SJiafei Pan/*
174*cc708597SJiafei Pan * This function determines if a core is disabled via COREDISR
175*cc708597SJiafei Pan * in:  w0  = core_mask_lsb
176*cc708597SJiafei Pan * out: w0  = 0, core not disabled
177*cc708597SJiafei Pan *      w0 != 0, core disabled
178*cc708597SJiafei Pan * uses x0, x1, x2
179*cc708597SJiafei Pan */
180*cc708597SJiafei Panfunc _soc_ck_disabled
181*cc708597SJiafei Pan	/* get base addr of dcfg block */
182*cc708597SJiafei Pan	mov	x1, #NXP_DCFG_ADDR
183*cc708597SJiafei Pan
184*cc708597SJiafei Pan	/* read COREDISR */
185*cc708597SJiafei Pan	ldr	w1, [x1, #DCFG_COREDISR_OFFSET]
186*cc708597SJiafei Pan	rev	w2, w1
187*cc708597SJiafei Pan
188*cc708597SJiafei Pan	/* test core bit */
189*cc708597SJiafei Pan	and	w0, w2, w0
190*cc708597SJiafei Pan	ret
191*cc708597SJiafei Panendfunc _soc_ck_disabled
192*cc708597SJiafei Pan
193*cc708597SJiafei Pan/*
194*cc708597SJiafei Pan *This function resets the system via SoC-specific methods
195*cc708597SJiafei Pan * in:  none
196*cc708597SJiafei Pan * out: none
197*cc708597SJiafei Pan * uses x0, x1, x2, x3
198*cc708597SJiafei Pan */
199*cc708597SJiafei Panfunc _soc_sys_reset
200*cc708597SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
201*cc708597SJiafei Pan
202*cc708597SJiafei Pan	/* make sure the mask is cleared in the reset request mask register */
203*cc708597SJiafei Pan	mov	w1, wzr
204*cc708597SJiafei Pan	str	w1, [x2, #DCFG_RSTRQMR1_OFFSET]
205*cc708597SJiafei Pan
206*cc708597SJiafei Pan	/* set the reset request */
207*cc708597SJiafei Pan	ldr	w1, =RSTCR_RESET_REQ
208*cc708597SJiafei Pan	ldr	x3, =DCFG_RSTCR_OFFSET
209*cc708597SJiafei Pan	rev	w0, w1
210*cc708597SJiafei Pan	str	w0, [x2, x3]
211*cc708597SJiafei Pan
212*cc708597SJiafei Pan	/*
213*cc708597SJiafei Pan	 * just in case this address range is mapped as cacheable,
214*cc708597SJiafei Pan	 * flush the write out of the dcaches
215*cc708597SJiafei Pan	 */
216*cc708597SJiafei Pan	add	x3, x2, x3
217*cc708597SJiafei Pan	dc	cvac, x3
218*cc708597SJiafei Pan	dsb	st
219*cc708597SJiafei Pan	isb
220*cc708597SJiafei Pan
221*cc708597SJiafei Pan	/* Note: this function does not return */
222*cc708597SJiafei Pan1:
223*cc708597SJiafei Pan	wfi
224*cc708597SJiafei Pan	b	1b
225*cc708597SJiafei Panendfunc _soc_sys_reset
226*cc708597SJiafei Pan
227*cc708597SJiafei Pan/*
228*cc708597SJiafei Pan * Part of SYSTEM_OFF
229*cc708597SJiafei Pan * this function turns off the SoC clocks
230*cc708597SJiafei Pan * Note: this function is not intended to return, and the only allowable
231*cc708597SJiafei Pan *       recovery is POR
232*cc708597SJiafei Pan * in:  none
233*cc708597SJiafei Pan * out: none
234*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9
235*cc708597SJiafei Pan */
236*cc708597SJiafei Panfunc _soc_sys_off
237*cc708597SJiafei Pan
238*cc708597SJiafei Pan	/* mask interrupts at the core */
239*cc708597SJiafei Pan	mrs	x1, DAIF
240*cc708597SJiafei Pan	mov	x0, #DAIF_SET_MASK
241*cc708597SJiafei Pan	orr	x0, x1, x0
242*cc708597SJiafei Pan	msr	DAIF, x0
243*cc708597SJiafei Pan
244*cc708597SJiafei Pan	/* disable icache, dcache, mmu @ EL1 */
245*cc708597SJiafei Pan	mov	x1, #SCTLR_I_C_M_MASK
246*cc708597SJiafei Pan	mrs	x0, sctlr_el1
247*cc708597SJiafei Pan	bic	x0, x0, x1
248*cc708597SJiafei Pan	msr	sctlr_el1, x0
249*cc708597SJiafei Pan
250*cc708597SJiafei Pan	/* disable dcache for EL3 */
251*cc708597SJiafei Pan	mrs	x1, SCTLR_EL3
252*cc708597SJiafei Pan	bic	x1, x1, #SCTLR_C_MASK
253*cc708597SJiafei Pan	/* make sure icache is enabled */
254*cc708597SJiafei Pan	orr	x1, x1, #SCTLR_I_MASK
255*cc708597SJiafei Pan	msr	SCTLR_EL3, x1
256*cc708597SJiafei Pan	isb
257*cc708597SJiafei Pan
258*cc708597SJiafei Pan	/* Enable dynamic retention ctrl (CPUECTLR[2:0]) and SMP (CPUECTLR[6]) */
259*cc708597SJiafei Pan	mrs	x0, CORTEX_A72_ECTLR_EL1
260*cc708597SJiafei Pan	orr	x0, x0, #CPUECTLR_TIMER_8TICKS
261*cc708597SJiafei Pan	orr	x0, x0, #CPUECTLR_SMPEN_EN
262*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x0
263*cc708597SJiafei Pan
264*cc708597SJiafei Pan	/* set WFIL2EN in SCFG_CLUSTERPMCR */
265*cc708597SJiafei Pan	ldr	x0, =SCFG_COREPMCR_OFFSET
266*cc708597SJiafei Pan	ldr	x1, =COREPMCR_WFIL2
267*cc708597SJiafei Pan	bl	write_reg_scfg
268*cc708597SJiafei Pan
269*cc708597SJiafei Pan	/* request LPM20 */
270*cc708597SJiafei Pan	mov	x0, #RCPM_POWMGTCSR_OFFSET
271*cc708597SJiafei Pan	bl	read_reg_rcpm
272*cc708597SJiafei Pan	orr	x1, x0, #RCPM_POWMGTCSR_LPM20_REQ
273*cc708597SJiafei Pan	mov	x0, #RCPM_POWMGTCSR_OFFSET
274*cc708597SJiafei Pan	bl	write_reg_rcpm
275*cc708597SJiafei Pan
276*cc708597SJiafei Pan	dsb  sy
277*cc708597SJiafei Pan	isb
278*cc708597SJiafei Pan1:
279*cc708597SJiafei Pan	wfi
280*cc708597SJiafei Pan	b	1b
281*cc708597SJiafei Panendfunc _soc_sys_off
282*cc708597SJiafei Pan
283*cc708597SJiafei Pan/*
284*cc708597SJiafei Pan * Write a register in the RCPM block
285*cc708597SJiafei Pan * in:  x0 = offset
286*cc708597SJiafei Pan * in:  w1 = value to write
287*cc708597SJiafei Pan * uses x0, x1, x2, x3
288*cc708597SJiafei Pan */
289*cc708597SJiafei Panfunc write_reg_rcpm
290*cc708597SJiafei Pan	ldr	x2, =NXP_RCPM_ADDR
291*cc708597SJiafei Pan	/* swap for BE */
292*cc708597SJiafei Pan	rev	w3, w1
293*cc708597SJiafei Pan	str	w3, [x2, x0]
294*cc708597SJiafei Pan	ret
295*cc708597SJiafei Panendfunc write_reg_rcpm
296*cc708597SJiafei Pan
297*cc708597SJiafei Pan/*
298*cc708597SJiafei Pan * Read a register in the RCPM block
299*cc708597SJiafei Pan * in:  x0 = offset
300*cc708597SJiafei Pan * out: w0 = value read
301*cc708597SJiafei Pan * uses x0, x1, x2
302*cc708597SJiafei Pan */
303*cc708597SJiafei Panfunc read_reg_rcpm
304*cc708597SJiafei Pan	ldr	x2, =NXP_RCPM_ADDR
305*cc708597SJiafei Pan	ldr	w1, [x2, x0]
306*cc708597SJiafei Pan	/* swap for BE */
307*cc708597SJiafei Pan	rev	w0, w1
308*cc708597SJiafei Pan	ret
309*cc708597SJiafei Panendfunc read_reg_rcpm
310*cc708597SJiafei Pan
311*cc708597SJiafei Pan/*
312*cc708597SJiafei Pan * Write a register in the SCFG block
313*cc708597SJiafei Pan * in:  x0 = offset
314*cc708597SJiafei Pan * in:  w1 = value to write
315*cc708597SJiafei Pan * uses x0, x1, x2, x3
316*cc708597SJiafei Pan */
317*cc708597SJiafei Panfunc write_reg_scfg
318*cc708597SJiafei Pan	mov	x2, #NXP_SCFG_ADDR
319*cc708597SJiafei Pan	/* swap for BE */
320*cc708597SJiafei Pan	rev	w3, w1
321*cc708597SJiafei Pan	str	w3, [x2, x0]
322*cc708597SJiafei Pan	ret
323*cc708597SJiafei Panendfunc write_reg_scfg
324*cc708597SJiafei Pan
325*cc708597SJiafei Pan/*
326*cc708597SJiafei Pan * Read a register in the SCFG block
327*cc708597SJiafei Pan * in:  x0 = offset
328*cc708597SJiafei Pan * out: w0 = value read
329*cc708597SJiafei Pan * uses x0, x1, x2
330*cc708597SJiafei Pan */
331*cc708597SJiafei Panfunc read_reg_scfg
332*cc708597SJiafei Pan	mov	x2, #NXP_SCFG_ADDR
333*cc708597SJiafei Pan	ldr	w1, [x2, x0]
334*cc708597SJiafei Pan	/* swap for BE */
335*cc708597SJiafei Pan	rev	w0, w1
336*cc708597SJiafei Pan	ret
337*cc708597SJiafei Panendfunc read_reg_scfg
338*cc708597SJiafei Pan
339*cc708597SJiafei Pan/*
340*cc708597SJiafei Pan * Part of CPU_OFF
341*cc708597SJiafei Pan * this function programs SoC & GIC registers in preparation for shutting down
342*cc708597SJiafei Pan * the core
343*cc708597SJiafei Pan * in:  x0 = core mask lsb
344*cc708597SJiafei Pan * out: none
345*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7
346*cc708597SJiafei Pan */
347*cc708597SJiafei Panfunc _soc_core_prep_off
348*cc708597SJiafei Pan	mov	x7, x30
349*cc708597SJiafei Pan	mov	x6, x0
350*cc708597SJiafei Pan
351*cc708597SJiafei Pan	/* Set retention control in CPUECTLR make sure smpen bit is set */
352*cc708597SJiafei Pan	mrs	x4, CORTEX_A72_ECTLR_EL1
353*cc708597SJiafei Pan	bic	x4, x4, #CPUECTLR_RET_MASK
354*cc708597SJiafei Pan	orr	x4, x4, #CPUECTLR_TIMER_8TICKS
355*cc708597SJiafei Pan	orr	x4, x4, #CPUECTLR_SMPEN_EN
356*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x4
357*cc708597SJiafei Pan
358*cc708597SJiafei Pan	/* save timer control current value */
359*cc708597SJiafei Pan	mov	x5, #NXP_TIMER_ADDR
360*cc708597SJiafei Pan	ldr	w4, [x5, #SYS_COUNTER_CNTCR_OFFSET]
361*cc708597SJiafei Pan	mov	w2, w4
362*cc708597SJiafei Pan	mov	x0, x6
363*cc708597SJiafei Pan	mov	x1, #TIMER_CNTRL_DATA
364*cc708597SJiafei Pan	bl	_setCoreData
365*cc708597SJiafei Pan
366*cc708597SJiafei Pan	/* enable the timer */
367*cc708597SJiafei Pan	orr	w4, w4, #CNTCR_EN_MASK
368*cc708597SJiafei Pan	str	w4, [x5, #SYS_COUNTER_CNTCR_OFFSET]
369*cc708597SJiafei Pan
370*cc708597SJiafei Pan	bl	_getGICC_BaseAddr
371*cc708597SJiafei Pan	mov	x5, x0
372*cc708597SJiafei Pan
373*cc708597SJiafei Pan	/* disable signaling of ints */
374*cc708597SJiafei Pan	ldr	w3, [x5, #GICC_CTLR_OFFSET]
375*cc708597SJiafei Pan	bic	w3, w3, #GICC_CTLR_EN_GRP0
376*cc708597SJiafei Pan	bic	w3, w3, #GICC_CTLR_EN_GRP1
377*cc708597SJiafei Pan	str	w3, [x5, #GICC_CTLR_OFFSET]
378*cc708597SJiafei Pan	dsb	sy
379*cc708597SJiafei Pan	isb
380*cc708597SJiafei Pan
381*cc708597SJiafei Pan
382*cc708597SJiafei Pan	/*
383*cc708597SJiafei Pan	 * set retention control in SCFG_RETREQCR
384*cc708597SJiafei Pan	 * Note: this register is msb 0
385*cc708597SJiafei Pan	 */
386*cc708597SJiafei Pan	ldr	x4, =SCFG_RETREQCR_OFFSET
387*cc708597SJiafei Pan	mov	x0, x4
388*cc708597SJiafei Pan	bl	read_reg_scfg
389*cc708597SJiafei Pan	rbit	w1, w6
390*cc708597SJiafei Pan	orr	w1, w0, w1
391*cc708597SJiafei Pan	mov	x0, x4
392*cc708597SJiafei Pan	bl	write_reg_scfg
393*cc708597SJiafei Pan
394*cc708597SJiafei Pan	/* set the priority filter */
395*cc708597SJiafei Pan	ldr	w2, [x5, #GICC_PMR_OFFSET]
396*cc708597SJiafei Pan	orr	w2, w2, #GICC_PMR_FILTER
397*cc708597SJiafei Pan	str	w2, [x5, #GICC_PMR_OFFSET]
398*cc708597SJiafei Pan
399*cc708597SJiafei Pan	/* setup GICC_CTLR */
400*cc708597SJiafei Pan	bic	w3, w3, #GICC_CTLR_ACKCTL_MASK
401*cc708597SJiafei Pan	orr	w3, w3, #GICC_CTLR_FIQ_EN_MASK
402*cc708597SJiafei Pan	orr	w3, w3, #GICC_CTLR_EOImodeS_MASK
403*cc708597SJiafei Pan	orr	w3, w3, #GICC_CTLR_CBPR_MASK
404*cc708597SJiafei Pan	str	w3, [x5, #GICC_CTLR_OFFSET]
405*cc708597SJiafei Pan
406*cc708597SJiafei Pan	/* setup the banked-per-core GICD registers */
407*cc708597SJiafei Pan	bl	_getGICD_BaseAddr
408*cc708597SJiafei Pan	mov	x5, x0
409*cc708597SJiafei Pan
410*cc708597SJiafei Pan	/* define SGI15 as Grp0 */
411*cc708597SJiafei Pan	ldr	w2, [x5, #GICD_IGROUPR0_OFFSET]
412*cc708597SJiafei Pan	bic	w2, w2, #GICD_IGROUP0_SGI15
413*cc708597SJiafei Pan	str	w2, [x5, #GICD_IGROUPR0_OFFSET]
414*cc708597SJiafei Pan
415*cc708597SJiafei Pan	/* set priority of SGI 15 to highest... */
416*cc708597SJiafei Pan	ldr	w2, [x5, #GICD_IPRIORITYR3_OFFSET]
417*cc708597SJiafei Pan	bic	w2, w2, #GICD_IPRIORITY_SGI15_MASK
418*cc708597SJiafei Pan	str	w2, [x5, #GICD_IPRIORITYR3_OFFSET]
419*cc708597SJiafei Pan
420*cc708597SJiafei Pan	/* enable SGI 15 */
421*cc708597SJiafei Pan	ldr	w2, [x5, #GICD_ISENABLER0_OFFSET]
422*cc708597SJiafei Pan	orr	w2, w2, #GICD_ISENABLE0_SGI15
423*cc708597SJiafei Pan	str	w2, [x5, #GICD_ISENABLER0_OFFSET]
424*cc708597SJiafei Pan
425*cc708597SJiafei Pan	/* enable the cpu interface */
426*cc708597SJiafei Pan	bl	_getGICC_BaseAddr
427*cc708597SJiafei Pan	mov	x2, x0
428*cc708597SJiafei Pan	orr	w3, w3, #GICC_CTLR_EN_GRP0
429*cc708597SJiafei Pan	str	w3, [x2, #GICC_CTLR_OFFSET]
430*cc708597SJiafei Pan
431*cc708597SJiafei Pan
432*cc708597SJiafei Pan	/* clear any pending SGIs */
433*cc708597SJiafei Pan	ldr	x2, =GICD_CPENDSGIR_CLR_MASK
434*cc708597SJiafei Pan	add	x0, x5, #GICD_CPENDSGIR3_OFFSET
435*cc708597SJiafei Pan	str	w2, [x0]
436*cc708597SJiafei Pan
437*cc708597SJiafei Pan	/*
438*cc708597SJiafei Pan	 * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR
439*cc708597SJiafei Pan	 * this is an lsb-0 register
440*cc708597SJiafei Pan	 */
441*cc708597SJiafei Pan	mov	x1, x6
442*cc708597SJiafei Pan	mov	x0, #RCPM_PCPH20SETR_OFFSET
443*cc708597SJiafei Pan	bl	write_reg_rcpm
444*cc708597SJiafei Pan
445*cc708597SJiafei Pan	dsb	sy
446*cc708597SJiafei Pan	isb
447*cc708597SJiafei Pan	mov	x30, x7
448*cc708597SJiafei Pan	ret
449*cc708597SJiafei Panendfunc _soc_core_prep_off
450*cc708597SJiafei Pan
451*cc708597SJiafei Pan/*
452*cc708597SJiafei Pan * Part of CPU_OFF
453*cc708597SJiafei Pan * this function performs the final steps to shutdown the core
454*cc708597SJiafei Pan * in:  x0 = core mask lsb
455*cc708597SJiafei Pan * out: none
456*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5
457*cc708597SJiafei Pan */
458*cc708597SJiafei Panfunc _soc_core_entr_off
459*cc708597SJiafei Pan	mov	x5, x30
460*cc708597SJiafei Pan	mov	x4, x0
461*cc708597SJiafei Pan
462*cc708597SJiafei Pan	bl	_getGICD_BaseAddr
463*cc708597SJiafei Pan	mov	x3, x0
464*cc708597SJiafei Pan
465*cc708597SJiafei Pan3:
466*cc708597SJiafei Pan	/* enter low-power state by executing wfi */
467*cc708597SJiafei Pan	wfi
468*cc708597SJiafei Pan
469*cc708597SJiafei Pan	/* see if we got hit by SGI 15 */
470*cc708597SJiafei Pan	add	x0, x3, #GICD_SPENDSGIR3_OFFSET
471*cc708597SJiafei Pan	ldr	w2, [x0]
472*cc708597SJiafei Pan	and	w2, w2, #GICD_SPENDSGIR3_SGI15_MASK
473*cc708597SJiafei Pan	cbz	w2, 4f
474*cc708597SJiafei Pan
475*cc708597SJiafei Pan	/* clear the pending SGI */
476*cc708597SJiafei Pan	ldr	x2, =GICD_CPENDSGIR_CLR_MASK
477*cc708597SJiafei Pan	add	x0, x3, #GICD_CPENDSGIR3_OFFSET
478*cc708597SJiafei Pan	str	w2, [x0]
479*cc708597SJiafei Pan4:
480*cc708597SJiafei Pan	/* check if core has been turned on */
481*cc708597SJiafei Pan	mov	x0, x4
482*cc708597SJiafei Pan	bl	_getCoreState
483*cc708597SJiafei Pan
484*cc708597SJiafei Pan	cmp	x0, #CORE_WAKEUP
485*cc708597SJiafei Pan	b.ne	3b
486*cc708597SJiafei Pan
487*cc708597SJiafei Pan	/* if we get here, then we have exited the wfi */
488*cc708597SJiafei Pan	dsb	sy
489*cc708597SJiafei Pan	isb
490*cc708597SJiafei Pan	mov	x30, x5
491*cc708597SJiafei Pan	ret
492*cc708597SJiafei Panendfunc _soc_core_entr_off
493*cc708597SJiafei Pan
494*cc708597SJiafei Pan/*
495*cc708597SJiafei Pan * Part of CPU_OFF
496*cc708597SJiafei Pan * this function starts the process of starting a core back up
497*cc708597SJiafei Pan * in:  x0 = core mask lsb
498*cc708597SJiafei Pan * out: none
499*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6
500*cc708597SJiafei Pan */
501*cc708597SJiafei Panfunc _soc_core_exit_off
502*cc708597SJiafei Pan	mov	x6, x30
503*cc708597SJiafei Pan	mov	x5, x0
504*cc708597SJiafei Pan
505*cc708597SJiafei Pan	/*
506*cc708597SJiafei Pan	 * Clear ph20 request in RCPM_PCPH20CLRR - no need
507*cc708597SJiafei Pan	 * to do that here, it has been done in _soc_core_restart
508*cc708597SJiafei Pan	 */
509*cc708597SJiafei Pan	bl	_getGICC_BaseAddr
510*cc708597SJiafei Pan	mov	x1, x0
511*cc708597SJiafei Pan
512*cc708597SJiafei Pan	/* read GICC_IAR */
513*cc708597SJiafei Pan	ldr	w0, [x1, #GICC_IAR_OFFSET]
514*cc708597SJiafei Pan
515*cc708597SJiafei Pan	/* write GICC_EIOR - signal end-of-interrupt */
516*cc708597SJiafei Pan	str	w0, [x1, #GICC_EOIR_OFFSET]
517*cc708597SJiafei Pan
518*cc708597SJiafei Pan	/* write GICC_DIR - disable interrupt */
519*cc708597SJiafei Pan	str	w0, [x1, #GICC_DIR_OFFSET]
520*cc708597SJiafei Pan
521*cc708597SJiafei Pan	/* disable signaling of grp0 ints */
522*cc708597SJiafei Pan	ldr	w3, [x1, #GICC_CTLR_OFFSET]
523*cc708597SJiafei Pan	bic	w3, w3, #GICC_CTLR_EN_GRP0
524*cc708597SJiafei Pan	str	w3, [x1, #GICC_CTLR_OFFSET]
525*cc708597SJiafei Pan
526*cc708597SJiafei Pan	/*
527*cc708597SJiafei Pan	 * Unset retention request in SCFG_RETREQCR
528*cc708597SJiafei Pan	 * Note: this register is msb-0
529*cc708597SJiafei Pan	 */
530*cc708597SJiafei Pan	ldr	x4, =SCFG_RETREQCR_OFFSET
531*cc708597SJiafei Pan	mov	x0, x4
532*cc708597SJiafei Pan	bl	read_reg_scfg
533*cc708597SJiafei Pan	rbit	w1, w5
534*cc708597SJiafei Pan	bic	w1, w0, w1
535*cc708597SJiafei Pan	mov	x0, x4
536*cc708597SJiafei Pan	bl	write_reg_scfg
537*cc708597SJiafei Pan
538*cc708597SJiafei Pan	/* restore timer ctrl */
539*cc708597SJiafei Pan	mov	x0, x5
540*cc708597SJiafei Pan	mov	x1, #TIMER_CNTRL_DATA
541*cc708597SJiafei Pan	bl	_getCoreData
542*cc708597SJiafei Pan	/* w0 = timer ctrl saved value */
543*cc708597SJiafei Pan	mov	x2, #NXP_TIMER_ADDR
544*cc708597SJiafei Pan	str	w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
545*cc708597SJiafei Pan
546*cc708597SJiafei Pan	dsb	sy
547*cc708597SJiafei Pan	isb
548*cc708597SJiafei Pan	mov	x30, x6
549*cc708597SJiafei Pan	ret
550*cc708597SJiafei Panendfunc _soc_core_exit_off
551*cc708597SJiafei Pan
552*cc708597SJiafei Pan/*
553*cc708597SJiafei Pan * Function loads a 64-bit execution address of the core in the soc registers
554*cc708597SJiafei Pan * BOOTLOCPTRL/H
555*cc708597SJiafei Pan * in:  x0, 64-bit address to write to BOOTLOCPTRL/H
556*cc708597SJiafei Pan * uses x0, x1, x2, x3
557*cc708597SJiafei Pan */
558*cc708597SJiafei Panfunc _soc_set_start_addr
559*cc708597SJiafei Pan	/* get the 64-bit base address of the scfg block */
560*cc708597SJiafei Pan	ldr	x2, =NXP_SCFG_ADDR
561*cc708597SJiafei Pan
562*cc708597SJiafei Pan	/* write the 32-bit BOOTLOCPTRL register */
563*cc708597SJiafei Pan	mov	x1, x0
564*cc708597SJiafei Pan	rev	w3, w1
565*cc708597SJiafei Pan	str	w3, [x2, #SCFG_BOOTLOCPTRL_OFFSET]
566*cc708597SJiafei Pan
567*cc708597SJiafei Pan	/* write the 32-bit BOOTLOCPTRH register */
568*cc708597SJiafei Pan	lsr	x1, x0, #32
569*cc708597SJiafei Pan	rev	w3, w1
570*cc708597SJiafei Pan	str	w3, [x2, #SCFG_BOOTLOCPTRH_OFFSET]
571*cc708597SJiafei Pan	ret
572*cc708597SJiafei Panendfunc _soc_set_start_addr
573*cc708597SJiafei Pan
574*cc708597SJiafei Pan/*
575*cc708597SJiafei Pan * This function returns the base address of the gic distributor
576*cc708597SJiafei Pan * in:  none
577*cc708597SJiafei Pan * out: x0 = base address of gic distributor
578*cc708597SJiafei Pan * uses x0
579*cc708597SJiafei Pan */
580*cc708597SJiafei Panfunc _getGICD_BaseAddr
581*cc708597SJiafei Pan#if (TEST_BL31)
582*cc708597SJiafei Pan	/* defect in simulator - gic base addresses are on 4Kb boundary */
583*cc708597SJiafei Pan	ldr	x0, =NXP_GICD_4K_ADDR
584*cc708597SJiafei Pan#else
585*cc708597SJiafei Pan	ldr	x0, =NXP_GICD_64K_ADDR
586*cc708597SJiafei Pan#endif
587*cc708597SJiafei Pan	ret
588*cc708597SJiafei Panendfunc _getGICD_BaseAddr
589*cc708597SJiafei Pan
590*cc708597SJiafei Pan/*
591*cc708597SJiafei Pan * This function returns the base address of the gic controller
592*cc708597SJiafei Pan * in:  none
593*cc708597SJiafei Pan * out: x0 = base address of gic controller
594*cc708597SJiafei Pan * uses x0
595*cc708597SJiafei Pan */
596*cc708597SJiafei Panfunc _getGICC_BaseAddr
597*cc708597SJiafei Pan#if (TEST_BL31)
598*cc708597SJiafei Pan	/* defect in simulator - gic base addresses are on 4Kb boundary */
599*cc708597SJiafei Pan	ldr	x0, =NXP_GICC_4K_ADDR
600*cc708597SJiafei Pan#else
601*cc708597SJiafei Pan	ldr	x0, =NXP_GICC_64K_ADDR
602*cc708597SJiafei Pan#endif
603*cc708597SJiafei Pan	ret
604*cc708597SJiafei Panendfunc _getGICC_BaseAddr
605*cc708597SJiafei Pan
606*cc708597SJiafei Pan/*
607*cc708597SJiafei Pan * Part of CPU_SUSPEND
608*cc708597SJiafei Pan * this function puts the calling core into standby state
609*cc708597SJiafei Pan * in:  x0 = core mask lsb
610*cc708597SJiafei Pan * out: none
611*cc708597SJiafei Pan * uses x0
612*cc708597SJiafei Pan */
613*cc708597SJiafei Panfunc _soc_core_entr_stdby
614*cc708597SJiafei Pan	dsb	sy
615*cc708597SJiafei Pan	isb
616*cc708597SJiafei Pan	wfi
617*cc708597SJiafei Pan
618*cc708597SJiafei Pan	ret
619*cc708597SJiafei Panendfunc _soc_core_entr_stdby
620*cc708597SJiafei Pan
621*cc708597SJiafei Pan
622*cc708597SJiafei Pan/*
623*cc708597SJiafei Pan * Part of CPU_SUSPEND
624*cc708597SJiafei Pan * this function performs SoC-specific programming prior to standby
625*cc708597SJiafei Pan * in:  x0 = core mask lsb
626*cc708597SJiafei Pan * out: none
627*cc708597SJiafei Pan * uses x0, x1
628*cc708597SJiafei Pan */
629*cc708597SJiafei Panfunc _soc_core_prep_stdby
630*cc708597SJiafei Pan	/* clear CORTEX_A72_ECTLR_EL1[2:0] */
631*cc708597SJiafei Pan	mrs	x1, CORTEX_A72_ECTLR_EL1
632*cc708597SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
633*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x1
634*cc708597SJiafei Pan
635*cc708597SJiafei Pan	ret
636*cc708597SJiafei Panendfunc _soc_core_prep_stdby
637*cc708597SJiafei Pan
638*cc708597SJiafei Pan/*
639*cc708597SJiafei Pan * Part of CPU_SUSPEND
640*cc708597SJiafei Pan * this function performs any SoC-specific cleanup after standby state
641*cc708597SJiafei Pan * in:  x0 = core mask lsb
642*cc708597SJiafei Pan * out: none
643*cc708597SJiafei Pan * uses none
644*cc708597SJiafei Pan */
645*cc708597SJiafei Panfunc _soc_core_exit_stdby
646*cc708597SJiafei Pan	ret
647*cc708597SJiafei Panendfunc _soc_core_exit_stdby
648*cc708597SJiafei Pan
649*cc708597SJiafei Pan/*
650*cc708597SJiafei Pan * Part of CPU_SUSPEND
651*cc708597SJiafei Pan * this function performs SoC-specific programming prior to power-down
652*cc708597SJiafei Pan * in:  x0 = core mask lsb
653*cc708597SJiafei Pan * out: none
654*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5
655*cc708597SJiafei Pan */
656*cc708597SJiafei Panfunc _soc_core_prep_pwrdn
657*cc708597SJiafei Pan	mov	x5, x30
658*cc708597SJiafei Pan	mov	x4, x0
659*cc708597SJiafei Pan
660*cc708597SJiafei Pan	/* enable CPU retention + set smp */
661*cc708597SJiafei Pan	mrs	x1, CORTEX_A72_ECTLR_EL1
662*cc708597SJiafei Pan	orr	x1, x1, #0x1
663*cc708597SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_MASK
664*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x1
665*cc708597SJiafei Pan
666*cc708597SJiafei Pan	/*
667*cc708597SJiafei Pan	 * set the retention request in SCFG_RETREQCR
668*cc708597SJiafei Pan	 * this is an msb-0 register
669*cc708597SJiafei Pan	 */
670*cc708597SJiafei Pan	ldr	x3, =SCFG_RETREQCR_OFFSET
671*cc708597SJiafei Pan	mov	x0, x3
672*cc708597SJiafei Pan	bl	read_reg_scfg
673*cc708597SJiafei Pan	rbit	w1, w4
674*cc708597SJiafei Pan	orr	w1, w0, w1
675*cc708597SJiafei Pan	mov	x0, x3
676*cc708597SJiafei Pan	bl	write_reg_scfg
677*cc708597SJiafei Pan
678*cc708597SJiafei Pan	/*
679*cc708597SJiafei Pan	 * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR
680*cc708597SJiafei Pan	 * this is an lsb-0 register
681*cc708597SJiafei Pan	 */
682*cc708597SJiafei Pan	mov	x1, x4
683*cc708597SJiafei Pan	mov	x0, #RCPM_PCPH20SETR_OFFSET
684*cc708597SJiafei Pan	bl	write_reg_rcpm
685*cc708597SJiafei Pan
686*cc708597SJiafei Pan	mov	x30, x5
687*cc708597SJiafei Pan	ret
688*cc708597SJiafei Panendfunc _soc_core_prep_pwrdn
689*cc708597SJiafei Pan
690*cc708597SJiafei Pan/*
691*cc708597SJiafei Pan * Part of CPU_SUSPEND
692*cc708597SJiafei Pan * this function puts the calling core into a power-down state
693*cc708597SJiafei Pan * in:  x0 = core mask lsb
694*cc708597SJiafei Pan * out: none
695*cc708597SJiafei Pan * uses x0
696*cc708597SJiafei Pan */
697*cc708597SJiafei Panfunc _soc_core_entr_pwrdn
698*cc708597SJiafei Pan	dsb	sy
699*cc708597SJiafei Pan	isb
700*cc708597SJiafei Pan	wfi
701*cc708597SJiafei Pan
702*cc708597SJiafei Pan	ret
703*cc708597SJiafei Panendfunc _soc_core_entr_pwrdn
704*cc708597SJiafei Pan
705*cc708597SJiafei Pan/*
706*cc708597SJiafei Pan * Part of CPU_SUSPEND
707*cc708597SJiafei Pan * this function cleans up after a core exits power-down
708*cc708597SJiafei Pan * in:  x0 = core mask lsb
709*cc708597SJiafei Pan * out: none
710*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5
711*cc708597SJiafei Pan */
712*cc708597SJiafei Panfunc _soc_core_exit_pwrdn
713*cc708597SJiafei Pan	mov	x5, x30
714*cc708597SJiafei Pan	mov	x4, x0
715*cc708597SJiafei Pan
716*cc708597SJiafei Pan	/*
717*cc708597SJiafei Pan	 * Set the PC_PH20_REQ bit in RCPM_PCPH20CLRR
718*cc708597SJiafei Pan	 * this is an lsb-0 register
719*cc708597SJiafei Pan	 */
720*cc708597SJiafei Pan	mov	x1, x4
721*cc708597SJiafei Pan	mov	x0, #RCPM_PCPH20CLRR_OFFSET
722*cc708597SJiafei Pan	bl	write_reg_rcpm
723*cc708597SJiafei Pan
724*cc708597SJiafei Pan	/*
725*cc708597SJiafei Pan	 * Unset the retention request in SCFG_RETREQCR
726*cc708597SJiafei Pan	 * this is an msb-0 register
727*cc708597SJiafei Pan	 */
728*cc708597SJiafei Pan	ldr	x3, =SCFG_RETREQCR_OFFSET
729*cc708597SJiafei Pan	mov	x0, x3
730*cc708597SJiafei Pan	bl	read_reg_scfg
731*cc708597SJiafei Pan	rbit	w1, w4
732*cc708597SJiafei Pan	bic	w1, w0, w1
733*cc708597SJiafei Pan	mov	x0, x3
734*cc708597SJiafei Pan	bl	write_reg_scfg
735*cc708597SJiafei Pan
736*cc708597SJiafei Pan	mov	x30, x5
737*cc708597SJiafei Pan	ret
738*cc708597SJiafei Panendfunc _soc_core_exit_pwrdn
739*cc708597SJiafei Pan
740*cc708597SJiafei Pan/*
741*cc708597SJiafei Pan * Part of CPU_SUSPEND
742*cc708597SJiafei Pan * this function performs SoC-specific programming prior to standby
743*cc708597SJiafei Pan * in:  x0 = core mask lsb
744*cc708597SJiafei Pan * out: none
745*cc708597SJiafei Pan * uses none
746*cc708597SJiafei Pan */
747*cc708597SJiafei Panfunc _soc_clstr_prep_stdby
748*cc708597SJiafei Pan	/* clear CORTEX_A72_ECTLR_EL1[2:0] */
749*cc708597SJiafei Pan	mrs	x1, CORTEX_A72_ECTLR_EL1
750*cc708597SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
751*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x1
752*cc708597SJiafei Pan
753*cc708597SJiafei Pan	ret
754*cc708597SJiafei Panendfunc _soc_clstr_prep_stdby
755*cc708597SJiafei Pan
756*cc708597SJiafei Pan/*
757*cc708597SJiafei Pan * Part of CPU_SUSPEND
758*cc708597SJiafei Pan * this function performs any SoC-specific cleanup after standby state
759*cc708597SJiafei Pan * in:  x0 = core mask lsb
760*cc708597SJiafei Pan * out: none
761*cc708597SJiafei Pan * uses none
762*cc708597SJiafei Pan */
763*cc708597SJiafei Panfunc _soc_clstr_exit_stdby
764*cc708597SJiafei Pan	ret
765*cc708597SJiafei Panendfunc _soc_clstr_exit_stdby
766*cc708597SJiafei Pan
767*cc708597SJiafei Pan/*
768*cc708597SJiafei Pan * Part of CPU_SUSPEND
769*cc708597SJiafei Pan * this function performs SoC-specific programming prior to power-down
770*cc708597SJiafei Pan * in:  x0 = core mask lsb
771*cc708597SJiafei Pan * out: none
772*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5
773*cc708597SJiafei Pan */
774*cc708597SJiafei Panfunc _soc_clstr_prep_pwrdn
775*cc708597SJiafei Pan	mov	x5, x30
776*cc708597SJiafei Pan	mov	x4, x0
777*cc708597SJiafei Pan
778*cc708597SJiafei Pan	/* enable CPU retention + set smp */
779*cc708597SJiafei Pan	mrs	x1, CORTEX_A72_ECTLR_EL1
780*cc708597SJiafei Pan	orr	x1, x1, #0x1
781*cc708597SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_MASK
782*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x1
783*cc708597SJiafei Pan
784*cc708597SJiafei Pan	/*
785*cc708597SJiafei Pan	 * Set the retention request in SCFG_RETREQCR
786*cc708597SJiafei Pan	 * this is an msb-0 register.
787*cc708597SJiafei Pan	 */
788*cc708597SJiafei Pan	ldr	x3, =SCFG_RETREQCR_OFFSET
789*cc708597SJiafei Pan	mov	x0, x3
790*cc708597SJiafei Pan	bl	read_reg_scfg
791*cc708597SJiafei Pan	rbit	w1, w4
792*cc708597SJiafei Pan	orr	w1, w0, w1
793*cc708597SJiafei Pan	mov	x0, x3
794*cc708597SJiafei Pan	bl	write_reg_scfg
795*cc708597SJiafei Pan
796*cc708597SJiafei Pan	/*
797*cc708597SJiafei Pan	 * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR
798*cc708597SJiafei Pan	 * this is an lsb-0 register.
799*cc708597SJiafei Pan	 */
800*cc708597SJiafei Pan	mov	x1, x4
801*cc708597SJiafei Pan	mov	x0, #RCPM_PCPH20SETR_OFFSET
802*cc708597SJiafei Pan	bl	write_reg_rcpm
803*cc708597SJiafei Pan
804*cc708597SJiafei Pan	mov	x30, x5
805*cc708597SJiafei Pan	ret
806*cc708597SJiafei Panendfunc _soc_clstr_prep_pwrdn
807*cc708597SJiafei Pan
808*cc708597SJiafei Pan/*
809*cc708597SJiafei Pan * Part of CPU_SUSPEND
810*cc708597SJiafei Pan * this function cleans up after a core exits power-down
811*cc708597SJiafei Pan * in:  x0 = core mask lsb
812*cc708597SJiafei Pan * out: none
813*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4, x5
814*cc708597SJiafei Pan */
815*cc708597SJiafei Panfunc _soc_clstr_exit_pwrdn
816*cc708597SJiafei Pan	mov	x5, x30
817*cc708597SJiafei Pan	mov	x4, x0
818*cc708597SJiafei Pan
819*cc708597SJiafei Pan	/*
820*cc708597SJiafei Pan	 * Set the PC_PH20_REQ bit in RCPM_PCPH20CLRR
821*cc708597SJiafei Pan	 * this is an lsb-0 register.
822*cc708597SJiafei Pan	 */
823*cc708597SJiafei Pan	mov	x1, x4
824*cc708597SJiafei Pan	mov	x0, #RCPM_PCPH20CLRR_OFFSET
825*cc708597SJiafei Pan	bl	write_reg_rcpm
826*cc708597SJiafei Pan
827*cc708597SJiafei Pan	/*
828*cc708597SJiafei Pan	 * Unset the retention request in SCFG_RETREQCR
829*cc708597SJiafei Pan	 * this is an msb-0 register.
830*cc708597SJiafei Pan	 */
831*cc708597SJiafei Pan	ldr	x3, =SCFG_RETREQCR_OFFSET
832*cc708597SJiafei Pan	mov	x0, x3
833*cc708597SJiafei Pan	bl	read_reg_scfg
834*cc708597SJiafei Pan	rbit	w1, w4
835*cc708597SJiafei Pan	bic	w1, w0, w1
836*cc708597SJiafei Pan	mov	x0, x3
837*cc708597SJiafei Pan	bl	write_reg_scfg
838*cc708597SJiafei Pan
839*cc708597SJiafei Pan	mov	x30, x5
840*cc708597SJiafei Pan	ret
841*cc708597SJiafei Panendfunc _soc_clstr_exit_pwrdn
842*cc708597SJiafei Pan
843*cc708597SJiafei Pan/*
844*cc708597SJiafei Pan * Part of CPU_SUSPEND
845*cc708597SJiafei Pan * this function performs SoC-specific programming prior to standby
846*cc708597SJiafei Pan * in:  x0 = core mask lsb
847*cc708597SJiafei Pan * out: none
848*cc708597SJiafei Pan * uses none
849*cc708597SJiafei Pan */
850*cc708597SJiafei Panfunc _soc_sys_prep_stdby
851*cc708597SJiafei Pan	/* clear CORTEX_A72_ECTLR_EL1[2:0] */
852*cc708597SJiafei Pan	mrs	x1, CORTEX_A72_ECTLR_EL1
853*cc708597SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
854*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x1
855*cc708597SJiafei Pan
856*cc708597SJiafei Pan	ret
857*cc708597SJiafei Panendfunc _soc_sys_prep_stdby
858*cc708597SJiafei Pan
859*cc708597SJiafei Pan/* Part of CPU_SUSPEND
860*cc708597SJiafei Pan * this function performs any SoC-specific cleanup after standby state
861*cc708597SJiafei Pan * in:  x0 = core mask lsb
862*cc708597SJiafei Pan * out: none
863*cc708597SJiafei Pan * uses none
864*cc708597SJiafei Pan */
865*cc708597SJiafei Panfunc _soc_sys_exit_stdby
866*cc708597SJiafei Pan	ret
867*cc708597SJiafei Panendfunc _soc_sys_exit_stdby
868*cc708597SJiafei Pan
869*cc708597SJiafei Pan/*
870*cc708597SJiafei Pan * Part of CPU_SUSPEND
871*cc708597SJiafei Pan * this function performs SoC-specific programming prior to
872*cc708597SJiafei Pan * suspend-to-power-down
873*cc708597SJiafei Pan * in:  x0 = core mask lsb
874*cc708597SJiafei Pan * out: none
875*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4
876*cc708597SJiafei Pan */
877*cc708597SJiafei Panfunc _soc_sys_prep_pwrdn
878*cc708597SJiafei Pan	mov	x4, x30
879*cc708597SJiafei Pan
880*cc708597SJiafei Pan	/* Enable dynamic retention contrl (CPUECTLR[2:0]) and SMP (CPUECTLR[6]) */
881*cc708597SJiafei Pan	mrs	x0, CORTEX_A72_ECTLR_EL1
882*cc708597SJiafei Pan	bic	x0, x0, #CPUECTLR_TIMER_MASK
883*cc708597SJiafei Pan	orr	x0, x0, #CPUECTLR_TIMER_8TICKS
884*cc708597SJiafei Pan	orr	x0, x0, #CPUECTLR_SMPEN_EN
885*cc708597SJiafei Pan	msr	CORTEX_A72_ECTLR_EL1, x0
886*cc708597SJiafei Pan
887*cc708597SJiafei Pan	/* Set WFIL2EN in SCFG_CLUSTERPMCR */
888*cc708597SJiafei Pan	ldr	x0, =SCFG_COREPMCR_OFFSET
889*cc708597SJiafei Pan	ldr	x1, =COREPMCR_WFIL2
890*cc708597SJiafei Pan	bl	write_reg_scfg
891*cc708597SJiafei Pan
892*cc708597SJiafei Pan	isb
893*cc708597SJiafei Pan	mov	x30, x4
894*cc708597SJiafei Pan	ret
895*cc708597SJiafei Panendfunc _soc_sys_prep_pwrdn
896*cc708597SJiafei Pan
897*cc708597SJiafei Pan/*
898*cc708597SJiafei Pan * Part of CPU_SUSPEND
899*cc708597SJiafei Pan * this function puts the calling core, and potentially the soc, into a
900*cc708597SJiafei Pan * low-power state
901*cc708597SJiafei Pan * in:  x0 = core mask lsb
902*cc708597SJiafei Pan * out: x0 = 0, success
903*cc708597SJiafei Pan *      x0 < 0, failure
904*cc708597SJiafei Pan * uses x0, x1, x2, x3, x4
905*cc708597SJiafei Pan */
906*cc708597SJiafei Panfunc _soc_sys_pwrdn_wfi
907*cc708597SJiafei Pan	mov	x4, x30
908*cc708597SJiafei Pan
909*cc708597SJiafei Pan	/* request LPM20 */
910*cc708597SJiafei Pan	mov	x0, #RCPM_POWMGTCSR_OFFSET
911*cc708597SJiafei Pan	bl	read_reg_rcpm
912*cc708597SJiafei Pan	orr	x1, x0, #RCPM_POWMGTCSR_LPM20_REQ
913*cc708597SJiafei Pan	mov	x0, #RCPM_POWMGTCSR_OFFSET
914*cc708597SJiafei Pan	bl	write_reg_rcpm
915*cc708597SJiafei Pan
916*cc708597SJiafei Pan	dsb	sy
917*cc708597SJiafei Pan	isb
918*cc708597SJiafei Pan	wfi
919*cc708597SJiafei Pan
920*cc708597SJiafei Pan	mov	x30, x4
921*cc708597SJiafei Pan	ret
922*cc708597SJiafei Panendfunc _soc_sys_pwrdn_wfi
923*cc708597SJiafei Pan
924*cc708597SJiafei Pan/*
925*cc708597SJiafei Pan * Part of CPU_SUSPEND
926*cc708597SJiafei Pan * this function performs any SoC-specific cleanup after power-down
927*cc708597SJiafei Pan * in:  x0 = core mask lsb
928*cc708597SJiafei Pan * out: none
929*cc708597SJiafei Pan * uses x0, x1
930*cc708597SJiafei Pan */
931*cc708597SJiafei Panfunc _soc_sys_exit_pwrdn
932*cc708597SJiafei Pan	/* clear WFIL2_EN in SCFG_COREPMCR */
933*cc708597SJiafei Pan	mov	x1, #NXP_SCFG_ADDR
934*cc708597SJiafei Pan	str	wzr, [x1, #SCFG_COREPMCR_OFFSET]
935*cc708597SJiafei Pan
936*cc708597SJiafei Pan	ret
937*cc708597SJiafei Panendfunc _soc_sys_exit_pwrdn
938