summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Williams <scwilliams@nvidia.com>2011-07-25 13:24:13 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:46:58 -0800
commitb9e403190bbbe1225abd87185e7dfb4518a1e992 (patch)
tree69c8ad3a09d54f9545ea9325909db50042e54ff6
parentd177f4e51d81f29699f6041909c26ae43a27bd76 (diff)
ARM: tegra: power: Add LP2 in idle support for secondary CPUs
Change-Id: Ie557f4429d65fb4cf701935b7ea6b1190140a878 Signed-off-by: Scott Williams <scwilliams@nvidia.com> Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com> Rebase-Id: Rf03d13e909ff708671ab09077d1de590182b9917
-rw-r--r--arch/arm/mach-tegra/cpuidle-t3.c16
-rw-r--r--arch/arm/mach-tegra/sleep-t3.S16
-rw-r--r--arch/arm/mach-tegra/sleep.h1
3 files changed, 26 insertions, 7 deletions
diff --git a/arch/arm/mach-tegra/cpuidle-t3.c b/arch/arm/mach-tegra/cpuidle-t3.c
index 4f2208b7ff61..7ea1657dff6b 100644
--- a/arch/arm/mach-tegra/cpuidle-t3.c
+++ b/arch/arm/mach-tegra/cpuidle-t3.c
@@ -266,6 +266,14 @@ static void tegra3_idle_enter_lp2_cpu_n(struct cpuidle_device *dev,
s64 sleep_time = request - tegra_lp2_exit_latency;
struct tegra_twd_context twd_context;
+ if (request < tegra_lp2_exit_latency) {
+ /*
+ * Not enough time left to enter LP2
+ */
+ tegra_cpu_wfi();
+ return;
+ }
+
tegra_lp2_set_trigger(sleep_time);
idle_stats.tear_down_count[cpu_number(dev->cpu)]++;
@@ -278,13 +286,7 @@ static void tegra3_idle_enter_lp2_cpu_n(struct cpuidle_device *dev,
tegra_twd_suspend(&twd_context);
- flush_cache_all();
- barrier();
-/* !!!FIXME!!! __cortex_a9_save(0); */
- /* CPUn is powergated */
-
- /* CPUn woke up */
- barrier();
+ tegra3_sleep_cpu_secondary(PLAT_PHYS_OFFSET - PAGE_OFFSET);
tegra_cpu_wake_by_time[dev->cpu] = LLONG_MAX;
diff --git a/arch/arm/mach-tegra/sleep-t3.S b/arch/arm/mach-tegra/sleep-t3.S
index 9a089a605378..abaea8b868f1 100644
--- a/arch/arm/mach-tegra/sleep-t3.S
+++ b/arch/arm/mach-tegra/sleep-t3.S
@@ -136,6 +136,22 @@ ENTRY(tegra3_sleep_cpu)
ENDPROC(tegra3_sleep_cpu)
/*
+ * tegra3_sleep_cpu_secondary(unsigned long v2p)
+ *
+ * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
+ */
+ENTRY(tegra3_sleep_cpu_secondary)
+ mov r3, lr @ set resume address to lr
+ bl tegra_cpu_save
+ bl tegra_cpu_exit_coherency
+
+ /* Powergate this CPU. */
+ mov r0, #0 @ power mode flags (!hotplug)
+ bl tegra3_cpu_reset
+ b . @ should never get here
+ENDPROC(tegra3_sleep_cpu_secondary)
+
+/*
* tegra3_tear_down_cpu
*
* Switches the CPU cluster to PLL-P and enters sleep.
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 3caefe15f021..a6f6b1740009 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -111,6 +111,7 @@ void tegra2_sleep_wfi(unsigned long v2p);
extern void tegra3_iram_start;
extern void tegra3_iram_end;
void tegra3_sleep_core(unsigned long v2p);
+void tegra3_sleep_cpu_secondary(unsigned long v2p);
void tegra3_hotplug_shutdown(void);
#endif