/* * Copyright (c) 2012, NVIDIA Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "flowctrl.h" #include "iomap.h" #include "reset.h" #include "sleep.h" #define PMC_SCRATCH41 0x140 #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) #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. * * r6: SoC ID * r8: CPU part number */ ENTRY(tegra_resume) check_cpu_part_num 0xc09, r8, r9 bleq v7_invalidate_l1 cpu_id r0 cmp r0, #0 @ CPU0? THUMB( it ne ) bne cpu_resume @ no tegra_get_soc_id TEGRA_APB_MISC_BASE, r6 /* Are we on Tegra20? */ cmp r6, #TEGRA20 beq 1f @ Yes /* Clear the flow controller flags for this CPU. */ cpu_to_csr_reg r1, r0 mov32 r2, TEGRA_FLOW_CTRL_BASE ldr r1, [r2, r1] /* Clear event & intr flag */ orr r1, r1, \ #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps @ & ext flags for CPU power mgnt bic r1, r1, r0 str r1, [r2] 1: mov32 r9, 0xc09 cmp r8, r9 bne end_ca9_scu_l2_resume #ifdef CONFIG_HAVE_ARM_SCU /* enable SCU */ mov32 r0, TEGRA_ARM_PERIF_BASE ldr r1, [r0] orr r1, r1, #1 str r1, [r0] #endif #ifdef CONFIG_CACHE_L2X0 /* L2 cache resume & re-enable */ bl l2c310_early_resume #endif end_ca9_scu_l2_resume: mov32 r9, 0xc0f cmp r8, r9 bleq tegra_init_l2_for_a15 b cpu_resume ENDPROC(tegra_resume) #endif .align L1_CACHE_SHIFT ENTRY(__tegra_cpu_reset_handler_start) /* * __tegra_cpu_reset_handler: * * Common handler for all CPU reset events. * * Register usage within the reset handler: * * Others: scratch * R6 = SoC ID * R7 = CPU present (to the OS) mask * R8 = CPU in LP1 state mask * R9 = CPU in LP2 state mask * R10 = CPU number * R11 = CPU mask * R12 = pointer to reset handler data * * NOTE: This code is copied to IRAM. All code and data accesses * must be position-independent. */ .align L1_CACHE_SHIFT ENTRY(__tegra_cpu_reset_handler) cpsid aif, 0x13 @ SVC mode, interrupts disabled tegra_get_soc_id TEGRA_APB_MISC_BASE, r6 #ifdef CONFIG_ARCH_TEGRA_2x_SOC t20_check: cmp r6, #TEGRA20 bne after_t20_check t20_errata: # Tegra20 is a Cortex-A9 r1p1 mrc p15, 0, r0, c1, c0, 0 @ read system control register orr r0, r0, #1 << 14 @ erratum 716044 mcr p15, 0, r0, c1, c0, 0 @ write system control register mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 4 @ erratum 742230 orr r0, r0, #1 << 11 @ erratum 751472 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register b after_errata after_t20_check: #endif #ifdef CONFIG_ARCH_TEGRA_3x_SOC t30_check: cmp r6, #TEGRA30 bne after_t30_check t30_errata: # Tegra30 is a Cortex-A9 r2p9 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 6 @ erratum 743622 orr r0, r0, #1 << 11 @ erratum 751472 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register b after_errata after_t30_check: #endif after_errata: mrc p15, 0, r10, c0, c0, 5 @ MPIDR and r10, r10, #0x3 @ R10 = CPU number mov r11, #1 mov r11, r11, lsl r10 @ R11 = CPU m