Revert "arm: tegra: optimize L2 enable/disable paths for secureos"
Deepak Nibade [Wed, 17 Oct 2012 15:19:20 +0000 (20:19 +0530)]
With this revert, Dalmore enters LP0 state in Main
Otherwise NULL exception is encountered (variable l2x0_base)
Revert is required till we get proper secureos code and we
ensure that T114 does not enter l2x0 code

This reverts commit 7274dfdea8e1512b863438d4f34074a67b5b4a97.

Change-Id: Ib3ff4f1664fdc1693c2768eb3ecc0205a456c982
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/145288
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>

Rebase-Id: R147929cee9916146be1ce2a0f22895afd5d3622f

arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/headsmp.S
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/sleep.S

index 31d4cc4..f533531 100644 (file)
@@ -2,7 +2,7 @@
  * arch/arm/mach-tegra/common.c
  *
  * Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2010-2012 NVIDIA Corporation. All rights reserved.
+ * Copyright (C) 2010-2012 NVIDIA Corporation
  *
  * Author:
  *     Colin Cross <ccross@android.com>
@@ -252,13 +252,62 @@ static __initdata struct tegra_clk_init_table tegra11x_clk_init_table[] = {
 };
 #endif
 
+#ifdef CONFIG_CACHE_L2X0
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_2x_SOC)
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
-#define CACHE_LINE_SIZE                32
-static inline void tegra_l2x0_disable_tz(void)
+static void tegra_cache_smc(bool enable, u32 arg)
 {
-       static u32 l2x0_way_mask;
+       void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+       bool need_affinity_switch;
+       bool can_switch_affinity;
+       bool l2x0_enabled;
+       cpumask_t local_cpu_mask;
+       cpumask_t saved_cpu_mask;
+       unsigned long flags;
+       long ret;
+
+       /*
+        * ISSUE : Some registers of PL310 controler must be written
+        *              from Secure context (and from CPU0)!
+        *
+        * When called form Normal we obtain an abort or do nothing.
+        * Instructions that must be called in Secure:
+        *      - Write to Control register (L2X0_CTRL==0x100)
+        *      - Write in Auxiliary controler (L2X0_AUX_CTRL==0x104)
+        *      - Invalidate all entries (L2X0_INV_WAY==0x77C),
+        *              mandatory at boot time.
+        *      - Tag and Data RAM Latency Control Registers
+        *              (0x108 & 0x10C) must be written in Secure.
+        */
+       need_affinity_switch = (smp_processor_id() != 0);
+       can_switch_affinity = !irqs_disabled();
+
+       WARN_ON(need_affinity_switch && !can_switch_affinity);
+       if (need_affinity_switch && can_switch_affinity) {
+               cpu_set(0, local_cpu_mask);
+               sched_getaffinity(0, &saved_cpu_mask);
+               ret = sched_setaffinity(0, &local_cpu_mask);
+               WARN_ON(ret != 0);
+       }
 
-       BUG_ON(smp_processor_id() != 0);
+       local_irq_save(flags);
+       l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1;
+       if (enable && !l2x0_enabled)
+               tegra_generic_smc(0xFFFFF100, 0x00000001, arg);
+       else if (!enable && l2x0_enabled)
+               tegra_generic_smc(0xFFFFF100, 0x00000002, arg);
+       local_irq_restore(flags);
+
+       if (need_affinity_switch && can_switch_affinity) {
+               ret = sched_setaffinity(0, &saved_cpu_mask);
+               WARN_ON(ret != 0);
+       }
+}
+
+static void tegra_l2x0_disable(void)
+{
+       unsigned long flags;
+       static u32 l2x0_way_mask;
 
        if (!l2x0_way_mask) {
                void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
@@ -270,65 +319,33 @@ static inline void tegra_l2x0_disable_tz(void)
                l2x0_way_mask = (1 << ways) - 1;
        }
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-       /* flush all ways on disable */
-       tegra_generic_smc_uncached(0xFFFFF100, 0x00000002, l2x0_way_mask);
-#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
-       if (tegra_is_cpu_in_lp2(0)) {
-               register unsigned long sp asm ("sp");
-               /* flush only the stack, if entering LP2 */
-               __cpuc_flush_dcache_area((void *)sp, (CACHE_LINE_SIZE * 2));
-               outer_flush_range(__pa(sp), __pa(sp) + (CACHE_LINE_SIZE * 2));
-
-               /* pass zero arg, so secureos flushes only its workspace */
-               tegra_generic_smc_uncached(0xFFFFF100, 0x00000002,
-                       l2x0_way_mask);
-       } else {
-               /* flush all ways on disable, if entering LP0/LP1 */
-               tegra_generic_smc_uncached(0xFFFFF100, 0x00000002,
-                       l2x0_way_mask);
-       }
-#endif
+       local_irq_save(flags);
+       tegra_cache_smc(false, l2x0_way_mask);
+       local_irq_restore(flags);
 }
