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