ARM: Tegra: Add CONFIG_TEGRA_USE_SECURE_KERNEL
[linux-3.10.git] / arch / arm / mach-tegra / headsmp.S
index b373768..06091dd 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CPU initialization routines for Tegra SoCs
  *
- * Copyright (c) 2009-2012, NVIDIA Corporation.
+ * Copyright (c) 2009-2013, NVIDIA CORPORATION.  All rights reserved.
  * Copyright (c) 2011 Google, Inc.
  * Author: Colin Cross <ccross@android.com>
  *         Gary King <gking@nvidia.com>
@@ -24,6 +24,7 @@
 #include <asm/assembler.h>
 #include <asm/cache.h>
 #include <asm/page.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include "flowctrl.h"
 #include "iomap.h"
@@ -35,7 +36,8 @@
 
 #define DEBUG_CPU_RESET_HANDLER        0       /* Non-zero enables debug code */
 
-#define RESET_DATA(x)  ((TEGRA_RESET_##x)*4)
+#define RESET_DATA_PHYS (TEGRA_RESET_HANDLER_BASE \
+       + __tegra_cpu_reset_handler_data - __tegra_cpu_reset_handler_start)
 
 #ifdef CONFIG_SMP
 /*
@@ -76,7 +78,7 @@ ENDPROC(tegra_secondary_startup)
  *       re-enabling sdram.
  */
 ENTRY(tegra_resume)
-#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
        mov32   r1, TEGRA_TMRUS_BASE
        ldr     r0, [r1]
        adr     r1, tegra_resume_entry_time
@@ -100,41 +102,103 @@ ENTRY(tegra_resume)
        movw    r0, #0x3FFD     @ enable, enable_ext, cluster_switch, immed, & bitmaps
        bic     r1, r1, r0
        str     r1, [r2]
-#endif
+#endif /* !CONFIG_ARCH_TEGRA_2x_SOC */
 
 #if defined(CONFIG_HAVE_ARM_SCU)
        /* enable SCU */
        mov32   r0, TEGRA_ARM_PERIF_BASE
        ldr     r1, [r0]
        orr     r1, r1, #1
-       str     r1, [r0]
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
+       orr     r1, r1, #8
 #endif
+       str     r1, [r0]
+#endif /* CONFIG_HAVE_ARM_SCU */
 
-#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
 #ifndef CONFIG_ARCH_TEGRA_11x_SOC
        mov32   r1, TEGRA_TMRUS_BASE
        ldr     r0, [r1]
        adr     r1, tegra_resume_smc_entry_time
        str     r0, [r1]
 
-       /* wake up (should have specified args?) */
+       /* wake up */
+       mov     r0, #0x00000003
        bl      tegra_generic_smc
 
        mov32   r1, TEGRA_TMRUS_BASE
        ldr     r0, [r1]
        adr     r1, tegra_resume_smc_exit_time
        str     r0, [r1]
