diff options
author | Alex Frid <afrid@nvidia.com> | 2011-05-12 22:51:34 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-05-18 12:02:11 -0700 |
commit | 6c7f0ecfe90d1b3c56d1616762acee6231f5a726 (patch) | |
tree | 4a542fcb590cc9510ed51b46c70606a01f375154 | |
parent | 0da4df6d395e7e693c45d92d6d82be9e49ec7bb7 (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.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/suspend-t3.c | 20 | ||||
-rw-r--r-- | arch/arm/mach-tegra/suspend.c | 2 |
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; |