xref: /rk3399_ARM-atf/plat/nxp/soc-ls1028a/aarch64/ls1028a.S (revision ab5964aadcf090c816804a798c0d49bc0c9b5183)
1*9d250f03SJiafei Pan/*
2*9d250f03SJiafei Pan * Copyright 2018-2021 NXP
3*9d250f03SJiafei Pan *
4*9d250f03SJiafei Pan * SPDX-License-Identifier: BSD-3-Clause
5*9d250f03SJiafei Pan */
6*9d250f03SJiafei Pan
7*9d250f03SJiafei Pan	.section .text, "ax"
8*9d250f03SJiafei Pan
9*9d250f03SJiafei Pan#include <asm_macros.S>
10*9d250f03SJiafei Pan
11*9d250f03SJiafei Pan#include <lib/psci/psci.h>
12*9d250f03SJiafei Pan#include <nxp_timer.h>
13*9d250f03SJiafei Pan#include <plat_gic.h>
14*9d250f03SJiafei Pan#include <pmu.h>
15*9d250f03SJiafei Pan
16*9d250f03SJiafei Pan#include <bl31_data.h>
17*9d250f03SJiafei Pan#include <plat_psci.h>
18*9d250f03SJiafei Pan#include <platform_def.h>
19*9d250f03SJiafei Pan
20*9d250f03SJiafei Pan	.global soc_init_lowlevel
21*9d250f03SJiafei Pan	.global soc_init_percpu
22*9d250f03SJiafei Pan	.global _set_platform_security
23*9d250f03SJiafei Pan	.global _soc_set_start_addr
24*9d250f03SJiafei Pan
25*9d250f03SJiafei Pan	.global _soc_core_release
26*9d250f03SJiafei Pan	.global _soc_ck_disabled
27*9d250f03SJiafei Pan	.global _soc_core_restart
28*9d250f03SJiafei Pan	.global _soc_core_prep_off
29*9d250f03SJiafei Pan	.global _soc_core_entr_off
30*9d250f03SJiafei Pan	.global _soc_core_exit_off
31*9d250f03SJiafei Pan	.global _soc_sys_reset
32*9d250f03SJiafei Pan	.global _soc_sys_off
33*9d250f03SJiafei Pan	.global _soc_core_prep_stdby
34*9d250f03SJiafei Pan	.global _soc_core_entr_stdby
35*9d250f03SJiafei Pan	.global _soc_core_exit_stdby
36*9d250f03SJiafei Pan	.global _soc_core_prep_pwrdn
37*9d250f03SJiafei Pan	.global _soc_core_entr_pwrdn
38*9d250f03SJiafei Pan	.global _soc_core_exit_pwrdn
39*9d250f03SJiafei Pan	.global _soc_clstr_prep_stdby
40*9d250f03SJiafei Pan	.global _soc_clstr_exit_stdby
41*9d250f03SJiafei Pan	.global _soc_clstr_prep_pwrdn
42*9d250f03SJiafei Pan	.global _soc_clstr_exit_pwrdn
43*9d250f03SJiafei Pan	.global _soc_sys_prep_stdby
44*9d250f03SJiafei Pan	.global _soc_sys_exit_stdby
45*9d250f03SJiafei Pan	.global _soc_sys_prep_pwrdn
46*9d250f03SJiafei Pan	.global _soc_sys_pwrdn_wfi
47*9d250f03SJiafei Pan	.global _soc_sys_exit_pwrdn
48*9d250f03SJiafei Pan
49*9d250f03SJiafei Pan	.equ TZPCDECPROT_0_SET_BASE, 0x02200804
50*9d250f03SJiafei Pan	.equ TZPCDECPROT_1_SET_BASE, 0x02200810
51*9d250f03SJiafei Pan	.equ TZPCDECPROT_2_SET_BASE, 0x0220081C
52*9d250f03SJiafei Pan
53*9d250f03SJiafei Pan	.equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110
54*9d250f03SJiafei Pan
55*9d250f03SJiafei Pan/*
56*9d250f03SJiafei Pan * This function initialize the soc.
57*9d250f03SJiafei Pan * in: void
58*9d250f03SJiafei Pan * out: void
59*9d250f03SJiafei Pan * uses x0 - x11
60*9d250f03SJiafei Pan */
61*9d250f03SJiafei Panfunc soc_init_lowlevel
62*9d250f03SJiafei Pan	/*
63*9d250f03SJiafei Pan	 * Called from C, so save the non-volatile regs
64*9d250f03SJiafei Pan	 * save these as pairs of registers to maintain the
65*9d250f03SJiafei Pan	 * required 16-byte alignment on the stack
66*9d250f03SJiafei Pan	 */
67*9d250f03SJiafei Pan	stp	x4,  x5,  [sp, #-16]!
68*9d250f03SJiafei Pan	stp	x6,  x7,  [sp, #-16]!
69*9d250f03SJiafei Pan	stp	x8,  x9,  [sp, #-16]!
70*9d250f03SJiafei Pan	stp	x10, x11, [sp, #-16]!
71*9d250f03SJiafei Pan	stp	x12, x13, [sp, #-16]!
72*9d250f03SJiafei Pan	stp	x18, x30, [sp, #-16]!
73*9d250f03SJiafei Pan
74*9d250f03SJiafei Pan	/*
75*9d250f03SJiafei Pan	 * Make sure the personality has been established by releasing cores
76*9d250f03SJiafei Pan	 * that are marked "to-be-disabled" from reset
77*9d250f03SJiafei Pan	 */
78*9d250f03SJiafei Pan	bl	release_disabled  /* 0-8 */
79*9d250f03SJiafei Pan
80*9d250f03SJiafei Pan	/* Set SCRATCHRW7 to 0x0 */
81*9d250f03SJiafei Pan	ldr	x0, =DCFG_SCRATCHRW7_OFFSET
82*9d250f03SJiafei Pan	mov	x1, xzr
83*9d250f03SJiafei Pan	bl	_write_reg_dcfg
84*9d250f03SJiafei Pan
85*9d250f03SJiafei Pan	/* Restore the aarch32/64 non-volatile registers */
86*9d250f03SJiafei Pan	ldp	x18, x30, [sp], #16
87*9d250f03SJiafei Pan	ldp	x12, x13, [sp], #16
88*9d250f03SJiafei Pan	ldp	x10, x11, [sp], #16
89*9d250f03SJiafei Pan	ldp	x8,  x9,  [sp], #16
90*9d250f03SJiafei Pan	ldp	x6,  x7,  [sp], #16
91*9d250f03SJiafei Pan	ldp	x4,  x5,  [sp], #16
92*9d250f03SJiafei Pan	ret
93*9d250f03SJiafei Panendfunc soc_init_lowlevel
94*9d250f03SJiafei Pan
95*9d250f03SJiafei Pan/*
96*9d250f03SJiafei Pan * void soc_init_percpu(void)
97*9d250f03SJiafei Pan *
98*9d250f03SJiafei Pan * This function performs any soc-specific initialization that is needed on
99*9d250f03SJiafei Pan * a per-core basis
100*9d250f03SJiafei Pan * in:  none
101*9d250f03SJiafei Pan * out: none
102*9d250f03SJiafei Pan * uses x0 - x3
103*9d250f03SJiafei Pan */
104*9d250f03SJiafei Panfunc soc_init_percpu
105*9d250f03SJiafei Pan	stp	x4,  x30,  [sp, #-16]!
106*9d250f03SJiafei Pan
107*9d250f03SJiafei Pan	bl	plat_my_core_mask
108*9d250f03SJiafei Pan	mov	x2, x0
109*9d250f03SJiafei Pan
110*9d250f03SJiafei Pan	/* x2 = core mask */
111*9d250f03SJiafei Pan
112*9d250f03SJiafei Pan	/* see if this core is marked for prefetch disable */
113*9d250f03SJiafei Pan	mov	x0, #PREFETCH_DIS_OFFSET
114*9d250f03SJiafei Pan	bl	_get_global_data  /* 0-1 */
115*9d250f03SJiafei Pan	tst	x0, x2
116*9d250f03SJiafei Pan	b.eq	1f
117*9d250f03SJiafei Pan	bl	_disable_ldstr_pfetch_A72  /* 0 */
118*9d250f03SJiafei Pan1:
119*9d250f03SJiafei Pan	mov	x0, #NXP_PMU_ADDR
120*9d250f03SJiafei Pan	bl	enable_timer_base_to_cluster
121*9d250f03SJiafei Pan
122*9d250f03SJiafei Pan	ldp	x4,  x30,  [sp], #16
123*9d250f03SJiafei Pan	ret
124*9d250f03SJiafei Panendfunc soc_init_percpu
125*9d250f03SJiafei Pan
126*9d250f03SJiafei Pan/*
127*9d250f03SJiafei Pan * This function determines if a core is disabled via COREDISABLEDSR
128*9d250f03SJiafei Pan * in:  w0  = core_mask_lsb
129*9d250f03SJiafei Pan * out: w0  = 0, core not disabled
130*9d250f03SJiafei Pan *      w0 != 0, core disabled
131*9d250f03SJiafei Pan * uses x0, x1
132*9d250f03SJiafei Pan */
133*9d250f03SJiafei Panfunc _soc_ck_disabled
134*9d250f03SJiafei Pan	/* get base addr of dcfg block */
135*9d250f03SJiafei Pan	ldr	x1, =NXP_DCFG_ADDR
136*9d250f03SJiafei Pan
137*9d250f03SJiafei Pan	/* read COREDISABLEDSR */
138*9d250f03SJiafei Pan	ldr	w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
139*9d250f03SJiafei Pan
140*9d250f03SJiafei Pan	/* test core bit */
141*9d250f03SJiafei Pan	and	w0, w1, w0
142*9d250f03SJiafei Pan
143*9d250f03SJiafei Pan	ret
144*9d250f03SJiafei Panendfunc _soc_ck_disabled
145*9d250f03SJiafei Pan
146*9d250f03SJiafei Pan/*
147*9d250f03SJiafei Pan * This function sets the security mechanisms in the SoC to implement the
148*9d250f03SJiafei Pan * Platform Security Policy
149*9d250f03SJiafei Pan */
150*9d250f03SJiafei Panfunc _set_platform_security
151*9d250f03SJiafei Pan	mov	x3, x30
152*9d250f03SJiafei Pan
153*9d250f03SJiafei Pan#if (!SUPPRESS_TZC)
154*9d250f03SJiafei Pan	/* initialize the tzpc */
155*9d250f03SJiafei Pan	bl	init_tzpc
156*9d250f03SJiafei Pan#endif
157*9d250f03SJiafei Pan
158*9d250f03SJiafei Pan#if (!SUPPRESS_SEC)
159*9d250f03SJiafei Pan	/* initialize secmon */
160*9d250f03SJiafei Pan	bl	initSecMon
161*9d250f03SJiafei Pan#endif
162*9d250f03SJiafei Pan
163*9d250f03SJiafei Pan	mov	x30, x3
164*9d250f03SJiafei Pan	ret
165*9d250f03SJiafei Panendfunc _set_platform_security
166*9d250f03SJiafei Pan
167*9d250f03SJiafei Pan/*
168*9d250f03SJiafei Pan * Part of CPU_ON
169*9d250f03SJiafei Pan *
170*9d250f03SJiafei Pan * This function releases a secondary core from reset
171*9d250f03SJiafei Pan * in:   x0 = core_mask_lsb
172*9d250f03SJiafei Pan * out:  none
173*9d250f03SJiafei Pan * uses: x0 - x3
174*9d250f03SJiafei Pan */
175*9d250f03SJiafei Pan_soc_core_release:
176*9d250f03SJiafei Pan	mov	x3, x30
177*9d250f03SJiafei Pan
178*9d250f03SJiafei Pan	/*
179*9d250f03SJiafei Pan	 * Write to CORE_HOLD to tell the bootrom that we want this core
180*9d250f03SJiafei Pan	 * to run
181*9d250f03SJiafei Pan	 */
182*9d250f03SJiafei Pan	ldr	x1, =NXP_SEC_REGFILE_ADDR
183*9d250f03SJiafei Pan	str	w0, [x1, #CORE_HOLD_OFFSET]
184*9d250f03SJiafei Pan
185*9d250f03SJiafei Pan	/* Read-modify-write BRRL to release core */
186*9d250f03SJiafei Pan	mov	x1, #NXP_RESET_ADDR
187*9d250f03SJiafei Pan	ldr	w2, [x1, #BRR_OFFSET]
188*9d250f03SJiafei Pan	orr	w2, w2, w0
189*9d250f03SJiafei Pan	str	w2, [x1, #BRR_OFFSET]
190*9d250f03SJiafei Pan	dsb	sy
191*9d250f03SJiafei Pan	isb
192*9d250f03SJiafei Pan
193*9d250f03SJiafei Pan	/* Send event */
194*9d250f03SJiafei Pan	sev
195*9d250f03SJiafei Pan	isb
196*9d250f03SJiafei Pan
197*9d250f03SJiafei Pan	mov	x30, x3
198*9d250f03SJiafei Pan	ret
199*9d250f03SJiafei Pan
200*9d250f03SJiafei Pan/*
201*9d250f03SJiafei Pan * This function writes a 64-bit address to bootlocptrh/l
202*9d250f03SJiafei Pan * in:  x0, 64-bit address to write to BOOTLOCPTRL/H
203*9d250f03SJiafei Pan * uses x0, x1, x2
204*9d250f03SJiafei Pan */
205*9d250f03SJiafei Panfunc _soc_set_start_addr
206*9d250f03SJiafei Pan	/* Get the 64-bit base address of the dcfg block */
207*9d250f03SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
208*9d250f03SJiafei Pan
209*9d250f03SJiafei Pan	/* Write the 32-bit BOOTLOCPTRL register */
210*9d250f03SJiafei Pan	mov	x1, x0
211*9d250f03SJiafei Pan	str	w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
212*9d250f03SJiafei Pan
213*9d250f03SJiafei Pan	/* Write the 32-bit BOOTLOCPTRH register */
214*9d250f03SJiafei Pan	lsr	x1, x0, #32
215*9d250f03SJiafei Pan	str	w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
216*9d250f03SJiafei Pan	ret
217*9d250f03SJiafei Panendfunc _soc_set_start_addr
218*9d250f03SJiafei Pan
219*9d250f03SJiafei Pan/*
220*9d250f03SJiafei Pan * Part of CPU_ON
221*9d250f03SJiafei Pan *
222*9d250f03SJiafei Pan * This function restarts a core shutdown via _soc_core_entr_off
223*9d250f03SJiafei Pan * in:  x0 = core mask lsb (of the target cpu)
224*9d250f03SJiafei Pan * out: x0 == 0, on success
225*9d250f03SJiafei Pan *      x0 != 0, on failure
226*9d250f03SJiafei Pan * uses x0 - x6
227*9d250f03SJiafei Pan */
228*9d250f03SJiafei Pan_soc_core_restart:
229*9d250f03SJiafei Pan	mov	x6, x30
230*9d250f03SJiafei Pan	mov	x4, x0
231*9d250f03SJiafei Pan
232*9d250f03SJiafei Pan	/* pgm GICD_CTLR - enable secure grp0  */
233*9d250f03SJiafei Pan	mov	x5, #NXP_GICD_ADDR
234*9d250f03SJiafei Pan	ldr	w2, [x5, #GICD_CTLR_OFFSET]
235*9d250f03SJiafei Pan	orr	w2, w2, #GICD_CTLR_EN_GRP_0
236*9d250f03SJiafei Pan	str	w2, [x5, #GICD_CTLR_OFFSET]
237*9d250f03SJiafei Pan	dsb	sy
238*9d250f03SJiafei Pan	isb
239*9d250f03SJiafei Pan
240*9d250f03SJiafei Pan	/* Poll on RWP til write completes */
241*9d250f03SJiafei Pan4:
242*9d250f03SJiafei Pan	ldr	w2, [x5, #GICD_CTLR_OFFSET]
243*9d250f03SJiafei Pan	tst	w2, #GICD_CTLR_RWP
244*9d250f03SJiafei Pan	b.ne	4b
245*9d250f03SJiafei Pan
246*9d250f03SJiafei Pan	/*
247*9d250f03SJiafei Pan	 * x4 = core mask lsb
248*9d250f03SJiafei Pan	 * x5 = gicd base addr
249*9d250f03SJiafei Pan	 */
250*9d250f03SJiafei Pan
251*9d250f03SJiafei Pan	mov	x0, x4
252*9d250f03SJiafei Pan	bl	get_mpidr_value
253*9d250f03SJiafei Pan
254*9d250f03SJiafei Pan	/* Generate target list bit */
255*9d250f03SJiafei Pan	and	x1, x0, #MPIDR_AFFINITY0_MASK
256*9d250f03SJiafei Pan	mov	x2, #1
257*9d250f03SJiafei Pan	lsl	x2, x2, x1
258*9d250f03SJiafei Pan
259*9d250f03SJiafei Pan	/* Get the affinity1 field */
260*9d250f03SJiafei Pan	and	x1, x0, #MPIDR_AFFINITY1_MASK
261*9d250f03SJiafei Pan	lsl	x1, x1, #8
262*9d250f03SJiafei Pan	orr	x2, x2, x1
263*9d250f03SJiafei Pan
264*9d250f03SJiafei Pan	/* Insert the INTID for SGI15 */
265*9d250f03SJiafei Pan	orr	x2, x2, #ICC_SGI0R_EL1_INTID
266*9d250f03SJiafei Pan
267*9d250f03SJiafei Pan	/* Fire the SGI */
268*9d250f03SJiafei Pan	msr	ICC_SGI0R_EL1, x2
269*9d250f03SJiafei Pan	dsb	sy
270*9d250f03SJiafei Pan	isb
271*9d250f03SJiafei Pan
272*9d250f03SJiafei Pan	/* Load '0' on success */
273*9d250f03SJiafei Pan	mov	x0, xzr
274*9d250f03SJiafei Pan
275*9d250f03SJiafei Pan	mov	x30, x6
276*9d250f03SJiafei Pan	ret
277*9d250f03SJiafei Pan
278*9d250f03SJiafei Pan/*
279*9d250f03SJiafei Pan * Part of CPU_OFF
280*9d250f03SJiafei Pan *
281*9d250f03SJiafei Pan * This function programs SoC & GIC registers in preparation for shutting down
282*9d250f03SJiafei Pan * the core
283*9d250f03SJiafei Pan * in:  x0 = core mask lsb
284*9d250f03SJiafei Pan * out: none
285*9d250f03SJiafei Pan * uses x0 - x7
286*9d250f03SJiafei Pan */
287*9d250f03SJiafei Pan_soc_core_prep_off:
288*9d250f03SJiafei Pan	mov	x8, x30
289*9d250f03SJiafei Pan	mov	x7, x0
290*9d250f03SJiafei Pan
291*9d250f03SJiafei Pan	/* x7 = core mask lsb */
292*9d250f03SJiafei Pan
293*9d250f03SJiafei Pan	mrs	x1, CPUECTLR_EL1
294*9d250f03SJiafei Pan
295*9d250f03SJiafei Pan	/* Set smp and disable L2 snoops in cpuectlr */
296*9d250f03SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_EN
297*9d250f03SJiafei Pan	orr	x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
298*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_INS_PREFETCH_MASK
299*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
300*9d250f03SJiafei Pan
301*9d250f03SJiafei Pan	/* Set retention control in cpuectlr */
302*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
303*9d250f03SJiafei Pan	orr	x1, x1, #CPUECTLR_TIMER_2TICKS
304*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x1
305*9d250f03SJiafei Pan
306*9d250f03SJiafei Pan	/* Get redistributor rd base addr for this core */
307*9d250f03SJiafei Pan	mov	x0, x7
308*9d250f03SJiafei Pan	bl	get_gic_rd_base
309*9d250f03SJiafei Pan	mov	x6, x0
310*9d250f03SJiafei Pan
311*9d250f03SJiafei Pan	/* Get redistributor sgi base addr for this core */
312*9d250f03SJiafei Pan	mov	x0, x7
313*9d250f03SJiafei Pan	bl	get_gic_sgi_base
314*9d250f03SJiafei Pan	mov	x5, x0
315*9d250f03SJiafei Pan
316*9d250f03SJiafei Pan	/*
317*9d250f03SJiafei Pan	 * x5 = gicr sgi base addr
318*9d250f03SJiafei Pan	 * x6 = gicr rd  base addr
319*9d250f03SJiafei Pan	 * x7 = core mask lsb
320*9d250f03SJiafei Pan	 */
321*9d250f03SJiafei Pan
322*9d250f03SJiafei Pan	/* Disable SGI 15 at redistributor - GICR_ICENABLER0 */
323*9d250f03SJiafei Pan	mov	w3, #GICR_ICENABLER0_SGI15
324*9d250f03SJiafei Pan	str	w3, [x5, #GICR_ICENABLER0_OFFSET]
325*9d250f03SJiafei Pan2:
326*9d250f03SJiafei Pan	/* Poll on rwp bit in GICR_CTLR */
327*9d250f03SJiafei Pan	ldr	w4, [x6, #GICR_CTLR_OFFSET]
328*9d250f03SJiafei Pan	tst	w4, #GICR_CTLR_RWP
329*9d250f03SJiafei Pan	b.ne	2b
330*9d250f03SJiafei Pan
331*9d250f03SJiafei Pan	/* Disable GRP1 interrupts at cpu interface */
332*9d250f03SJiafei Pan	msr	ICC_IGRPEN1_EL3, xzr
333*9d250f03SJiafei Pan
334*9d250f03SJiafei Pan	/* Disable GRP0 ints at cpu interface */
335*9d250f03SJiafei Pan	msr	ICC_IGRPEN0_EL1, xzr
336*9d250f03SJiafei Pan
337*9d250f03SJiafei Pan	/* Program the redistributor - poll on GICR_CTLR.RWP as needed */
338*9d250f03SJiafei Pan
339*9d250f03SJiafei Pan	/* Define SGI 15 as Grp0 - GICR_IGROUPR0 */
340*9d250f03SJiafei Pan	ldr	w4, [x5, #GICR_IGROUPR0_OFFSET]
341*9d250f03SJiafei Pan	bic	w4, w4, #GICR_IGROUPR0_SGI15
342*9d250f03SJiafei Pan	str	w4, [x5, #GICR_IGROUPR0_OFFSET]
343*9d250f03SJiafei Pan
344*9d250f03SJiafei Pan	/* Define SGI 15 as Grp0 - GICR_IGRPMODR0 */
345*9d250f03SJiafei Pan	ldr	w3, [x5, #GICR_IGRPMODR0_OFFSET]
346*9d250f03SJiafei Pan	bic	w3, w3, #GICR_IGRPMODR0_SGI15
347*9d250f03SJiafei Pan	str	w3, [x5, #GICR_IGRPMODR0_OFFSET]
348*9d250f03SJiafei Pan
349*9d250f03SJiafei Pan	/* Set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
350*9d250f03SJiafei Pan	ldr	w4, [x5, #GICR_IPRIORITYR3_OFFSET]
351*9d250f03SJiafei Pan	bic	w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
352*9d250f03SJiafei Pan	str	w4, [x5, #GICR_IPRIORITYR3_OFFSET]
353*9d250f03SJiafei Pan
354*9d250f03SJiafei Pan	/* Enable SGI 15 at redistributor - GICR_ISENABLER0 */
355*9d250f03SJiafei Pan	mov	w3, #GICR_ISENABLER0_SGI15
356*9d250f03SJiafei Pan	str	w3, [x5, #GICR_ISENABLER0_OFFSET]
357*9d250f03SJiafei Pan	dsb	sy
358*9d250f03SJiafei Pan	isb
359*9d250f03SJiafei Pan3:
360*9d250f03SJiafei Pan	/* Poll on rwp bit in GICR_CTLR */
361*9d250f03SJiafei Pan	ldr	w4, [x6, #GICR_CTLR_OFFSET]
362*9d250f03SJiafei Pan	tst	w4, #GICR_CTLR_RWP
363*9d250f03SJiafei Pan	b.ne	3b
364*9d250f03SJiafei Pan
365*9d250f03SJiafei Pan	/* Quiesce the debug interfaces */
366*9d250f03SJiafei Pan	mrs	x3, osdlr_el1
367*9d250f03SJiafei Pan	orr	x3, x3, #OSDLR_EL1_DLK_LOCK
368*9d250f03SJiafei Pan	msr	osdlr_el1, x3
369*9d250f03SJiafei Pan	isb
370*9d250f03SJiafei Pan
371*9d250f03SJiafei Pan	/* Enable grp0 ints */
372*9d250f03SJiafei Pan	mov	x3, #ICC_IGRPEN0_EL1_EN
373*9d250f03SJiafei Pan	msr	ICC_IGRPEN0_EL1, x3
374*9d250f03SJiafei Pan
375*9d250f03SJiafei Pan	/*
376*9d250f03SJiafei Pan	 * x5 = gicr sgi base addr
377*9d250f03SJiafei Pan	 * x6 = gicr rd  base addr
378*9d250f03SJiafei Pan	 * x7 = core mask lsb
379*9d250f03SJiafei Pan	 */
380*9d250f03SJiafei Pan
381*9d250f03SJiafei Pan	/* Clear any pending interrupts */
382*9d250f03SJiafei Pan	mvn	w1, wzr
383*9d250f03SJiafei Pan	str	w1, [x5, #GICR_ICPENDR0_OFFSET]
384*9d250f03SJiafei Pan
385*9d250f03SJiafei Pan	/* Make sure system counter is enabled */
386*9d250f03SJiafei Pan	ldr	x3, =NXP_TIMER_ADDR
387*9d250f03SJiafei Pan	ldr	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
388*9d250f03SJiafei Pan	tst	w0, #SYS_COUNTER_CNTCR_EN
389*9d250f03SJiafei Pan	b.ne	4f
390*9d250f03SJiafei Pan	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
391*9d250f03SJiafei Pan	str	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
392*9d250f03SJiafei Pan4:
393*9d250f03SJiafei Pan	/* Enable the core timer and mask timer interrupt */
394*9d250f03SJiafei Pan	mov	x1, #CNTP_CTL_EL0_EN
395*9d250f03SJiafei Pan	orr	x1, x1, #CNTP_CTL_EL0_IMASK
396*9d250f03SJiafei Pan	msr	cntp_ctl_el0, x1
397*9d250f03SJiafei Pan
398*9d250f03SJiafei Pan	isb
399*9d250f03SJiafei Pan	mov	x30, x8
400*9d250f03SJiafei Pan	ret
401*9d250f03SJiafei Pan
402*9d250f03SJiafei Pan/*
403*9d250f03SJiafei Pan * Part of CPU_OFF
404*9d250f03SJiafei Pan *
405*9d250f03SJiafei Pan * This function performs the final steps to shutdown the core
406*9d250f03SJiafei Pan * in:  x0 = core mask lsb
407*9d250f03SJiafei Pan * out: none
408*9d250f03SJiafei Pan * uses x0 - x5
409*9d250f03SJiafei Pan */
410*9d250f03SJiafei Pan_soc_core_entr_off:
411*9d250f03SJiafei Pan	mov	x5, x30
412*9d250f03SJiafei Pan	mov	x4, x0
413*9d250f03SJiafei Pan
414*9d250f03SJiafei Pan	/* x4 = core mask */
415*9d250f03SJiafei Pan1:
416*9d250f03SJiafei Pan	/* Enter low-power state by executing wfi */
417*9d250f03SJiafei Pan	wfi
418*9d250f03SJiafei Pan
419*9d250f03SJiafei Pan	/* See if SGI15 woke us up */
420*9d250f03SJiafei Pan	mrs	x2, ICC_IAR0_EL1
421*9d250f03SJiafei Pan	mov	x3, #ICC_IAR0_EL1_SGI15
422*9d250f03SJiafei Pan	cmp	x2, x3
423*9d250f03SJiafei Pan	b.ne	1b
424*9d250f03SJiafei Pan
425*9d250f03SJiafei Pan	/* Deactivate the int */
426*9d250f03SJiafei Pan	msr	ICC_EOIR0_EL1, x2
427*9d250f03SJiafei Pan
428*9d250f03SJiafei Pan	/* x4 = core mask */
429*9d250f03SJiafei Pan2:
430*9d250f03SJiafei Pan	/* Check if core has been turned on */
431*9d250f03SJiafei Pan	mov	x0, x4
432*9d250f03SJiafei Pan	bl	_getCoreState
433*9d250f03SJiafei Pan
434*9d250f03SJiafei Pan	/* x0 = core state */
435*9d250f03SJiafei Pan
436*9d250f03SJiafei Pan	cmp	x0, #CORE_WAKEUP
437*9d250f03SJiafei Pan	b.ne	1b
438*9d250f03SJiafei Pan
439*9d250f03SJiafei Pan	/* If we get here, then we have exited the wfi */
440*9d250f03SJiafei Pan	mov	x30, x5
441*9d250f03SJiafei Pan	ret
442*9d250f03SJiafei Pan
443*9d250f03SJiafei Pan/*
444*9d250f03SJiafei Pan * Part of CPU_OFF
445*9d250f03SJiafei Pan *
446*9d250f03SJiafei Pan * This function starts the process of starting a core back up
447*9d250f03SJiafei Pan * in:  x0 = core mask lsb
448*9d250f03SJiafei Pan * out: none
449*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6
450*9d250f03SJiafei Pan */
451*9d250f03SJiafei Pan_soc_core_exit_off:
452*9d250f03SJiafei Pan	mov	x6, x30
453*9d250f03SJiafei Pan	mov	x5, x0
454*9d250f03SJiafei Pan
455*9d250f03SJiafei Pan	/* Disable forwarding of GRP0 ints at cpu interface */
456*9d250f03SJiafei Pan	msr	ICC_IGRPEN0_EL1, xzr
457*9d250f03SJiafei Pan
458*9d250f03SJiafei Pan	/* Get redistributor sgi base addr for this core */
459*9d250f03SJiafei Pan	mov	x0, x5
460*9d250f03SJiafei Pan	bl	get_gic_sgi_base
461*9d250f03SJiafei Pan	mov	x4, x0
462*9d250f03SJiafei Pan
463*9d250f03SJiafei Pan	/* x4 = gicr sgi base addr */
464*9d250f03SJiafei Pan	/* x5 = core mask */
465*9d250f03SJiafei Pan
466*9d250f03SJiafei Pan	/* Disable SGI 15 at redistributor - GICR_ICENABLER0 */
467*9d250f03SJiafei Pan	mov	w1, #GICR_ICENABLER0_SGI15
468*9d250f03SJiafei Pan	str	w1, [x4, #GICR_ICENABLER0_OFFSET]
469*9d250f03SJiafei Pan
470*9d250f03SJiafei Pan	/* Get redistributor rd base addr for this core */
471*9d250f03SJiafei Pan	mov	x0, x5
472*9d250f03SJiafei Pan	bl	get_gic_rd_base
473*9d250f03SJiafei Pan	mov	x4, x0
474*9d250f03SJiafei Pan
475*9d250f03SJiafei Pan	/* x4 = gicr rd  base addr */
476*9d250f03SJiafei Pan2:
477*9d250f03SJiafei Pan	/* Poll on rwp bit in GICR_CTLR */
478*9d250f03SJiafei Pan	ldr	w2, [x4, #GICR_CTLR_OFFSET]
479*9d250f03SJiafei Pan	tst	w2, #GICR_CTLR_RWP
480*9d250f03SJiafei Pan	b.ne	2b
481*9d250f03SJiafei Pan
482*9d250f03SJiafei Pan	/* x4 = gicr rd  base addr */
483*9d250f03SJiafei Pan
484*9d250f03SJiafei Pan	/* Unlock the debug interfaces */
485*9d250f03SJiafei Pan	mrs	x3, osdlr_el1
486*9d250f03SJiafei Pan	bic	x3, x3, #OSDLR_EL1_DLK_LOCK
487*9d250f03SJiafei Pan	msr	osdlr_el1, x3
488*9d250f03SJiafei Pan	isb
489*9d250f03SJiafei Pan
490*9d250f03SJiafei Pan	dsb	sy
491*9d250f03SJiafei Pan	isb
492*9d250f03SJiafei Pan	mov	x30, x6
493*9d250f03SJiafei Pan	ret
494*9d250f03SJiafei Pan
495*9d250f03SJiafei Pan/*
496*9d250f03SJiafei Pan * This function requests a reset of the entire SOC
497*9d250f03SJiafei Pan * in:  none
498*9d250f03SJiafei Pan * out: none
499*9d250f03SJiafei Pan * uses: x0, x1, x2, x3, x4, x5, x6
500*9d250f03SJiafei Pan */
501*9d250f03SJiafei Pan_soc_sys_reset:
502*9d250f03SJiafei Pan	mov	x3, x30
503*9d250f03SJiafei Pan
504*9d250f03SJiafei Pan	/* Make sure the mask is cleared in the reset request mask register */
505*9d250f03SJiafei Pan	mov	x0, #RST_RSTRQMR1_OFFSET
506*9d250f03SJiafei Pan	mov	w1, wzr
507*9d250f03SJiafei Pan	bl	_write_reg_reset
508*9d250f03SJiafei Pan
509*9d250f03SJiafei Pan	/* Set the reset request */
510*9d250f03SJiafei Pan	mov	x4, #RST_RSTCR_OFFSET
511*9d250f03SJiafei Pan	mov	x0, x4
512*9d250f03SJiafei Pan	mov	w1, #RSTCR_RESET_REQ
513*9d250f03SJiafei Pan	bl	_write_reg_reset
514*9d250f03SJiafei Pan
515*9d250f03SJiafei Pan	/* x4 = RST_RSTCR_OFFSET */
516*9d250f03SJiafei Pan
517*9d250f03SJiafei Pan	/*
518*9d250f03SJiafei Pan	 * Just in case this address range is mapped as cacheable,
519*9d250f03SJiafei Pan	 * flush the write out of the dcaches
520*9d250f03SJiafei Pan	 */
521*9d250f03SJiafei Pan	mov	x2, #NXP_RESET_ADDR
522*9d250f03SJiafei Pan	add	x2, x2, x4
523*9d250f03SJiafei Pan	dc	cvac, x2
524*9d250f03SJiafei Pan	dsb	st
525*9d250f03SJiafei Pan	isb
526*9d250f03SJiafei Pan
527*9d250f03SJiafei Pan	/* This function does not return */
528*9d250f03SJiafei Pan1:
529*9d250f03SJiafei Pan	wfi
530*9d250f03SJiafei Pan	b	1b
531*9d250f03SJiafei Pan
532*9d250f03SJiafei Pan/*
533*9d250f03SJiafei Pan * Part of SYSTEM_OFF
534*9d250f03SJiafei Pan *
535*9d250f03SJiafei Pan * This function turns off the SoC clocks
536*9d250f03SJiafei Pan * Note: this function is not intended to return, and the only allowable
537*9d250f03SJiafei Pan *       recovery is POR
538*9d250f03SJiafei Pan * in:  none
539*9d250f03SJiafei Pan * out: none
540*9d250f03SJiafei Pan * uses x0, x1, x2, x3
541*9d250f03SJiafei Pan */
542*9d250f03SJiafei Pan_soc_sys_off:
543*9d250f03SJiafei Pan	/*
544*9d250f03SJiafei Pan	 * Disable sec, spi and flexspi
545*9d250f03SJiafei Pan	 * TBD - Check if eNETC needs to be disabled
546*9d250f03SJiafei Pan	 */
547*9d250f03SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
548*9d250f03SJiafei Pan	ldr	x0, =DCFG_DEVDISR1_OFFSET
549*9d250f03SJiafei Pan	ldr	w1, =DCFG_DEVDISR1_SEC
550*9d250f03SJiafei Pan	str	w1, [x2, x0]
551*9d250f03SJiafei Pan	ldr	x0, =DCFG_DEVDISR4_OFFSET
552*9d250f03SJiafei Pan	ldr	w1, =DCFG_DEVDISR4_SPI_QSPI
553*9d250f03SJiafei Pan	str	w1, [x2, x0]
554*9d250f03SJiafei Pan
555*9d250f03SJiafei Pan	/* Set TPMWAKEMR0 */
556*9d250f03SJiafei Pan	ldr	x0, =TPMWAKEMR0_ADDR
557*9d250f03SJiafei Pan	mov	w1, #0x1
558*9d250f03SJiafei Pan	str	w1, [x0]
559*9d250f03SJiafei Pan
560*9d250f03SJiafei Pan	/* Disable icache, dcache, mmu @ EL1 */
561*9d250f03SJiafei Pan	mov	x1, #SCTLR_I_C_M_MASK
562*9d250f03SJiafei Pan	mrs	x0, sctlr_el1
563*9d250f03SJiafei Pan	bic	x0, x0, x1
564*9d250f03SJiafei Pan	msr	sctlr_el1, x0
565*9d250f03SJiafei Pan
566*9d250f03SJiafei Pan	/* Disable L2 prefetches */
567*9d250f03SJiafei Pan	mrs	x0, CPUECTLR_EL1
568*9d250f03SJiafei Pan	orr	x0, x0, #CPUECTLR_SMPEN_EN
569*9d250f03SJiafei Pan	bic	x0, x0, #CPUECTLR_TIMER_MASK
570*9d250f03SJiafei Pan	orr	x0, x0, #CPUECTLR_TIMER_2TICKS
571*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x0
572*9d250f03SJiafei Pan	dsb	sy
573*9d250f03SJiafei Pan	isb
574*9d250f03SJiafei Pan
575*9d250f03SJiafei Pan	/* Disable CCI snoop domain */
576*9d250f03SJiafei Pan	ldr	x0, =NXP_CCI_ADDR
577*9d250f03SJiafei Pan	mov	w1, #0x1
578*9d250f03SJiafei Pan	str	w1, [x0]
579*9d250f03SJiafei Pan
580*9d250f03SJiafei Pan	bl	get_pmu_idle_core_mask
581*9d250f03SJiafei Pan
582*9d250f03SJiafei Pan	/* x3 = pmu base addr */
583*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
584*9d250f03SJiafei Pan4:
585*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_PCPW20SR_OFFSET]
586*9d250f03SJiafei Pan	cmp	w1, w0
587*9d250f03SJiafei Pan	b.ne	4b
588*9d250f03SJiafei Pan
589*9d250f03SJiafei Pan	bl	get_pmu_idle_cluster_mask
590*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
591*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLAINACTSETR_OFFSET]
592*9d250f03SJiafei Pan
593*9d250f03SJiafei Pan	bl	get_pmu_idle_core_mask
594*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
595*9d250f03SJiafei Pan1:
596*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_PCPW20SR_OFFSET]
597*9d250f03SJiafei Pan	cmp	w1, w0
598*9d250f03SJiafei Pan	b.ne	1b
599*9d250f03SJiafei Pan
600*9d250f03SJiafei Pan	bl	get_pmu_flush_cluster_mask
601*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
602*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET]
603*9d250f03SJiafei Pan2:
604*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_CLL2FLUSHSR_OFFSET]
605*9d250f03SJiafei Pan	cmp	w1, w0
606*9d250f03SJiafei Pan	b.ne	2b
607*9d250f03SJiafei Pan
608*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET]
609*9d250f03SJiafei Pan
610*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLSINACTSETR_OFFSET]
611*9d250f03SJiafei Pan
612*9d250f03SJiafei Pan	mov	x2, #DAIF_SET_MASK
613*9d250f03SJiafei Pan	mrs	x1, spsr_el1
614*9d250f03SJiafei Pan	orr	x1, x1, x2
615*9d250f03SJiafei Pan	msr	spsr_el1, x1
616*9d250f03SJiafei Pan
617*9d250f03SJiafei Pan	mrs	x1, spsr_el2
618*9d250f03SJiafei Pan	orr	x1, x1, x2
619*9d250f03SJiafei Pan	msr	spsr_el2, x1
620*9d250f03SJiafei Pan
621*9d250f03SJiafei Pan	/* Force the debug interface to be quiescent */
622*9d250f03SJiafei Pan	mrs	x0, osdlr_el1
623*9d250f03SJiafei Pan	orr	x0, x0, #0x1
624*9d250f03SJiafei Pan	msr	osdlr_el1, x0
625*9d250f03SJiafei Pan
626*9d250f03SJiafei Pan	/* Invalidate all TLB entries at all 3 exception levels */
627*9d250f03SJiafei Pan	tlbi	alle1
628*9d250f03SJiafei Pan	tlbi	alle2
629*9d250f03SJiafei Pan	tlbi	alle3
630*9d250f03SJiafei Pan
631*9d250f03SJiafei Pan	/* x3 = pmu base addr */
632*9d250f03SJiafei Pan
633*9d250f03SJiafei Pan	/* Request lpm20 */
634*9d250f03SJiafei Pan	ldr	x0, =PMU_POWMGTCSR_OFFSET
635*9d250f03SJiafei Pan	ldr	w1, =PMU_POWMGTCSR_VAL
636*9d250f03SJiafei Pan	str	w1, [x3, x0]
637*9d250f03SJiafei Pan	isb
638*9d250f03SJiafei Pan	dsb	sy
639*9d250f03SJiafei Pan5:
640*9d250f03SJiafei Pan	wfe
641*9d250f03SJiafei Pan	b.eq	5b
642*9d250f03SJiafei Pan
643*9d250f03SJiafei Pan/*
644*9d250f03SJiafei Pan * Part of CPU_SUSPEND
645*9d250f03SJiafei Pan *
646*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to standby
647*9d250f03SJiafei Pan * in:  x0 = core mask lsb
648*9d250f03SJiafei Pan * out: none
649*9d250f03SJiafei Pan * uses x0, x1
650*9d250f03SJiafei Pan */
651*9d250f03SJiafei Pan_soc_core_prep_stdby:
652*9d250f03SJiafei Pan	/* Clear CPUECTLR_EL1[2:0] */
653*9d250f03SJiafei Pan	mrs	x1, CPUECTLR_EL1
654*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
655*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x1
656*9d250f03SJiafei Pan
657*9d250f03SJiafei Pan	ret
658*9d250f03SJiafei Pan
659*9d250f03SJiafei Pan/*
660*9d250f03SJiafei Pan * Part of CPU_SUSPEND
661*9d250f03SJiafei Pan *
662*9d250f03SJiafei Pan * This function puts the calling core into standby state
663*9d250f03SJiafei Pan * in:  x0 = core mask lsb
664*9d250f03SJiafei Pan * out: none
665*9d250f03SJiafei Pan * uses x0
666*9d250f03SJiafei Pan */
667*9d250f03SJiafei Pan_soc_core_entr_stdby:
668*9d250f03SJiafei Pan	/* X0 = core mask lsb */
669*9d250f03SJiafei Pan	dsb	sy
670*9d250f03SJiafei Pan	isb
671*9d250f03SJiafei Pan	wfi
672*9d250f03SJiafei Pan
673*9d250f03SJiafei Pan	ret
674*9d250f03SJiafei Pan
675*9d250f03SJiafei Pan/*
676*9d250f03SJiafei Pan * Part of CPU_SUSPEND
677*9d250f03SJiafei Pan *
678*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after standby state
679*9d250f03SJiafei Pan * in:  x0 = core mask lsb
680*9d250f03SJiafei Pan * out: none
681*9d250f03SJiafei Pan * uses none
682*9d250f03SJiafei Pan */
683*9d250f03SJiafei Pan_soc_core_exit_stdby:
684*9d250f03SJiafei Pan	ret
685*9d250f03SJiafei Pan
686*9d250f03SJiafei Pan/*
687*9d250f03SJiafei Pan * Part of CPU_SUSPEND
688*9d250f03SJiafei Pan *
689*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to power-down
690*9d250f03SJiafei Pan * in:  x0 = core mask lsb
691*9d250f03SJiafei Pan * out: none
692*9d250f03SJiafei Pan * uses x0, x1, x2
693*9d250f03SJiafei Pan */
694*9d250f03SJiafei Pan_soc_core_prep_pwrdn:
695*9d250f03SJiafei Pan	/* Make sure system counter is enabled */
696*9d250f03SJiafei Pan	ldr	x2, =NXP_TIMER_ADDR
697*9d250f03SJiafei Pan	ldr	w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
698*9d250f03SJiafei Pan	tst	w0, #SYS_COUNTER_CNTCR_EN
699*9d250f03SJiafei Pan	b.ne	1f
700*9d250f03SJiafei Pan	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
701*9d250f03SJiafei Pan	str	w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
702*9d250f03SJiafei Pan1:
703*9d250f03SJiafei Pan	/*
704*9d250f03SJiafei Pan	 * Enable dynamic retention control (CPUECTLR[2:0])
705*9d250f03SJiafei Pan	 * Set the SMPEN bit (CPUECTLR[6])
706*9d250f03SJiafei Pan	 */
707*9d250f03SJiafei Pan	mrs	x1, CPUECTLR_EL1
708*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_RET_MASK
709*9d250f03SJiafei Pan	orr	x1, x1, #CPUECTLR_TIMER_2TICKS
710*9d250f03SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_EN
711*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x1
712*9d250f03SJiafei Pan
713*9d250f03SJiafei Pan	isb
714*9d250f03SJiafei Pan	ret
715*9d250f03SJiafei Pan
716*9d250f03SJiafei Pan/*
717*9d250f03SJiafei Pan * Part of CPU_SUSPEND
718*9d250f03SJiafei Pan *
719*9d250f03SJiafei Pan * This function puts the calling core into a power-down state
720*9d250f03SJiafei Pan * in:  x0 = core mask lsb
721*9d250f03SJiafei Pan * out: none
722*9d250f03SJiafei Pan * uses x0
723*9d250f03SJiafei Pan */
724*9d250f03SJiafei Pan_soc_core_entr_pwrdn:
725*9d250f03SJiafei Pan	/* X0 = core mask lsb */
726*9d250f03SJiafei Pan	dsb	sy
727*9d250f03SJiafei Pan	isb
728*9d250f03SJiafei Pan	wfi
729*9d250f03SJiafei Pan
730*9d250f03SJiafei Pan	ret
731*9d250f03SJiafei Pan
732*9d250f03SJiafei Pan/*
733*9d250f03SJiafei Pan * Part of CPU_SUSPEND
734*9d250f03SJiafei Pan *
735*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after power-down state
736*9d250f03SJiafei Pan * in:  x0 = core mask lsb
737*9d250f03SJiafei Pan * out: none
738*9d250f03SJiafei Pan * uses none
739*9d250f03SJiafei Pan */
740*9d250f03SJiafei Pan_soc_core_exit_pwrdn:
741*9d250f03SJiafei Pan	ret
742*9d250f03SJiafei Pan
743*9d250f03SJiafei Pan/*
744*9d250f03SJiafei Pan * Part of CPU_SUSPEND
745*9d250f03SJiafei Pan *
746*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to standby
747*9d250f03SJiafei Pan * in:  x0 = core mask lsb
748*9d250f03SJiafei Pan * out: none
749*9d250f03SJiafei Pan * uses x0, x1
750*9d250f03SJiafei Pan */
751*9d250f03SJiafei Pan_soc_clstr_prep_stdby:
752*9d250f03SJiafei Pan	/* Clear CPUECTLR_EL1[2:0] */
753*9d250f03SJiafei Pan	mrs	x1, CPUECTLR_EL1
754*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
755*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x1
756*9d250f03SJiafei Pan
757*9d250f03SJiafei Pan	ret
758*9d250f03SJiafei Pan
759*9d250f03SJiafei Pan/*
760*9d250f03SJiafei Pan * Part of CPU_SUSPEND
761*9d250f03SJiafei Pan *
762*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after standby state
763*9d250f03SJiafei Pan * in:  x0 = core mask lsb
764*9d250f03SJiafei Pan * out: none
765*9d250f03SJiafei Pan * uses none
766*9d250f03SJiafei Pan */
767*9d250f03SJiafei Pan_soc_clstr_exit_stdby:
768*9d250f03SJiafei Pan	ret
769*9d250f03SJiafei Pan
770*9d250f03SJiafei Pan/*
771*9d250f03SJiafei Pan * Part of CPU_SUSPEND
772*9d250f03SJiafei Pan *
773*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to power-down
774*9d250f03SJiafei Pan * in:  x0 = core mask lsb
775*9d250f03SJiafei Pan * out: none
776*9d250f03SJiafei Pan * uses x0, x1, x2
777*9d250f03SJiafei Pan */
778*9d250f03SJiafei Pan_soc_clstr_prep_pwrdn:
779*9d250f03SJiafei Pan	/* Make sure system counter is enabled */
780*9d250f03SJiafei Pan	ldr	x2, =NXP_TIMER_ADDR
781*9d250f03SJiafei Pan	ldr	w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
782*9d250f03SJiafei Pan	tst	w0, #SYS_COUNTER_CNTCR_EN
783*9d250f03SJiafei Pan	b.ne	1f
784*9d250f03SJiafei Pan	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
785*9d250f03SJiafei Pan	str	w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
786*9d250f03SJiafei Pan1:
787*9d250f03SJiafei Pan	/*
788*9d250f03SJiafei Pan	 * Enable dynamic retention control (CPUECTLR[2:0])
789*9d250f03SJiafei Pan	 * Set the SMPEN bit (CPUECTLR[6])
790*9d250f03SJiafei Pan	 */
791*9d250f03SJiafei Pan	mrs	x1, CPUECTLR_EL1
792*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_RET_MASK
793*9d250f03SJiafei Pan	orr	x1, x1, #CPUECTLR_TIMER_2TICKS
794*9d250f03SJiafei Pan	orr	x1, x1, #CPUECTLR_SMPEN_EN
795*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x1
796*9d250f03SJiafei Pan
797*9d250f03SJiafei Pan	isb
798*9d250f03SJiafei Pan	ret
799*9d250f03SJiafei Pan
800*9d250f03SJiafei Pan/*
801*9d250f03SJiafei Pan * Part of CPU_SUSPEND
802*9d250f03SJiafei Pan *
803*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after power-down state
804*9d250f03SJiafei Pan * in:  x0 = core mask lsb
805*9d250f03SJiafei Pan * out: none
806*9d250f03SJiafei Pan * uses none
807*9d250f03SJiafei Pan */
808*9d250f03SJiafei Pan_soc_clstr_exit_pwrdn:
809*9d250f03SJiafei Pan	ret
810*9d250f03SJiafei Pan
811*9d250f03SJiafei Pan/*
812*9d250f03SJiafei Pan * Part of CPU_SUSPEND
813*9d250f03SJiafei Pan *
814*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to standby
815*9d250f03SJiafei Pan * in:  x0 = core mask lsb
816*9d250f03SJiafei Pan * out: none
817*9d250f03SJiafei Pan * uses x0, x1
818*9d250f03SJiafei Pan */
819*9d250f03SJiafei Pan_soc_sys_prep_stdby:
820*9d250f03SJiafei Pan	/* Clear CPUECTLR_EL1[2:0] */
821*9d250f03SJiafei Pan	mrs	x1, CPUECTLR_EL1
822*9d250f03SJiafei Pan	bic	x1, x1, #CPUECTLR_TIMER_MASK
823*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x1
824*9d250f03SJiafei Pan
825*9d250f03SJiafei Pan	ret
826*9d250f03SJiafei Pan
827*9d250f03SJiafei Pan/*
828*9d250f03SJiafei Pan * Part of CPU_SUSPEND
829*9d250f03SJiafei Pan *
830*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after standby state
831*9d250f03SJiafei Pan * in:  x0 = core mask lsb
832*9d250f03SJiafei Pan * out: none
833*9d250f03SJiafei Pan * uses none
834*9d250f03SJiafei Pan */
835*9d250f03SJiafei Pan_soc_sys_exit_stdby:
836*9d250f03SJiafei Pan	ret
837*9d250f03SJiafei Pan
838*9d250f03SJiafei Pan/*
839*9d250f03SJiafei Pan * Part of CPU_SUSPEND
840*9d250f03SJiafei Pan *
841*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to
842*9d250f03SJiafei Pan * suspend-to-power-down
843*9d250f03SJiafei Pan * in:  x0 = core mask lsb
844*9d250f03SJiafei Pan * out: none
845*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4
846*9d250f03SJiafei Pan */
847*9d250f03SJiafei Pan_soc_sys_prep_pwrdn:
848*9d250f03SJiafei Pan	/* Set retention control */
849*9d250f03SJiafei Pan	mrs	x0, CPUECTLR_EL1
850*9d250f03SJiafei Pan	bic	x0, x0, #CPUECTLR_TIMER_MASK
851*9d250f03SJiafei Pan	orr	x0, x0, #CPUECTLR_TIMER_2TICKS
852*9d250f03SJiafei Pan	orr	x0, x0, #CPUECTLR_SMPEN_EN
853*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x0
854*9d250f03SJiafei Pan	dsb	sy
855*9d250f03SJiafei Pan	isb
856*9d250f03SJiafei Pan	ret
857*9d250f03SJiafei Pan
858*9d250f03SJiafei Pan/*
859*9d250f03SJiafei Pan * Part of CPU_SUSPEND
860*9d250f03SJiafei Pan *
861*9d250f03SJiafei Pan * This function puts the calling core, and potentially the soc, into a
862*9d250f03SJiafei Pan * low-power state
863*9d250f03SJiafei Pan * in:  x0 = core mask lsb
864*9d250f03SJiafei Pan * out: x0 = 0, success
865*9d250f03SJiafei Pan *      x0 < 0, failure
866*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x13, x14, x15,
867*9d250f03SJiafei Pan *      x16, x17, x18
868*9d250f03SJiafei Pan */
869*9d250f03SJiafei Pan_soc_sys_pwrdn_wfi:
870*9d250f03SJiafei Pan	mov	x18, x30
871*9d250f03SJiafei Pan
872*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
873*9d250f03SJiafei Pan
874*9d250f03SJiafei Pan	/* x3 = pmu base addr */
875*9d250f03SJiafei Pan
876*9d250f03SJiafei Pan	/* Backup epu registers to stack */
877*9d250f03SJiafei Pan	ldr	x2, =NXP_EPU_ADDR
878*9d250f03SJiafei Pan	ldr	w4, [x2, #EPU_EPIMCR10_OFFSET]
879*9d250f03SJiafei Pan	ldr	w5, [x2, #EPU_EPCCR10_OFFSET]
880*9d250f03SJiafei Pan	ldr	w6, [x2, #EPU_EPCTR10_OFFSET]
881*9d250f03SJiafei Pan	ldr	w7, [x2, #EPU_EPGCR_OFFSET]
882*9d250f03SJiafei Pan	stp	x4,  x5,  [sp, #-16]!
883*9d250f03SJiafei Pan	stp	x6,  x7,  [sp, #-16]!
884*9d250f03SJiafei Pan
885*9d250f03SJiafei Pan	/*
886*9d250f03SJiafei Pan	 * x2 = epu base addr
887*9d250f03SJiafei Pan	 * x3 = pmu base addr
888*9d250f03SJiafei Pan	 */
889*9d250f03SJiafei Pan
890*9d250f03SJiafei Pan	/* Set up EPU event to receive the wake signal from PMU */
891*9d250f03SJiafei Pan	mov	w4, #EPU_EPIMCR10_VAL
892*9d250f03SJiafei Pan	mov	w5, #EPU_EPCCR10_VAL
893*9d250f03SJiafei Pan	mov	w6, #EPU_EPCTR10_VAL
894*9d250f03SJiafei Pan	mov	w7, #EPU_EPGCR_VAL
895*9d250f03SJiafei Pan	str	w4, [x2, #EPU_EPIMCR10_OFFSET]
896*9d250f03SJiafei Pan	str	w5, [x2, #EPU_EPCCR10_OFFSET]
897*9d250f03SJiafei Pan	str	w6, [x2, #EPU_EPCTR10_OFFSET]
898*9d250f03SJiafei Pan	str	w7, [x2, #EPU_EPGCR_OFFSET]
899*9d250f03SJiafei Pan
900*9d250f03SJiafei Pan	ldr	x2, =NXP_GICD_ADDR
901*9d250f03SJiafei Pan
902*9d250f03SJiafei Pan	/*
903*9d250f03SJiafei Pan	 * x2 = gicd base addr
904*9d250f03SJiafei Pan	 * x3 = pmu base addr
905*9d250f03SJiafei Pan	 */
906*9d250f03SJiafei Pan
907*9d250f03SJiafei Pan	/* Backup flextimer/mmc/usb interrupt router */
908*9d250f03SJiafei Pan	ldr	x0, =GICD_IROUTER60_OFFSET
909*9d250f03SJiafei Pan	ldr	x1, =GICD_IROUTER76_OFFSET
910*9d250f03SJiafei Pan	ldr	w4, [x2, x0]
911*9d250f03SJiafei Pan	ldr	w5, [x2, x1]
912*9d250f03SJiafei Pan	ldr	x0, =GICD_IROUTER112_OFFSET
913*9d250f03SJiafei Pan	ldr	x1, =GICD_IROUTER113_OFFSET
914*9d250f03SJiafei Pan	ldr	w6, [x2, x0]
915*9d250f03SJiafei Pan	ldr	w7, [x2, x1]
916*9d250f03SJiafei Pan	stp	x4,  x5,  [sp, #-16]!
917*9d250f03SJiafei Pan	stp	x6,  x7,  [sp, #-16]!
918*9d250f03SJiafei Pan
919*9d250f03SJiafei Pan	/*
920*9d250f03SJiafei Pan	 * x2 = gicd base addr
921*9d250f03SJiafei Pan	 * x3 = pmu base addr
922*9d250f03SJiafei Pan	 * x0 = GICD_IROUTER112_OFFSET
923*9d250f03SJiafei Pan	 * x1 = GICD_IROUTER113_OFFSET
924*9d250f03SJiafei Pan	 */
925*9d250f03SJiafei Pan
926*9d250f03SJiafei Pan	/* Re-route interrupt to cluster 1 */
927*9d250f03SJiafei Pan	ldr	w4, =GICD_IROUTER_VALUE
928*9d250f03SJiafei Pan	str	w4, [x2, x0]
929*9d250f03SJiafei Pan	str	w4, [x2, x1]
930*9d250f03SJiafei Pan	ldr	x0, =GICD_IROUTER60_OFFSET
931*9d250f03SJiafei Pan	ldr	x1, =GICD_IROUTER76_OFFSET
932*9d250f03SJiafei Pan	str	w4, [x2, x0]
933*9d250f03SJiafei Pan	str	w4, [x2, x1]
934*9d250f03SJiafei Pan	dsb	sy
935*9d250f03SJiafei Pan	isb
936*9d250f03SJiafei Pan
937*9d250f03SJiafei Pan	/* x3 = pmu base addr */
938*9d250f03SJiafei Pan
939*9d250f03SJiafei Pan	/* Disable sec, Check for eNETC, spi and qspi */
940*9d250f03SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
941*9d250f03SJiafei Pan	ldr	x0, =DCFG_DEVDISR1_OFFSET
942*9d250f03SJiafei Pan	ldr	w1, =DCFG_DEVDISR1_SEC
943*9d250f03SJiafei Pan	str	w1, [x2, x0]
944*9d250f03SJiafei Pan
945*9d250f03SJiafei Pan	ldr	x0, =DCFG_DEVDISR4_OFFSET
946*9d250f03SJiafei Pan	ldr	w1, =DCFG_DEVDISR4_SPI_QSPI
947*9d250f03SJiafei Pan	str	w1, [x2, x0]
948*9d250f03SJiafei Pan
949*9d250f03SJiafei Pan	/* x3 = pmu base addr */
950*9d250f03SJiafei Pan
951*9d250f03SJiafei Pan	/* Set TPMWAKEMR0 */
952*9d250f03SJiafei Pan	ldr	x0, =TPMWAKEMR0_ADDR
953*9d250f03SJiafei Pan	mov	w1, #0x1
954*9d250f03SJiafei Pan	str	w1, [x0]
955*9d250f03SJiafei Pan
956*9d250f03SJiafei Pan	/* Disable CCI snoop domain */
957*9d250f03SJiafei Pan	ldr	x0, =NXP_CCI_ADDR
958*9d250f03SJiafei Pan	mov	w1, #0x1
959*9d250f03SJiafei Pan	str	w1, [x0]
960*9d250f03SJiafei Pan
961*9d250f03SJiafei Pan	/* Setup retention control */
962*9d250f03SJiafei Pan	mrs	x0, CPUECTLR_EL1
963*9d250f03SJiafei Pan	orr	x0, x0, #CPUECTLR_SMPEN_EN
964*9d250f03SJiafei Pan	orr	x0, x0, #CPUECTLR_TIMER_2TICKS
965*9d250f03SJiafei Pan	msr	CPUECTLR_EL1, x0
966*9d250f03SJiafei Pan	dsb	sy
967*9d250f03SJiafei Pan	isb
968*9d250f03SJiafei Pan
969*9d250f03SJiafei Pan	bl	get_pmu_idle_core_mask
970*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
971*9d250f03SJiafei Pan8:
972*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_PCPW20SR_OFFSET]
973*9d250f03SJiafei Pan	cmp	w1, w0
974*9d250f03SJiafei Pan	b.ne	8b
975*9d250f03SJiafei Pan
976*9d250f03SJiafei Pan	/* x3 = NXP_PMU_ADDR */
977*9d250f03SJiafei Pan	/* 1 cluster SoC */
978*9d250f03SJiafei Pan
979*9d250f03SJiafei Pan	bl	get_pmu_idle_cluster_mask
980*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
981*9d250f03SJiafei Pan
982*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLAINACTSETR_OFFSET]
983*9d250f03SJiafei Pan
984*9d250f03SJiafei Pan	bl	get_pmu_idle_core_mask
985*9d250f03SJiafei Pan	/* x3 = NXP_PMU_ADDR */
986*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
987*9d250f03SJiafei Pan1:
988*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_PCPW20SR_OFFSET]
989*9d250f03SJiafei Pan	cmp	w1, w0
990*9d250f03SJiafei Pan	b.ne	1b
991*9d250f03SJiafei Pan
992*9d250f03SJiafei Pan	/* x3 = NXP_PMU_ADDR */
993*9d250f03SJiafei Pan	bl	get_pmu_flush_cluster_mask
994*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
995*9d250f03SJiafei Pan
996*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET]
997*9d250f03SJiafei Pan
998*9d250f03SJiafei Pan	/* x3 = NXP_PMU_ADDR */
999*9d250f03SJiafei Pan2:
1000*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_CLL2FLUSHSR_OFFSET]
1001*9d250f03SJiafei Pan	cmp	w1, w0
1002*9d250f03SJiafei Pan	b.ne	2b
1003*9d250f03SJiafei Pan
1004*9d250f03SJiafei Pan	/* x3 = NXP_PMU_ADDR */
1005*9d250f03SJiafei Pan
1006*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET]
1007*9d250f03SJiafei Pan
1008*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLSINACTSETR_OFFSET]
1009*9d250f03SJiafei Pan
1010*9d250f03SJiafei Pan	/* Force the debug interface to be quiescent */
1011*9d250f03SJiafei Pan	mrs	x0, osdlr_el1
1012*9d250f03SJiafei Pan	orr	x0, x0, #0x1
1013*9d250f03SJiafei Pan	msr	osdlr_el1, x0
1014*9d250f03SJiafei Pan
1015*9d250f03SJiafei Pan	/*
1016*9d250f03SJiafei Pan	 * Enable the WakeRequest signal
1017*9d250f03SJiafei Pan	 * x3 is cpu mask starting from cpu1 to cpu0
1018*9d250f03SJiafei Pan	 */
1019*9d250f03SJiafei Pan	bl	get_tot_num_cores
1020*9d250f03SJiafei Pan	sub	x0, x0, #1
1021*9d250f03SJiafei Pan	mov	x3, #0x1
1022*9d250f03SJiafei Pan	lsl	x3, x3, x0
1023*9d250f03SJiafei Pan2:
1024*9d250f03SJiafei Pan	mov	x0, x3
1025*9d250f03SJiafei Pan	bl	get_gic_rd_base  // 0-2
1026*9d250f03SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1027*9d250f03SJiafei Pan	orr	w1, w1, #GICR_WAKER_SLEEP_BIT
1028*9d250f03SJiafei Pan	str	w1, [x0, #GICR_WAKER_OFFSET]
1029*9d250f03SJiafei Pan1:
1030*9d250f03SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1031*9d250f03SJiafei Pan	cmp	w1, #GICR_WAKER_ASLEEP
1032*9d250f03SJiafei Pan	b.ne	1b
1033*9d250f03SJiafei Pan
1034*9d250f03SJiafei Pan	lsr	x3, x3, #1
1035*9d250f03SJiafei Pan	cbnz	x3, 2b
1036*9d250f03SJiafei Pan
1037*9d250f03SJiafei Pan	/* Invalidate all TLB entries at all 3 exception levels */
1038*9d250f03SJiafei Pan	tlbi	alle1
1039*9d250f03SJiafei Pan	tlbi	alle2
1040*9d250f03SJiafei Pan	tlbi	alle3
1041*9d250f03SJiafei Pan
1042*9d250f03SJiafei Pan	/* Request lpm20 */
1043*9d250f03SJiafei Pan	mov	x3, #NXP_PMU_ADDR
1044*9d250f03SJiafei Pan	ldr	x0, =PMU_POWMGTCSR_OFFSET
1045*9d250f03SJiafei Pan	ldr	w1, =PMU_POWMGTCSR_VAL
1046*9d250f03SJiafei Pan	str	w1, [x3, x0]
1047*9d250f03SJiafei Pan
1048*9d250f03SJiafei Pan	ldr	x5, =NXP_EPU_ADDR
1049*9d250f03SJiafei Pan4:
1050*9d250f03SJiafei Pan	wfe
1051*9d250f03SJiafei Pan	ldr	w1, [x5, #EPU_EPCTR10_OFFSET]
1052*9d250f03SJiafei Pan	cmp	w1, #0
1053*9d250f03SJiafei Pan	b.eq	4b
1054*9d250f03SJiafei Pan
1055*9d250f03SJiafei Pan	/* x3 = NXP_PMU_ADDR */
1056*9d250f03SJiafei Pan
1057*9d250f03SJiafei Pan	bl	get_pmu_idle_cluster_mask
1058*9d250f03SJiafei Pan	mov	x3, NXP_PMU_ADDR
1059*9d250f03SJiafei Pan
1060*9d250f03SJiafei Pan	/* Re-enable the GPP ACP */
1061*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLAINACTCLRR_OFFSET]
1062*9d250f03SJiafei Pan	str	w0, [x3, #PMU_CLSINACTCLRR_OFFSET]
1063*9d250f03SJiafei Pan
1064*9d250f03SJiafei Pan	/* x3 = NXP_PMU_ADDR */
1065*9d250f03SJiafei Pan3:
1066*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_CLAINACTSETR_OFFSET]
1067*9d250f03SJiafei Pan	cbnz	w1, 3b
1068*9d250f03SJiafei Pan4:
1069*9d250f03SJiafei Pan	ldr	w1, [x3, #PMU_CLSINACTSETR_OFFSET]
1070*9d250f03SJiafei Pan	cbnz	w1, 4b
1071*9d250f03SJiafei Pan
1072*9d250f03SJiafei Pan	/*
1073*9d250f03SJiafei Pan	 * Enable the WakeRequest signal on cpu 0-1
1074*9d250f03SJiafei Pan	 * x3 is cpu mask starting from cpu1
1075*9d250f03SJiafei Pan	 */
1076*9d250f03SJiafei Pan	bl	get_tot_num_cores
1077*9d250f03SJiafei Pan	sub	x0, x0, #1
1078*9d250f03SJiafei Pan	mov	x3, #0x1
1079*9d250f03SJiafei Pan	lsl	x3, x3, x0
1080*9d250f03SJiafei Pan2:
1081*9d250f03SJiafei Pan	mov	x0, x3
1082*9d250f03SJiafei Pan	bl	get_gic_rd_base  // 0-2
1083*9d250f03SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1084*9d250f03SJiafei Pan	bic	w1, w1, #GICR_WAKER_SLEEP_BIT
1085*9d250f03SJiafei Pan	str	w1, [x0, #GICR_WAKER_OFFSET]
1086*9d250f03SJiafei Pan1:
1087*9d250f03SJiafei Pan	ldr	w1, [x0, #GICR_WAKER_OFFSET]
1088*9d250f03SJiafei Pan	cbnz	w1, 1b
1089*9d250f03SJiafei Pan
1090*9d250f03SJiafei Pan	lsr	x3, x3, #1
1091*9d250f03SJiafei Pan	cbnz	x3, 2b
1092*9d250f03SJiafei Pan
1093*9d250f03SJiafei Pan	/* Enable CCI snoop domain */
1094*9d250f03SJiafei Pan	ldr	x0, =NXP_CCI_ADDR
1095*9d250f03SJiafei Pan	str	wzr, [x0]
1096*9d250f03SJiafei Pan	dsb	sy
1097*9d250f03SJiafei Pan	isb
1098*9d250f03SJiafei Pan
1099*9d250f03SJiafei Pan	ldr	x3, =NXP_EPU_ADDR
1100*9d250f03SJiafei Pan
1101*9d250f03SJiafei Pan	/* x3 = epu base addr */
1102*9d250f03SJiafei Pan
1103*9d250f03SJiafei Pan	/* Enable sec, enetc, spi and qspi */
1104*9d250f03SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
1105*9d250f03SJiafei Pan	str	wzr, [x2, #DCFG_DEVDISR1_OFFSET]
1106*9d250f03SJiafei Pan	str	wzr, [x2, #DCFG_DEVDISR2_OFFSET]
1107*9d250f03SJiafei Pan	str	wzr, [x2, #DCFG_DEVDISR4_OFFSET]
1108*9d250f03SJiafei Pan
1109*9d250f03SJiafei Pan	/* Restore flextimer/mmc/usb interrupt router */
1110*9d250f03SJiafei Pan	ldr	x3, =NXP_GICD_ADDR
1111*9d250f03SJiafei Pan	ldp	x0, x2, [sp], #16
1112*9d250f03SJiafei Pan	ldr	x1, =GICD_IROUTER113_OFFSET
1113*9d250f03SJiafei Pan	str	w2, [x3, x1]
1114*9d250f03SJiafei Pan	ldr	x1, =GICD_IROUTER112_OFFSET
1115*9d250f03SJiafei Pan	str	w0, [x3, x1]
1116*9d250f03SJiafei Pan	ldp	x0, x2, [sp], #16
1117*9d250f03SJiafei Pan	ldr	x1, =GICD_IROUTER76_OFFSET
1118*9d250f03SJiafei Pan	str	w2, [x3, x1]
1119*9d250f03SJiafei Pan	ldr	x1, =GICD_IROUTER60_OFFSET
1120*9d250f03SJiafei Pan	str	w0, [x3, x1]
1121*9d250f03SJiafei Pan
1122*9d250f03SJiafei Pan	/* Restore EPU registers */
1123*9d250f03SJiafei Pan	ldr	x3, =NXP_EPU_ADDR
1124*9d250f03SJiafei Pan	ldp	x0, x2, [sp], #16
1125*9d250f03SJiafei Pan	str	w2, [x3, #EPU_EPGCR_OFFSET]
1126*9d250f03SJiafei Pan	str	w0, [x3, #EPU_EPCTR10_OFFSET]
1127*9d250f03SJiafei Pan	ldp	x2, x1, [sp], #16
1128*9d250f03SJiafei Pan	str	w1, [x3, #EPU_EPCCR10_OFFSET]
1129*9d250f03SJiafei Pan	str	w2, [x3, #EPU_EPIMCR10_OFFSET]
1130*9d250f03SJiafei Pan
1131*9d250f03SJiafei Pan	dsb	sy
1132*9d250f03SJiafei Pan	isb
1133*9d250f03SJiafei Pan	mov	x30, x18
1134*9d250f03SJiafei Pan	ret
1135*9d250f03SJiafei Pan
1136*9d250f03SJiafei Pan/*
1137*9d250f03SJiafei Pan * Part of CPU_SUSPEND
1138*9d250f03SJiafei Pan *
1139*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after power-down
1140*9d250f03SJiafei Pan * in:  x0 = core mask lsb
1141*9d250f03SJiafei Pan * out: none
1142*9d250f03SJiafei Pan * uses x0, x1
1143*9d250f03SJiafei Pan */
1144*9d250f03SJiafei Pan_soc_sys_exit_pwrdn:
1145*9d250f03SJiafei Pan	/* Enable stack alignment checking */
1146*9d250f03SJiafei Pan	mrs	x1, SCTLR_EL1
1147*9d250f03SJiafei Pan	orr	x1, x1, #0x4
1148*9d250f03SJiafei Pan	msr	SCTLR_EL1, x1
1149*9d250f03SJiafei Pan
1150*9d250f03SJiafei Pan	/* Enable debug interface */
1151*9d250f03SJiafei Pan	mrs	x1, osdlr_el1
1152*9d250f03SJiafei Pan	bic	x1, x1, #OSDLR_EL1_DLK_LOCK
1153*9d250f03SJiafei Pan	msr	osdlr_el1, x1
1154*9d250f03SJiafei Pan
1155*9d250f03SJiafei Pan	/* Enable i-cache */
1156*9d250f03SJiafei Pan	mrs	x1, SCTLR_EL3
1157*9d250f03SJiafei Pan	orr	x1, x1, #SCTLR_I_MASK
1158*9d250f03SJiafei Pan	msr	SCTLR_EL3, x1
1159*9d250f03SJiafei Pan
1160*9d250f03SJiafei Pan	isb
1161*9d250f03SJiafei Pan	ret
1162*9d250f03SJiafei Pan
1163*9d250f03SJiafei Pan/*
1164*9d250f03SJiafei Pan * This function setc up the TrustZone Address Space Controller (TZASC)
1165*9d250f03SJiafei Pan * in:  none
1166*9d250f03SJiafei Pan * out: none
1167*9d250f03SJiafei Pan * uses x0, x1
1168*9d250f03SJiafei Pan */
1169*9d250f03SJiafei Paninit_tzpc:
1170*9d250f03SJiafei Pan	/* Set Non Secure access for all devices protected via TZPC */
1171*9d250f03SJiafei Pan	ldr	x1, =TZPCDECPROT_0_SET_BASE   /* decode Protection-0 Set Reg */
1172*9d250f03SJiafei Pan	mov	w0, #0xFF		      /* set decode region to NS, Bits[7:0] */
1173*9d250f03SJiafei Pan	str	w0, [x1]
1174*9d250f03SJiafei Pan
1175*9d250f03SJiafei Pan	ldr	x1, =TZPCDECPROT_1_SET_BASE   /* decode Protection-1 Set Reg */
1176*9d250f03SJiafei Pan	mov	w0, #0xFF		      /* set decode region to NS, Bits[7:0] */
1177*9d250f03SJiafei Pan	str	w0, [x1]
1178*9d250f03SJiafei Pan
1179*9d250f03SJiafei Pan	ldr	x1, =TZPCDECPROT_2_SET_BASE   /* decode Protection-2 Set Reg */
1180*9d250f03SJiafei Pan	mov	w0, #0xFF		      /* set decode region to NS, Bits[7:0] */
1181*9d250f03SJiafei Pan	str	w0, [x1]
1182*9d250f03SJiafei Pan
1183*9d250f03SJiafei Pan	 /* entire SRAM as NS */
1184*9d250f03SJiafei Pan	ldr	x1, =NXP_OCRAM_TZPC_ADDR      /* secure RAM region size Reg */
1185*9d250f03SJiafei Pan	mov	w0, #0x00000000		      /* 0x00000000 = no secure region */
1186*9d250f03SJiafei Pan	str	w0, [x1]
1187*9d250f03SJiafei Pan
1188*9d250f03SJiafei Pan	ret
1189*9d250f03SJiafei Pan
1190*9d250f03SJiafei Pan/*
1191*9d250f03SJiafei Pan * This function performs any needed initialization on SecMon for
1192*9d250f03SJiafei Pan * boot services
1193*9d250f03SJiafei Pan */
1194*9d250f03SJiafei PaninitSecMon:
1195*9d250f03SJiafei Pan	/* Read the register hpcomr */
1196*9d250f03SJiafei Pan	ldr	x1, =NXP_SNVS_ADDR
1197*9d250f03SJiafei Pan	ldr	w0, [x1, #SECMON_HPCOMR_OFFSET]
1198*9d250f03SJiafei Pan	/* Turn off secure access for the privileged registers */
1199*9d250f03SJiafei Pan	orr	w0, w0, #SECMON_HPCOMR_NPSWAEN
1200*9d250f03SJiafei Pan	/* Write back */
1201*9d250f03SJiafei Pan	str	w0, [x1, #SECMON_HPCOMR_OFFSET]
1202*9d250f03SJiafei Pan
1203*9d250f03SJiafei Pan	ret
1204*9d250f03SJiafei Pan
1205*9d250f03SJiafei Pan/*
1206*9d250f03SJiafei Pan * This function checks to see if cores which are to be disabled have been
1207*9d250f03SJiafei Pan * released from reset - if not, it releases them
1208*9d250f03SJiafei Pan * in:  none
1209*9d250f03SJiafei Pan * out: none
1210*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
1211*9d250f03SJiafei Pan */
1212*9d250f03SJiafei Panrelease_disabled:
1213*9d250f03SJiafei Pan	stp	x18, x30, [sp, #-16]!
1214*9d250f03SJiafei Pan
1215*9d250f03SJiafei Pan	/*
1216*9d250f03SJiafei Pan	 * Get the number of cpus on this device
1217*9d250f03SJiafei Pan	 * Calling the below c function.
1218*9d250f03SJiafei Pan	 * No need to Callee saved registers x9-x15,
1219*9d250f03SJiafei Pan	 * as these registers are not used by the callee
1220*9d250f03SJiafei Pan	 * prior to calling the below C-routine.
1221*9d250f03SJiafei Pan	 */
1222*9d250f03SJiafei Pan	bl	get_tot_num_cores
1223*9d250f03SJiafei Pan	mov	x6, x0
1224*9d250f03SJiafei Pan
1225*9d250f03SJiafei Pan	/* Read COREDISABLESR */
1226*9d250f03SJiafei Pan	mov	x0, #NXP_DCFG_ADDR
1227*9d250f03SJiafei Pan	ldr	w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
1228*9d250f03SJiafei Pan
1229*9d250f03SJiafei Pan	mov	x0, #NXP_RESET_ADDR
1230*9d250f03SJiafei Pan	ldr	w5, [x0, #BRR_OFFSET]
1231*9d250f03SJiafei Pan
1232*9d250f03SJiafei Pan	/* Load the core mask for the first core */
1233*9d250f03SJiafei Pan	mov	x7, #1
1234*9d250f03SJiafei Pan
1235*9d250f03SJiafei Pan	/*
1236*9d250f03SJiafei Pan	 * x4 = COREDISABLESR
1237*9d250f03SJiafei Pan	 * x5 = BRR
1238*9d250f03SJiafei Pan	 * x6 = loop count
1239*9d250f03SJiafei Pan	 * x7 = core mask bit
1240*9d250f03SJiafei Pan	 */
1241*9d250f03SJiafei Pan2:
1242*9d250f03SJiafei Pan	/* Check if the core is to be disabled */
1243*9d250f03SJiafei Pan	tst	x4, x7
1244*9d250f03SJiafei Pan	b.eq	1f
1245*9d250f03SJiafei Pan
1246*9d250f03SJiafei Pan	/* See if disabled cores have already been released from reset */
1247*9d250f03SJiafei Pan	tst	x5, x7
1248*9d250f03SJiafei Pan	b.ne	1f
1249*9d250f03SJiafei Pan
1250*9d250f03SJiafei Pan	/* If core has not been released, then release it (0-3) */
1251*9d250f03SJiafei Pan	mov	x0, x7
1252*9d250f03SJiafei Pan	bl	_soc_core_release
1253*9d250f03SJiafei Pan
1254*9d250f03SJiafei Pan	/* Record the core state in the data area (0-3) */
1255*9d250f03SJiafei Pan	mov	x0, x7
1256*9d250f03SJiafei Pan	mov	x1, #CORE_DISABLED
1257*9d250f03SJiafei Pan	bl	_setCoreState
1258*9d250f03SJiafei Pan1:
1259*9d250f03SJiafei Pan	/* Decrement the counter */
1260*9d250f03SJiafei Pan	subs	x6, x6, #1
1261*9d250f03SJiafei Pan	b.le	3f
1262*9d250f03SJiafei Pan	/* Shift the core mask to the next core */
1263*9d250f03SJiafei Pan	lsl	x7, x7, #1
1264*9d250f03SJiafei Pan	/* Continue */
1265*9d250f03SJiafei Pan	b	2b
1266*9d250f03SJiafei Pan3:
1267*9d250f03SJiafei Pan	ldp	x18, x30, [sp], #16
1268*9d250f03SJiafei Pan	ret
1269*9d250f03SJiafei Pan
1270*9d250f03SJiafei Pan/*
1271*9d250f03SJiafei Pan * Write a register in the DCFG block
1272*9d250f03SJiafei Pan * in:  x0 = offset
1273*9d250f03SJiafei Pan * in:  w1 = value to write
1274*9d250f03SJiafei Pan * uses x0, x1, x2
1275*9d250f03SJiafei Pan */
1276*9d250f03SJiafei Pan_write_reg_dcfg:
1277*9d250f03SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
1278*9d250f03SJiafei Pan	str	w1, [x2, x0]
1279*9d250f03SJiafei Pan	ret
1280*9d250f03SJiafei Pan
1281*9d250f03SJiafei Pan/*
1282*9d250f03SJiafei Pan * Read a register in the DCFG block
1283*9d250f03SJiafei Pan * in:  x0 = offset
1284*9d250f03SJiafei Pan * out: w0 = value read
1285*9d250f03SJiafei Pan * uses x0, x1, x2
1286*9d250f03SJiafei Pan */
1287*9d250f03SJiafei Pan_read_reg_dcfg:
1288*9d250f03SJiafei Pan	ldr	x2, =NXP_DCFG_ADDR
1289*9d250f03SJiafei Pan	ldr	w1, [x2, x0]
1290*9d250f03SJiafei Pan	mov	w0, w1
1291*9d250f03SJiafei Pan	ret
1292*9d250f03SJiafei Pan
1293*9d250f03SJiafei Pan/*
1294*9d250f03SJiafei Pan * This function returns an mpidr value for a core, given a core_mask_lsb
1295*9d250f03SJiafei Pan * in:  x0 = core mask lsb
1296*9d250f03SJiafei Pan * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
1297*9d250f03SJiafei Pan * uses x0, x1
1298*9d250f03SJiafei Pan */
1299*9d250f03SJiafei Panget_mpidr_value:
1300*9d250f03SJiafei Pan	/* Convert a core mask to an SoC core number */
1301*9d250f03SJiafei Pan	clz	w0, w0
1302*9d250f03SJiafei Pan	mov	w1, #31
1303*9d250f03SJiafei Pan	sub	w0, w1, w0
1304*9d250f03SJiafei Pan
1305*9d250f03SJiafei Pan	/* Get the mpidr core number from the SoC core number */
1306*9d250f03SJiafei Pan	mov	w1, wzr
1307*9d250f03SJiafei Pan	tst	x0, #1
1308*9d250f03SJiafei Pan	b.eq	1f
1309*9d250f03SJiafei Pan	orr	w1, w1, #1
1310*9d250f03SJiafei Pan1:
1311*9d250f03SJiafei Pan	/* Extract the cluster number */
1312*9d250f03SJiafei Pan	lsr	w0, w0, #1
1313*9d250f03SJiafei Pan	orr	w0, w1, w0, lsl #8
1314*9d250f03SJiafei Pan
1315*9d250f03SJiafei Pan	ret
1316*9d250f03SJiafei Pan
1317*9d250f03SJiafei Pan/*
1318*9d250f03SJiafei Pan * This function returns the redistributor base address for the core specified
1319*9d250f03SJiafei Pan * in x1
1320*9d250f03SJiafei Pan * in:  x0 - core mask lsb of specified core
1321*9d250f03SJiafei Pan * out: x0 = redistributor rd base address for specified core
1322*9d250f03SJiafei Pan * uses x0, x1, x2
1323*9d250f03SJiafei Pan */
1324*9d250f03SJiafei Panget_gic_rd_base:
1325*9d250f03SJiafei Pan	/* Get the 0-based core number */
1326*9d250f03SJiafei Pan	clz	w1, w0
1327*9d250f03SJiafei Pan	mov	w2, #0x20
1328*9d250f03SJiafei Pan	sub	w2, w2, w1
1329*9d250f03SJiafei Pan	sub	w2, w2, #1
1330*9d250f03SJiafei Pan
1331*9d250f03SJiafei Pan	/* x2 = core number / loop counter */
1332*9d250f03SJiafei Pan	ldr	x0, =NXP_GICR_ADDR
1333*9d250f03SJiafei Pan	mov	x1, #GIC_RD_OFFSET
1334*9d250f03SJiafei Pan2:
1335*9d250f03SJiafei Pan	cbz	x2, 1f
1336*9d250f03SJiafei Pan	add	x0, x0, x1
1337*9d250f03SJiafei Pan	sub	x2, x2, #1
1338*9d250f03SJiafei Pan	b	2b
1339*9d250f03SJiafei Pan1:
1340*9d250f03SJiafei Pan	ret
1341*9d250f03SJiafei Pan
1342*9d250f03SJiafei Pan/*
1343*9d250f03SJiafei Pan * This function returns the redistributor base address for the core specified
1344*9d250f03SJiafei Pan * in x1
1345*9d250f03SJiafei Pan * in:  x0 - core mask lsb of specified core
1346*9d250f03SJiafei Pan * out: x0 = redistributor sgi base address for specified core
1347*9d250f03SJiafei Pan * uses x0, x1, x2
1348*9d250f03SJiafei Pan */
1349*9d250f03SJiafei Panget_gic_sgi_base:
1350*9d250f03SJiafei Pan	/* Get the 0-based core number */
1351*9d250f03SJiafei Pan	clz	w1, w0
1352*9d250f03SJiafei Pan	mov	w2, #0x20
1353*9d250f03SJiafei Pan	sub	w2, w2, w1
1354*9d250f03SJiafei Pan	sub	w2, w2, #1
1355*9d250f03SJiafei Pan
1356*9d250f03SJiafei Pan	/* x2 = core number / loop counter */
1357*9d250f03SJiafei Pan	ldr	x0, =NXP_GICR_SGI_ADDR
1358*9d250f03SJiafei Pan	mov	x1, #GIC_SGI_OFFSET
1359*9d250f03SJiafei Pan2:
1360*9d250f03SJiafei Pan	cbz	x2, 1f
1361*9d250f03SJiafei Pan	add	x0, x0, x1
1362*9d250f03SJiafei Pan	sub	x2, x2, #1
1363*9d250f03SJiafei Pan	b	2b
1364*9d250f03SJiafei Pan1:
1365*9d250f03SJiafei Pan	ret
1366*9d250f03SJiafei Pan
1367*9d250f03SJiafei Pan/*
1368*9d250f03SJiafei Pan * Write a register in the RESET block
1369*9d250f03SJiafei Pan * in:  x0 = offset
1370*9d250f03SJiafei Pan * in:  w1 = value to write
1371*9d250f03SJiafei Pan * uses x0, x1, x2
1372*9d250f03SJiafei Pan */
1373*9d250f03SJiafei Pan_write_reg_reset:
1374*9d250f03SJiafei Pan	ldr	x2, =NXP_RESET_ADDR
1375*9d250f03SJiafei Pan	str	w1, [x2, x0]
1376*9d250f03SJiafei Pan	ret
1377*9d250f03SJiafei Pan
1378*9d250f03SJiafei Pan/*
1379*9d250f03SJiafei Pan * Read a register in the RESET block
1380*9d250f03SJiafei Pan * in:  x0 = offset
1381*9d250f03SJiafei Pan * out: w0 = value read
1382*9d250f03SJiafei Pan * uses x0, x1
1383*9d250f03SJiafei Pan */
1384*9d250f03SJiafei Pan_read_reg_reset:
1385*9d250f03SJiafei Pan	ldr	x1, =NXP_RESET_ADDR
1386*9d250f03SJiafei Pan	ldr	w0, [x1, x0]
1387*9d250f03SJiafei Pan	ret
1388