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