blob: 3d41d37a6438b1aad05e12b8aa3ef2f8987027f3 [file] [log] [blame]
Wang Dongsheng13d2bb72015-06-04 12:01:09 +08001/*
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
Hongbo Zhang4f6e6102016-07-21 18:09:38 +080015#define RCPM_TWAITSR 0x04C
16
Wang Dongsheng13d2bb72015-06-04 12:01:09 +080017#define SCFG_CORE0_SFT_RST 0x130
18#define SCFG_CORESRENCR 0x204
19
Hongbo Zhang4f6e6102016-07-21 18:09:38 +080020#define DCFG_CCSR_RSTCR 0x0B0
21#define DCFG_CCSR_RSTCR_RESET_REQ 0x2
22#define DCFG_CCSR_BRR 0x0E4
23#define DCFG_CCSR_SCRATCHRW1 0x200
24
25#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0
26#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0
27#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0
28#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0
29#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0
30#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0
31#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
Hongbo Zhang539e4f12016-08-19 17:20:33 +080032#define PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK 0x0
Wang Dongsheng13d2bb72015-06-04 12:01:09 +080033
34 .pushsection ._secure.text, "ax"
35
36 .arch_extension sec
37
Hongbo Zhang4f6e6102016-07-21 18:09:38 +080038 .align 5
39
Wang Dongsheng13d2bb72015-06-04 12:01:09 +080040#define ONE_MS (GENERIC_TIMER_CLK / 1000)
41#define RESET_WAIT (30 * ONE_MS)
42
Hongbo Zhang4f6e6102016-07-21 18:09:38 +080043.globl psci_version
44psci_version:
45 movw r0, #0
46 movt r0, #1
47
48 bx lr
49
50_ls102x_psci_supported_table:
51 .word ARM_PSCI_0_2_FN_PSCI_VERSION
52 .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
53 .word ARM_PSCI_0_2_FN_CPU_SUSPEND
54 .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
55 .word ARM_PSCI_0_2_FN_CPU_OFF
56 .word PSCI_FN_CPU_OFF_FEATURE_MASK
57 .word ARM_PSCI_0_2_FN_CPU_ON
58 .word PSCI_FN_CPU_ON_FEATURE_MASK
59 .word ARM_PSCI_0_2_FN_AFFINITY_INFO
60 .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
61 .word ARM_PSCI_0_2_FN_SYSTEM_OFF
62 .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
63 .word ARM_PSCI_0_2_FN_SYSTEM_RESET
64 .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
Hongbo Zhang539e4f12016-08-19 17:20:33 +080065 .word ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
66 .word PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK
Hongbo Zhang4f6e6102016-07-21 18:09:38 +080067 .word 0
68 .word ARM_PSCI_RET_NI
69
70.globl psci_features
71psci_features:
72 adr r2, _ls102x_psci_supported_table
731: ldr r3, [r2]
74 cmp r3, #0
75 beq out_psci_features
76 cmp r1, r3
77 addne r2, r2, #8
78 bne 1b
79
80out_psci_features:
81 ldr r0, [r2, #4]
82 bx lr
83
Hongbo Zhang08f6ac82016-07-21 18:09:37 +080084@ r0: return value ARM_PSCI_RET_SUCCESS or ARM_PSCI_RET_INVAL
85@ r1: input target CPU ID in MPIDR format, original value in r1 may be dropped
86@ r4: output validated CPU ID if ARM_PSCI_RET_SUCCESS returns, meaningless for
87@ ARM_PSCI_RET_INVAL,suppose caller saves r4 before calling
88LENTRY(psci_check_target_cpu_id)
89 @ Get the real CPU number
90 and r4, r1, #0xff
91 mov r0, #ARM_PSCI_RET_INVAL
92
93 @ Bit[31:24], bits must be zero.
94 tst r1, #0xff000000
95 bxne lr
96
97 @ Affinity level 2 - Cluster: only one cluster in LS1021xa.
98 tst r1, #0xff0000
99 bxne lr
100
101 @ Affinity level 1 - Processors: should be in 0xf00 format.
102 lsr r1, r1, #8
103 teq r1, #0xf
104 bxne lr
105
106 @ Affinity level 0 - CPU: only 0, 1 are valid in LS1021xa.
107 cmp r4, #2
108 bxge lr
109
110 mov r0, #ARM_PSCI_RET_SUCCESS
111 bx lr
112ENDPROC(psci_check_target_cpu_id)
113
Wang Dongsheng13d2bb72015-06-04 12:01:09 +0800114 @ r1 = target CPU
115 @ r2 = target PC
116.globl psci_cpu_on
117psci_cpu_on:
Chen-Yu Tsai6e147952016-06-19 12:38:44 +0800118 push {r4, r5, r6, lr}
Wang Dongsheng13d2bb72015-06-04 12:01:09 +0800119
120 @ Clear and Get the correct CPU number
121 @ r1 = 0xf01
Hongbo Zhang08f6ac82016-07-21 18:09:37 +0800122 bl psci_check_target_cpu_id
123 cmp r0, #ARM_PSCI_RET_INVAL
124 beq out_psci_cpu_on
Wang Dongsheng13d2bb72015-06-04 12:01:09 +0800125
Chen-Yu Tsai6e147952016-06-19 12:38:44 +0800126 mov r0, r4
127 mov r1, r2
128 bl psci_save_target_pc
129 mov r1, r4
Wang Dongsheng13d2bb72015-06-04 12:01:09 +0800130
131 @ Get DCFG base address
132 movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
133 movt r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
134
135 @ Detect target CPU state
136 ldr r2, [r4, #DCFG_CCSR_BRR]
137 rev r2, r2
138 lsr r2, r2, r1
139 ands r2, r2, #1
140 beq holdoff_release
141
142 @ Reset target CPU
143 @ Get SCFG base address
144 movw r0, #(CONFIG_SYS_FSL_SCFG_ADDR & 0xffff)
145 movt r0, #(CONFIG_SYS_FSL_SCFG_ADDR >> 16)
146
147 @ Enable CORE Soft Reset
148 movw r5, #0
149 movt r5, #(1 << 15)
150 rev r5, r5
151 str r5, [r0, #SCFG_CORESRENCR]
152
153 @ Get CPUx offset register
154 mov r6, #0x4
155 mul r6, r6, r1
156 add r2, r0, r6
157
158 @ Do reset on target CPU
159 movw r5, #0
160 movt r5, #(1 << 15)
161 rev r5, r5
162 str r5, [r2, #SCFG_CORE0_SFT_RST]
163
164 @ Wait target CPU up
165 timer_wait r2, RESET_WAIT
166
167 @ Disable CORE soft reset
168 mov r5, #0
169 str r5, [r0, #SCFG_CORESRENCR]
170
171holdoff_release:
172 @ Release on target CPU
173 ldr r2, [r4, #DCFG_CCSR_BRR]
174 mov r6, #1
175 lsl r6, r6, r1 @ 32 bytes per CPU
176
177 rev r6, r6
178 orr r2, r2, r6
179 str r2, [r4, #DCFG_CCSR_BRR]
180
181 @ Set secondary boot entry
182 ldr r6, =psci_cpu_entry
183 rev r6, r6
184 str r6, [r4, #DCFG_CCSR_SCRATCHRW1]
185
186 isb
187 dsb
188
189 @ Return
190 mov r0, #ARM_PSCI_RET_SUCCESS
191
Hongbo Zhang08f6ac82016-07-21 18:09:37 +0800192out_psci_cpu_on:
Chen-Yu Tsai6e147952016-06-19 12:38:44 +0800193 pop {r4, r5, r6, lr}
Wang Dongsheng13d2bb72015-06-04 12:01:09 +0800194 bx lr
195
196.globl psci_cpu_off
197psci_cpu_off:
198 bl psci_cpu_off_common
199
2001: wfi
201 b 1b
202
Hongbo Zhang4f6e6102016-07-21 18:09:38 +0800203.globl psci_affinity_info
204psci_affinity_info:
205 push {lr}
206
207 mov r0, #ARM_PSCI_RET_INVAL
208
209 @ Verify Affinity level
210 cmp r2, #0
211 bne out_affinity_info
212
213 bl psci_check_target_cpu_id
214 cmp r0, #ARM_PSCI_RET_INVAL
215 beq out_affinity_info
216 mov r1, r4
217
218 @ Get RCPM base address
219 movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff)
220 movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16)
221
222 mov r0, #PSCI_AFFINITY_LEVEL_ON
223
224 @ Detect target CPU state
225 ldr r2, [r4, #RCPM_TWAITSR]
226 rev r2, r2
227 lsr r2, r2, r1
228 ands r2, r2, #1
229 beq out_affinity_info
230
231 mov r0, #PSCI_AFFINITY_LEVEL_OFF
232
233out_affinity_info:
234 pop {pc}
235
236.globl psci_system_reset
237psci_system_reset:
238 @ Get DCFG base address
239 movw r1, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
240 movt r1, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
241
242 mov r2, #DCFG_CCSR_RSTCR_RESET_REQ
243 rev r2, r2
244 str r2, [r1, #DCFG_CCSR_RSTCR]
245
2461: wfi
247 b 1b
248
Hongbo Zhang539e4f12016-08-19 17:20:33 +0800249.globl psci_system_suspend
250psci_system_suspend:
251 push {lr}
252
253 bl ls1_system_suspend
254
255 pop {pc}
256
Wang Dongsheng13d2bb72015-06-04 12:01:09 +0800257 .popsection