xref: /rk3399_ARM-atf/plat/nxp/soc-ls1088a/aarch64/ls1088a.S (revision 2ea18c7df31f8239e1052f39cf26f1bb8c9d0c25)
1*9df5ba05SJiafei Pan/*
2*9df5ba05SJiafei Pan * Copyright 2022 NXP
3*9df5ba05SJiafei Pan *
4*9df5ba05SJiafei Pan * SPDX-License-Identifier: BSD-3-Clause
5*9df5ba05SJiafei Pan */
6*9df5ba05SJiafei Pan
7*9df5ba05SJiafei Pan.section .text, "ax"
8*9df5ba05SJiafei Pan
9*9df5ba05SJiafei Pan#include <asm_macros.S>
10*9df5ba05SJiafei Pan#include <lib/psci/psci.h>
11*9df5ba05SJiafei Pan#include <nxp_timer.h>
12*9df5ba05SJiafei Pan#include <plat_gic.h>
13*9df5ba05SJiafei Pan
14*9df5ba05SJiafei Pan#include "bl31_data.h"
15*9df5ba05SJiafei Pan#include "plat_psci.h"
16*9df5ba05SJiafei Pan#include "platform_def.h"
17*9df5ba05SJiafei Pan
18*9df5ba05SJiafei Pan/*
19*9df5ba05SJiafei Pan * the BASE address for these offsets is AUX_01_DATA in the
20*9df5ba05SJiafei Pan * bootcore's psci data region
21*9df5ba05SJiafei Pan */
22*9df5ba05SJiafei Pan#define DEVDISR2_MASK_OFFSET	0x0    /* references AUX_01_DATA */
23*9df5ba05SJiafei Pan#define DEVDISR5_MASK_OFFSET	0x8    /* references AUX_02_DATA */
24*9df5ba05SJiafei Pan
25*9df5ba05SJiafei Pan/*
26*9df5ba05SJiafei Pan * the BASE address for these offsets is AUX_04_DATA in the
27*9df5ba05SJiafei Pan * bootcore's psci data region
28*9df5ba05SJiafei Pan */
29*9df5ba05SJiafei Pan#define GICD_BASE_ADDR_OFFSET	0x0    /* references AUX_04_DATA */
30*9df5ba05SJiafei Pan#define GICC_BASE_ADDR_OFFSET	0x8    /* references AUX_05_DATA */
31*9df5ba05SJiafei Pan
32*9df5ba05SJiafei Pan#define IPSTPACK_RETRY_CNT	0x10000
33*9df5ba05SJiafei Pan#define DDR_SLEEP_RETRY_CNT	0x10000
34*9df5ba05SJiafei Pan#define CPUACTLR_EL1		S3_1_C15_C2_0
35*9df5ba05SJiafei Pan#define DDR_SDRAM_CFG_2_FRCSR	0x80000000
36*9df5ba05SJiafei Pan#define DDR_SDRAM_CFG_2_OFFSET	0x114
37*9df5ba05SJiafei Pan#define DDR_TIMING_CFG_4_OFFSET	0x160
38*9df5ba05SJiafei Pan#define DDR_CNTRL_BASE_ADDR	0x01080000
39*9df5ba05SJiafei Pan
40*9df5ba05SJiafei Pan#define DLL_LOCK_MASK		0x3
41*9df5ba05SJiafei Pan#define DLL_LOCK_VALUE		0x2
42*9df5ba05SJiafei Pan
43*9df5ba05SJiafei Pan#define ERROR_DDR_SLEEP		-1
44*9df5ba05SJiafei Pan#define ERROR_DDR_WAKE		-2
45*9df5ba05SJiafei Pan#define ERROR_NO_QUIESCE	-3
46*9df5ba05SJiafei Pan
47*9df5ba05SJiafei Pan#define CORE_RESTARTABLE	0
48*9df5ba05SJiafei Pan#define CORE_NOT_RESTARTABLE	1
49*9df5ba05SJiafei Pan
50*9df5ba05SJiafei Pan.global soc_init_lowlevel
51*9df5ba05SJiafei Pan.global soc_init_percpu
52*9df5ba05SJiafei Pan
53*9df5ba05SJiafei Pan.global _soc_core_release
54*9df5ba05SJiafei Pan.global _soc_core_restart
55*9df5ba05SJiafei Pan.global _soc_ck_disabled
56*9df5ba05SJiafei Pan.global _soc_sys_reset
57*9df5ba05SJiafei Pan.global _soc_sys_off
58*9df5ba05SJiafei Pan
59*9df5ba05SJiafei Pan.global _soc_core_prep_off
60*9df5ba05SJiafei Pan.global _soc_core_entr_off
61*9df5ba05SJiafei Pan.global _soc_core_exit_off
62*9df5ba05SJiafei Pan
63*9df5ba05SJiafei Pan.global _soc_core_prep_stdby
64*9df5ba05SJiafei Pan.global _soc_core_entr_stdby
65*9df5ba05SJiafei Pan.global _soc_core_exit_stdby
66*9df5ba05SJiafei Pan.global _soc_core_prep_pwrdn
67*9df5ba05SJiafei Pan.global _soc_core_entr_pwrdn
68*9df5ba05SJiafei Pan.global _soc_core_exit_pwrdn
69*9df5ba05SJiafei Pan.global _soc_clstr_prep_stdby
70*9df5ba05SJiafei Pan.global _soc_clstr_exit_stdby
71*9df5ba05SJiafei Pan.global _soc_clstr_prep_pwrdn
72*9df5ba05SJiafei Pan.global _soc_clstr_exit_pwrdn
73*9df5ba05SJiafei Pan.global _soc_sys_prep_stdby
74*9df5ba05SJiafei Pan.global _soc_sys_exit_stdby
75*9df5ba05SJiafei Pan.global _soc_sys_prep_pwrdn
76*9df5ba05SJiafei Pan.global _soc_sys_pwrdn_wfi
77*9df5ba05SJiafei Pan.global _soc_sys_exit_pwrdn
78*9df5ba05SJiafei Pan
79*9df5ba05SJiafei Pan.global _set_platform_security
80*9df5ba05SJiafei Pan.global _soc_set_start_addr
81*9df5ba05SJiafei Pan
82*9df5ba05SJiafei Pan.equ TZPCDECPROT_0_SET_BASE, 0x02200804
83*9df5ba05SJiafei Pan.equ TZPCDECPROT_1_SET_BASE, 0x02200810
84*9df5ba05SJiafei Pan.equ TZPCDECPROT_2_SET_BASE, 0x0220081C
85*9df5ba05SJiafei Pan
86*9df5ba05SJiafei Pan.equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110
87*9df5ba05SJiafei Pan
88*9df5ba05SJiafei Pan.equ MPIDR_AFFINITY0_MASK, 0x00FF
89*9df5ba05SJiafei Pan.equ MPIDR_AFFINITY1_MASK, 0xFF00
90*9df5ba05SJiafei Pan.equ CPUECTLR_DISABLE_TWALK_PREFETCH, 0x4000000000
91*9df5ba05SJiafei Pan.equ CPUECTLR_INS_PREFETCH_MASK, 0x1800000000
92*9df5ba05SJiafei Pan.equ CPUECTLR_DAT_PREFETCH_MASK, 0x0300000000
93*9df5ba05SJiafei Pan.equ OSDLR_EL1_DLK_LOCK, 0x1
94*9df5ba05SJiafei Pan.equ CNTP_CTL_EL0_EN, 0x1
95*9df5ba05SJiafei Pan.equ CNTP_CTL_EL0_IMASK, 0x2
96*9df5ba05SJiafei Pan/* shifted value for incrementing cluster count in mpidr */
97*9df5ba05SJiafei Pan.equ MPIDR_CLUSTER, 0x100
98*9df5ba05SJiafei Pan
99*9df5ba05SJiafei Pan/*
100*9df5ba05SJiafei Pan * This function initialize the soc,
101*9df5ba05SJiafei Pan * in: none
102*9df5ba05SJiafei Pan * out: none
103*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11
104*9df5ba05SJiafei Pan */
105*9df5ba05SJiafei Panfunc soc_init_lowlevel
106*9df5ba05SJiafei Pan	/*
107*9df5ba05SJiafei Pan	 * called from C, so save the non-volatile regs
108*9df5ba05SJiafei Pan	 * save these as pairs of registers to maintain the
109*9df5ba05SJiafei Pan	 * required 16-byte alignment on the stack
110*9df5ba05SJiafei Pan	 */
111*9df5ba05SJiafei Pan	stp	x4, x5, [sp, #-16]!
112*9df5ba05SJiafei Pan	stp	x6, x7, [sp, #-16]!
113*9df5ba05SJiafei Pan	stp	x8, x9, [sp, #-16]!
114*9df5ba05SJiafei Pan	stp	x10, x11, [sp, #-16]!
115*9df5ba05SJiafei Pan	stp	x12, x13, [sp, #-16]!
116*9df5ba05SJiafei Pan	stp	x18, x30, [sp, #-16]!
117*9df5ba05SJiafei Pan
118*9df5ba05SJiafei Pan	/*
119*9df5ba05SJiafei Pan	 * make sure the personality has been established by releasing cores
120*9df5ba05SJiafei Pan	 * that are marked "to-be-disabled" from reset
121*9df5ba05SJiafei Pan	 */
122*9df5ba05SJiafei Pan	bl	release_disabled
123*9df5ba05SJiafei Pan
124*9df5ba05SJiafei Pan	/* set SCRATCHRW7 to 0x0 */
125*9df5ba05SJiafei Pan	ldr	x0, =DCFG_SCRATCHRW7_OFFSET
126*9df5ba05SJiafei Pan	mov	x1, xzr
127*9df5ba05SJiafei Pan	bl	_write_reg_dcfg
128*9df5ba05SJiafei Pan
129*9df5ba05SJiafei Pan	/* restore the aarch32/64 non-volatile registers */
130*9df5ba05SJiafei Pan	ldp	x18, x30, [sp], #16
131*9df5ba05SJiafei Pan	ldp	x12, x13, [sp], #16
132*9df5ba05SJiafei Pan	ldp	x10, x11, [sp], #16
133*9df5ba05SJiafei Pan	ldp	x8, x9, [sp], #16
134*9df5ba05SJiafei Pan	ldp	x6, x7, [sp], #16
135*9df5ba05SJiafei Pan	ldp	x4, x5, [sp], #16
136*9df5ba05SJiafei Pan	ret
137*9df5ba05SJiafei Panendfunc soc_init_lowlevel
138*9df5ba05SJiafei Pan
139*9df5ba05SJiafei Pan/*
140*9df5ba05SJiafei Pan * void soc_init_percpu(void)
141*9df5ba05SJiafei Pan * this function performs any soc-specific initialization that is needed on
142*9df5ba05SJiafei Pan * a per-core basis
143*9df5ba05SJiafei Pan * in:  none
144*9df5ba05SJiafei Pan * out: none
145*9df5ba05SJiafei Pan * uses x0, x1, x2, x3
146*9df5ba05SJiafei Pan */
147*9df5ba05SJiafei Panfunc soc_init_percpu
148*9df5ba05SJiafei Pan	stp	x4, x30, [sp, #-16]!
149*9df5ba05SJiafei Pan
150*9df5ba05SJiafei Pan	bl	plat_my_core_mask
151*9df5ba05SJiafei Pan	mov	x2, x0
152*9df5ba05SJiafei Pan
153*9df5ba05SJiafei Pan	/* x2 = core mask */
154*9df5ba05SJiafei Pan
155*9df5ba05SJiafei Pan	/* see if this core is marked for prefetch disable */
156*9df5ba05SJiafei Pan	mov	x0, #PREFETCH_DIS_OFFSET
157*9df5ba05SJiafei Pan	bl	_get_global_data
158*9df5ba05SJiafei Pan	tst	x0, x2
159*9df5ba05SJiafei Pan	b.eq	1f
160*9df5ba05SJiafei Pan	bl	_disable_ldstr_pfetch_A53
161*9df5ba05SJiafei Pan1:
162*9df5ba05SJiafei Pan	mov	x0, #NXP_PMU_ADDR
163*9df5ba05SJiafei Pan	bl	enable_timer_base_to_cluster
164*9df5ba05SJiafei Pan	ldp	x4, x30, [sp], #16
165*9df5ba05SJiafei Pan	ret
166*9df5ba05SJiafei Panendfunc soc_init_percpu
167*9df5ba05SJiafei Pan
168*9df5ba05SJiafei Pan/*
169*9df5ba05SJiafei Pan * this function sets the security mechanisms in the SoC to implement the
170*9df5ba05SJiafei Pan * Platform Security Policy
171*9df5ba05SJiafei Pan */
172*9df5ba05SJiafei Panfunc _set_platform_security
173*9df5ba05SJiafei Pan	mov	x3, x30
174*9df5ba05SJiafei Pan
175*9df5ba05SJiafei Pan#if (!SUPPRESS_TZC)
176*9df5ba05SJiafei Pan	/* initialize the tzpc */
177*9df5ba05SJiafei Pan	bl	init_tzpc
178*9df5ba05SJiafei Pan#endif
179*9df5ba05SJiafei Pan
180*9df5ba05SJiafei Pan#if (!SUPPRESS_SEC)
181*9df5ba05SJiafei Pan	/* initialize secmon */
182*9df5ba05SJiafei Pan	bl	initSecMon
183*9df5ba05SJiafei Pan#endif
184*9df5ba05SJiafei Pan	mov	x30, x3
185*9df5ba05SJiafei Pan	ret
186*9df5ba05SJiafei Panendfunc _set_platform_security
187*9df5ba05SJiafei Pan
188*9df5ba05SJiafei Pan/*
189*9df5ba05SJiafei Pan * this function writes a 64-bit address to bootlocptrh/l
190*9df5ba05SJiafei Pan * in:  x0, 64-bit address to write to BOOTLOCPTRL/H
191*9df5ba05SJiafei Pan * out: none
192*9df5ba05SJiafei Pan * uses x0, x1, x2
193*9df5ba05SJiafei Pan */
194*9df5ba05SJiafei Panfunc _soc_set_start_addr
195*9df5ba05SJiafei Pan	/* get the 64-bit base address of the dcfg block */
196*9df5ba05SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
197*9df5ba05SJiafei Pan
198*9df5ba05SJiafei Pan	/* write the 32-bit BOOTLOCPTRL register */
199*9df5ba05SJiafei Pan	mov	x1, x0
200*9df5ba05SJiafei Pan	str	w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
201*9df5ba05SJiafei Pan
202*9df5ba05SJiafei Pan	/* write the 32-bit BOOTLOCPTRH register */
203*9df5ba05SJiafei Pan	lsr	x1, x0, #32
204*9df5ba05SJiafei Pan	str	w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
205*9df5ba05SJiafei Pan	ret
206*9df5ba05SJiafei Panendfunc _soc_set_start_addr
207*9df5ba05SJiafei Pan
208*9df5ba05SJiafei Pan/*
209*9df5ba05SJiafei Pan * part of CPU_ON
210*9df5ba05SJiafei Pan * this function releases a secondary core from reset
211*9df5ba05SJiafei Pan * in: x0 = core_mask_lsb
212*9df5ba05SJiafei Pan * out: none
213*9df5ba05SJiafei Pan * uses: x0, x1, x2, x3
214*9df5ba05SJiafei Pan */
215*9df5ba05SJiafei Pan_soc_core_release:
216*9df5ba05SJiafei Pan	mov	x3, x30
217*9df5ba05SJiafei Pan
218*9df5ba05SJiafei Pan	/* x0 = core mask */
219*9df5ba05SJiafei Pan
220*9df5ba05SJiafei Pan	ldr	x1, =NXP_SEC_REGFILE_ADDR
221*9df5ba05SJiafei Pan	/*
222*9df5ba05SJiafei Pan	 * write to CORE_HOLD to tell the bootrom that we want this core
223*9df5ba05SJiafei Pan	 * to run
224*9df5ba05SJiafei Pan	 */
225*9df5ba05SJiafei Pan	str	w0, [x1, #CORE_HOLD_OFFSET]
226*9df5ba05SJiafei Pan
227*9df5ba05SJiafei Pan	/* x0 = core mask */
228*9df5ba05SJiafei Pan
229*9df5ba05SJiafei Pan	/* read-modify-write BRRL to release core */
230*9df5ba05SJiafei Pan	mov	x1, #NXP_RESET_ADDR
231*9df5ba05SJiafei Pan	ldr	w2, [x1, #BRR_OFFSET]
232*9df5ba05SJiafei Pan	orr	w2, w2, w0
233*9df5ba05SJiafei Pan	str	w2, [x1, #BRR_OFFSET]
234*9df5ba05SJiafei Pan	dsb	sy
235*9df5ba05SJiafei Pan	isb
236*9df5ba05SJiafei Pan
237*9df5ba05SJiafei Pan	/* send event */
238*9df5ba05SJiafei Pan	sev
239*9df5ba05SJiafei Pan	isb
240*9df5ba05SJiafei Pan
241*9df5ba05SJiafei Pan	mov	x30, x3
242*9df5ba05SJiafei Pan	ret
243*9df5ba05SJiafei Pan
244*9df5ba05SJiafei Pan/*
245*9df5ba05SJiafei Pan * this function determines if a core is disabled via COREDISABLEDSR
246*9df5ba05SJiafei Pan * in:  w0  = core_mask_lsb
247*9df5ba05SJiafei Pan * out: w0  = 0, core not disabled
248*9df5ba05SJiafei Pan *      w0 != 0, core disabled
249*9df5ba05SJiafei Pan * uses x0, x1
250*9df5ba05SJiafei Pan */
251*9df5ba05SJiafei Pan_soc_ck_disabled:
252*9df5ba05SJiafei Pan	/* get base addr of dcfg block */
253*9df5ba05SJiafei Pan	ldr	x1, =NXP_DCFG_ADDR
254*9df5ba05SJiafei Pan
255*9df5ba05SJiafei Pan	/* read COREDISABLEDSR */
256*9df5ba05SJiafei Pan	ldr	w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
257*9df5ba05SJiafei Pan
258*9df5ba05SJiafei Pan	/* test core bit */
259*9df5ba05SJiafei Pan	and	w0, w1, w0
260*9df5ba05SJiafei Pan
261*9df5ba05SJiafei Pan	ret
262*9df5ba05SJiafei Pan
263*9df5ba05SJiafei Pan/*
264*9df5ba05SJiafei Pan * part of CPU_ON
265*9df5ba05SJiafei Pan * this function restarts a core shutdown via _soc_core_entr_off
266*9df5ba05SJiafei Pan * in:  x0 = core mask lsb (of the target cpu)
267*9df5ba05SJiafei Pan * out: x0 == 0, on success
268*9df5ba05SJiafei Pan *      x0 != 0, on failure
269*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6
270*9df5ba05SJiafei Pan */
271*9df5ba05SJiafei Pan_soc_core_restart:
272*9df5ba05SJiafei Pan	mov	x6, x30
273*9df5ba05SJiafei Pan	mov	x4, x0
274*9df5ba05SJiafei Pan
275*9df5ba05SJiafei Pan	/* x4 = core mask lsb */
276*9df5ba05SJiafei Pan
277*9df5ba05SJiafei Pan	/* pgm GICD_CTLR - enable secure grp0  */
278*9df5ba05SJiafei Pan	mov	x5, #NXP_GICD_ADDR
279*9df5ba05SJiafei Pan	ldr	w2, [x5, #GICD_CTLR_OFFSET]
280*9df5ba05SJiafei Pan	orr	w2, w2, #GICD_CTLR_EN_GRP_0
281*9df5ba05SJiafei Pan	str	w2, [x5, #GICD_CTLR_OFFSET]
282*9df5ba05SJiafei Pan	dsb	sy
283*9df5ba05SJiafei Pan	isb
284*9df5ba05SJiafei Pan	/* poll on RWP til write completes */
285*9df5ba05SJiafei Pan4:
286*9df5ba05SJiafei Pan	ldr	w2, [x5, #GICD_CTLR_OFFSET]
287*9df5ba05SJiafei Pan	tst	w2, #GICD_CTLR_RWP
288*9df5ba05SJiafei Pan	b.ne	4b
289*9df5ba05SJiafei Pan
290*9df5ba05SJiafei Pan	/*
291*9df5ba05SJiafei Pan	 * x4 = core mask lsb
292*9df5ba05SJiafei Pan	 * x5 = gicd base addr
293*9df5ba05SJiafei Pan	 */
294*9df5ba05SJiafei Pan
295*9df5ba05SJiafei Pan	mov	x0, x4
296*9df5ba05SJiafei Pan	bl	get_mpidr_value
297*9df5ba05SJiafei Pan
298*9df5ba05SJiafei Pan	/*
299*9df5ba05SJiafei Pan	 * x0 = mpidr of target core
300*9df5ba05SJiafei Pan	 * x4 = core mask lsb of target core
301*9df5ba05SJiafei Pan	 * x5 = gicd base addr
302*9df5ba05SJiafei Pan	 */
303*9df5ba05SJiafei Pan
304*9df5ba05SJiafei Pan	/* generate target list bit */
305*9df5ba05SJiafei Pan	and	x1, x0, #MPIDR_AFFINITY0_MASK
306*9df5ba05SJiafei Pan	mov	x2, #1
307*9df5ba05SJiafei Pan	lsl	x2, x2, x1
308*9df5ba05SJiafei Pan	/* get the affinity1 field */
309*9df5ba05SJiafei Pan	and	x1, x0, #MPIDR_AFFINITY1_MASK
310*9df5ba05SJiafei Pan	lsl	x1, x1, #8
311*9df5ba05SJiafei Pan	orr	x2, x2, x1
312*9df5ba05SJiafei Pan	/* insert the INTID for SGI15 */
313*9df5ba05SJiafei Pan	orr	x2, x2, #ICC_SGI0R_EL1_INTID
314*9df5ba05SJiafei Pan	/* fire the SGI */
315*9df5ba05SJiafei Pan	msr	ICC_SGI0R_EL1, x2
316*9df5ba05SJiafei Pan	dsb	sy
317*9df5ba05SJiafei Pan	isb
318*9df5ba05SJiafei Pan
319*9df5ba05SJiafei Pan	/* load '0' on success */
320*9df5ba05SJiafei Pan	mov	x0, xzr
321*9df5ba05SJiafei Pan
322*9df5ba05SJiafei Pan	mov	x30, x6
323*9df5ba05SJiafei Pan	ret
324*9df5ba05SJiafei Pan
325*9df5ba05SJiafei Pan/*
326*9df5ba05SJiafei Pan * part of CPU_OFF
327*9df5ba05SJiafei Pan * this function programs SoC & GIC registers in preparation for shutting down
328*9df5ba05SJiafei Pan * the core
329*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
330*9df5ba05SJiafei Pan * out: none
331*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7
332*9df5ba05SJiafei Pan */
333*9df5ba05SJiafei Pan_soc_core_prep_off:
334*9df5ba05SJiafei Pan	mov	x8, x30
335*9df5ba05SJiafei Pan	mov	x7, x0
336*9df5ba05SJiafei Pan
337*9df5ba05SJiafei Pan	/* x7 = core mask lsb */
338*9df5ba05SJiafei Pan
339*9df5ba05SJiafei Pan	mrs	x1, CPUECTLR_EL1
340*9df5ba05SJiafei Pan	/* set smp and disable L2 snoops in cpuectlr */
341*9df5ba05SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_EN
342*9df5ba05SJiafei Pan	orr	x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
343*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_INS_PREFETCH_MASK
344*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
345*9df5ba05SJiafei Pan	/* set retention control in cpuectlr */
346*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
347*9df5ba05SJiafei Pan	orr	x1, x1, #CPUECTLR_TIMER_8TICKS
348*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x1
349*9df5ba05SJiafei Pan
350*9df5ba05SJiafei Pan	/* get redistributor rd base addr for this core */
351*9df5ba05SJiafei Pan	mov	x0, x7
352*9df5ba05SJiafei Pan	bl	get_gic_rd_base
353*9df5ba05SJiafei Pan	mov	x6, x0
354*9df5ba05SJiafei Pan
355*9df5ba05SJiafei Pan	/* get redistributor sgi base addr for this core */
356*9df5ba05SJiafei Pan	mov	x0, x7
357*9df5ba05SJiafei Pan	bl	get_gic_sgi_base
358*9df5ba05SJiafei Pan	mov	x5, x0
359*9df5ba05SJiafei Pan
360*9df5ba05SJiafei Pan	/* x5 = gicr sgi base addr
361*9df5ba05SJiafei Pan	 * x6 = gicr rd  base addr
362*9df5ba05SJiafei Pan	 * x7 = core mask lsb
363*9df5ba05SJiafei Pan	 */
364*9df5ba05SJiafei Pan
365*9df5ba05SJiafei Pan	/* disable SGI 15 at redistributor - GICR_ICENABLER0 */
366*9df5ba05SJiafei Pan	mov	w3, #GICR_ICENABLER0_SGI15
367*9df5ba05SJiafei Pan	str	w3, [x5, #GICR_ICENABLER0_OFFSET]
368*9df5ba05SJiafei Pan2:
369*9df5ba05SJiafei Pan	/* poll on rwp bit in GICR_CTLR */
370*9df5ba05SJiafei Pan	ldr	w4, [x6, #GICR_CTLR_OFFSET]
371*9df5ba05SJiafei Pan	tst	w4, #GICR_CTLR_RWP
372*9df5ba05SJiafei Pan	b.ne	2b
373*9df5ba05SJiafei Pan
374*9df5ba05SJiafei Pan	/* disable GRP1 interrupts at cpu interface */
375*9df5ba05SJiafei Pan	msr	ICC_IGRPEN1_EL3, xzr
376*9df5ba05SJiafei Pan
377*9df5ba05SJiafei Pan	/* disable GRP0 ints at cpu interface */
378*9df5ba05SJiafei Pan	msr	ICC_IGRPEN0_EL1, xzr
379*9df5ba05SJiafei Pan
380*9df5ba05SJiafei Pan	/* program the redistributor - poll on GICR_CTLR.RWP as needed */
381*9df5ba05SJiafei Pan
382*9df5ba05SJiafei Pan	/* define SGI 15 as Grp0 - GICR_IGROUPR0 */
383*9df5ba05SJiafei Pan	ldr	w4, [x5, #GICR_IGROUPR0_OFFSET]
384*9df5ba05SJiafei Pan	bic	w4, w4, #GICR_IGROUPR0_SGI15
385*9df5ba05SJiafei Pan	str	w4, [x5, #GICR_IGROUPR0_OFFSET]
386*9df5ba05SJiafei Pan
387*9df5ba05SJiafei Pan	/* define SGI 15 as Grp0 - GICR_IGRPMODR0 */
388*9df5ba05SJiafei Pan	ldr	w3, [x5, #GICR_IGRPMODR0_OFFSET]
389*9df5ba05SJiafei Pan	bic	w3, w3, #GICR_IGRPMODR0_SGI15
390*9df5ba05SJiafei Pan	str	w3, [x5, #GICR_IGRPMODR0_OFFSET]
391*9df5ba05SJiafei Pan
392*9df5ba05SJiafei Pan	/* set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
393*9df5ba05SJiafei Pan	ldr	w4, [x5, #GICR_IPRIORITYR3_OFFSET]
394*9df5ba05SJiafei Pan	bic	w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
395*9df5ba05SJiafei Pan	str	w4, [x5, #GICR_IPRIORITYR3_OFFSET]
396*9df5ba05SJiafei Pan
397*9df5ba05SJiafei Pan	/* enable SGI 15 at redistributor - GICR_ISENABLER0 */
398*9df5ba05SJiafei Pan	mov	w3, #GICR_ISENABLER0_SGI15
399*9df5ba05SJiafei Pan	str	w3, [x5, #GICR_ISENABLER0_OFFSET]
400*9df5ba05SJiafei Pan	dsb	sy
401*9df5ba05SJiafei Pan	isb
402*9df5ba05SJiafei Pan3:
403*9df5ba05SJiafei Pan	/* poll on rwp bit in GICR_CTLR */
404*9df5ba05SJiafei Pan	ldr	w4, [x6, #GICR_CTLR_OFFSET]
405*9df5ba05SJiafei Pan	tst	w4, #GICR_CTLR_RWP
406*9df5ba05SJiafei Pan	b.ne	3b
407*9df5ba05SJiafei Pan
408*9df5ba05SJiafei Pan	/* quiesce the debug interfaces */
409*9df5ba05SJiafei Pan	mrs	x3, osdlr_el1
410*9df5ba05SJiafei Pan	orr	x3, x3, #OSDLR_EL1_DLK_LOCK
411*9df5ba05SJiafei Pan	msr	osdlr_el1, x3
412*9df5ba05SJiafei Pan	isb
413*9df5ba05SJiafei Pan
414*9df5ba05SJiafei Pan	/* enable grp0 ints */
415*9df5ba05SJiafei Pan	mov	x3, #ICC_IGRPEN0_EL1_EN
416*9df5ba05SJiafei Pan	msr	ICC_IGRPEN0_EL1, x3
417*9df5ba05SJiafei Pan
418*9df5ba05SJiafei Pan	/*
419*9df5ba05SJiafei Pan	 * x5 = gicr sgi base addr
420*9df5ba05SJiafei Pan	 * x6 = gicr rd  base addr
421*9df5ba05SJiafei Pan	 * x7 = core mask lsb
422*9df5ba05SJiafei Pan	 */
423*9df5ba05SJiafei Pan
424*9df5ba05SJiafei Pan	/* clear any pending interrupts */
425*9df5ba05SJiafei Pan	mvn	w1, wzr
426*9df5ba05SJiafei Pan	str	w1, [x5, #GICR_ICPENDR0_OFFSET]
427*9df5ba05SJiafei Pan
428*9df5ba05SJiafei Pan	/* make sure system counter is enabled */
429*9df5ba05SJiafei Pan	ldr	x3, =NXP_TIMER_ADDR
430*9df5ba05SJiafei Pan	ldr	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
431*9df5ba05SJiafei Pan	tst	w0, #SYS_COUNTER_CNTCR_EN
432*9df5ba05SJiafei Pan	b.ne	4f
433*9df5ba05SJiafei Pan	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
434*9df5ba05SJiafei Pan	str	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
435*9df5ba05SJiafei Pan4:
436*9df5ba05SJiafei Pan	/* enable the core timer and mask timer interrupt */
437*9df5ba05SJiafei Pan	mov	x1, #CNTP_CTL_EL0_EN
438*9df5ba05SJiafei Pan	orr	x1, x1, #CNTP_CTL_EL0_IMASK
439*9df5ba05SJiafei Pan	msr	cntp_ctl_el0, x1
440*9df5ba05SJiafei Pan
441*9df5ba05SJiafei Pan	mov	x30, x8
442*9df5ba05SJiafei Pan	ret
443*9df5ba05SJiafei Pan
444*9df5ba05SJiafei Pan/*
445*9df5ba05SJiafei Pan * part of CPU_OFF
446*9df5ba05SJiafei Pan * this function performs the final steps to shutdown the core
447*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
448*9df5ba05SJiafei Pan * out: none
449*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5
450*9df5ba05SJiafei Pan */
451*9df5ba05SJiafei Pan_soc_core_entr_off:
452*9df5ba05SJiafei Pan	mov	x5, x30
453*9df5ba05SJiafei Pan	mov	x4, x0
454*9df5ba05SJiafei Pan
455*9df5ba05SJiafei Pan	/* x4 = core mask */
456*9df5ba05SJiafei Pan1:
457*9df5ba05SJiafei Pan	/* enter low-power state by executing wfi */
458*9df5ba05SJiafei Pan	wfi
459*9df5ba05SJiafei Pan
460*9df5ba05SJiafei Pan	/* see if SGI15 woke us up */
461*9df5ba05SJiafei Pan	mrs	x2, ICC_IAR0_EL1
462*9df5ba05SJiafei Pan	mov	x3, #ICC_IAR0_EL1_SGI15
463*9df5ba05SJiafei Pan	cmp	x2, x3
464*9df5ba05SJiafei Pan	b.ne	2f
465*9df5ba05SJiafei Pan
466*9df5ba05SJiafei Pan	/* deactivate the int */
467*9df5ba05SJiafei Pan	msr	ICC_EOIR0_EL1, x2
468*9df5ba05SJiafei Pan
469*9df5ba05SJiafei Pan	/* x4 = core mask */
470*9df5ba05SJiafei Pan2:
471*9df5ba05SJiafei Pan	/* check if core has been turned on */
472*9df5ba05SJiafei Pan	mov	x0, x4
473*9df5ba05SJiafei Pan	bl	_getCoreState
474*9df5ba05SJiafei Pan
475*9df5ba05SJiafei Pan	/* x0 = core state */
476*9df5ba05SJiafei Pan
477*9df5ba05SJiafei Pan	cmp	x0, #CORE_WAKEUP
478*9df5ba05SJiafei Pan	b.ne	1b
479*9df5ba05SJiafei Pan
480*9df5ba05SJiafei Pan	/* if we get here, then we have exited the wfi */
481*9df5ba05SJiafei Pan
482*9df5ba05SJiafei Pan	mov	x30, x5
483*9df5ba05SJiafei Pan	ret
484*9df5ba05SJiafei Pan
485*9df5ba05SJiafei Pan/*
486*9df5ba05SJiafei Pan * part of CPU_OFF
487*9df5ba05SJiafei Pan * this function starts the process of starting a core back up
488*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
489*9df5ba05SJiafei Pan * out: none
490*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6
491*9df5ba05SJiafei Pan */
492*9df5ba05SJiafei Pan_soc_core_exit_off:
493*9df5ba05SJiafei Pan	mov	x6, x30
494*9df5ba05SJiafei Pan	mov	x5, x0
495*9df5ba05SJiafei Pan
496*9df5ba05SJiafei Pan	/* disable forwarding of GRP0 ints at cpu interface */
497*9df5ba05SJiafei Pan	msr	ICC_IGRPEN0_EL1, xzr
498*9df5ba05SJiafei Pan
499*9df5ba05SJiafei Pan	/* get redistributor sgi base addr for this core */
500*9df5ba05SJiafei Pan	mov	x0, x5
501*9df5ba05SJiafei Pan	bl	get_gic_sgi_base
502*9df5ba05SJiafei Pan	mov	x4, x0
503*9df5ba05SJiafei Pan
504*9df5ba05SJiafei Pan	/*
505*9df5ba05SJiafei Pan	 * x4 = gicr sgi base addr
506*9df5ba05SJiafei Pan	 * x5 = core mask
507*9df5ba05SJiafei Pan	 */
508*9df5ba05SJiafei Pan
509*9df5ba05SJiafei Pan	/* disable SGI 15 at redistributor - GICR_ICENABLER0 */
510*9df5ba05SJiafei Pan	mov	w1, #GICR_ICENABLER0_SGI15
511*9df5ba05SJiafei Pan	str	w1, [x4, #GICR_ICENABLER0_OFFSET]
512*9df5ba05SJiafei Pan
513*9df5ba05SJiafei Pan	/* get redistributor rd base addr for this core */
514*9df5ba05SJiafei Pan	mov	x0, x5
515*9df5ba05SJiafei Pan	bl	get_gic_rd_base
516*9df5ba05SJiafei Pan	mov	x4, x0
517*9df5ba05SJiafei Pan
518*9df5ba05SJiafei Pan	/* x4 = gicr rd  base addr */
519*9df5ba05SJiafei Pan2:
520*9df5ba05SJiafei Pan	/* poll on rwp bit in GICR_CTLR */
521*9df5ba05SJiafei Pan	ldr	w2, [x4, #GICR_CTLR_OFFSET]
522*9df5ba05SJiafei Pan	tst	w2, #GICR_CTLR_RWP
523*9df5ba05SJiafei Pan	b.ne	2b
524*9df5ba05SJiafei Pan
525*9df5ba05SJiafei Pan	/* x4 = gicr rd  base addr */
526*9df5ba05SJiafei Pan
527*9df5ba05SJiafei Pan	/* unlock the debug interfaces */
528*9df5ba05SJiafei Pan	mrs	x3, osdlr_el1
529*9df5ba05SJiafei Pan	bic	x3, x3, #OSDLR_EL1_DLK_LOCK
530*9df5ba05SJiafei Pan	msr	osdlr_el1, x3
531*9df5ba05SJiafei Pan	isb
532*9df5ba05SJiafei Pan
533*9df5ba05SJiafei Pan	dsb	sy
534*9df5ba05SJiafei Pan	isb
535*9df5ba05SJiafei Pan	mov	x30, x6
536*9df5ba05SJiafei Pan	ret
537*9df5ba05SJiafei Pan
538*9df5ba05SJiafei Pan/*
539*9df5ba05SJiafei Pan * this function requests a reset of the entire SOC
540*9df5ba05SJiafei Pan * in:  none
541*9df5ba05SJiafei Pan * out: none
542*9df5ba05SJiafei Pan * uses: x0, x1, x2, x3, x4, x5, x6
543*9df5ba05SJiafei Pan */
544*9df5ba05SJiafei Pan_soc_sys_reset:
545*9df5ba05SJiafei Pan	mov	x3, x30
546*9df5ba05SJiafei Pan
547*9df5ba05SJiafei Pan	/* make sure the mask is cleared in the reset request mask register */
548*9df5ba05SJiafei Pan	mov	x0, #RST_RSTRQMR1_OFFSET
549*9df5ba05SJiafei Pan	mov	w1, wzr
550*9df5ba05SJiafei Pan	bl	_write_reg_reset
551*9df5ba05SJiafei Pan
552*9df5ba05SJiafei Pan	/* set the reset request */
553*9df5ba05SJiafei Pan	mov	x4, #RST_RSTCR_OFFSET
554*9df5ba05SJiafei Pan	mov	x0, x4
555*9df5ba05SJiafei Pan	mov	w1, #RSTCR_RESET_REQ
556*9df5ba05SJiafei Pan	bl	_write_reg_reset
557*9df5ba05SJiafei Pan
558*9df5ba05SJiafei Pan	/* x4 = RST_RSTCR_OFFSET */
559*9df5ba05SJiafei Pan
560*9df5ba05SJiafei Pan	/*
561*9df5ba05SJiafei Pan	 * just in case this address range is mapped as cacheable,
562*9df5ba05SJiafei Pan	 * flush the write out of the dcaches
563*9df5ba05SJiafei Pan	 */
564*9df5ba05SJiafei Pan	mov	x2, #NXP_RESET_ADDR
565*9df5ba05SJiafei Pan	add	x2, x2, x4
566*9df5ba05SJiafei Pan	dc	cvac, x2
567*9df5ba05SJiafei Pan	dsb	st
568*9df5ba05SJiafei Pan	isb
569*9df5ba05SJiafei Pan
570*9df5ba05SJiafei Pan	/* this function does not return */
571*9df5ba05SJiafei Pan	b	.
572*9df5ba05SJiafei Pan
573*9df5ba05SJiafei Pan/*
574*9df5ba05SJiafei Pan * this function turns off the SoC
575*9df5ba05SJiafei Pan * Note: this function is not intended to return, and the only allowable
576*9df5ba05SJiafei Pan *       recovery is POR
577*9df5ba05SJiafei Pan * in:  none
578*9df5ba05SJiafei Pan * out: none
579*9df5ba05SJiafei Pan * uses x0, x1, x2, x3
580*9df5ba05SJiafei Pan */
581*9df5ba05SJiafei Pan_soc_sys_off:
582*9df5ba05SJiafei Pan	/*
583*9df5ba05SJiafei Pan	 * A-009810: LPM20 entry sequence might cause
584*9df5ba05SJiafei Pan	 * spurious timeout reset request
585*9df5ba05SJiafei Pan	 * workaround: MASK RESET REQ RPTOE
586*9df5ba05SJiafei Pan	 */
587*9df5ba05SJiafei Pan	ldr	x0, =NXP_RESET_ADDR
588*9df5ba05SJiafei Pan	ldr	w1, [x0, #RST_RSTRQMR1_OFFSET]
589*9df5ba05SJiafei Pan	orr	w1, w1, #RSTRQMR_RPTOE_MASK
590*9df5ba05SJiafei Pan	str	w1, [x0, #RST_RSTRQMR1_OFFSET]
591*9df5ba05SJiafei Pan
592*9df5ba05SJiafei Pan	/* disable SEC, QBman spi and qspi */
593*9df5ba05SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
594*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR1_OFFSET
595*9df5ba05SJiafei Pan	ldr	w1, =DCFG_DEVDISR1_SEC
596*9df5ba05SJiafei Pan	str	w1, [x2, x0]
597*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR3_OFFSET
598*9df5ba05SJiafei Pan	ldr	w1, =DCFG_DEVDISR3_QBMAIN
599*9df5ba05SJiafei Pan	str	w1, [x2, x0]
600*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR4_OFFSET
601*9df5ba05SJiafei Pan	ldr	w1, =DCFG_DEVDISR4_SPI_QSPI
602*9df5ba05SJiafei Pan	str	w1, [x2, x0]
603*9df5ba05SJiafei Pan
604*9df5ba05SJiafei Pan	/* set TPMWAKEMR0 */
605*9df5ba05SJiafei Pan	ldr	x0, =TPMWAKEMR0_ADDR
606*9df5ba05SJiafei Pan	mov	w1, #0x1
607*9df5ba05SJiafei Pan	str	w1, [x0]
608*9df5ba05SJiafei Pan
609*9df5ba05SJiafei Pan	/* disable icache, dcache, mmu @ EL1 */
610*9df5ba05SJiafei Pan	mov	x1, #SCTLR_I_C_M_MASK
611*9df5ba05SJiafei Pan	mrs	x0, sctlr_el1
612*9df5ba05SJiafei Pan	bic	x0, x0, x1
613*9df5ba05SJiafei Pan	msr	sctlr_el1, x0
614*9df5ba05SJiafei Pan
615*9df5ba05SJiafei Pan	/* disable L2 prefetches */
616*9df5ba05SJiafei Pan	mrs	x0, CPUECTLR_EL1
617*9df5ba05SJiafei Pan	orr	x0, x0, #CPUECTLR_SMPEN_EN
618*9df5ba05SJiafei Pan	orr	x0, x0, #CPUECTLR_TIMER_8TICKS
619*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x0
620*9df5ba05SJiafei Pan	dsb	sy
621*9df5ba05SJiafei Pan	isb
622*9df5ba05SJiafei Pan
623*9df5ba05SJiafei Pan	/* disable CCN snoop domain */
624*9df5ba05SJiafei Pan	ldr	x0, =NXP_CCI_ADDR
625*9df5ba05SJiafei Pan	mov	w1, #0x1
626*9df5ba05SJiafei Pan	str	w1, [x0]
627*9df5ba05SJiafei Pan
628*9df5ba05SJiafei Pan	mov	x2, #DAIF_SET_MASK
629*9df5ba05SJiafei Pan
630*9df5ba05SJiafei Pan	mrs	x1, spsr_el1
631*9df5ba05SJiafei Pan	orr	x1, x1, x2
632*9df5ba05SJiafei Pan	msr	spsr_el1, x1
633*9df5ba05SJiafei Pan
634*9df5ba05SJiafei Pan	mrs	x1, spsr_el2
635*9df5ba05SJiafei Pan	orr	x1, x1, x2
636*9df5ba05SJiafei Pan	msr	spsr_el2, x1
637*9df5ba05SJiafei Pan
638*9df5ba05SJiafei Pan	bl	get_pmu_idle_cluster_mask
639*9df5ba05SJiafei Pan	mov	x3, #NXP_PMU_ADDR
640*9df5ba05SJiafei Pan
641*9df5ba05SJiafei Pan	/* x3 = pmu base addr */
642*9df5ba05SJiafei Pan
643*9df5ba05SJiafei Pan	/* idle the ACP interfaces */
644*9df5ba05SJiafei Pan	str	w0, [x3, #PMU_CLAINACTSETR_OFFSET]
645*9df5ba05SJiafei Pan
646*9df5ba05SJiafei Pan	/* force the debug interface to be quiescent */
647*9df5ba05SJiafei Pan	mrs	x0, osdlr_el1
648*9df5ba05SJiafei Pan	orr	x0, x0, #0x1
649*9df5ba05SJiafei Pan	msr	osdlr_el1, x0
650*9df5ba05SJiafei Pan
651*9df5ba05SJiafei Pan	bl	get_pmu_flush_cluster_mask
652*9df5ba05SJiafei Pan	/* x3 = pmu base addr */
653*9df5ba05SJiafei Pan	mov	x3, #NXP_PMU_ADDR
654*9df5ba05SJiafei Pan
655*9df5ba05SJiafei Pan	/* clear flush request and status */
656*9df5ba05SJiafei Pan	ldr	x2, =PMU_CLSL2FLUSHCLRR_OFFSET
657*9df5ba05SJiafei Pan	str	w0, [x3, x2]
658*9df5ba05SJiafei Pan
659*9df5ba05SJiafei Pan	/* close the Skyros master port */
660*9df5ba05SJiafei Pan	ldr	x2, =PMU_CLSINACTSETR_OFFSET
661*9df5ba05SJiafei Pan	str	w0, [x3, x2]
662*9df5ba05SJiafei Pan
663*9df5ba05SJiafei Pan	/* request lpm20 */
664*9df5ba05SJiafei Pan	ldr	x0, =PMU_POWMGTCSR_OFFSET
665*9df5ba05SJiafei Pan	ldr	w1, =PMU_POWMGTCSR_VAL
666*9df5ba05SJiafei Pan	str	w1, [x3, x0]
667*9df5ba05SJiafei Pan
668*9df5ba05SJiafei Pan	/* this function does not return */
669*9df5ba05SJiafei Pan1:
670*9df5ba05SJiafei Pan	wfi
671*9df5ba05SJiafei Pan	b	1b
672*9df5ba05SJiafei Pan
673*9df5ba05SJiafei Pan/*
674*9df5ba05SJiafei Pan * part of CPU_SUSPEND
675*9df5ba05SJiafei Pan * this function performs SoC-specific programming prior to standby
676*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
677*9df5ba05SJiafei Pan * out: none
678*9df5ba05SJiafei Pan * uses x0, x1
679*9df5ba05SJiafei Pan */
680*9df5ba05SJiafei Pan_soc_core_prep_stdby:
681*9df5ba05SJiafei Pan	/* clear CPUECTLR_EL1[2:0] */
682*9df5ba05SJiafei Pan	mrs	x1, CPUECTLR_EL1
683*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
684*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x1
685*9df5ba05SJiafei Pan
686*9df5ba05SJiafei Pan	ret
687*9df5ba05SJiafei Pan
688*9df5ba05SJiafei Pan/*
689*9df5ba05SJiafei Pan * part of CPU_SUSPEND
690*9df5ba05SJiafei Pan * this function puts the calling core into standby state
691*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
692*9df5ba05SJiafei Pan * out: none
693*9df5ba05SJiafei Pan * uses x0
694*9df5ba05SJiafei Pan */
695*9df5ba05SJiafei Pan_soc_core_entr_stdby:
696*9df5ba05SJiafei Pan	/* X0 = core mask lsb */
697*9df5ba05SJiafei Pan	dsb	sy
698*9df5ba05SJiafei Pan	isb
699*9df5ba05SJiafei Pan	wfi
700*9df5ba05SJiafei Pan
701*9df5ba05SJiafei Pan	ret
702*9df5ba05SJiafei Pan
703*9df5ba05SJiafei Pan/*
704*9df5ba05SJiafei Pan * part of CPU_SUSPEND
705*9df5ba05SJiafei Pan * this function performs any SoC-specific cleanup after standby state
706*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
707*9df5ba05SJiafei Pan * out: none
708*9df5ba05SJiafei Pan * uses none
709*9df5ba05SJiafei Pan */
710*9df5ba05SJiafei Pan_soc_core_exit_stdby:
711*9df5ba05SJiafei Pan	ret
712*9df5ba05SJiafei Pan
713*9df5ba05SJiafei Pan/*
714*9df5ba05SJiafei Pan * part of CPU_SUSPEND
715*9df5ba05SJiafei Pan * this function performs SoC-specific programming prior to power-down
716*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
717*9df5ba05SJiafei Pan * out: none
718*9df5ba05SJiafei Pan * uses x0, x1, x2, x3
719*9df5ba05SJiafei Pan */
720*9df5ba05SJiafei Pan_soc_core_prep_pwrdn:
721*9df5ba05SJiafei Pan	/* make sure system counter is enabled */
722*9df5ba05SJiafei Pan	ldr	x3, =NXP_TIMER_ADDR
723*9df5ba05SJiafei Pan	ldr	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
724*9df5ba05SJiafei Pan	tst	w0, #SYS_COUNTER_CNTCR_EN
725*9df5ba05SJiafei Pan	b.ne	1f
726*9df5ba05SJiafei Pan	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
727*9df5ba05SJiafei Pan	str	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
728*9df5ba05SJiafei Pan1:
729*9df5ba05SJiafei Pan	/*
730*9df5ba05SJiafei Pan	 * enable dynamic retention control (CPUECTLR[2:0])
731*9df5ba05SJiafei Pan	 * set the SMPEN bit (CPUECTLR[6])
732*9df5ba05SJiafei Pan	 */
733*9df5ba05SJiafei Pan	mrs	x1, CPUECTLR_EL1
734*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_RET_MASK
735*9df5ba05SJiafei Pan	orr	x1, x1, #CPUECTLR_TIMER_8TICKS
736*9df5ba05SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_EN
737*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x1
738*9df5ba05SJiafei Pan
739*9df5ba05SJiafei Pan	isb
740*9df5ba05SJiafei Pan	ret
741*9df5ba05SJiafei Pan
742*9df5ba05SJiafei Pan/*
743*9df5ba05SJiafei Pan * part of CPU_SUSPEND
744*9df5ba05SJiafei Pan * this function puts the calling core into a power-down state
745*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
746*9df5ba05SJiafei Pan * out: none
747*9df5ba05SJiafei Pan * uses x0
748*9df5ba05SJiafei Pan */
749*9df5ba05SJiafei Pan_soc_core_entr_pwrdn:
750*9df5ba05SJiafei Pan	/* X0 = core mask lsb */
751*9df5ba05SJiafei Pan	dsb	sy
752*9df5ba05SJiafei Pan	isb
753*9df5ba05SJiafei Pan	wfi
754*9df5ba05SJiafei Pan
755*9df5ba05SJiafei Pan	ret
756*9df5ba05SJiafei Pan
757*9df5ba05SJiafei Pan/*
758*9df5ba05SJiafei Pan * part of CPU_SUSPEND
759*9df5ba05SJiafei Pan * this function cleans up after a core exits power-down
760*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
761*9df5ba05SJiafei Pan * out: none
762*9df5ba05SJiafei Pan * uses
763*9df5ba05SJiafei Pan */
764*9df5ba05SJiafei Pan_soc_core_exit_pwrdn:
765*9df5ba05SJiafei Pan	ret
766*9df5ba05SJiafei Pan
767*9df5ba05SJiafei Pan/*
768*9df5ba05SJiafei Pan * part of CPU_SUSPEND
769*9df5ba05SJiafei Pan * this function performs SoC-specific programming prior to standby
770*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
771*9df5ba05SJiafei Pan * out: none
772*9df5ba05SJiafei Pan * uses x0, x1
773*9df5ba05SJiafei Pan */
774*9df5ba05SJiafei Pan_soc_clstr_prep_stdby:
775*9df5ba05SJiafei Pan	/* clear CPUECTLR_EL1[2:0] */
776*9df5ba05SJiafei Pan	mrs	x1, CPUECTLR_EL1
777*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
778*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x1
779*9df5ba05SJiafei Pan
780*9df5ba05SJiafei Pan	ret
781*9df5ba05SJiafei Pan
782*9df5ba05SJiafei Pan/*
783*9df5ba05SJiafei Pan * part of CPU_SUSPEND
784*9df5ba05SJiafei Pan * this function performs any SoC-specific cleanup after standby state
785*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
786*9df5ba05SJiafei Pan * out: none
787*9df5ba05SJiafei Pan * uses none
788*9df5ba05SJiafei Pan */
789*9df5ba05SJiafei Pan_soc_clstr_exit_stdby:
790*9df5ba05SJiafei Pan	ret
791*9df5ba05SJiafei Pan
792*9df5ba05SJiafei Pan/*
793*9df5ba05SJiafei Pan * part of CPU_SUSPEND
794*9df5ba05SJiafei Pan * this function performs SoC-specific programming prior to power-down
795*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
796*9df5ba05SJiafei Pan * out: none
797*9df5ba05SJiafei Pan * uses x0, x1, x2, x3
798*9df5ba05SJiafei Pan */
799*9df5ba05SJiafei Pan_soc_clstr_prep_pwrdn:
800*9df5ba05SJiafei Pan	/* make sure system counter is enabled */
801*9df5ba05SJiafei Pan	ldr	x3, =NXP_TIMER_ADDR
802*9df5ba05SJiafei Pan	ldr	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
803*9df5ba05SJiafei Pan	tst	w0, #SYS_COUNTER_CNTCR_EN
804*9df5ba05SJiafei Pan	b.ne	1f
805*9df5ba05SJiafei Pan	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
806*9df5ba05SJiafei Pan	str	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
807*9df5ba05SJiafei Pan1:
808*9df5ba05SJiafei Pan	/*
809*9df5ba05SJiafei Pan	 * enable dynamic retention control (CPUECTLR[2:0])
810*9df5ba05SJiafei Pan	 * set the SMPEN bit (CPUECTLR[6])
811*9df5ba05SJiafei Pan	 */
812*9df5ba05SJiafei Pan	mrs	x1, CPUECTLR_EL1
813*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_RET_MASK
814*9df5ba05SJiafei Pan	orr	x1, x1, #CPUECTLR_TIMER_8TICKS
815*9df5ba05SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_EN
816*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x1
817*9df5ba05SJiafei Pan
818*9df5ba05SJiafei Pan	isb
819*9df5ba05SJiafei Pan	ret
820*9df5ba05SJiafei Pan
821*9df5ba05SJiafei Pan/*
822*9df5ba05SJiafei Pan * part of CPU_SUSPEND
823*9df5ba05SJiafei Pan * this function cleans up after a core exits power-down
824*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
825*9df5ba05SJiafei Pan * out: none
826*9df5ba05SJiafei Pan * uses
827*9df5ba05SJiafei Pan */
828*9df5ba05SJiafei Pan_soc_clstr_exit_pwrdn:
829*9df5ba05SJiafei Pan	ret
830*9df5ba05SJiafei Pan
831*9df5ba05SJiafei Pan/*
832*9df5ba05SJiafei Pan * part of CPU_SUSPEND
833*9df5ba05SJiafei Pan * this function performs SoC-specific programming prior to standby
834*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
835*9df5ba05SJiafei Pan * out: none
836*9df5ba05SJiafei Pan * uses x0, x1
837*9df5ba05SJiafei Pan */
838*9df5ba05SJiafei Pan_soc_sys_prep_stdby:
839*9df5ba05SJiafei Pan	/* clear CPUECTLR_EL1[2:0] */
840*9df5ba05SJiafei Pan	mrs	x1, CPUECTLR_EL1
841*9df5ba05SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
842*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x1
843*9df5ba05SJiafei Pan
844*9df5ba05SJiafei Pan	ret
845*9df5ba05SJiafei Pan
846*9df5ba05SJiafei Pan/*
847*9df5ba05SJiafei Pan * part of CPU_SUSPEND
848*9df5ba05SJiafei Pan * this function performs any SoC-specific cleanup after standby state
849*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
850*9df5ba05SJiafei Pan * out: none
851*9df5ba05SJiafei Pan * uses none
852*9df5ba05SJiafei Pan */
853*9df5ba05SJiafei Pan_soc_sys_exit_stdby:
854*9df5ba05SJiafei Pan	ret
855*9df5ba05SJiafei Pan
856*9df5ba05SJiafei Pan/*
857*9df5ba05SJiafei Pan * part of CPU_SUSPEND
858*9df5ba05SJiafei Pan * this function performs SoC-specific programming prior to
859*9df5ba05SJiafei Pan * suspend-to-power-down
860*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
861*9df5ba05SJiafei Pan * out: none
862*9df5ba05SJiafei Pan * uses x0
863*9df5ba05SJiafei Pan */
864*9df5ba05SJiafei Pan_soc_sys_prep_pwrdn:
865*9df5ba05SJiafei Pan	/* set retention control */
866*9df5ba05SJiafei Pan	mrs	x0, CPUECTLR_EL1
867*9df5ba05SJiafei Pan	bic	x0, x0, #CPUECTLR_TIMER_MASK
868*9df5ba05SJiafei Pan	orr	x0, x0, #CPUECTLR_TIMER_8TICKS
869*9df5ba05SJiafei Pan	orr	x0, x0, #CPUECTLR_SMPEN_EN
870*9df5ba05SJiafei Pan	msr	CPUECTLR_EL1, x0
871*9df5ba05SJiafei Pan	dsb	sy
872*9df5ba05SJiafei Pan	isb
873*9df5ba05SJiafei Pan
874*9df5ba05SJiafei Pan	ret
875*9df5ba05SJiafei Pan
876*9df5ba05SJiafei Pan/*
877*9df5ba05SJiafei Pan * part of CPU_SUSPEND
878*9df5ba05SJiafei Pan * this function puts the calling core, and potentially the soc, into a
879*9df5ba05SJiafei Pan * low-power state
880*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
881*9df5ba05SJiafei Pan * out: x0 = 0, success
882*9df5ba05SJiafei Pan *      x0 < 0, failure
883*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
884*9df5ba05SJiafei Pan */
885*9df5ba05SJiafei Pan_soc_sys_pwrdn_wfi:
886*9df5ba05SJiafei Pan	/* Save LR to stack */
887*9df5ba05SJiafei Pan	stp	x18, x30, [sp, #-16]!
888*9df5ba05SJiafei Pan
889*9df5ba05SJiafei Pan	/* Poll PCPW20SR for all secondary cores to be placed in PW20 */
890*9df5ba05SJiafei Pan	bl	get_tot_num_cores
891*9df5ba05SJiafei Pan	mov	x3, #0x1
892*9df5ba05SJiafei Pan	lsl	x3, x3, x0
893*9df5ba05SJiafei Pan	sub	x3, x3, #2
894*9df5ba05SJiafei Pan1:
895*9df5ba05SJiafei Pan	mov	x0, #NXP_PMU_ADDR
896*9df5ba05SJiafei Pan	ldr	w1, [x0, #PMU_PCPW20SR_OFFSET]
897*9df5ba05SJiafei Pan	cmp	w1, w3
898*9df5ba05SJiafei Pan	b.ne	1b
899*9df5ba05SJiafei Pan
900*9df5ba05SJiafei Pan	/* backup EPU registers to stack */
901*9df5ba05SJiafei Pan	mov	x3, #NXP_PMU_ADDR
902*9df5ba05SJiafei Pan	ldr	x2, =NXP_EPU_ADDR
903*9df5ba05SJiafei Pan	ldr	w4, [x2, #EPU_EPIMCR10_OFFSET]
904*9df5ba05SJiafei Pan	ldr	w5, [x2, #EPU_EPCCR10_OFFSET]
905*9df5ba05SJiafei Pan	ldr	w6, [x2, #EPU_EPCTR10_OFFSET]
906*9df5ba05SJiafei Pan	ldr	w7, [x2, #EPU_EPGCR_OFFSET]
907*9df5ba05SJiafei Pan	stp	x4, x5, [sp, #-16]!
908*9df5ba05SJiafei Pan	stp	x6, x7, [sp, #-16]!
909*9df5ba05SJiafei Pan
910*9df5ba05SJiafei Pan	/*
911*9df5ba05SJiafei Pan	 * x2 = epu base addr
912*9df5ba05SJiafei Pan	 * x3 = pmu base addr
913*9df5ba05SJiafei Pan	 */
914*9df5ba05SJiafei Pan
915*9df5ba05SJiafei Pan	/* set up EPU event to receive the wake signal from PMU */
916*9df5ba05SJiafei Pan	mov	w4, #EPU_EPIMCR10_VAL
917*9df5ba05SJiafei Pan	mov	w5, #EPU_EPCCR10_VAL
918*9df5ba05SJiafei Pan	mov	w6, #EPU_EPCTR10_VAL
919*9df5ba05SJiafei Pan	mov	w7, #EPU_EPGCR_VAL
920*9df5ba05SJiafei Pan	str	w4, [x2, #EPU_EPIMCR10_OFFSET]
921*9df5ba05SJiafei Pan	str	w5, [x2, #EPU_EPCCR10_OFFSET]
922*9df5ba05SJiafei Pan	str	w6, [x2, #EPU_EPCTR10_OFFSET]
923*9df5ba05SJiafei Pan	str	w7, [x2, #EPU_EPGCR_OFFSET]
924*9df5ba05SJiafei Pan
925*9df5ba05SJiafei Pan	/*
926*9df5ba05SJiafei Pan	 * A-010194: There is logic problem
927*9df5ba05SJiafei Pan	 * in the path of GIC-to-PMU to issue
928*9df5ba05SJiafei Pan	 * wake request to core0
929*9df5ba05SJiafei Pan	 * Workaround: Re-target the wakeup interrupts
930*9df5ba05SJiafei Pan	 * to a core other than the last active core0
931*9df5ba05SJiafei Pan	 */
932*9df5ba05SJiafei Pan	ldr	x2, =NXP_GICD_ADDR
933*9df5ba05SJiafei Pan
934*9df5ba05SJiafei Pan	/* backup flextimer/mmc/usb interrupt router */
935*9df5ba05SJiafei Pan	ldr	x0, =GICD_IROUTER60_OFFSET
936*9df5ba05SJiafei Pan	ldr	x1, =GICD_IROUTER76_OFFSET
937*9df5ba05SJiafei Pan	ldr	w4, [x2, x0]
938*9df5ba05SJiafei Pan	ldr	w5, [x2, x1]
939*9df5ba05SJiafei Pan	ldr	x0, =GICD_IROUTER112_OFFSET
940*9df5ba05SJiafei Pan	ldr	x1, =GICD_IROUTER113_OFFSET
941*9df5ba05SJiafei Pan	ldr	w6, [x2, x0]
942*9df5ba05SJiafei Pan	ldr	w7, [x2, x1]
943*9df5ba05SJiafei Pan	stp	x4, x5, [sp, #-16]!
944*9df5ba05SJiafei Pan	stp	x6,  x7,  [sp, #-16]!
945*9df5ba05SJiafei Pan
946*9df5ba05SJiafei Pan	/*
947*9df5ba05SJiafei Pan	 * x2 = gicd base addr
948*9df5ba05SJiafei Pan	 * x0 = GICD_IROUTER112_OFFSET
949*9df5ba05SJiafei Pan	 * x1 = GICD_IROUTER113_OFFSET
950*9df5ba05SJiafei Pan	 */
951*9df5ba05SJiafei Pan
952*9df5ba05SJiafei Pan	/* re-route interrupt to cluster 1 */
953*9df5ba05SJiafei Pan	ldr	w4, =GICD_IROUTER_VALUE
954*9df5ba05SJiafei Pan	str	w4, [x2, x0]
955*9df5ba05SJiafei Pan	str	w4, [x2, x1]
956*9df5ba05SJiafei Pan	ldr	x0, =GICD_IROUTER60_OFFSET
957*9df5ba05SJiafei Pan	ldr	x1, =GICD_IROUTER76_OFFSET
958*9df5ba05SJiafei Pan	str	w4, [x2, x0]
959*9df5ba05SJiafei Pan	str	w4, [x2, x1]
960*9df5ba05SJiafei Pan	dsb	sy
961*9df5ba05SJiafei Pan	isb
962*9df5ba05SJiafei Pan
963*9df5ba05SJiafei Pan	/* backup flextimer/mmc/usb interrupt enabler */
964*9df5ba05SJiafei Pan	ldr	x0, =GICD_ISENABLER_1
965*9df5ba05SJiafei Pan	ldr	w4, [x2, x0]
966*9df5ba05SJiafei Pan	ldr	x1, =GICD_ISENABLER_2
967*9df5ba05SJiafei Pan	ldr	w5, [x2, x1]
968*9df5ba05SJiafei Pan	stp	x4, x5, [sp, #-16]!
969*9df5ba05SJiafei Pan
970*9df5ba05SJiafei Pan	ldr	x0, =GICD_ISENABLER_3
971*9df5ba05SJiafei Pan	ldr	w4, [x2, x0]
972*9df5ba05SJiafei Pan	ldr	x1, =GICD_ICENABLER_1
973*9df5ba05SJiafei Pan	ldr	w5, [x2, x1]
974*9df5ba05SJiafei Pan	stp	x4, x5, [sp, #-16]!
975*9df5ba05SJiafei Pan
976*9df5ba05SJiafei Pan	ldr	x0, =GICD_ICENABLER_2
977*9df5ba05SJiafei Pan	ldr	w4, [x2, x0]
978*9df5ba05SJiafei Pan	ldr	x1, =GICD_ICENABLER_3
979*9df5ba05SJiafei Pan	ldr	w5, [x2, x1]
980*9df5ba05SJiafei Pan	stp	x4, x5, [sp, #-16]!
981*9df5ba05SJiafei Pan
982*9df5ba05SJiafei Pan	/* enable related interrupt routing */
983*9df5ba05SJiafei Pan	ldr	w4, =GICD_ISENABLER_1_VALUE
984*9df5ba05SJiafei Pan	ldr	x0, =GICD_ISENABLER_1
985*9df5ba05SJiafei Pan	str	w4, [x2, x0]
986*9df5ba05SJiafei Pan	dsb	sy
987*9df5ba05SJiafei Pan	isb
988*9df5ba05SJiafei Pan
989*9df5ba05SJiafei Pan	ldr	w4, =GICD_ISENABLER_2_VALUE
990*9df5ba05SJiafei Pan	ldr	x0, =GICD_ISENABLER_2
991*9df5ba05SJiafei Pan	str	w4, [x2, x0]
992*9df5ba05SJiafei Pan	dsb	sy
993*9df5ba05SJiafei Pan	isb
994*9df5ba05SJiafei Pan
995*9df5ba05SJiafei Pan	ldr	w4, =GICD_ISENABLER_3_VALUE
996*9df5ba05SJiafei Pan	ldr	x0, =GICD_ISENABLER_3
997*9df5ba05SJiafei Pan	str	w4, [x2, x0]
998*9df5ba05SJiafei Pan	dsb	sy
999*9df5ba05SJiafei Pan	isb
1000*9df5ba05SJiafei Pan
1001*9df5ba05SJiafei Pan	/* set POWMGTDCR [STP_PV_EN] = 1 */
1002*9df5ba05SJiafei Pan	ldr	x2, =NXP_POWMGTDCR
1003*9df5ba05SJiafei Pan	ldr	w4, =0x01
1004*9df5ba05SJiafei Pan	str	w4, [x2]
1005*9df5ba05SJiafei Pan
1006*9df5ba05SJiafei Pan	/* program IPSTPCR for override stop request (except DDR) */
1007*9df5ba05SJiafei Pan	mov	x3, #NXP_PMU_ADDR
1008*9df5ba05SJiafei Pan
1009*9df5ba05SJiafei Pan	/* build an override mask for IPSTPCR4/IPSTPACK4/DEVDISR5 */
1010*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPPDEXPCR4_OFFSET
1011*9df5ba05SJiafei Pan	ldr	w7, [x3, x2]
1012*9df5ba05SJiafei Pan
1013*9df5ba05SJiafei Pan	mov	x5, xzr
1014*9df5ba05SJiafei Pan	ldr	x6, =IPPDEXPCR4_MASK
1015*9df5ba05SJiafei Pan	and	x6, x6, x7
1016*9df5ba05SJiafei Pan	cbz	x6, 1f
1017*9df5ba05SJiafei Pan
1018*9df5ba05SJiafei Pan	/*
1019*9df5ba05SJiafei Pan	 * x5 = override mask
1020*9df5ba05SJiafei Pan	 * x6 = IPPDEXPCR bits for DEVDISR5
1021*9df5ba05SJiafei Pan	 * x7 = IPPDEXPCR
1022*9df5ba05SJiafei Pan	 */
1023*9df5ba05SJiafei Pan
1024*9df5ba05SJiafei Pan	/* get the overrides */
1025*9df5ba05SJiafei Pan	orr	x4, x5, #DEVDISR5_FLX_TMR
1026*9df5ba05SJiafei Pan	tst	x6, #IPPDEXPCR_FLX_TMR
1027*9df5ba05SJiafei Pan	csel	x5, x5, x4, EQ
1028*9df5ba05SJiafei Pan1:
1029*9df5ba05SJiafei Pan	/* store the DEVDISR5 override mask */
1030*9df5ba05SJiafei Pan	ldr	x2, =BC_PSCI_BASE
1031*9df5ba05SJiafei Pan	add	x2, x2, #AUX_01_DATA
1032*9df5ba05SJiafei Pan	str	w5, [x2, #DEVDISR5_MASK_OFFSET]
1033*9df5ba05SJiafei Pan
1034*9df5ba05SJiafei Pan	mov	x3, #NXP_PMU_ADDR
1035*9df5ba05SJiafei Pan
1036*9df5ba05SJiafei Pan	/* write IPSTPCR0 - no overrides */
1037*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPCR0_OFFSET
1038*9df5ba05SJiafei Pan	ldr	w5, =IPSTPCR0_VALUE
1039*9df5ba05SJiafei Pan	str	w5, [x3, x2]
1040*9df5ba05SJiafei Pan
1041*9df5ba05SJiafei Pan	/* write IPSTPCR1 - no overrides */
1042*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPCR1_OFFSET
1043*9df5ba05SJiafei Pan	ldr	w5, =IPSTPCR1_VALUE
1044*9df5ba05SJiafei Pan	str	w5, [x3, x2]
1045*9df5ba05SJiafei Pan
1046*9df5ba05SJiafei Pan	/* write IPSTPCR2 - no overrides */
1047*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPCR2_OFFSET
1048*9df5ba05SJiafei Pan	ldr	w5, =IPSTPCR2_VALUE
1049*9df5ba05SJiafei Pan	str	w5, [x3, x2]
1050*9df5ba05SJiafei Pan
1051*9df5ba05SJiafei Pan	/* write IPSTPCR3 - no overrides */
1052*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPCR3_OFFSET
1053*9df5ba05SJiafei Pan	ldr	w5, =IPSTPCR3_VALUE
1054*9df5ba05SJiafei Pan	str	w5, [x3, x2]
1055*9df5ba05SJiafei Pan
1056*9df5ba05SJiafei Pan	/* write IPSTPCR4 - overrides possible */
1057*9df5ba05SJiafei Pan	ldr	x2, =BC_PSCI_BASE
1058*9df5ba05SJiafei Pan	add	x2, x2, #AUX_01_DATA
1059*9df5ba05SJiafei Pan	ldr	w6, [x2, #DEVDISR5_MASK_OFFSET]
1060*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPCR4_OFFSET
1061*9df5ba05SJiafei Pan	ldr	w5, =IPSTPCR4_VALUE
1062*9df5ba05SJiafei Pan	bic	x5, x5, x6
1063*9df5ba05SJiafei Pan	str	w5, [x3, x2]
1064*9df5ba05SJiafei Pan
1065*9df5ba05SJiafei Pan	/* write IPSTPCR5 - no overrides */
1066*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPCR5_OFFSET
1067*9df5ba05SJiafei Pan	ldr	w5, =IPSTPCR5_VALUE
1068*9df5ba05SJiafei Pan	str	w5, [x3, x2]
1069*9df5ba05SJiafei Pan
1070*9df5ba05SJiafei Pan	/* write IPSTPCR6 - no overrides */
1071*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPCR6_OFFSET
1072*9df5ba05SJiafei Pan	ldr	w5, =IPSTPCR6_VALUE
1073*9df5ba05SJiafei Pan	str	w5, [x3, x2]
1074*9df5ba05SJiafei Pan
1075*9df5ba05SJiafei Pan	/* poll IPSTPACK for IP stop acknowledgment (except DDR) */
1076*9df5ba05SJiafei Pan	mov	x3, #NXP_PMU_ADDR
1077*9df5ba05SJiafei Pan
1078*9df5ba05SJiafei Pan	/* poll on IPSTPACK0 */
1079*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPACK0_OFFSET
1080*9df5ba05SJiafei Pan	ldr	x4, =IPSTPCR0_VALUE
1081*9df5ba05SJiafei Pan	ldr	x7, =IPSTPACK_RETRY_CNT
1082*9df5ba05SJiafei Pan3:
1083*9df5ba05SJiafei Pan	ldr	w0, [x3, x2]
1084*9df5ba05SJiafei Pan	cmp	x0, x4
1085*9df5ba05SJiafei Pan	b.eq	14f
1086*9df5ba05SJiafei Pan	sub	x7, x7, #1
1087*9df5ba05SJiafei Pan	cbnz	x7, 3b
1088*9df5ba05SJiafei Pan
1089*9df5ba05SJiafei Pan14:
1090*9df5ba05SJiafei Pan	/* poll on IPSTPACK1 */
1091*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPACK1_OFFSET
1092*9df5ba05SJiafei Pan	ldr	x4, =IPSTPCR1_VALUE
1093*9df5ba05SJiafei Pan	ldr	x7, =IPSTPACK_RETRY_CNT
1094*9df5ba05SJiafei Pan4:
1095*9df5ba05SJiafei Pan	ldr	w0, [x3, x2]
1096*9df5ba05SJiafei Pan	cmp	x0, x4
1097*9df5ba05SJiafei Pan	b.eq	15f
1098*9df5ba05SJiafei Pan	sub	x7, x7, #1
1099*9df5ba05SJiafei Pan	cbnz	x7, 4b
1100*9df5ba05SJiafei Pan
1101*9df5ba05SJiafei Pan15:
1102*9df5ba05SJiafei Pan	/* poll on IPSTPACK2 */
1103*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPACK2_OFFSET
1104*9df5ba05SJiafei Pan	ldr	x4, =IPSTPCR2_VALUE
1105*9df5ba05SJiafei Pan	ldr	x7, =IPSTPACK_RETRY_CNT
1106*9df5ba05SJiafei Pan5:
1107*9df5ba05SJiafei Pan	ldr	w0, [x3, x2]
1108*9df5ba05SJiafei Pan	cmp	x0, x4
1109*9df5ba05SJiafei Pan	b.eq	16f
1110*9df5ba05SJiafei Pan	sub	x7, x7, #1
1111*9df5ba05SJiafei Pan	cbnz	x7, 5b
1112*9df5ba05SJiafei Pan
1113*9df5ba05SJiafei Pan16:
1114*9df5ba05SJiafei Pan	/* poll on IPSTPACK3 */
1115*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPACK3_OFFSET
1116*9df5ba05SJiafei Pan	ldr	x4, =IPSTPCR3_VALUE
1117*9df5ba05SJiafei Pan	ldr	x7, =IPSTPACK_RETRY_CNT
1118*9df5ba05SJiafei Pan6:
1119*9df5ba05SJiafei Pan	ldr	w0, [x3, x2]
1120*9df5ba05SJiafei Pan	cmp	x0, x4
1121*9df5ba05SJiafei Pan	b.eq	17f
1122*9df5ba05SJiafei Pan	sub	x7, x7, #1
1123*9df5ba05SJiafei Pan	cbnz	x7, 6b
1124*9df5ba05SJiafei Pan
1125*9df5ba05SJiafei Pan17:
1126*9df5ba05SJiafei Pan	/* poll on IPSTPACK4 */
1127*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPACK4_OFFSET
1128*9df5ba05SJiafei Pan	ldr	x4, =IPSTPCR4_VALUE
1129*9df5ba05SJiafei Pan	ldr	x7, =IPSTPACK_RETRY_CNT
1130*9df5ba05SJiafei Pan7:
1131*9df5ba05SJiafei Pan	ldr	w0, [x3, x2]
1132*9df5ba05SJiafei Pan	cmp	x0, x4
1133*9df5ba05SJiafei Pan	b.eq	18f
1134*9df5ba05SJiafei Pan	sub	x7, x7, #1
1135*9df5ba05SJiafei Pan	cbnz	x7, 7b
1136*9df5ba05SJiafei Pan
1137*9df5ba05SJiafei Pan18:
1138*9df5ba05SJiafei Pan	/* poll on IPSTPACK5 */
1139*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPACK5_OFFSET
1140*9df5ba05SJiafei Pan	ldr	x4, =IPSTPCR5_VALUE
1141*9df5ba05SJiafei Pan	ldr	x7, =IPSTPACK_RETRY_CNT
1142*9df5ba05SJiafei Pan8:
1143*9df5ba05SJiafei Pan	ldr	w0, [x3, x2]
1144*9df5ba05SJiafei Pan	cmp	x0, x4
1145*9df5ba05SJiafei Pan	b.eq	19f
1146*9df5ba05SJiafei Pan	sub	x7, x7, #1
1147*9df5ba05SJiafei Pan	cbnz	x7, 8b
1148*9df5ba05SJiafei Pan
1149*9df5ba05SJiafei Pan19:
1150*9df5ba05SJiafei Pan	/* poll on IPSTPACK6 */
1151*9df5ba05SJiafei Pan	ldr	x2, =PMU_IPSTPACK6_OFFSET
1152*9df5ba05SJiafei Pan	ldr	x4, =IPSTPCR6_VALUE
1153*9df5ba05SJiafei Pan	ldr	x7, =IPSTPACK_RETRY_CNT
1154*9df5ba05SJiafei Pan9:
1155*9df5ba05SJiafei Pan	ldr	w0, [x3, x2]
1156*9df5ba05SJiafei Pan	cmp	x0, x4
1157*9df5ba05SJiafei Pan	b.eq	20f
1158*9df5ba05SJiafei Pan	sub	x7, x7, #1
1159*9df5ba05SJiafei Pan	cbnz	x7, 9b
1160*9df5ba05SJiafei Pan
1161*9df5ba05SJiafei Pan20:
1162*9df5ba05SJiafei Pan	/* save current DEVDISR states to DDR. */
1163*9df5ba05SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
1164*9df5ba05SJiafei Pan
1165*9df5ba05SJiafei Pan	/* save DEVDISR1 and load new value */
1166*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR1_OFFSET
1167*9df5ba05SJiafei Pan	ldr	w1, [x2, x0]
1168*9df5ba05SJiafei Pan	mov	w13, w1
1169*9df5ba05SJiafei Pan	ldr	x1, =DEVDISR1_VALUE
1170*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1171*9df5ba05SJiafei Pan	/* save DEVDISR2 and load new value */
1172*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR2_OFFSET
1173*9df5ba05SJiafei Pan	ldr	w1, [x2, x0]
1174*9df5ba05SJiafei Pan	mov	w14, w1
1175*9df5ba05SJiafei Pan	ldr	x1, =DEVDISR2_VALUE
1176*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1177*9df5ba05SJiafei Pan
1178*9df5ba05SJiafei Pan	/* x6 = DEVDISR5 override mask */
1179*9df5ba05SJiafei Pan
1180*9df5ba05SJiafei Pan	/* save DEVDISR3 and load new value */
1181*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR3_OFFSET
1182*9df5ba05SJiafei Pan	ldr	w1, [x2, x0]
1183*9df5ba05SJiafei Pan	mov	w15, w1
1184*9df5ba05SJiafei Pan	ldr	x1, =DEVDISR3_VALUE
1185*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1186*9df5ba05SJiafei Pan
1187*9df5ba05SJiafei Pan	/* save DEVDISR4 and load new value */
1188*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR4_OFFSET
1189*9df5ba05SJiafei Pan	ldr	w1, [x2, x0]
1190*9df5ba05SJiafei Pan	mov	w16, w1
1191*9df5ba05SJiafei Pan	/* not stop uart print */
1192*9df5ba05SJiafei Pan	ldr	x1, =0x0000332
1193*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1194*9df5ba05SJiafei Pan
1195*9df5ba05SJiafei Pan	/* save DEVDISR5 and load new value */
1196*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR5_OFFSET
1197*9df5ba05SJiafei Pan	ldr	w1, [x2, x0]
1198*9df5ba05SJiafei Pan	mov	w17, w1
1199*9df5ba05SJiafei Pan	/* Enable this wakeup will fail, should enable OCRAM */
1200*9df5ba05SJiafei Pan	ldr	x1, =0x00102300
1201*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1202*9df5ba05SJiafei Pan
1203*9df5ba05SJiafei Pan	/* save DEVDISR6 and load new value */
1204*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR6_OFFSET
1205*9df5ba05SJiafei Pan	ldr	w1, [x2, x0]
1206*9df5ba05SJiafei Pan	mov	w18, w1
1207*9df5ba05SJiafei Pan	ldr	x1, =DEVDISR6_VALUE
1208*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1209*9df5ba05SJiafei Pan
1210*9df5ba05SJiafei Pan	/*
1211*9df5ba05SJiafei Pan	 * w13 = DEVDISR1 saved value
1212*9df5ba05SJiafei Pan	 * w14 = DEVDISR2 saved value
1213*9df5ba05SJiafei Pan	 * w15 = DEVDISR3 saved value
1214*9df5ba05SJiafei Pan	 * w16 = DEVDISR4 saved value
1215*9df5ba05SJiafei Pan	 * w17 = DEVDISR5 saved value
1216*9df5ba05SJiafei Pan	 * w18 = DEVDISR6 saved value
1217*9df5ba05SJiafei Pan	 */
1218*9df5ba05SJiafei Pan	/*
1219*9df5ba05SJiafei Pan	 * A-009810: LPM20 entry sequence might cause
1220*9df5ba05SJiafei Pan	 * spurious timeout reset request
1221*9df5ba05SJiafei Pan	 * workaround: MASK RESET REQ RPTOE
1222*9df5ba05SJiafei Pan	 */
1223*9df5ba05SJiafei Pan	ldr	x0, =NXP_RESET_ADDR
1224*9df5ba05SJiafei Pan	ldr	w1, =RSTRQMR_RPTOE_MASK
1225*9df5ba05SJiafei Pan	str	w1, [x0, #RST_RSTRQMR1_OFFSET]
1226*9df5ba05SJiafei Pan
1227*9df5ba05SJiafei Pan	/* disable SEC, QBman spi and qspi */
1228*9df5ba05SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
1229*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR1_OFFSET
1230*9df5ba05SJiafei Pan	ldr	w1, =DCFG_DEVDISR1_SEC
1231*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1232*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR3_OFFSET
1233*9df5ba05SJiafei Pan	ldr	w1, =DCFG_DEVDISR3_QBMAIN
1234*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1235*9df5ba05SJiafei Pan	ldr	x0, =DCFG_DEVDISR4_OFFSET
1236*9df5ba05SJiafei Pan	ldr	w1, =DCFG_DEVDISR4_SPI_QSPI
1237*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1238*9df5ba05SJiafei Pan
1239*9df5ba05SJiafei Pan	/*
1240*9df5ba05SJiafei Pan	 * write the GICR_WAKER.ProcessorSleep bits to 1
1241*9df5ba05SJiafei Pan	 * enable the WakeRequest signal
1242*9df5ba05SJiafei Pan	 * x3 is cpu mask starting from cpu7
1243*9df5ba05SJiafei Pan	 */
1244*9df5ba05SJiafei Pan	bl	get_tot_num_cores
1245*9df5ba05SJiafei Pan	sub	x0, x0, #1
1246*9df5ba05SJiafei Pan	mov	x3, #0x1
1247*9df5ba05SJiafei Pan	lsl	x3, x3, x0
1248*9df5ba05SJiafei Pan2:
1249*9df5ba05SJiafei Pan	mov	x0, x3
1250*9df5ba05SJiafei Pan	bl	get_gic_rd_base
1251*9df5ba05SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1252*9df5ba05SJiafei Pan	orr	w1, w1, #GICR_WAKER_SLEEP_BIT
1253*9df5ba05SJiafei Pan	str	w1, [x0, #GICR_WAKER_OFFSET]
1254*9df5ba05SJiafei Pan1:
1255*9df5ba05SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1256*9df5ba05SJiafei Pan	cmp	w1, #GICR_WAKER_ASLEEP
1257*9df5ba05SJiafei Pan	b.ne	1b
1258*9df5ba05SJiafei Pan
1259*9df5ba05SJiafei Pan	lsr	x3, x3, #1
1260*9df5ba05SJiafei Pan	cbnz	x3, 2b
1261*9df5ba05SJiafei Pan
1262*9df5ba05SJiafei Pan	/* x3 = pmu base addr */
1263*9df5ba05SJiafei Pan
1264*9df5ba05SJiafei Pan	/* perform Icache Warming Sequence */
1265*9df5ba05SJiafei Pan	ldr	x5, =IPSTPCR4_VALUE
1266*9df5ba05SJiafei Pan	mov	x6, DDR_CNTRL_BASE_ADDR
1267*9df5ba05SJiafei Pan	mov	x7, #NXP_PMU_ADDR
1268*9df5ba05SJiafei Pan	mov	x8, #NXP_DCFG_ADDR
1269*9df5ba05SJiafei Pan	mov	x10, #PMU_IPSTPCR4_OFFSET
1270*9df5ba05SJiafei Pan	mov	x11, #PMU_IPSTPACK4_OFFSET
1271*9df5ba05SJiafei Pan	mov	x12, #PMU_IPSTPCR3_OFFSET
1272*9df5ba05SJiafei Pan	mov	x18, #PMU_IPSTPCR2_OFFSET
1273*9df5ba05SJiafei Pan	mov	x19, #PMU_IPSTPCR1_OFFSET
1274*9df5ba05SJiafei Pan	mov	x21, #PMU_IPSTPCR0_OFFSET
1275*9df5ba05SJiafei Pan	ldr	x22, =DCFG_DEVDISR5_OFFSET
1276*9df5ba05SJiafei Pan	ldr	x23, =NXP_EPU_ADDR
1277*9df5ba05SJiafei Pan	mov	x9, #CORE_RESTARTABLE
1278*9df5ba05SJiafei Pan	bl	final_pwrdown
1279*9df5ba05SJiafei Pan
1280*9df5ba05SJiafei Pan	/*
1281*9df5ba05SJiafei Pan	 * disable the WakeRequest signal on cpu 0-7
1282*9df5ba05SJiafei Pan	 * x3 is cpu mask starting from cpu7
1283*9df5ba05SJiafei Pan	 */
1284*9df5ba05SJiafei Pan	bl	get_tot_num_cores
1285*9df5ba05SJiafei Pan	sub	x0, x0, #1
1286*9df5ba05SJiafei Pan	mov	x3, #0x1
1287*9df5ba05SJiafei Pan	lsl	x3, x3, x0
1288*9df5ba05SJiafei Pan2:
1289*9df5ba05SJiafei Pan	mov	x0, x3
1290*9df5ba05SJiafei Pan	bl	get_gic_rd_base
1291*9df5ba05SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1292*9df5ba05SJiafei Pan	bic	w1, w1, #GICR_WAKER_SLEEP_BIT
1293*9df5ba05SJiafei Pan	str	w1, [x0, #GICR_WAKER_OFFSET]
1294*9df5ba05SJiafei Pan1:
1295*9df5ba05SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1296*9df5ba05SJiafei Pan	cbnz	w1, 1b
1297*9df5ba05SJiafei Pan
1298*9df5ba05SJiafei Pan	lsr	x3, x3, #1
1299*9df5ba05SJiafei Pan	cbnz	x3, 2b
1300*9df5ba05SJiafei Pan
1301*9df5ba05SJiafei Pan	/* set SGI for secondary core wakeup */
1302*9df5ba05SJiafei Pan	ldr	x0, =0x1000002
1303*9df5ba05SJiafei Pan	msr	S3_0_C12_C11_7, x0
1304*9df5ba05SJiafei Pan	isb
1305*9df5ba05SJiafei Pan	ldr	x0, =0x2000004
1306*9df5ba05SJiafei Pan	msr	S3_0_C12_C11_7, x0
1307*9df5ba05SJiafei Pan	isb
1308*9df5ba05SJiafei Pan	ldr	x0, =0x3000008
1309*9df5ba05SJiafei Pan	msr	S3_0_C12_C11_7, x0
1310*9df5ba05SJiafei Pan	isb
1311*9df5ba05SJiafei Pan	ldr	x0, =0x4010001
1312*9df5ba05SJiafei Pan	msr	S3_0_C12_C11_7, x0
1313*9df5ba05SJiafei Pan	isb
1314*9df5ba05SJiafei Pan	ldr	x0, =0x5010002
1315*9df5ba05SJiafei Pan	msr	S3_0_C12_C11_7, x0
1316*9df5ba05SJiafei Pan	isb
1317*9df5ba05SJiafei Pan	ldr	x0, =0x6010004
1318*9df5ba05SJiafei Pan	msr	S3_0_C12_C11_7, x0
1319*9df5ba05SJiafei Pan	isb
1320*9df5ba05SJiafei Pan	ldr	x0, =0x7010008
1321*9df5ba05SJiafei Pan	msr	S3_0_C12_C11_7, x0
1322*9df5ba05SJiafei Pan
1323*9df5ba05SJiafei Pan	/* enable SEC, QBman spi and qspi */
1324*9df5ba05SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
1325*9df5ba05SJiafei Pan	str	wzr, [x2, #DCFG_DEVDISR1_OFFSET]
1326*9df5ba05SJiafei Pan	str	wzr, [x2, #DCFG_DEVDISR3_OFFSET]
1327*9df5ba05SJiafei Pan	str	wzr, [x2, #DCFG_DEVDISR4_OFFSET]
1328*9df5ba05SJiafei Pan
1329*9df5ba05SJiafei Pan	/* clear POWMGTDCR [STP_PV_EN] */
1330*9df5ba05SJiafei Pan	ldr	x2, =NXP_POWMGTDCR
1331*9df5ba05SJiafei Pan	ldr	w4, [x2]
1332*9df5ba05SJiafei Pan	bic	w4, w4, #0x01
1333*9df5ba05SJiafei Pan	str	w4, [x2]
1334*9df5ba05SJiafei Pan
1335*9df5ba05SJiafei Pan	/* restore flextimer/mmc/usb interrupt enabler */
1336*9df5ba05SJiafei Pan	ldr	x3, =NXP_GICD_ADDR
1337*9df5ba05SJiafei Pan	ldp	x0, x2, [sp], #16
1338*9df5ba05SJiafei Pan	ldr	x1, =GICD_ICENABLER_2
1339*9df5ba05SJiafei Pan	mvn	w0, w0
1340*9df5ba05SJiafei Pan	str	w0, [x3, x1]
1341*9df5ba05SJiafei Pan	ldr	x1, =GICD_ICENABLER_3
1342*9df5ba05SJiafei Pan	mvn	w2, w2
1343*9df5ba05SJiafei Pan	str	w2, [x3, x1]
1344*9df5ba05SJiafei Pan
1345*9df5ba05SJiafei Pan	ldp	x0, x2, [sp], #16
1346*9df5ba05SJiafei Pan	ldr	x1, =GICD_ISENABLER_3
1347*9df5ba05SJiafei Pan	str	w0, [x3, x1]
1348*9df5ba05SJiafei Pan	ldr	x1, =GICD_ICENABLER_1
1349*9df5ba05SJiafei Pan	mvn	w2, w2
1350*9df5ba05SJiafei Pan	str	w0, [x3, x1]
1351*9df5ba05SJiafei Pan
1352*9df5ba05SJiafei Pan	ldp	x0, x2, [sp], #16
1353*9df5ba05SJiafei Pan	ldr	x1, =GICD_ISENABLER_1
1354*9df5ba05SJiafei Pan	str	w0, [x3, x1]
1355*9df5ba05SJiafei Pan	ldr	x1, =GICD_ISENABLER_2
1356*9df5ba05SJiafei Pan	str	w0, [x3, x1]
1357*9df5ba05SJiafei Pan
1358*9df5ba05SJiafei Pan	/* restore flextimer/mmc/usb interrupt router */
1359*9df5ba05SJiafei Pan	ldr	x3, =NXP_GICD_ADDR
1360*9df5ba05SJiafei Pan	ldp	x0, x2, [sp], #16
1361*9df5ba05SJiafei Pan	ldr	x1, =GICD_IROUTER113_OFFSET
1362*9df5ba05SJiafei Pan	str	w2, [x3, x1]
1363*9df5ba05SJiafei Pan	ldr	x1, =GICD_IROUTER112_OFFSET
1364*9df5ba05SJiafei Pan	str	w0, [x3, x1]
1365*9df5ba05SJiafei Pan	ldp	x0, x2, [sp], #16
1366*9df5ba05SJiafei Pan	ldr	x1, =GICD_IROUTER76_OFFSET
1367*9df5ba05SJiafei Pan	str	w2, [x3, x1]
1368*9df5ba05SJiafei Pan	ldr	x1, =GICD_IROUTER60_OFFSET
1369*9df5ba05SJiafei Pan	str	w0, [x3, x1]
1370*9df5ba05SJiafei Pan
1371*9df5ba05SJiafei Pan	/* restore EPU registers */
1372*9df5ba05SJiafei Pan	ldr	x3, =NXP_EPU_ADDR
1373*9df5ba05SJiafei Pan	ldp	x0, x2, [sp], #16
1374*9df5ba05SJiafei Pan	str	w2, [x3, #EPU_EPGCR_OFFSET]
1375*9df5ba05SJiafei Pan	str	w0, [x3, #EPU_EPCTR10_OFFSET]
1376*9df5ba05SJiafei Pan	ldp	x2, x1, [sp], #16
1377*9df5ba05SJiafei Pan	str	w1, [x3, #EPU_EPCCR10_OFFSET]
1378*9df5ba05SJiafei Pan	str	w2, [x3, #EPU_EPIMCR10_OFFSET]
1379*9df5ba05SJiafei Pan
1380*9df5ba05SJiafei Pan	isb
1381*9df5ba05SJiafei Pan	/* Restor LR */
1382*9df5ba05SJiafei Pan	ldp	x18, x30, [sp], #16
1383*9df5ba05SJiafei Pan	ret
1384*9df5ba05SJiafei Pan
1385*9df5ba05SJiafei Pan/*
1386*9df5ba05SJiafei Pan * part of CPU_SUSPEND
1387*9df5ba05SJiafei Pan * this function performs any SoC-specific cleanup after power-down
1388*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
1389*9df5ba05SJiafei Pan * out: none
1390*9df5ba05SJiafei Pan * uses x0, x1
1391*9df5ba05SJiafei Pan */
1392*9df5ba05SJiafei Pan_soc_sys_exit_pwrdn:
1393*9df5ba05SJiafei Pan	mrs	x1, SCTLR_EL1
1394*9df5ba05SJiafei Pan	orr	x1, x1, #SCTLR_I_MASK
1395*9df5ba05SJiafei Pan	msr	SCTLR_EL1, x1
1396*9df5ba05SJiafei Pan	isb
1397*9df5ba05SJiafei Pan	ret
1398*9df5ba05SJiafei Pan
1399*9df5ba05SJiafei Pan/*
1400*9df5ba05SJiafei Pan * this function checks to see if cores which are to be disabled have been
1401*9df5ba05SJiafei Pan * released from reset - if not, it releases them
1402*9df5ba05SJiafei Pan * in:  none
1403*9df5ba05SJiafei Pan * out: none
1404*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
1405*9df5ba05SJiafei Pan */
1406*9df5ba05SJiafei Panrelease_disabled:
1407*9df5ba05SJiafei Pan	mov	x8, x30
1408*9df5ba05SJiafei Pan
1409*9df5ba05SJiafei Pan	/* read COREDISABLESR */
1410*9df5ba05SJiafei Pan	mov	x0, #NXP_DCFG_ADDR
1411*9df5ba05SJiafei Pan	ldr	w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
1412*9df5ba05SJiafei Pan
1413*9df5ba05SJiafei Pan	/* get the number of cpus on this device */
1414*9df5ba05SJiafei Pan	mov	x6, #PLATFORM_CORE_COUNT
1415*9df5ba05SJiafei Pan
1416*9df5ba05SJiafei Pan	mov	x0, #NXP_RESET_ADDR
1417*9df5ba05SJiafei Pan	ldr	w5, [x0, #BRR_OFFSET]
1418*9df5ba05SJiafei Pan
1419*9df5ba05SJiafei Pan	/* load the core mask for the first core */
1420*9df5ba05SJiafei Pan	mov	x7, #1
1421*9df5ba05SJiafei Pan
1422*9df5ba05SJiafei Pan	/*
1423*9df5ba05SJiafei Pan	 * x4 = COREDISABLESR
1424*9df5ba05SJiafei Pan	 * x5 = BRR
1425*9df5ba05SJiafei Pan	 * x6 = loop count
1426*9df5ba05SJiafei Pan	 * x7 = core mask bit
1427*9df5ba05SJiafei Pan	 */
1428*9df5ba05SJiafei Pan2:
1429*9df5ba05SJiafei Pan	/* check if the core is to be disabled */
1430*9df5ba05SJiafei Pan	tst	x4, x7
1431*9df5ba05SJiafei Pan	b.eq	1f
1432*9df5ba05SJiafei Pan
1433*9df5ba05SJiafei Pan	/* see if disabled cores have already been released from reset */
1434*9df5ba05SJiafei Pan	tst	x5, x7
1435*9df5ba05SJiafei Pan	b.ne	1f
1436*9df5ba05SJiafei Pan
1437*9df5ba05SJiafei Pan	/* if core has not been released, then release it (0-3) */
1438*9df5ba05SJiafei Pan	mov	x0, x7
1439*9df5ba05SJiafei Pan	bl	_soc_core_release
1440*9df5ba05SJiafei Pan
1441*9df5ba05SJiafei Pan	/* record the core state in the data area (0-3) */
1442*9df5ba05SJiafei Pan	mov	x0, x7
1443*9df5ba05SJiafei Pan	mov	x1, #CORE_DISABLED
1444*9df5ba05SJiafei Pan	bl	_setCoreState
1445*9df5ba05SJiafei Pan
1446*9df5ba05SJiafei Pan1:
1447*9df5ba05SJiafei Pan	/* decrement the counter */
1448*9df5ba05SJiafei Pan	subs	x6, x6, #1
1449*9df5ba05SJiafei Pan	b.le	3f
1450*9df5ba05SJiafei Pan
1451*9df5ba05SJiafei Pan	/* shift the core mask to the next core */
1452*9df5ba05SJiafei Pan	lsl	x7, x7, #1
1453*9df5ba05SJiafei Pan	/* continue */
1454*9df5ba05SJiafei Pan	b	2b
1455*9df5ba05SJiafei Pan3:
1456*9df5ba05SJiafei Pan	mov	x30, x8
1457*9df5ba05SJiafei Pan	ret
1458*9df5ba05SJiafei Pan
1459*9df5ba05SJiafei Pan/*
1460*9df5ba05SJiafei Pan * write a register in the DCFG block
1461*9df5ba05SJiafei Pan * in:  x0 = offset
1462*9df5ba05SJiafei Pan * in:  w1 = value to write
1463*9df5ba05SJiafei Pan * uses x0, x1, x2
1464*9df5ba05SJiafei Pan */
1465*9df5ba05SJiafei Pan_write_reg_dcfg:
1466*9df5ba05SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
1467*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1468*9df5ba05SJiafei Pan	ret
1469*9df5ba05SJiafei Pan
1470*9df5ba05SJiafei Pan/*
1471*9df5ba05SJiafei Pan * read a register in the DCFG block
1472*9df5ba05SJiafei Pan * in:  x0 = offset
1473*9df5ba05SJiafei Pan * out: w0 = value read
1474*9df5ba05SJiafei Pan * uses x0, x1
1475*9df5ba05SJiafei Pan */
1476*9df5ba05SJiafei Pan_read_reg_dcfg:
1477*9df5ba05SJiafei Pan	ldr	x1, =NXP_DCFG_ADDR
1478*9df5ba05SJiafei Pan	ldr	w0, [x1, x0]
1479*9df5ba05SJiafei Pan	ret
1480*9df5ba05SJiafei Pan
1481*9df5ba05SJiafei Pan/*
1482*9df5ba05SJiafei Pan * this function sets up the TrustZone Address Space Controller (TZASC)
1483*9df5ba05SJiafei Pan * in:  none
1484*9df5ba05SJiafei Pan * out: none
1485*9df5ba05SJiafei Pan * uses x0, x1
1486*9df5ba05SJiafei Pan */
1487*9df5ba05SJiafei Paninit_tzpc:
1488*9df5ba05SJiafei Pan	/*
1489*9df5ba05SJiafei Pan	 * set Non Secure access for all devices protected via TZPC
1490*9df5ba05SJiafei Pan	 * decode Protection-0 Set Reg
1491*9df5ba05SJiafei Pan	 */
1492*9df5ba05SJiafei Pan	ldr	x1, =TZPCDECPROT_0_SET_BASE
1493*9df5ba05SJiafei Pan	/* set decode region to NS, Bits[7:0] */
1494*9df5ba05SJiafei Pan	mov	w0, #0xFF
1495*9df5ba05SJiafei Pan	str	w0, [x1]
1496*9df5ba05SJiafei Pan
1497*9df5ba05SJiafei Pan	/* decode Protection-1 Set Reg */
1498*9df5ba05SJiafei Pan	ldr	x1, =TZPCDECPROT_1_SET_BASE
1499*9df5ba05SJiafei Pan	/* set decode region to NS, Bits[7:0] */
1500*9df5ba05SJiafei Pan	mov	w0, #0xFF
1501*9df5ba05SJiafei Pan	str	w0, [x1]
1502*9df5ba05SJiafei Pan
1503*9df5ba05SJiafei Pan	/* decode Protection-2 Set Reg */
1504*9df5ba05SJiafei Pan	ldr	x1, =TZPCDECPROT_2_SET_BASE
1505*9df5ba05SJiafei Pan	/* set decode region to NS, Bits[7:0] */
1506*9df5ba05SJiafei Pan	mov	w0, #0xFF
1507*9df5ba05SJiafei Pan	str	w0, [x1]
1508*9df5ba05SJiafei Pan
1509*9df5ba05SJiafei Pan	/*
1510*9df5ba05SJiafei Pan	 * entire SRAM as NS
1511*9df5ba05SJiafei Pan	 * secure RAM region size Reg
1512*9df5ba05SJiafei Pan	 */
1513*9df5ba05SJiafei Pan	ldr	x1, =NXP_OCRAM_TZPC_ADDR
1514*9df5ba05SJiafei Pan	/* 0x00000000 = no secure region */
1515*9df5ba05SJiafei Pan	mov	w0, #0x00000000
1516*9df5ba05SJiafei Pan	str	w0, [x1]
1517*9df5ba05SJiafei Pan
1518*9df5ba05SJiafei Pan	ret
1519*9df5ba05SJiafei Pan
1520*9df5ba05SJiafei Pan/* this function performs initialization on SecMon for boot services */
1521*9df5ba05SJiafei PaninitSecMon:
1522*9df5ba05SJiafei Pan	/* read the register hpcomr */
1523*9df5ba05SJiafei Pan	ldr	x1, =NXP_SNVS_ADDR
1524*9df5ba05SJiafei Pan	ldr	w0, [x1, #SECMON_HPCOMR_OFFSET]
1525*9df5ba05SJiafei Pan	/* turn off secure access for the privileged registers */
1526*9df5ba05SJiafei Pan	orr	w0, w0, #SECMON_HPCOMR_NPSWAEN
1527*9df5ba05SJiafei Pan	/* write back */
1528*9df5ba05SJiafei Pan	str	w0, [x1, #SECMON_HPCOMR_OFFSET]
1529*9df5ba05SJiafei Pan
1530*9df5ba05SJiafei Pan	ret
1531*9df5ba05SJiafei Pan
1532*9df5ba05SJiafei Pan/*
1533*9df5ba05SJiafei Pan * this function returns the redistributor base address for the core specified
1534*9df5ba05SJiafei Pan * in x1
1535*9df5ba05SJiafei Pan * in:  x0 - core mask lsb of specified core
1536*9df5ba05SJiafei Pan * out: x0 = redistributor rd base address for specified core
1537*9df5ba05SJiafei Pan * uses x0, x1, x2
1538*9df5ba05SJiafei Pan */
1539*9df5ba05SJiafei Panget_gic_rd_base:
1540*9df5ba05SJiafei Pan	/* get the 0-based core number */
1541*9df5ba05SJiafei Pan	clz	w1, w0
1542*9df5ba05SJiafei Pan	mov	w2, #0x20
1543*9df5ba05SJiafei Pan	sub	w2, w2, w1
1544*9df5ba05SJiafei Pan	sub	w2, w2, #1
1545*9df5ba05SJiafei Pan
1546*9df5ba05SJiafei Pan	/* x2 = core number / loop counter */
1547*9df5ba05SJiafei Pan
1548*9df5ba05SJiafei Pan	ldr	x0, =NXP_GICR_ADDR
1549*9df5ba05SJiafei Pan	mov	x1, #GIC_RD_OFFSET
1550*9df5ba05SJiafei Pan2:
1551*9df5ba05SJiafei Pan	cbz	x2, 1f
1552*9df5ba05SJiafei Pan	add	x0, x0, x1
1553*9df5ba05SJiafei Pan	sub	x2, x2, #1
1554*9df5ba05SJiafei Pan	b	2b
1555*9df5ba05SJiafei Pan1:
1556*9df5ba05SJiafei Pan	ret
1557*9df5ba05SJiafei Pan
1558*9df5ba05SJiafei Pan/*
1559*9df5ba05SJiafei Pan * this function returns the redistributor base address for the core specified
1560*9df5ba05SJiafei Pan * in x1
1561*9df5ba05SJiafei Pan * in:  x0 - core mask lsb of specified core
1562*9df5ba05SJiafei Pan * out: x0 = redistributor sgi base address for specified core
1563*9df5ba05SJiafei Pan * uses x0, x1, x2
1564*9df5ba05SJiafei Pan */
1565*9df5ba05SJiafei Panget_gic_sgi_base:
1566*9df5ba05SJiafei Pan	/* get the 0-based core number */
1567*9df5ba05SJiafei Pan	clz	w1, w0
1568*9df5ba05SJiafei Pan	mov	w2, #0x20
1569*9df5ba05SJiafei Pan	sub	w2, w2, w1
1570*9df5ba05SJiafei Pan	sub	w2, w2, #1
1571*9df5ba05SJiafei Pan
1572*9df5ba05SJiafei Pan	/* x2 = core number / loop counter */
1573*9df5ba05SJiafei Pan
1574*9df5ba05SJiafei Pan	ldr	x0, =NXP_GICR_SGI_ADDR
1575*9df5ba05SJiafei Pan	mov	x1, #GIC_SGI_OFFSET
1576*9df5ba05SJiafei Pan2:
1577*9df5ba05SJiafei Pan	cbz	x2, 1f
1578*9df5ba05SJiafei Pan	add	x0, x0, x1
1579*9df5ba05SJiafei Pan	sub	x2, x2, #1
1580*9df5ba05SJiafei Pan	b	2b
1581*9df5ba05SJiafei Pan1:
1582*9df5ba05SJiafei Pan	ret
1583*9df5ba05SJiafei Pan
1584*9df5ba05SJiafei Pan/*
1585*9df5ba05SJiafei Pan * this function returns an mpidr value for a core, given a core_mask_lsb
1586*9df5ba05SJiafei Pan * in:  x0 = core mask lsb
1587*9df5ba05SJiafei Pan * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
1588*9df5ba05SJiafei Pan * uses x0, x1
1589*9df5ba05SJiafei Pan */
1590*9df5ba05SJiafei Panget_mpidr_value:
1591*9df5ba05SJiafei Pan	/* convert a core mask to an SoC core number */
1592*9df5ba05SJiafei Pan	clz	w0, w0
1593*9df5ba05SJiafei Pan	mov	w1, #31
1594*9df5ba05SJiafei Pan	sub	w0, w1, w0
1595*9df5ba05SJiafei Pan
1596*9df5ba05SJiafei Pan	/* w0 = SoC core number */
1597*9df5ba05SJiafei Pan
1598*9df5ba05SJiafei Pan	mov	w1, wzr
1599*9df5ba05SJiafei Pan2:
1600*9df5ba05SJiafei Pan	cmp	w0, #CORES_PER_CLUSTER
1601*9df5ba05SJiafei Pan	b.lt	1f
1602*9df5ba05SJiafei Pan	sub	w0, w0, #CORES_PER_CLUSTER
1603*9df5ba05SJiafei Pan	add	w1, w1, #MPIDR_CLUSTER
1604*9df5ba05SJiafei Pan	b	2b
1605*9df5ba05SJiafei Pan
1606*9df5ba05SJiafei Pan	/* insert the mpidr core number */
1607*9df5ba05SJiafei Pan1:
1608*9df5ba05SJiafei Pan	orr	w0, w1, w0
1609*9df5ba05SJiafei Pan	ret
1610*9df5ba05SJiafei Pan
1611*9df5ba05SJiafei Pan/*
1612*9df5ba05SJiafei Pan * write a register in the RESET block
1613*9df5ba05SJiafei Pan * in:  x0 = offset
1614*9df5ba05SJiafei Pan * in:  w1 = value to write
1615*9df5ba05SJiafei Pan * uses x0, x1, x2
1616*9df5ba05SJiafei Pan */
1617*9df5ba05SJiafei Pan_write_reg_reset:
1618*9df5ba05SJiafei Pan	ldr	x2, =NXP_RESET_ADDR
1619*9df5ba05SJiafei Pan	str	w1, [x2, x0]
1620*9df5ba05SJiafei Pan	ret
1621*9df5ba05SJiafei Pan
1622*9df5ba05SJiafei Pan/*
1623*9df5ba05SJiafei Pan * read a register in the RESET block
1624*9df5ba05SJiafei Pan * in:  x0 = offset
1625*9df5ba05SJiafei Pan * out: w0 = value read
1626*9df5ba05SJiafei Pan * uses x0, x1
1627*9df5ba05SJiafei Pan */
1628*9df5ba05SJiafei Pan_read_reg_reset:
1629*9df5ba05SJiafei Pan	ldr	x1, =NXP_RESET_ADDR
1630*9df5ba05SJiafei Pan	ldr	w0, [x1, x0]
1631*9df5ba05SJiafei Pan	ret
1632*9df5ba05SJiafei Pan
1633*9df5ba05SJiafei Pan/*
1634*9df5ba05SJiafei Pan * this function will pwrdown ddr and the final core - it will do this
1635*9df5ba05SJiafei Pan * by loading itself into the icache and then executing from there
1636*9df5ba05SJiafei Pan * in:  x5  = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
1637*9df5ba05SJiafei Pan *      x6  = DDR_CNTRL_BASE_ADDR
1638*9df5ba05SJiafei Pan *      x7  = NXP_PMU_ADDR
1639*9df5ba05SJiafei Pan *      x8  = NXP_DCFG_ADDR
1640*9df5ba05SJiafei Pan *      x9  = 0, restartable
1641*9df5ba05SJiafei Pan *          = 1, non-restartable
1642*9df5ba05SJiafei Pan *      x10 = PMU_IPSTPCR4_OFFSET
1643*9df5ba05SJiafei Pan *      x11 = PMU_IPSTPACK4_OFFSET
1644*9df5ba05SJiafei Pan *      x12 = PMU_IPSTPCR3_OFFSET
1645*9df5ba05SJiafei Pan *      x18 = PMU_IPSTPCR2_OFFSET
1646*9df5ba05SJiafei Pan *      x19 = PMU_IPSTPCR1_OFFSET
1647*9df5ba05SJiafei Pan *      x21 = PMU_IPSTPCR0_OFFSET
1648*9df5ba05SJiafei Pan *      w13 = DEVDISR1 saved value
1649*9df5ba05SJiafei Pan *      w14 = DEVDISR2 saved value
1650*9df5ba05SJiafei Pan *      w15 = DEVDISR3 saved value
1651*9df5ba05SJiafei Pan *      w16 = DEVDISR4 saved value
1652*9df5ba05SJiafei Pan *      w17 = DEVDISR5 saved value
1653*9df5ba05SJiafei Pan *      x22 = DCFG_DEVDISR5_OFFSET
1654*9df5ba05SJiafei Pan *      x23 = NXP_EPU_ADDR
1655*9df5ba05SJiafei Pan * out: none
1656*9df5ba05SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x13, x14, x15, x16, x17
1657*9df5ba05SJiafei Pan * x10, x11, x12, x18, x19, x21, x22, x23
1658*9df5ba05SJiafei Pan */
1659*9df5ba05SJiafei Pan
1660*9df5ba05SJiafei Panfinal_pwrdown:
1661*9df5ba05SJiafei Pan	/* delay */
1662*9df5ba05SJiafei Pan	mov	w4, #0xffffff
1663*9df5ba05SJiafei Pan554:
1664*9df5ba05SJiafei Pan	sub	w4, w4, #1
1665*9df5ba05SJiafei Pan	cmp	w4, #0
1666*9df5ba05SJiafei Pan	b.ge	554b
1667*9df5ba05SJiafei Pan
1668*9df5ba05SJiafei Pan	mov	x0, xzr
1669*9df5ba05SJiafei Pan	b	touch_line_0
1670*9df5ba05SJiafei Pan
1671*9df5ba05SJiafei Pan/* 4Kb aligned */
1672*9df5ba05SJiafei Pan.align 12
1673*9df5ba05SJiafei Panstart_line_0:
1674*9df5ba05SJiafei Pan	mov	x0, #1
1675*9df5ba05SJiafei Pan	/* put ddr in self refresh - start */
1676*9df5ba05SJiafei Pan	mov	x2, #DDR_SDRAM_CFG_2_FRCSR
1677*9df5ba05SJiafei Pan	ldr	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
1678*9df5ba05SJiafei Pan	orr	w3, w3, w2
1679*9df5ba05SJiafei Pan	/* put ddr in self refresh - end */
1680*9df5ba05SJiafei Pan	str	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
1681*9df5ba05SJiafei Pan	nop
1682*9df5ba05SJiafei Pan	nop
1683*9df5ba05SJiafei Pantouch_line_0:
1684*9df5ba05SJiafei Pan	cbz	x0, touch_line_1
1685*9df5ba05SJiafei Pan
1686*9df5ba05SJiafei Panstart_line_1:
1687*9df5ba05SJiafei Pan	/* quiesce ddr clocks - start */
1688*9df5ba05SJiafei Pan	orr	w3, w5, #DCFG_DEVDISR5_MEM
1689*9df5ba05SJiafei Pan	mov	w4, w3
1690*9df5ba05SJiafei Pan	/* quiesce ddr clocks - end */
1691*9df5ba05SJiafei Pan	str	w4, [x7, x10]
1692*9df5ba05SJiafei Pan	mov	w3, #DCFG_DEVDISR5_MEM
1693*9df5ba05SJiafei Pan	/* poll on ipstpack4 - start */
1694*9df5ba05SJiafei Pan	mov	x2, #DDR_SLEEP_RETRY_CNT
1695*9df5ba05SJiafei Pan	nop
1696*9df5ba05SJiafei Pan	nop
1697*9df5ba05SJiafei Pantouch_line_1:
1698*9df5ba05SJiafei Pan	cbz	x0, touch_line_2
1699*9df5ba05SJiafei Pan
1700*9df5ba05SJiafei Panstart_line_2:
1701*9df5ba05SJiafei Pan	/* x11 = PMU_IPSTPACK4_OFFSET */
1702*9df5ba05SJiafei Pan	ldr	w1, [x7, x11]
1703*9df5ba05SJiafei Pan	tst	w1, w3
1704*9df5ba05SJiafei Pan	b.ne	5f
1705*9df5ba05SJiafei Pan	subs	x2, x2, #1
1706*9df5ba05SJiafei Pan	/* poll on ipstpack4 - end */
1707*9df5ba05SJiafei Pan	b.gt	start_line_2
1708*9df5ba05SJiafei Pan
1709*9df5ba05SJiafei Pan	/* if we get here, we have a timeout err */
1710*9df5ba05SJiafei Pan	mov	w4, w5
1711*9df5ba05SJiafei Pan	/* x10 = PMU_IPSTPCR4_OFFSET re-enable ddr clks interface */
1712*9df5ba05SJiafei Pan	str	w4, [x7, x10]
1713*9df5ba05SJiafei Pantouch_line_2:
1714*9df5ba05SJiafei Pan	cbz	x0, touch_line_3
1715*9df5ba05SJiafei Pan
1716*9df5ba05SJiafei Panstart_line_3:
1717*9df5ba05SJiafei Pan	/* load error code */
1718*9df5ba05SJiafei Pan	mov	x0, #ERROR_DDR_SLEEP
1719*9df5ba05SJiafei Pan	b	2f
1720*9df5ba05SJiafei Pan5:
1721*9df5ba05SJiafei Pan	wfe
1722*9df5ba05SJiafei Pan	ldr	w1, [x23, #EPU_EPCTR10_OFFSET]
1723*9df5ba05SJiafei Pan	cbz	w1, 5b
1724*9df5ba05SJiafei Pan
1725*9df5ba05SJiafei Pan	mov	w4, w5
1726*9df5ba05SJiafei Pantouch_line_3:
1727*9df5ba05SJiafei Pan	cbz	x0, touch_line_4
1728*9df5ba05SJiafei Pan
1729*9df5ba05SJiafei Panstart_line_4:
1730*9df5ba05SJiafei Pan	/* re-enable ddr in devdisr5 */
1731*9df5ba05SJiafei Pan	str	w4, [x8, x22]
1732*9df5ba05SJiafei Pan	/* re-enable ddr clk in ipstpcr4 */
1733*9df5ba05SJiafei Pan	str	w4, [x7, x10]
1734*9df5ba05SJiafei Pan13:
1735*9df5ba05SJiafei Pan	/* poll on ipstpack4 - start */
1736*9df5ba05SJiafei Pan	ldr	w1, [x7, x11]
1737*9df5ba05SJiafei Pan	tst	w1, w3
1738*9df5ba05SJiafei Pan	b.eq	2f
1739*9df5ba05SJiafei Pan	nop
1740*9df5ba05SJiafei Pan	b	13b
1741*9df5ba05SJiafei Pan	/* poll on ipstpack4 - end */
1742*9df5ba05SJiafei Pan2:
1743*9df5ba05SJiafei Pantouch_line_4:
1744*9df5ba05SJiafei Pan	cbz	x0, touch_line_5
1745*9df5ba05SJiafei Pan
1746*9df5ba05SJiafei Panstart_line_5:
1747*9df5ba05SJiafei Pan	/* take ddr out-of self refresh - start */
1748*9df5ba05SJiafei Pan	mov	x2, #DDR_SDRAM_CFG_2_FRCSR
1749*9df5ba05SJiafei Pan	ldr	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
1750*9df5ba05SJiafei Pan	mov	w4, w3
1751*9df5ba05SJiafei Pan	bic	w4, w4, w2
1752*9df5ba05SJiafei Pan	mov	w3, w4
1753*9df5ba05SJiafei Pan	/* wait for ddr cntrlr clock- start */
1754*9df5ba05SJiafei Pan	mov	x1, #DDR_SLEEP_RETRY_CNT
1755*9df5ba05SJiafei Pan3:
1756*9df5ba05SJiafei Pan	subs	x1, x1, #1
1757*9df5ba05SJiafei Pantouch_line_5:
1758*9df5ba05SJiafei Pan	cbz	x0, touch_line_6
1759*9df5ba05SJiafei Pan
1760*9df5ba05SJiafei Panstart_line_6:
1761*9df5ba05SJiafei Pan	/* wait for ddr cntrlr clock - end */
1762*9df5ba05SJiafei Pan	b.gt	3b
1763*9df5ba05SJiafei Pan	/* take ddr out-of self refresh - end */
1764*9df5ba05SJiafei Pan	str	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
1765*9df5ba05SJiafei Pan	mov	w1, w17
1766*9df5ba05SJiafei Pan	/* reset devdisr5 */
1767*9df5ba05SJiafei Pan	str	w1, [x8, #DCFG_DEVDISR5_OFFSET]
1768*9df5ba05SJiafei Pan	mov	w1, w16
1769*9df5ba05SJiafei Pan	/* reset devdisr4 */
1770*9df5ba05SJiafei Pan	str	w1, [x8, #DCFG_DEVDISR4_OFFSET]
1771*9df5ba05SJiafei Pan	mov	w1, w15
1772*9df5ba05SJiafei Pantouch_line_6:
1773*9df5ba05SJiafei Pan	cbz	x0, touch_line_7
1774*9df5ba05SJiafei Pan
1775*9df5ba05SJiafei Panstart_line_7:
1776*9df5ba05SJiafei Pan	/* reset devdisr3 */
1777*9df5ba05SJiafei Pan	str	w1, [x8, #DCFG_DEVDISR3_OFFSET]
1778*9df5ba05SJiafei Pan	mov	w1, w14
1779*9df5ba05SJiafei Pan	/* reset devdisr2 */
1780*9df5ba05SJiafei Pan	str	w1, [x8, #DCFG_DEVDISR2_OFFSET]
1781*9df5ba05SJiafei Pan	mov	w1, w13
1782*9df5ba05SJiafei Pan	/* reset devdisr1 */
1783*9df5ba05SJiafei Pan	str	w1, [x8, #DCFG_DEVDISR1_OFFSET]
1784*9df5ba05SJiafei Pan	/* reset ipstpcr4 */
1785*9df5ba05SJiafei Pan	str	wzr, [x7, x10]
1786*9df5ba05SJiafei Pan	/* reset ipstpcr3 */
1787*9df5ba05SJiafei Pan	str	wzr, [x7, x12]
1788*9df5ba05SJiafei Pantouch_line_7:
1789*9df5ba05SJiafei Pan	cbz	x0, touch_line_8
1790*9df5ba05SJiafei Pan
1791*9df5ba05SJiafei Panstart_line_8:
1792*9df5ba05SJiafei Pan	/* reset ipstpcr2 */
1793*9df5ba05SJiafei Pan	str	wzr, [x7, x18]
1794*9df5ba05SJiafei Pan	/* reset ipstpcr1 */
1795*9df5ba05SJiafei Pan	str	wzr, [x7, x19]
1796*9df5ba05SJiafei Pan	/* reset ipstpcr0 */
1797*9df5ba05SJiafei Pan	str	wzr, [x7, x21]
1798*9df5ba05SJiafei Pan
1799*9df5ba05SJiafei Pantouch_line_8:
1800*9df5ba05SJiafei Pan	cbz	x0, touch_line_9
1801*9df5ba05SJiafei Pan
1802*9df5ba05SJiafei Panstart_line_9:
1803*9df5ba05SJiafei Pan	b	continue_restart
1804*9df5ba05SJiafei Pantouch_line_9:
1805*9df5ba05SJiafei Pan	cbz	x0, start_line_0
1806*9df5ba05SJiafei Pan
1807*9df5ba05SJiafei Pan/* execute here after ddr is back up */
1808*9df5ba05SJiafei Pancontinue_restart:
1809*9df5ba05SJiafei Pan	/*
1810*9df5ba05SJiafei Pan	 * if x0 = 1, all is well
1811*9df5ba05SJiafei Pan	 * if x0 < 1, we had an error
1812*9df5ba05SJiafei Pan	 */
1813*9df5ba05SJiafei Pan	cmp	x0, #1
1814*9df5ba05SJiafei Pan	b.ne	4f
1815*9df5ba05SJiafei Pan	mov	x0, #0
1816*9df5ba05SJiafei Pan4:
1817*9df5ba05SJiafei Pan	ret
1818