]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/armv7/ls102xa/psci.S
ARMv7: PSCI: ls102xa: check target CPU ID before further operations
[u-boot] / arch / arm / cpu / armv7 / ls102xa / psci.S
1 /*
2  * Copyright 2015 Freescale Semiconductor, Inc.
3  * Author: Wang Dongsheng <dongsheng.wang@freescale.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <config.h>
9 #include <linux/linkage.h>
10
11 #include <asm/armv7.h>
12 #include <asm/arch-armv7/generictimer.h>
13 #include <asm/psci.h>
14
15 #define SCFG_CORE0_SFT_RST      0x130
16 #define SCFG_CORESRENCR         0x204
17
18 #define DCFG_CCSR_BRR           0x0E4
19 #define DCFG_CCSR_SCRATCHRW1    0x200
20
21         .pushsection ._secure.text, "ax"
22
23         .arch_extension sec
24
25 #define ONE_MS          (GENERIC_TIMER_CLK / 1000)
26 #define RESET_WAIT      (30 * ONE_MS)
27
28 @ r0: return value ARM_PSCI_RET_SUCCESS or ARM_PSCI_RET_INVAL
29 @ r1: input target CPU ID in MPIDR format, original value in r1 may be dropped
30 @ r4: output validated CPU ID if ARM_PSCI_RET_SUCCESS returns, meaningless for
31 @ ARM_PSCI_RET_INVAL,suppose caller saves r4 before calling
32 LENTRY(psci_check_target_cpu_id)
33         @ Get the real CPU number
34         and     r4, r1, #0xff
35         mov     r0, #ARM_PSCI_RET_INVAL
36
37         @ Bit[31:24], bits must be zero.
38         tst     r1, #0xff000000
39         bxne    lr
40
41         @ Affinity level 2 - Cluster: only one cluster in LS1021xa.
42         tst     r1, #0xff0000
43         bxne    lr
44
45         @ Affinity level 1 - Processors: should be in 0xf00 format.
46         lsr     r1, r1, #8
47         teq     r1, #0xf
48         bxne    lr
49
50         @ Affinity level 0 - CPU: only 0, 1 are valid in LS1021xa.
51         cmp     r4, #2
52         bxge    lr
53
54         mov     r0, #ARM_PSCI_RET_SUCCESS
55         bx      lr
56 ENDPROC(psci_check_target_cpu_id)
57
58         @ r1 = target CPU
59         @ r2 = target PC
60 .globl  psci_cpu_on
61 psci_cpu_on:
62         push    {r4, r5, r6, lr}
63
64         @ Clear and Get the correct CPU number
65         @ r1 = 0xf01
66         bl      psci_check_target_cpu_id
67         cmp     r0, #ARM_PSCI_RET_INVAL
68         beq     out_psci_cpu_on
69
70         mov     r0, r4
71         mov     r1, r2
72         bl      psci_save_target_pc
73         mov     r1, r4
74
75         @ Get DCFG base address
76         movw    r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
77         movt    r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
78
79         @ Detect target CPU state
80         ldr     r2, [r4, #DCFG_CCSR_BRR]
81         rev     r2, r2
82         lsr     r2, r2, r1
83         ands    r2, r2, #1
84         beq     holdoff_release
85
86         @ Reset target CPU
87         @ Get SCFG base address
88         movw    r0, #(CONFIG_SYS_FSL_SCFG_ADDR & 0xffff)
89         movt    r0, #(CONFIG_SYS_FSL_SCFG_ADDR >> 16)
90
91         @ Enable CORE Soft Reset
92         movw    r5, #0
93         movt    r5, #(1 << 15)
94         rev     r5, r5
95         str     r5, [r0, #SCFG_CORESRENCR]
96
97         @ Get CPUx offset register
98         mov     r6, #0x4
99         mul     r6, r6, r1
100         add     r2, r0, r6
101
102         @ Do reset on target CPU
103         movw    r5, #0
104         movt    r5, #(1 << 15)
105         rev     r5, r5
106         str     r5, [r2, #SCFG_CORE0_SFT_RST]
107
108         @ Wait target CPU up
109         timer_wait      r2, RESET_WAIT
110
111         @ Disable CORE soft reset
112         mov     r5, #0
113         str     r5, [r0, #SCFG_CORESRENCR]
114
115 holdoff_release:
116         @ Release on target CPU
117         ldr     r2, [r4, #DCFG_CCSR_BRR]
118         mov     r6, #1
119         lsl     r6, r6, r1      @ 32 bytes per CPU
120
121         rev     r6, r6
122         orr     r2, r2, r6
123         str     r2, [r4, #DCFG_CCSR_BRR]
124
125         @ Set secondary boot entry
126         ldr     r6, =psci_cpu_entry
127         rev     r6, r6
128         str     r6, [r4, #DCFG_CCSR_SCRATCHRW1]
129
130         isb
131         dsb
132
133         @ Return
134         mov     r0, #ARM_PSCI_RET_SUCCESS
135
136 out_psci_cpu_on:
137         pop     {r4, r5, r6, lr}
138         bx      lr
139
140 .globl  psci_cpu_off
141 psci_cpu_off:
142         bl      psci_cpu_off_common
143
144 1:      wfi
145         b       1b
146
147         .popsection