summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-05-12 22:51:34 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-05-18 12:02:11 -0700
commit6c7f0ecfe90d1b3c56d1616762acee6231f5a726 (patch)
tree4a542fcb590cc9510ed51b46c70606a01f375154
parent0da4df6d395e7e693c45d92d6d82be9e49ec7bb7 (diff)
ARM: tegra: power: Use CPU LP mode for Tegra3 deep sleep
Change-Id: If23b48fb414332f5dd25307a098569a5474283c6 Reviewed-on: http://git-master/r/31471 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/power.h2
-rw-r--r--arch/arm/mach-tegra/suspend-t3.c20
-rw-r--r--arch/arm/mach-tegra/suspend.c2
3 files changed, 22 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/power.h
index 2cade3c13106..580eb1913335 100644
--- a/arch/arm/mach-tegra/power.h
+++ b/arch/arm/mach-tegra/power.h
@@ -196,6 +196,7 @@ static inline bool tegra_lp2_is_allowed(struct cpuidle_device *dev,
{ return true; }
#define tegra_lp0_suspend_mc() do {} while (0)
#define tegra_lp0_resume_mc() do {} while (0)
+#define tegra_lp0_cpu_mode(enter) do {} while (0)
#else
#define INSTRUMENT_CLUSTER_SWITCH 1 /* Should be zero for shipping code */
#define DEBUG_CLUSTER_SWITCH 1 /* Should be zero for shipping code */
@@ -221,6 +222,7 @@ bool tegra_lp2_is_allowed(struct cpuidle_device *dev,
struct cpuidle_state *state);
void tegra_lp0_suspend_mc(void);
void tegra_lp0_resume_mc(void);
+void tegra_lp0_cpu_mode(bool enter);
#endif
#if DEBUG_CLUSTER_SWITCH
extern unsigned int tegra_cluster_debug;
diff --git a/arch/arm/mach-tegra/suspend-t3.c b/arch/arm/mach-tegra/suspend-t3.c
index eac364f44b75..d67662bff417 100644
--- a/arch/arm/mach-tegra/suspend-t3.c
+++ b/arch/arm/mach-tegra/suspend-t3.c
@@ -270,6 +270,7 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
unsigned int current_cluster = is_lp_cluster()
? TEGRA_POWER_CLUSTER_LP
: TEGRA_POWER_CLUSTER_G;
+ unsigned long irq_flags;
if ((target_cluster == TEGRA_POWER_CLUSTER_MASK) || !target_cluster)
return -EINVAL;
@@ -296,7 +297,7 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
(flags & TEGRA_POWER_CLUSTER_FORCE) ? "force" : "",
us));
- local_irq_disable();
+ local_irq_save(irq_flags);
#ifdef CONFIG_PM
if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
if (us)
@@ -309,7 +310,7 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
} else
#endif
tegra_suspend_lp2(us, flags);
- local_irq_enable();
+ local_irq_restore(irq_flags);
DEBUG_CLUSTER(("%s: %s\r\n", __func__, is_lp_cluster() ? "LP" : "G"));
@@ -405,3 +406,18 @@ void tegra_lp0_resume_mc(void)
writel(mc_reserved_rsv, mc + MC_RESERVED_RSV);
writel(mc_emem_arb_override, mc + MC_EMEM_ARB_OVERRIDE);
}
+
+void tegra_lp0_cpu_mode(bool enter)
+{
+ static bool entered_on_g = false;
+ unsigned int flags;
+
+ if (enter)
+ entered_on_g = !is_lp_cluster();
+
+ if (entered_on_g) {
+ flags = enter ? TEGRA_POWER_CLUSTER_LP : TEGRA_POWER_CLUSTER_G;
+ flags |= TEGRA_POWER_CLUSTER_IMMEDIATE;
+ tegra_cluster_control(0, flags);
+ }
+}
diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c
index a67ad9e8ee99..6ec768901027 100644
--- a/arch/arm/mach-tegra/suspend.c
+++ b/arch/arm/mach-tegra/suspend.c
@@ -875,6 +875,7 @@ static int tegra_suspend_enter(suspend_state_t state)
pr_info("Entering suspend state LP%d\n", lp_state);
if (do_lp0) {
+ tegra_lp0_cpu_mode(true);
tegra_irq_suspend();
tegra_dma_suspend();
tegra_debug_uart_suspend();
@@ -931,6 +932,7 @@ static int tegra_suspend_enter(suspend_state_t state)
tegra_debug_uart_resume();
tegra_dma_resume();
tegra_irq_resume();
+ tegra_lp0_cpu_mode(false);
}
secs = rtc_after - rtc_before;