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