Commit 1801ead6f421db1272d7479ebc9467ccdf5eb90a

Authored by Dmitry Osipenko
Committed by Greg Kroah-Hartman
1 parent a4cb200d87

ARM: tegra: Re-add removed SoC id macro to tegra_resume()

commit e4a680099a6e97ecdbb81081cff9e4a489a4dc44 upstream.

Commit d127e9c ("ARM: tegra: make tegra_resume can work with current and later
chips") removed tegra_get_soc_id macro leaving used cpu register corrupted after
branching to v7_invalidate_l1() and as result causing execution of unintended
code on tegra20. Possibly it was expected that r6 would be SoC id func argument
since common cpu reset handler is setting r6 before branching to tegra_resume(),
but neither tegra20_lp1_reset() nor tegra30_lp1_reset() aren't setting r6
register before jumping to resume function. Fix it by re-adding macro.

Fixes: d127e9c (ARM: tegra: make tegra_resume can work with current and later chips)
Reviewed-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 1 additions and 0 deletions Inline Diff

arch/arm/mach-tegra/reset-handler.S
1 /* 1 /*
2 * Copyright (c) 2012, NVIDIA Corporation. All rights reserved. 2 * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation. 6 * version 2, as published by the Free Software Foundation.
7 * 7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT 8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details. 11 * more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17 #include <linux/linkage.h> 17 #include <linux/linkage.h>
18 #include <linux/init.h> 18 #include <linux/init.h>
19 19
20 #include <asm/cache.h> 20 #include <asm/cache.h>
21 #include <asm/asm-offsets.h> 21 #include <asm/asm-offsets.h>
22 #include <asm/hardware/cache-l2x0.h> 22 #include <asm/hardware/cache-l2x0.h>
23 23
24 #include "flowctrl.h" 24 #include "flowctrl.h"
25 #include "fuse.h" 25 #include "fuse.h"
26 #include "iomap.h" 26 #include "iomap.h"
27 #include "reset.h" 27 #include "reset.h"
28 #include "sleep.h" 28 #include "sleep.h"
29 29
30 #define PMC_SCRATCH41 0x140 30 #define PMC_SCRATCH41 0x140
31 31
32 #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) 32 #define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
33 33
34 #ifdef CONFIG_PM_SLEEP 34 #ifdef CONFIG_PM_SLEEP
35 /* 35 /*
36 * tegra_resume 36 * tegra_resume
37 * 37 *
38 * CPU boot vector when restarting the a CPU following 38 * CPU boot vector when restarting the a CPU following
39 * an LP2 transition. Also branched to by LP0 and LP1 resume after 39 * an LP2 transition. Also branched to by LP0 and LP1 resume after
40 * re-enabling sdram. 40 * re-enabling sdram.
41 * 41 *
42 * r6: SoC ID 42 * r6: SoC ID
43 * r8: CPU part number 43 * r8: CPU part number
44 */ 44 */
45 ENTRY(tegra_resume) 45 ENTRY(tegra_resume)
46 check_cpu_part_num 0xc09, r8, r9 46 check_cpu_part_num 0xc09, r8, r9
47 bleq v7_invalidate_l1 47 bleq v7_invalidate_l1
48 48
49 cpu_id r0 49 cpu_id r0
50 cmp r0, #0 @ CPU0? 50 cmp r0, #0 @ CPU0?
51 THUMB( it ne ) 51 THUMB( it ne )
52 bne cpu_resume @ no 52 bne cpu_resume @ no
53 53
54 tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
54 /* Are we on Tegra20? */ 55 /* Are we on Tegra20? */
55 cmp r6, #TEGRA20 56 cmp r6, #TEGRA20
56 beq 1f @ Yes 57 beq 1f @ Yes
57 /* Clear the flow controller flags for this CPU. */ 58 /* Clear the flow controller flags for this CPU. */
58 cpu_to_csr_reg r1, r0 59 cpu_to_csr_reg r1, r0
59 mov32 r2, TEGRA_FLOW_CTRL_BASE 60 mov32 r2, TEGRA_FLOW_CTRL_BASE
60 ldr r1, [r2, r1] 61 ldr r1, [r2, r1]
61 /* Clear event & intr flag */ 62 /* Clear event & intr flag */
62 orr r1, r1, \ 63 orr r1, r1, \
63 #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG 64 #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
64 movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps 65 movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps
65 @ & ext flags for CPU power mgnt 66 @ & ext flags for CPU power mgnt
66 bic r1, r1, r0 67 bic r1, r1, r0
67 str r1, [r2] 68 str r1, [r2]
68 1: 69 1:
69 70
70 mov32 r9, 0xc09 71 mov32 r9, 0xc09
71 cmp r8, r9 72 cmp r8, r9
72 bne end_ca9_scu_l2_resume 73 bne end_ca9_scu_l2_resume
73 #ifdef CONFIG_HAVE_ARM_SCU 74 #ifdef CONFIG_HAVE_ARM_SCU
74 /* enable SCU */ 75 /* enable SCU */
75 mov32 r0, TEGRA_ARM_PERIF_BASE 76 mov32 r0, TEGRA_ARM_PERIF_BASE
76 ldr r1, [r0] 77 ldr r1, [r0]
77 orr r1, r1, #1 78 orr r1, r1, #1
78 str r1, [r0] 79 str r1, [r0]
79 #endif 80 #endif
80 81
81 /* L2 cache resume & re-enable */ 82 /* L2 cache resume & re-enable */
82 l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr 83 l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
83 end_ca9_scu_l2_resume: 84 end_ca9_scu_l2_resume:
84 mov32 r9, 0xc0f 85 mov32 r9, 0xc0f
85 cmp r8, r9 86 cmp r8, r9
86 bleq tegra_init_l2_for_a15 87 bleq tegra_init_l2_for_a15
87 88
88 b cpu_resume 89 b cpu_resume
89 ENDPROC(tegra_resume) 90 ENDPROC(tegra_resume)
90 #endif 91 #endif
91 92
92 #ifdef CONFIG_CACHE_L2X0 93 #ifdef CONFIG_CACHE_L2X0
93 .globl l2x0_saved_regs_addr 94 .globl l2x0_saved_regs_addr
94 l2x0_saved_regs_addr: 95 l2x0_saved_regs_addr:
95 .long 0 96 .long 0
96 #endif 97 #endif
97 98
98 .align L1_CACHE_SHIFT 99 .align L1_CACHE_SHIFT
99 ENTRY(__tegra_cpu_reset_handler_start) 100 ENTRY(__tegra_cpu_reset_handler_start)
100 101
101 /* 102 /*
102 * __tegra_cpu_reset_handler: 103 * __tegra_cpu_reset_handler:
103 * 104 *
104 * Common handler for all CPU reset events. 105 * Common handler for all CPU reset events.
105 * 106 *
106 * Register usage within the reset handler: 107 * Register usage within the reset handler:
107 * 108 *
108 * Others: scratch 109 * Others: scratch
109 * R6 = SoC ID 110 * R6 = SoC ID
110 * R7 = CPU present (to the OS) mask 111 * R7 = CPU present (to the OS) mask
111 * R8 = CPU in LP1 state mask 112 * R8 = CPU in LP1 state mask
112 * R9 = CPU in LP2 state mask 113 * R9 = CPU in LP2 state mask
113 * R10 = CPU number 114 * R10 = CPU number
114 * R11 = CPU mask 115 * R11 = CPU mask
115 * R12 = pointer to reset handler data 116 * R12 = pointer to reset handler data
116 * 117 *
117 * NOTE: This code is copied to IRAM. All code and data accesses 118 * NOTE: This code is copied to IRAM. All code and data accesses
118 * must be position-independent. 119 * must be position-independent.
119 */ 120 */
120 121
121 .align L1_CACHE_SHIFT 122 .align L1_CACHE_SHIFT
122 ENTRY(__tegra_cpu_reset_handler) 123 ENTRY(__tegra_cpu_reset_handler)
123 124
124 cpsid aif, 0x13 @ SVC mode, interrupts disabled 125 cpsid aif, 0x13 @ SVC mode, interrupts disabled
125 126
126 tegra_get_soc_id TEGRA_APB_MISC_BASE, r6 127 tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
127 #ifdef CONFIG_ARCH_TEGRA_2x_SOC 128 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
128 t20_check: 129 t20_check:
129 cmp r6, #TEGRA20 130 cmp r6, #TEGRA20
130 bne after_t20_check 131 bne after_t20_check
131 t20_errata: 132 t20_errata:
132 # Tegra20 is a Cortex-A9 r1p1 133 # Tegra20 is a Cortex-A9 r1p1
133 mrc p15, 0, r0, c1, c0, 0 @ read system control register 134 mrc p15, 0, r0, c1, c0, 0 @ read system control register
134 orr r0, r0, #1 << 14 @ erratum 716044 135 orr r0, r0, #1 << 14 @ erratum 716044
135 mcr p15, 0, r0, c1, c0, 0 @ write system control register 136 mcr p15, 0, r0, c1, c0, 0 @ write system control register
136 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 137 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
137 orr r0, r0, #1 << 4 @ erratum 742230 138 orr r0, r0, #1 << 4 @ erratum 742230
138 orr r0, r0, #1 << 11 @ erratum 751472 139 orr r0, r0, #1 << 11 @ erratum 751472
139 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 140 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
140 b after_errata 141 b after_errata
141 after_t20_check: 142 after_t20_check:
142 #endif 143 #endif
143 #ifdef CONFIG_ARCH_TEGRA_3x_SOC 144 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
144 t30_check: 145 t30_check:
145 cmp r6, #TEGRA30 146 cmp r6, #TEGRA30
146 bne after_t30_check 147 bne after_t30_check
147 t30_errata: 148 t30_errata:
148 # Tegra30 is a Cortex-A9 r2p9 149 # Tegra30 is a Cortex-A9 r2p9
149 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 150 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
150 orr r0, r0, #1 << 6 @ erratum 743622 151 orr r0, r0, #1 << 6 @ erratum 743622
151 orr r0, r0, #1 << 11 @ erratum 751472 152 orr r0, r0, #1 << 11 @ erratum 751472
152 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 153 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
153 b after_errata 154 b after_errata
154 after_t30_check: 155 after_t30_check:
155 #endif 156 #endif
156 after_errata: 157 after_errata:
157 mrc p15, 0, r10, c0, c0, 5 @ MPIDR 158 mrc p15, 0, r10, c0, c0, 5 @ MPIDR
158 and r10, r10, #0x3 @ R10 = CPU number 159 and r10, r10, #0x3 @ R10 = CPU number
159 mov r11, #1 160 mov r11, #1
160 mov r11, r11, lsl r10 @ R11 = CPU mask 161 mov r11, r11, lsl r10 @ R11 = CPU mask
161 adr r12, __tegra_cpu_reset_handler_data 162 adr r12, __tegra_cpu_reset_handler_data
162 163
163 #ifdef CONFIG_SMP 164 #ifdef CONFIG_SMP
164 /* Does the OS know about this CPU? */ 165 /* Does the OS know about this CPU? */
165 ldr r7, [r12, #RESET_DATA(MASK_PRESENT)] 166 ldr r7, [r12, #RESET_DATA(MASK_PRESENT)]
166 tst r7, r11 @ if !present 167 tst r7, r11 @ if !present
167 bleq __die @ CPU not present (to OS) 168 bleq __die @ CPU not present (to OS)
168 #endif 169 #endif
169 170
170 #ifdef CONFIG_ARCH_TEGRA_2x_SOC 171 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
171 /* Are we on Tegra20? */ 172 /* Are we on Tegra20? */
172 cmp r6, #TEGRA20 173 cmp r6, #TEGRA20
173 bne 1f 174 bne 1f
174 /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ 175 /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
175 mov32 r5, TEGRA_PMC_BASE 176 mov32 r5, TEGRA_PMC_BASE
176 mov r0, #0 177 mov r0, #0
177 cmp r10, #0 178 cmp r10, #0
178 strne r0, [r5, #PMC_SCRATCH41] 179 strne r0, [r5, #PMC_SCRATCH41]
179 1: 180 1:
180 #endif 181 #endif
181 182
182 /* Waking up from LP1? */ 183 /* Waking up from LP1? */
183 ldr r8, [r12, #RESET_DATA(MASK_LP1)] 184 ldr r8, [r12, #RESET_DATA(MASK_LP1)]
184 tst r8, r11 @ if in_lp1 185 tst r8, r11 @ if in_lp1
185 beq __is_not_lp1 186 beq __is_not_lp1
186 cmp r10, #0 187 cmp r10, #0
187 bne __die @ only CPU0 can be here 188 bne __die @ only CPU0 can be here
188 ldr lr, [r12, #RESET_DATA(STARTUP_LP1)] 189 ldr lr, [r12, #RESET_DATA(STARTUP_LP1)]
189 cmp lr, #0 190 cmp lr, #0
190 bleq __die @ no LP1 startup handler 191 bleq __die @ no LP1 startup handler
191 THUMB( add lr, lr, #1 ) @ switch to Thumb mode 192 THUMB( add lr, lr, #1 ) @ switch to Thumb mode
192 bx lr 193 bx lr
193 __is_not_lp1: 194 __is_not_lp1:
194 195
195 /* Waking up from LP2? */ 196 /* Waking up from LP2? */
196 ldr r9, [r12, #RESET_DATA(MASK_LP2)] 197 ldr r9, [r12, #RESET_DATA(MASK_LP2)]
197 tst r9, r11 @ if in_lp2 198 tst r9, r11 @ if in_lp2
198 beq __is_not_lp2 199 beq __is_not_lp2
199 ldr lr, [r12, #RESET_DATA(STARTUP_LP2)] 200 ldr lr, [r12, #RESET_DATA(STARTUP_LP2)]
200 cmp lr, #0 201 cmp lr, #0
201 bleq __die @ no LP2 startup handler 202 bleq __die @ no LP2 startup handler
202 bx lr 203 bx lr
203 204
204 __is_not_lp2: 205 __is_not_lp2:
205 206
206 #ifdef CONFIG_SMP 207 #ifdef CONFIG_SMP
207 /* 208 /*
208 * Can only be secondary boot (initial or hotplug) 209 * Can only be secondary boot (initial or hotplug)
209 * CPU0 can't be here for Tegra20/30 210 * CPU0 can't be here for Tegra20/30
210 */ 211 */
211 cmp r6, #TEGRA114 212 cmp r6, #TEGRA114
212 beq __no_cpu0_chk 213 beq __no_cpu0_chk
213 cmp r10, #0 214 cmp r10, #0
214 bleq __die @ CPU0 cannot be here 215 bleq __die @ CPU0 cannot be here
215 __no_cpu0_chk: 216 __no_cpu0_chk:
216 ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] 217 ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
217 cmp lr, #0 218 cmp lr, #0
218 bleq __die @ no secondary startup handler 219 bleq __die @ no secondary startup handler
219 bx lr 220 bx lr
220 #endif 221 #endif
221 222
222 /* 223 /*
223 * We don't know why the CPU reset. Just kill it. 224 * We don't know why the CPU reset. Just kill it.
224 * The LR register will contain the address we died at + 4. 225 * The LR register will contain the address we died at + 4.
225 */ 226 */
226 227
227 __die: 228 __die:
228 sub lr, lr, #4 229 sub lr, lr, #4
229 mov32 r7, TEGRA_PMC_BASE 230 mov32 r7, TEGRA_PMC_BASE
230 str lr, [r7, #PMC_SCRATCH41] 231 str lr, [r7, #PMC_SCRATCH41]
231 232
232 mov32 r7, TEGRA_CLK_RESET_BASE 233 mov32 r7, TEGRA_CLK_RESET_BASE
233 234
234 /* Are we on Tegra20? */ 235 /* Are we on Tegra20? */
235 cmp r6, #TEGRA20 236 cmp r6, #TEGRA20
236 bne 1f 237 bne 1f
237 238
238 #ifdef CONFIG_ARCH_TEGRA_2x_SOC 239 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
239 mov32 r0, 0x1111 240 mov32 r0, 0x1111
240 mov r1, r0, lsl r10 241 mov r1, r0, lsl r10
241 str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET 242 str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET
242 #endif 243 #endif
243 1: 244 1:
244 #ifdef CONFIG_ARCH_TEGRA_3x_SOC 245 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
245 mov32 r6, TEGRA_FLOW_CTRL_BASE 246 mov32 r6, TEGRA_FLOW_CTRL_BASE
246 247
247 cmp r10, #0 248 cmp r10, #0
248 moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS 249 moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS
249 moveq r2, #FLOW_CTRL_CPU0_CSR 250 moveq r2, #FLOW_CTRL_CPU0_CSR
250 movne r1, r10, lsl #3 251 movne r1, r10, lsl #3
251 addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8) 252 addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8)
252 addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8) 253 addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8)
253 254
254 /* Clear CPU "event" and "interrupt" flags and power gate 255 /* Clear CPU "event" and "interrupt" flags and power gate
255 it when halting but not before it is in the "WFI" state. */ 256 it when halting but not before it is in the "WFI" state. */
256 ldr r0, [r6, +r2] 257 ldr r0, [r6, +r2]
257 orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG 258 orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
258 orr r0, r0, #FLOW_CTRL_CSR_ENABLE 259 orr r0, r0, #FLOW_CTRL_CSR_ENABLE
259 str r0, [r6, +r2] 260 str r0, [r6, +r2]
260 261
261 /* Unconditionally halt this CPU */ 262 /* Unconditionally halt this CPU */
262 mov r0, #FLOW_CTRL_WAITEVENT 263 mov r0, #FLOW_CTRL_WAITEVENT
263 str r0, [r6, +r1] 264 str r0, [r6, +r1]
264 ldr r0, [r6, +r1] @ memory barrier 265 ldr r0, [r6, +r1] @ memory barrier
265 266
266 dsb 267 dsb
267 isb 268 isb
268 wfi @ CPU should be power gated here 269 wfi @ CPU should be power gated here
269 270
270 /* If the CPU didn't power gate above just kill it's clock. */ 271 /* If the CPU didn't power gate above just kill it's clock. */
271 272
272 mov r0, r11, lsl #8 273 mov r0, r11, lsl #8
273 str r0, [r7, #348] @ CLK_CPU_CMPLX_SET 274 str r0, [r7, #348] @ CLK_CPU_CMPLX_SET
274 #endif 275 #endif
275 276
276 /* If the CPU still isn't dead, just spin here. */ 277 /* If the CPU still isn't dead, just spin here. */
277 b . 278 b .
278 ENDPROC(__tegra_cpu_reset_handler) 279 ENDPROC(__tegra_cpu_reset_handler)
279 280
280 .align L1_CACHE_SHIFT 281 .align L1_CACHE_SHIFT
281 .type __tegra_cpu_reset_handler_data, %object 282 .type __tegra_cpu_reset_handler_data, %object
282 .globl __tegra_cpu_reset_handler_data 283 .globl __tegra_cpu_reset_handler_data
283 __tegra_cpu_reset_handler_data: 284 __tegra_cpu_reset_handler_data:
284 .rept TEGRA_RESET_DATA_SIZE 285 .rept TEGRA_RESET_DATA_SIZE
285 .long 0 286 .long 0
286 .endr 287 .endr
287 .align L1_CACHE_SHIFT 288 .align L1_CACHE_SHIFT
288 289
289 ENTRY(__tegra_cpu_reset_handler_end) 290 ENTRY(__tegra_cpu_reset_handler_end)
290 291