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