+#endif /* CONFIG_TRUSTED_FOUNDATIONS  */
 
-static inline void tegra_init_cache_tz(bool init)
+void tegra_init_cache(bool init)
 {
        void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
        u32 aux_ctrl;
-
-       BUG_ON(smp_processor_id() != 0);
-
-       if (init) {
-               /* init L2 from secureos */
-               tegra_generic_smc(0xFFFFF100, 0x00000001, 0x0);
-
-               /* common init called for outer call hookup */
-               aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
-               l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
-
-#ifdef CONFIG_OUTER_CACHE
-               /* use our outer_disable() routine */
-               outer_cache.disable = tegra_l2x0_disable_tz;
+#ifndef CONFIG_TRUSTED_FOUNDATIONS
+       u32 cache_type;
+       u32 tag_latency, data_latency;
 #endif
-       } else {
-               /* reenable L2 in secureos */
-               aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
-               tegra_generic_smc_uncached(0xFFFFF100, 0x00000004, aux_ctrl);
-       }
-}
-#endif /* CONFIG_TRUSTED_FOUNDATIONS  */
 
-#ifdef CONFIG_CACHE_L2X0
-void tegra_init_cache(bool init)
-{
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
-       /* enable/re-enable of L2 handled by secureos */
-       tegra_init_cache_tz(init);
+       /* issue the SMC to enable the L2 */
+       aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+       tegra_cache_smc(true, aux_ctrl);
+
+       /* after init, reread aux_ctrl and register handlers */
+       aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+       l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
+
+       /* override outer_disable() with our disable */
+       outer_cache.disable = tegra_l2x0_disable;
 #else
-       void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
-       u32 aux_ctrl;
-       u32 cache_type;
-       u32 tag_latency = 0x770, data_latency = 0x770;
 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
        tag_latency = 0x331;
        data_latency = 0x441;
@@ -351,6 +368,9 @@ void tegra_init_cache(bool init)
                        data_latency = 0x551;
                }
        }
+#else
+       tag_latency = 0x770;
+       data_latency = 0x770;
 #endif
 #endif
        writel_relaxed(tag_latency, p + L2X0_TAG_LATENCY_CTRL);
@@ -379,9 +399,14 @@ void tegra_init_cache(bool init)
                writel(aux_ctrl, p + L2X0_AUX_CTRL);
        }
        l2x0_enable();
-#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+#endif
 }
-#endif /* CONFIG_CACHE_L2X0 */
+#else
+void tegra_init_cache(bool init)
+{
+}
+#endif
+#endif
 
 static void __init tegra_init_power(void)
 {
index 9c97fd2..6827f58 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CPU initialization routines for Tegra SoCs
  *
- * Copyright (c) 2009-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2009-2012, NVIDIA Corporation.
  * Copyright (c) 2011 Google, Inc.
  * Author: Colin Cross <ccross@android.com>
  *         Gary King <gking@nvidia.com>
@@ -87,9 +87,8 @@ ENTRY(tegra_resume)
 #endif
 
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
-       /* wake up */
-       mov     r0, #0x00000003
-       bl      tegra_generic_smc_local
+       /* wake up (should have specified args?) */
+       bl      tegra_generic_smc
 #endif
 
        b       cpu_resume
index 6ea6ccb..61951cc 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CPU complex suspend & resume functions for Tegra SoCs
  *
- * Copyright (c) 2009-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2009-2012, NVIDIA Corporation.
  *
  * 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
@@ -103,7 +103,6 @@ struct suspend_context {
 };
 
 #ifdef CONFIG_PM_SLEEP
-void *tegra_cpu_context;        /* non-cacheable page for CPU context */
 phys_addr_t tegra_pgd_phys;    /* pgd used by hotplug & LP2 bootup */
 static pgd_t *tegra_pgd;
 static DEFINE_SPINLOCK(tegra_lp2_lock);
@@ -272,37 +271,6 @@ static __init int create_suspend_pgtable(void)
 
        return 0;
 }
