aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap-smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/omap-smp.c')
-rw-r--r--arch/arm/mach-omap2/omap-smp.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index e99bc6cd471..c1bf3ef0ba0 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -24,17 +24,37 @@
24#include <asm/hardware/gic.h> 24#include <asm/hardware/gic.h>
25#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/omap-secure.h>
27 28
28#include "common.h" 29#include "common.h"
29 30
31#include "clockdomain.h"
32
30/* SCU base address */ 33/* SCU base address */
31static void __iomem *scu_base; 34static void __iomem *scu_base;
32 35
33static DEFINE_SPINLOCK(boot_lock); 36static DEFINE_SPINLOCK(boot_lock);
34 37
38void __iomem *omap4_get_scu_base(void)
39{
40 return scu_base;
41}
42
35void __cpuinit platform_secondary_init(unsigned int cpu) 43void __cpuinit platform_secondary_init(unsigned int cpu)
36{ 44{
37 /* 45 /*
46 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
47 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
48 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
49 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
50 * OMAP443X GP devices- SMP bit isn't accessible.
51 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
52 */
53 if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
54 omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
55 4, 0, 0, 0, 0, 0);
56
57 /*
38 * If any interrupts are already enabled for the primary 58 * If any interrupts are already enabled for the primary
39 * core (e.g. timer irq), then they will not have been enabled 59 * core (e.g. timer irq), then they will not have been enabled
40 * for us: do so 60 * for us: do so
@@ -50,6 +70,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
50 70
51int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 71int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
52{ 72{
73 static struct clockdomain *cpu1_clkdm;
74 static bool booted;
53 /* 75 /*
54 * Set synchronisation state between this boot processor 76 * Set synchronisation state between this boot processor
55 * and the secondary one 77 * and the secondary one
@@ -65,6 +87,29 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
65 omap_modify_auxcoreboot0(0x200, 0xfffffdff); 87 omap_modify_auxcoreboot0(0x200, 0xfffffdff);
66 flush_cache_all(); 88 flush_cache_all();
67 smp_wmb(); 89 smp_wmb();
90
91 if (!cpu1_clkdm)
92 cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
93
94 /*
95 * The SGI(Software Generated Interrupts) are not wakeup capable
96 * from low power states. This is known limitation on OMAP4 and
97 * needs to be worked around by using software forced clockdomain
98 * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to
99 * software force wakeup. The clockdomain is then put back to
100 * hardware supervised mode.
101 * More details can be found in OMAP4430 TRM - Version J
102 * Section :
103 * 4.3.4.2 Power States of CPU0 and CPU1
104 */
105 if (booted) {
106 clkdm_wakeup(cpu1_clkdm);
107 clkdm_allow_idle(cpu1_clkdm);
108 } else {
109 dsb_sev();
110 booted = true;
111 }
112
68 gic_raise_softirq(cpumask_of(cpu), 1); 113 gic_raise_softirq(cpumask_of(cpu), 1);
69 114
70 /* 115 /*