ARM: tegra: smp: Add support for Cortex-A15 boot_secondary
Scott Williams [Fri, 3 Feb 2012 19:00:50 +0000 (11:00 -0800)]
Cortex-A15 does not have a memory-mapped SCU in the PERIPHBASE
aperture. Instead, the number of CPUs present is obtained from
the architectural L2 Cache Control (L2CTLR) register.

Enable HAVE_ARM_SCU only on platforms that have a memory-mapped
SCU and add the necessary conditionals to prevent access to the
memory-mapped SCU address range on platforms that don't.

Change-Id: I4027d034fe79339fab0030a44780240785206cba
Signed-off-by: Scott Williams <scwilliams@nvidia.com>
Reviewed-on: http://git-master/r/79341
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Mark Stadler <mastadler@nvidia.com>
Reviewed-by: Jeff Smith <jsmith@nvidia.com>
Reviewed-by: Bo Yan <byan@nvidia.com>
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>

Rebase-Id: R62dcd56e7abed8ef5cef60325c6ca52fbfb43b22

arch/arm/Kconfig
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/headsmp.S
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/sleep.h

index d6d562e..b1f81ae 100644 (file)
@@ -1481,7 +1481,8 @@ config SMP
        depends on GENERIC_CLOCKEVENTS
        depends on HAVE_SMP
        depends on MMU
-       select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
+       select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP && \
+                (!ARCH_TEGRA || ARCH_TEGRA_HAS_ARM_SCU)
        select USE_GENERIC_SMP_HELPERS
        help
          This enables support for systems with more than one CPU. If you have
index 604491d..5ebcc2e 100644 (file)
@@ -8,6 +8,7 @@ config ARCH_TEGRA_2x_SOC
        depends on !ARCH_TEGRA_11x_SOC
        select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
        select ARCH_SUPPORTS_MSI if TEGRA_PCI
+       select ARCH_TEGRA_HAS_ARM_SCU
        select ARCH_TEGRA_HAS_PCIE
        select ARM_CPU_SUSPEND if PM
        select ARM_ERRATA_716044
@@ -38,6 +39,7 @@ config ARCH_TEGRA_3x_SOC
        bool "Enable support for Tegra30 family"
        depends on !ARCH_TEGRA_11x_SOC
        select ARCH_SUPPORTS_MSI if TEGRA_PCI
+       select ARCH_TEGRA_HAS_ARM_SCU
        select ARCH_TEGRA_HAS_PCIE
        select ARCH_TEGRA_HAS_SATA
        select ARCH_TEGRA_HAS_DUAL_3D
@@ -83,6 +85,9 @@ config ARCH_TEGRA_11x_SOC
          Support for NVIDIA Tegra 11x family of SoCs, based upon the
          ARM Cortex-A15MP CPU
 
+config ARCH_TEGRA_HAS_ARM_SCU
+       bool
+
 config ARCH_TEGRA_HAS_DUAL_3D
        bool
 
index ad82faa..f93d30a 100644 (file)
@@ -81,6 +81,7 @@ ENTRY(tegra_resume)
        str     r1, [r2]
 #endif
 
+#ifdef CONFIG_HAVE_ARM_SCU
        /* enable SCU */
        mov32   r0, TEGRA_ARM_PERIF_BASE
        ldr     r1, [r0]
@@ -91,6 +92,7 @@ ENTRY(tegra_resume)
        orr     r1, r1, #(1 << 6)       @ Enable SCU standby.
 #endif
        str     r1, [r0]
+#endif
 
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
        /* wake up (should have specified args?) */
index 7a1fb16..9fe3810 100644 (file)
@@ -51,14 +51,29 @@ const struct cpumask *const tegra_cpu_init_mask = to_cpumask(tegra_cpu_init_bits
 #define CAR_BOND_OUT_V_CPU_G   (1<<0)
 #endif
 
+#ifdef CONFIG_HAVE_ARM_SCU
 static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
+static inline unsigned int get_core_count(void)
+{
+       return scu_get_core_count(scu_base);
+}
+#else
+static inline unsigned int get_core_count(void)
+{
+       u32 l2ctlr;
+
+       __asm__("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
+
+       return ((l2ctlr >> 24) & 3) + 1;
+}
+#endif
 
 static unsigned int available_cpus(void)
 {
        static unsigned int ncores;
 
        if (ncores == 0) {
-               ncores = scu_get_core_count(scu_base);
+               ncores = get_core_count();
 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
                if (ncores > 1) {
                        u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG);
@@ -305,7 +320,10 @@ static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
                        __raw_writel(scu_ctrl, scu_base);
        }
 #endif
+
+#ifdef CONFIG_HAVE_ARM_SCU
        scu_enable(scu_base);
+#endif
 }
 
 struct smp_operations tegra_smp_ops __initdata = {
index bb54acc..30ec005 100644 (file)
 #ifdef CONFIG_CACHE_L2X0
 #define TEGRA_PL310_VIRT (TEGRA_ARM_PL310_BASE - IO_CPU_PHYS + IO_CPU_VIRT)
 #endif
+#ifdef CONFIG_HAVE_ARM_SCU
 #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
                                        + IO_CPU_VIRT)
+#endif
 #define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
                                        + IO_PPSB_VIRT)
 #define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
        bic     \tmp1, \tmp1, #(1<<6) | (1<<0)  @ clear ACTLR.SMP | ACTLR.FW
        mcr     p15, 0, \tmp1, c1, c0, 1        @ ACTLR
        isb
+#ifdef CONFIG_HAVE_ARM_SCU
        cpu_id  \tmp1
        mov     \tmp1, \tmp1, lsl #2
        mov     \tmp2, #0xf
        mov32   \tmp1, TEGRA_ARM_PERIF_VIRT + 0xC
        str     \tmp2, [\tmp1]                  @ invalidate SCU tags for CPU
        dsb
+#endif
 .endm
 
 #define DEBUG_CONTEXT_STACK    0