diff options
author | Colin Cross <ccross@android.com> | 2011-04-03 00:47:27 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:34:21 -0800 |
commit | bc2b6b4c1dd531e9c204ac20ca2b790b5182de4d (patch) | |
tree | e30d953ddd03b4e7c8fc875217225dc1a295b9fe /arch/arm/mach-tegra/platsmp.c | |
parent | 120c356d1deff9aa1619afa948d07a90aea6959e (diff) |
ARM: tegra: simplify platsmp.c
The synchronization between cpus is handled in the generic ARM
code, no need to do it in boot_secondary
Change-Id: I2c490823d962c88e177e267c2a46278976925a38
Signed-off-by: Colin Cross <ccross@android.com>
Diffstat (limited to 'arch/arm/mach-tegra/platsmp.c')
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 76 |
1 files changed, 17 insertions, 59 deletions
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 7d2b5d03c1df..ae6067e7f039 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -7,101 +7,59 @@ * Copyright (C) 2009 Palm * All Rights Reserved * + * Copyright (C) 2010 NVIDIA Corporation + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#include <linux/kernel.h> #include <linux/init.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/smp.h> #include <linux/io.h> +#include <linux/smp.h> -#include <asm/cacheflush.h> #include <asm/hardware/gic.h> -#include <asm/mach-types.h> #include <asm/smp_scu.h> #include <mach/iomap.h> -extern void tegra_secondary_startup(void); - -static DEFINE_SPINLOCK(boot_lock); -static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); - #define EVP_CPU_RESET_VECTOR \ (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c) +#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \ + (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340) #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344) +extern void tegra_secondary_startup(void); + +static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); + void __cpuinit platform_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ gic_secondary_init(0); - - /* - * Synchronise with the boot thread. - */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); } int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { - unsigned long old_boot_vector; - unsigned long boot_vector; - unsigned long timeout; u32 reg; - /* - * set synchronisation state between this boot processor - * and the secondary one - */ - spin_lock(&boot_lock); - + smp_wmb(); /* set the reset vector to point to the secondary_startup routine */ + writel(virt_to_phys(tegra_secondary_startup), EVP_CPU_RESET_VECTOR); - boot_vector = virt_to_phys(tegra_secondary_startup); - old_boot_vector = readl(EVP_CPU_RESET_VECTOR); - writel(boot_vector, EVP_CPU_RESET_VECTOR); - - /* enable cpu clock on cpu1 */ + /* enable cpu clock on cpu */ reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + writel(reg & ~(1 << (8 + cpu)), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - reg = (1<<13) | (1<<9) | (1<<5) | (1<<1); + reg = 0x1111 << cpu; writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); - smp_wmb(); - flush_cache_all(); - /* unhalt the cpu */ - writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14); - - timeout = jiffies + (1 * HZ); - while (time_before(jiffies, timeout)) { - if (readl(EVP_CPU_RESET_VECTOR) != boot_vector) - break; - udelay(10); - } - - /* put the old boot vector back */ - writel(old_boot_vector, EVP_CPU_RESET_VECTOR); - - /* - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ - spin_unlock(&boot_lock); + writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14 + 0x8 * (cpu - 1)); return 0; } |