From 8fba90b4d4f400af56cf9f2e998d0562f087fcd9 Mon Sep 17 00:00:00 2001 From: Mayuresh Kulkarni Date: Sat, 20 Feb 2010 13:31:13 +0530 Subject: tegra pm: implement suspend_ops We implement suspend_ops->valid, suspend_ops->begin, suspend_ops->enter and suspend_ops->end. For suspend_ops->begin : Check if CPU1 is in reset or not. If not, reset it and maintain this state. For suspend_ops->end : Check if CPU1 was reseted by suspend_ops->begin. If yes, take it out of reset. For harmony board, add a timed wake lock as a WAR. For suspend_ops->enter : Do a odm query for lowest power state. Call the appropriate low power state (LP1/LP0) routine based on SOC type. Change-Id: I6f4be75978573bba94e95723c023abc091e06d1e --- arch/arm/mach-tegra/suspend_ops.c | 70 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 24 deletions(-) mode change 100644 => 100755 arch/arm/mach-tegra/suspend_ops.c diff --git a/arch/arm/mach-tegra/suspend_ops.c b/arch/arm/mach-tegra/suspend_ops.c old mode 100644 new mode 100755 index 0aef7afe151e..9f2a756dc3ad --- a/arch/arm/mach-tegra/suspend_ops.c +++ b/arch/arm/mach-tegra/suspend_ops.c @@ -22,10 +22,23 @@ #include #include "nvcommon.h" +#include "nvodm_query.h" +#include +#include + +extern void cpu_ap20_do_lp0(void); +extern void cpu_ap20_do_lp1(void); +extern unsigned int check_for_cpu1_reset(void); + +#if defined(CONFIG_TEGRA_ODM_HARMONY) +static struct wake_lock suspend_ops_wake_lock; +static bool wake_lock_initialized = false; +#endif + +static bool Cpu1PoweredOff = false; int tegra_state_valid(suspend_state_t state) { - printk("%s CALLED\n", __func__); if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX) return 1; return 0; @@ -33,49 +46,58 @@ int tegra_state_valid(suspend_state_t state) int tegra_state_begin(suspend_state_t state) { - printk("%s CALLED with state = %d\n", __func__, state); - return 0; -} - -int tegra_state_prepare(void) -{ - printk("%s CALLED \n", __func__); + if(check_for_cpu1_reset() == 0) { + cpu_down(1); + Cpu1PoweredOff = true; + } return 0; } int tegra_state_enter(suspend_state_t state) { - printk("%s CALLED with state = %d\n", __func__, state); - return 0; -} + const NvOdmSocPowerStateInfo *LPStateInfo; -void tegra_state_finish(void) -{ - printk("%s CALLED \n", __func__); + LPStateInfo = NvOdmQueryLowestSocPowerState(); + if (LPStateInfo->LowestPowerState == NvOdmSocPowerState_DeepSleep) { +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) + /* do AP20 LP0 */ + cpu_ap20_do_lp0(); +#endif + } + else if (LPStateInfo->LowestPowerState == NvOdmSocPowerState_Suspend) { +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) + /* do AP20 LP1 */ + cpu_ap20_do_lp1(); +#endif + } + return 0; } void tegra_state_end(void) { - printk("%s CALLED \n", __func__); -} + if(Cpu1PoweredOff) { + cpu_up(1); + Cpu1PoweredOff = false; + } -void tegra_state_recover(void) -{ - printk("%s CALLED \n", __func__); +#if defined(CONFIG_TEGRA_ODM_HARMONY) + if(!wake_lock_initialized) { + wake_lock_init(&suspend_ops_wake_lock, WAKE_LOCK_SUSPEND, "tegra_suspend_ops"); + wake_lock_initialized = true; + } + wake_lock_timeout(&suspend_ops_wake_lock, 1000); +#endif } static struct platform_suspend_ops tegra_suspend_ops = { .valid = tegra_state_valid, .begin = tegra_state_begin, - .prepare = tegra_state_prepare, .enter = tegra_state_enter, - .finish = tegra_state_finish, - .end = tegra_state_end, - .recover = tegra_state_recover + .end = tegra_state_end }; -void tegra_set_suspend_ops() +void tegra_set_suspend_ops(void) { suspend_set_ops(&tegra_suspend_ops); } -- cgit v1.2.3