+#endif /* !CONFIG_ARCH_TEGRA_11x_SOC */
+#endif /* CONFIG_TEGRA_USE_SECURE_KERNEL */
+
+#ifdef CONFIG_CACHE_L2X0
+#if !defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+               !defined(CONFIG_ARCH_TEGRA_14x_SOC)
+       adr     r0, tegra_resume_l2_init
+       ldr     r1, [r0]
+       tst     r1, #1
+       beq     no_l2_init
+       /* Enable L2 */
+       bic     r1, #1
+       str     r1, [r0]
+       mov32   r3, TEGRA_ARM_PL310_BASE
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
+       mov32   r0, 0x331                       /* tag latency */
+       mov32   r1, 0x441                       /* data latency */
+#elif defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
+#ifdef CONFIG_TEGRA_SILICON_PLATFORM
+       mov32   r0, TEGRA_FLOW_CTRL_BASE + 0x2c /* FLOW_CTRL_CLUSTER_CONTROL */
+       mov32   r2, RESET_DATA_PHYS
+       ldr     r1, [r0]
+       tst     r1, #1                          /* 0 == G, 1 == LP */
+       ldrne   r0, [r2, #RESET_DATA(C1_L2_TAG_LATENCY)]
+       ldrne   r1, [r2, #RESET_DATA(C1_L2_DATA_LATENCY)]
+       ldreq   r0, [r2, #RESET_DATA(C0_L2_TAG_LATENCY)]
+       ldreq   r1, [r2, #RESET_DATA(C0_L2_DATA_LATENCY)]
+#else /* !CONFIG_TEGRA_SILICON_PLATFORM */
+       mov32   r0, #0x770                      /* tag latency */
+       mov32   r1, #0x770                      /* data latency */
+#endif /* ?CONFIG_TEGRA_SILICON_PLATFORM */
+#endif /* CONFIG_ARCH_TEGRA_3x_SOC || CONFIG_ARCH_TEGRA_14x_SOC */
+       str     r0, [r3, #L2X0_TAG_LATENCY_CTRL]
+       str     r1, [r3, #L2X0_DATA_LATENCY_CTRL]
+#ifndef CONFIG_TEGRA_FPGA_PLATFORM
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
+       mov32   r0, 0x40000007  /* Enable double line fill */
+#else
+       mov     r0, #7
 #endif
-#endif
+       str     r0, [r3, #L2X0_PREFETCH_CTRL]
+#endif /* !CONFIG_TEGRA_FPGA_PLATFORM */
+       mov     r0, #3
+       str     r0, [r3, #L2X0_POWER_CTRL]
+       /* figure out aux ctrl */
+       ldr     r2, [r3, #L2X0_CACHE_TYPE]
+       and     r2, r2, #0x700
+       lsl     r2, r2, #(17-8)
+       mov32   r4, 0x7C400001
+       orr     r2, r2, r4
+       ldr     r4, [r3, #L2X0_AUX_CTRL]
+       mov32   r5, 0x8200c3fe
+       and     r4, r4, r5
+       orr     r2, r2, r4
+       str     r2, [r3, #L2X0_AUX_CTRL]
+       mov     r2, #1
+       str     r2, [r3, #L2X0_CTRL]
+#endif /* ?CONFIG_TEGRA_USE_SECURE_KERNEL */
+#endif /* CONFIG_CACHE_L2X0 */
+no_l2_init:
        b       cpu_resume
 ENDPROC(tegra_resume)
 
-#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
        .globl tegra_resume_timestamps_start
 #ifndef CONFIG_ARCH_TEGRA_11x_SOC
        .globl tegra_resume_smc_entry_time
        .globl tegra_resume_smc_exit_time
-#endif
+#endif /* !CONFIG_ARCH_TEGRA_11x_SOC */
        .globl tegra_resume_entry_time
        .globl tegra_resume_timestamps_end
 tegra_resume_timestamps_start:
@@ -143,54 +207,42 @@ tegra_resume_smc_entry_time:
        .long   0
 tegra_resume_smc_exit_time:
        .long   0
-#endif
+#endif /* !CONFIG_ARCH_TEGRA_11x_SOC */
 tegra_resume_entry_time:
        .long   0
 tegra_resume_timestamps_end:
-ENTRY(__tegra_resume_timestamps_end)
-#endif
-#endif
+#endif /* CONFIG_TEGRA_USE_SECURE_KERNEL */
+#ifdef CONFIG_CACHE_L2X0
+       .globl tegra_resume_l2_init
+tegra_resume_l2_init:
+       .long 0
+#endif /* CONFIG_CACHE_L2X0 */
+#endif /* CONFIG_PM_SLEEP */
 
 /*
  *     __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
+ *       arrays, exclusive monitor, etc.) so that they can be safely
+ *       enabled. Instruction caching and branch prediction are enabled.
  *
- *       For tegra chips with CONFIG_HAVE_ARM_SCU undefined, it means there is
- *       an integrated SCU in L2 memory system, this is true for Cortex-A15
- *       MP processors. In this case, we only need to set the correct L2 cache
- *       data RAM latency and enable i-cache/branch prediction
+ *       Cortex-A15 has an integrated SCU in L2 memory system, we only
+ *       need to set the correct L2 cache data RAM latency and enable
+ *       i-cache/branch prediction.
  */
 __invalidate_cpu_state:
        clrex
        mov     r0, #0
        mcr     p15, 0, r0, c1, c0, 1   @ disable SMP, prefetch, broadcast
        isb
-#if defined(CONFIG_HAVE_ARM_SCU)
-       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, c5, 0   @ invalidate instruction TLB
-       mcr     p15, 0, r0, c8, c6, 0   @ invalidate data TLB
-       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
+       mrc     p15, 0, r0, c0, c0, 0   @ main ID register
+       ubfx    r1, r0, #4, #28
+       ldr     r0, =0x00f0000
+       bic     r1, r1, r0
+       ldr     r0, =0x410fc09
+       teq     r1, r0
+       beq     cortex_a9
 
-       dsb
-       mov     r0, #0x1800
-       mcr     p15, 0, r0, c1, c0, 0   @ enable branch prediction, i-cache
-       isb
-       /* fall through */
-#else
        mrc     p15, 0x1, r0, c15, c0, 3        @ L2 prefetch control reg
        tst     r0, #0x1000
        orreq   r0, r0, #0x1000                 @ disable throttling
@@ -216,16 +268,34 @@ __enable_i_cache_branch_pred:
        mcr     p15, 0, r0, c1, c0, 0   @ enable branch prediction, i-cache
        mov     pc, lr
        /* no fall through, just return to the caller */
+
+cortex_a9:
+       /* Following is for Cortex-A9 */
+       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, c5, 0   @ invalidate instruction TLB
+       mcr     p15, 0, r0, c8, c6, 0   @ invalidate data TLB
+       mcr     p15, 0, r0, c8, c7, 0   @ invalidate unified TLB
+       dsb
+       isb
+
+#if defined(CONFIG_HAVE_ARM_SCU)
+       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
 #endif
 
-/*
- *     tegra_invalidate_cache
- *
- *       Invalidates the L1 data cache (no clean) during initial boot of a cpu
- *
- *       Corrupted registers: r0-r6
- */
-tegra_invalidate_cache:
+       dsb
+       mov     r0, #0x1800
+       mcr     p15, 0, r0, c1, c0, 0   @ enable branch prediction, i-cache
+       isb
+
+       /* Invalidates L1 d-cache during initial cpu boot (corrupt r0-r6) */
+
        mov     r0, #0
        mcr     p15, 2, r0, c0, c0, 0
        mrc     p15, 1, r0, c0, c0, 0
@@ -302,7 +372,7 @@ ENTRY(__tegra_cpu_reset_handler)
 #if DEBUG_CPU_RESET_HANDLER
        b       .
 #endif
-#ifndef CONFIG_TRUSTED_FOUNDATIONS
+#ifndef CONFIG_TEGRA_USE_SECURE_KERNEL
        cpsid   aif, 0x13                       @ SVC mode, interrupts disabled
        mrc     p15, 0, r0, c0, c0, 0           @ read main ID register
        and     r5, r0, #0x00f00000             @ variant
@@ -446,6 +516,11 @@ __tegra_cpu_reset_handler_data:
        .rept   TEGRA_RESET_DATA_SIZE
        .long   0
        .endr
-       .size   __tegra_cpu_reset_handler_data, . - __tegra_cpu_reset_handler_data
+       .size   __tegra_cpu_reset_handler_data, \
+       . - __tegra_cpu_reset_handler_data
        .align L1_CACHE_SHIFT
 ENTRY(__tegra_cpu_reset_handler_end)
+
+       .globl  __tegra_cpu_reset_handler_data_offset
+       .equ    __tegra_cpu_reset_handler_data_offset, \
+       __tegra_cpu_reset_handler_data - __tegra_cpu_reset_handler_start