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