-/*
- * alloc_suspend_context
- *
- * Allocate a non-cacheable page to hold the CPU contexts.
- * The standard ARM CPU context save functions don't work if there's
- * an external L2 cache controller (like a PL310) in system.
- */
-static __init int alloc_suspend_context(void)
-{
-       pgprot_t prot = __pgprot_modify(pgprot_kernel, L_PTE_MT_MASK,
-                                       L_PTE_MT_BUFFERABLE | L_PTE_XN);
-       struct page *ctx_page;
-
-       ctx_page = alloc_pages(GFP_KERNEL, 0);
-       if (IS_ERR_OR_NULL(ctx_page))
-               goto fail;
-
-       tegra_cpu_context = vm_map_ram(&ctx_page, 1, -1, prot);
-       if (IS_ERR_OR_NULL(tegra_cpu_context))
-               goto fail;
-
-       return 0;
-
-fail:
-       if (!IS_ERR(ctx_page) && ctx_page)
-               __free_page(ctx_page);
-       if (!IS_ERR(tegra_cpu_context) && tegra_cpu_context)
-               vm_unmap_ram((void *)tegra_cpu_context, 1);
-       tegra_cpu_context = NULL;
-       return -ENOMEM;
-}
 
 /* ensures that sufficient time is passed for a register write to
  * serialize into the 32KHz domain */
@@ -548,25 +516,15 @@ bool tegra_set_cpu_in_lp2(int cpu)
        return last_cpu;
 }
 
