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 "iomap.h" 26#include "reset.h" 27#include "sleep.h" 28 29#define APB_MISC_GP_HIDREV 0x804 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 */ 42ENTRY(tegra_resume) 43 bl v7_invalidate_l1 44 /* Enable coresight */ 45 mov32 r0, 0xC5ACCE55 46 mcr p14, 0, r0, c7, c12, 6 47 48 cpu_id r0 49 cmp r0, #0 @ CPU0? 50 bne cpu_resume @ no 51 52#ifdef CONFIG_ARCH_TEGRA_3x_SOC 53 /* Are we on Tegra20? */ 54 mov32 r6, TEGRA_APB_MISC_BASE 55 ldr r0, [r6, #APB_MISC_GP_HIDREV] 56 and r0, r0, #0xff00 57 cmp r0, #(0x20 << 8) 58 beq 1f @ Yes 59 /* Clear the flow controller flags for this CPU. */ 60 mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR 61 ldr r1, [r2] 62 /* Clear event & intr flag */ 63 orr r1, r1, \ 64 #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG 65 movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps 66 bic r1, r1, r0 67 str r1, [r2] 681: 69#endif 70 71#ifdef CONFIG_HAVE_ARM_SCU 72 /* enable SCU */ 73 mov32 r0, TEGRA_ARM_PERIF_BASE 74 ldr r1, [r0] 75 orr r1, r1, #1 76 str r1, [r0] 77#endif 78 79 /* L2 cache resume & re-enable */ 80 l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr 81 82 b cpu_resume 83ENDPROC(tegra_resume) 84#endif 85 86#ifdef CONFIG_CACHE_L2X0 87 .globl l2x0_saved_regs_addr 88l2x0_saved_regs_addr: 89 .long 0 90#endif 91 92 .align L1_CACHE_SHIFT 93ENTRY(__tegra_cpu_reset_handler_start) 94 95/* 96 * __tegra_cpu_reset_handler: 97 * 98 * Common handler for all CPU reset events. 99 * 100 * Register usage within the reset handler: 101 * 102 * R7 = CPU present (to the OS) mask 103 * R8 = CPU in LP1 state mask 104 * R9 = CPU in LP2 state mask 105 * R10 = CPU number 106 * R11 = CPU mask 107 * R12 = pointer to reset handler data 108 * 109 * NOTE: This code is copied to IRAM. All code and data accesses 110 * must be position-independent. 111 */ 112 113 .align L1_CACHE_SHIFT 114ENTRY(__tegra_cpu_reset_handler) 115 116 cpsid aif, 0x13 @ SVC mode, interrupts disabled 117 mrc p15, 0, r10, c0, c0, 5 @ MPIDR 118 and r10, r10, #0x3 @ R10 = CPU number 119 mov r11, #1 120 mov r11, r11, lsl r10 @ R11 = CPU mask 121 adr r12, __tegra_cpu_reset_handler_data 122 123#ifdef CONFIG_SMP 124 /* Does the OS know about this CPU? */ 125 ldr r7, [r12, #RESET_DATA(MASK_PRESENT)] 126 tst r7, r11 @ if !present 127 bleq __die @ CPU not present (to OS) 128#endif 129 130#ifdef CONFIG_ARCH_TEGRA_2x_SOC 131 /* Are we on Tegra20? */ 132 mov32 r6, TEGRA_APB_MISC_BASE 133 ldr r0, [r6, #APB_MISC_GP_HIDREV] 134 and r0, r0, #0xff00 135 cmp r0, #(0x20 << 8) 136 bne 1f 137 /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ 138 mov32 r6, TEGRA_PMC_BASE 139 mov r0, #0 140 cmp r10, #0 141 strne r0, [r6, #PMC_SCRATCH41] 1421: 143#endif 144 145 /* Waking up from LP2? */ 146 ldr r9, [r12, #RESET_DATA(MASK_LP2)] 147 tst r9, r11 @ if in_lp2 148 beq __is_not_lp2 149 ldr lr, [r12, #RESET_DATA(STARTUP_LP2)] 150 cmp lr, #0 151 bleq __die @ no LP2 startup handler 152 bx lr 153 154__is_not_lp2: 155 156#ifdef CONFIG_SMP 157 /* 158 * Can only be secondary boot (initial or hotplug) but CPU 0 159 * cannot be here. 160 */ 161 cmp r10, #0 162 bleq __die @ CPU0 cannot be here 163 ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] 164 cmp lr, #0 165 bleq __die @ no secondary startup handler 166 bx lr 167#endif 168 169/* 170 * We don't know why the CPU reset. Just kill it. 171 * The LR register will contain the address we died at + 4. 172 */ 173 174__die: 175 sub lr, lr, #4 176 mov32 r7, TEGRA_PMC_BASE 177 str lr, [r7, #PMC_SCRATCH41] 178 179 mov32 r7, TEGRA_CLK_RESET_BASE 180 181 /* Are we on Tegra20? */ 182 mov32 r6, TEGRA_APB_MISC_BASE 183 ldr r0, [r6, #APB_MISC_GP_HIDREV] 184 and r0, r0, #0xff00 185 cmp r0, #(0x20 << 8) 186 bne 1f 187 188#ifdef CONFIG_ARCH_TEGRA_2x_SOC 189 mov32 r0, 0x1111 190 mov r1, r0, lsl r10 191 str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET 192#endif 1931: 194#ifdef CONFIG_ARCH_TEGRA_3x_SOC 195 mov32 r6, TEGRA_FLOW_CTRL_BASE 196 197 cmp r10, #0 198 moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS 199 moveq r2, #FLOW_CTRL_CPU0_CSR 200 movne r1, r10, lsl #3 201 addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8) 202 addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8) 203 204 /* Clear CPU "event" and "interrupt" flags and power gate 205 it when halting but not before it is in the "WFI" state. */ 206 ldr r0, [r6, +r2] 207 orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG 208 orr r0, r0, #FLOW_CTRL_CSR_ENABLE 209 str r0, [r6, +r2] 210 211 /* Unconditionally halt this CPU */ 212 mov r0, #FLOW_CTRL_WAITEVENT 213 str r0, [r6, +r1] 214 ldr r0, [r6, +r1] @ memory barrier 215 216 dsb 217 isb 218 wfi @ CPU should be power gated here 219 220 /* If the CPU didn't power gate above just kill it's clock. */ 221 222 mov r0, r11, lsl #8 223 str r0, [r7, #348] @ CLK_CPU_CMPLX_SET 224#endif 225 226 /* If the CPU still isn't dead, just spin here. */ 227 b . 228ENDPROC(__tegra_cpu_reset_handler) 229 230 .align L1_CACHE_SHIFT 231 .type __tegra_cpu_reset_handler_data, %object 232 .globl __tegra_cpu_reset_handler_data 233__tegra_cpu_reset_handler_data: 234 .rept TEGRA_RESET_DATA_SIZE 235 .long 0 236 .endr 237 .align L1_CACHE_SHIFT 238 239ENTRY(__tegra_cpu_reset_handler_end) 240