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