-bool tegra_is_cpu_in_lp2(int cpu)
-{
-       bool in_lp2;
-
-       spin_lock(&tegra_lp2_lock);
-       in_lp2 = cpumask_test_cpu(cpu, &tegra_in_lp2);
-       spin_unlock(&tegra_lp2_lock);
-       return in_lp2;
-}
-
 static void tegra_sleep_core(enum tegra_suspend_mode mode,
                             unsigned long v2p)
 {
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
        if (mode == TEGRA_SUSPEND_LP0) {
-               tegra_generic_smc_uncached(0xFFFFFFFC, 0xFFFFFFE3,
+               tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE3,
                                  virt_to_phys(tegra_resume));
        } else {
-               tegra_generic_smc_uncached(0xFFFFFFFC, 0xFFFFFFE6,
+               tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE6,
                                  (TEGRA_RESET_HANDLER_BASE +
                                   tegra_cpu_reset_handler_offset));
        }
@@ -581,7 +539,7 @@ static void tegra_sleep_core(enum tegra_suspend_mode mode,
 static inline void tegra_sleep_cpu(unsigned long v2p)
 {
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
-       tegra_generic_smc_uncached(0xFFFFFFFC, 0xFFFFFFE4,
+       tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE4,
                          (TEGRA_RESET_HANDLER_BASE +
                           tegra_cpu_reset_handler_offset));
 #endif
@@ -1166,13 +1124,6 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
                goto fail;
        }
 
-       if (alloc_suspend_context() < 0) {
-               pr_err("%s: alloc_suspend_context failed -- LP0/LP1/LP2 unavailable\n",
-                               __func__);
-               plat->suspend_mode = TEGRA_SUSPEND_NONE;
-               goto fail;
-       }
-
        if ((tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) &&
            (tegra_revision == TEGRA_REVISION_A01) &&
            (plat->suspend_mode == TEGRA_SUSPEND_LP0)) {
index 26d8073..259c31a 100644 (file)
@@ -83,7 +83,6 @@ unsigned long tegra_cpu_power_off_time(void);
 unsigned long tegra_cpu_lp2_min_residency(void);
 void tegra_clear_cpu_in_lp2(int cpu);
 bool tegra_set_cpu_in_lp2(int cpu);
-bool tegra_is_cpu_in_lp2(int cpu);
 
 int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags);
 
@@ -234,8 +233,6 @@ extern bool tegra_all_cpus_booted __read_mostly;
 
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
 void tegra_generic_smc(u32 type, u32 subtype, u32 arg);
-void tegra_generic_smc_local(u32 type, u32 subtype, u32 arg);
-void tegra_generic_smc_uncached(u32 type, u32 subtype, u32 arg);
 #endif
 
 /* The debug channel uart base physical address */
index 1baaf04..0b6268d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/sleep.S
  *
- * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
  * Copyright (c) 2011, Google, Inc.
  *
  * Author: Colin Cross <ccross@android.com>
@@ -294,74 +294,27 @@ ENDPROC(tegra_cpu_pllp)
 
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
 /*
- * Issue SMC with ctx kept on an uncached stack
+ * tegra_generic_smc
+ *
+ * r0 = smc type
+ * r1 = smc subtype
+ * r2 = argument passed to smc
+ *
+ * issues SMC (secure monitor call) instruction with
+ * the specified parameters.
  */
-.macro smc_issue_smc tmp
-       cpu_id  \tmp
-       cmp     \tmp, #0
-       bne     .
+ENTRY(tegra_generic_smc)
+       adr     r3, __tegra_smc_stack
+       stmia   r3, {r4-r12, lr}
        mov     r3, #0
        mov     r4, #0
        dsb
        smc     #0
-.endm
-
-ENTRY(tegra_generic_smc_uncached)
-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_CACHE_L2X0)
-       mov32   r3, tegra_cpu_context           @ borrow CPU0's non-cached
-       ldr     r3, [r3]                        @ context grows up
-       stmia   r3, {r4-r12, sp, lr}
-
-       smc_issue_smc r5
-
-       mov32   r3, tegra_cpu_context           @ borrow CPU0's non-cached
-       ldr     r3, [r3]                        @ context grows up
-       ldmia   r3, {r4-r12, sp, pc}
-#else
-       mov     pc, lr
-#endif
-ENDPROC(tegra_generic_smc_uncached)
-
-/*
- * Issue SMC with ctx kept on a cacheable stack
- *     (args in R0, R1, R2 and R3 holds save/restore ptr)
- */
-ENTRY(tegra_generic_smc_cached)
-       stmia   r3, {r4-r12, sp, lr}
-       adr     r4, __tegra_smc_current_ctx     @ save current ptr
-       str     r3, [r4]
-
-       smc_issue_smc r5
-
-       adr     r4, __tegra_smc_current_ctx     @ restore from saved ptr
-       ldr     r3, [r4]
-       ldmia   r3, {r4-r12, sp, pc}
-ENDPROC(tegra_generic_smc_cached)
-       .type   __tegra_smc_current_ctx, %object
-__tegra_smc_current_ctx:
-       .long   0
-       .size   __tegra_smc_current_ctx, . - __tegra_smc_current_ctx
-
-#define TEGRA_SMC_SAVED_WORDS  11
-
-/* SMC issued using the current cacheable SP stack */
-ENTRY(tegra_generic_smc)
-       mov     r3, sp                                  @ use current stack
-       sub     r3, #(TEGRA_SMC_SAVED_WORDS << 2)       @ context grows up
-       b       tegra_generic_smc_cached
+       adr     r3, __tegra_smc_stack
+       ldmia   r3, {r4-r12, pc}
 ENDPROC(tegra_generic_smc)
-
-/* SMC issued using a local cacheable stack */
-ENTRY(tegra_generic_smc_local)
-       adr     r3, __tegra_smc_stack                   @ use local stack
-       b       tegra_generic_smc_cached
-ENDPROC(tegra_generic_smc_local)
-
-       .align  L1_CACHE_SHIFT
-       .type   __tegra_smc_stack, %object
+       .type   __tegra_smc_stack, %object
 __tegra_smc_stack:
-       .rept   TEGRA_SMC_SAVED_WORDS
-       .long   0
-       .endr
-       .size   __tegra_smc_stack, . - __tegra_smc_stack
+       .long   0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+       .size   __tegra_smc_stack, . - __tegra_smc_stack
 #endif