/* * arch/arm/mach-tegra/headsmp.S * * CPU initialization routines for Tegra SoCs * * Copyright (c) 2009-2012, NVIDIA Corporation. All rights reserved. * Copyright (c) 2011 Google, Inc. * Author: Colin Cross * Gary King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */ #include #include #include #include #include #include #include #include "asm_macros.h" #include "reset.h" #include "sleep.h" #define DEBUG_CPU_RESET_HANDLER 0 /* Non-zero enables debug code */ #define PMC_SCRATCH41 0x140 #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) #ifdef CONFIG_SMP /* * tegra_secondary_startup * * Initial secondary processor boot vector; jumps to kernel's * secondary_startup routine. Used for initial boot and hotplug * of secondary CPUs. */ ENTRY(tegra_secondary_startup) bl __invalidate_cpu_state b secondary_startup ENDPROC(tegra_secondary_startup) #endif #ifdef CONFIG_PM_SLEEP /* * tegra_resume * * CPU boot vector when restarting the a CPU following * an LP2 transition. Also branched to by LP0 and LP1 resume after * re-enabling sdram. */ ENTRY(tegra_resume) bl __invalidate_cpu_state cpu_id r0 cmp r0, #0 @ CPU0? bne tegra_cpu_resume_phys @ no #ifndef CONFIG_ARCH_TEGRA_2x_SOC @ Clear the flow controller flags for this CPU. mov32 r2, TEGRA_FLOW_CTRL_BASE+8 @ CPU0 CSR ldr r1, [r2] orr r1, r1, #(1 << 15) | (1 << 14) @ write to clear event & intr movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps bic r1, r1, r0 str r1, [r2] #endif /* enable SCU */ mov32 r0, TEGRA_ARM_PERIF_BASE ldr r1, [r0] orr r1, r1, #1 str r1, [r0] #ifdef CONFIG_TRUSTED_FOUNDATIONS /* wake up */ mov r0, #0x00000003 bl tegra_generic_smc_local #endif b tegra_cpu_resume_phys ENDPROC(tegra_resume) #endif /* * __invalidate_cpu_state * * Invalidates volatile CPU state (SCU tags, caches, branch address * arrays, exclusive monitor, etc.) so that they can be safely enabled * instruction caching and branch predicition enabled */ __invalidate_cpu_state: clrex mov r0, #0 mcr p15, 0, r0, c1, c0, 1 @ disable SMP, prefetch, broadcast isb mcr p15, 0, r0, c7, c5, 0 @ invalidate BTAC, i-cache mcr p15, 0, r0, c7, c5, 6 @ invalidate branch pred array mcr p15, 0, r0, c8, c7, 0 @ invalidate unified TLB dsb isb cpu_id r0 cmp r0, #0 mov32 r1, (TEGRA_ARM_PERIF_BASE + 0xC) movne r0, r0, lsl #2 movne r2, #0xf movne r2, r2, lsl r0 strne r2, [r1] @ invalidate SCU tags for CPU dsb mov r0, #0x1800 mcr p15, 0, r0, c1, c0, 0 @ enable branch prediction, i-cache isb /* fall through */ /* * tegra_invalidate_l1 * * Invalidates the L1 data cache (no clean) during initial boot of a cpu * * Corrupted registers: r0-r6 */ tegra_invalidate_l1: mov r0, #0 mcr p15, 2, r0, c0, c0, 0 mrc p15, 1, r0, c0, c0, 0 movw r1, #0x7fff and r2, r1, r0, lsr #13 movw r1, #0x3ff and r3, r1, r0, lsr #3 @ NumWays - 1 add r2, r2, #1 @ NumSets and r0, r0, #0x7 add r0, r0, #4 @ SetShift clz r1, r3 @ WayShift add r4, r3, #1 @ NumWays 1: sub r2, r2, #1 @ NumSets-- mov r3, r4 @ Temp = NumWays 2: subs r3, r3, #1 @ Temp-- mov r5, r3, lsl r1 mov r6, r2, lsl r0 orr r5, r5, r6 @ Reg = (Temp<