summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/pm.c
diff options
context:
space:
mode:
authorYudong Tan <ytan@nvidia.com>2011-08-18 15:26:52 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:48:39 -0800
commit6d76e260493dc5f8c071f6330f3f6490952125f9 (patch)
tree04e8fb9d7742ccdc9e2010119d4e95c4e5b4803a /arch/arm/mach-tegra/pm.c
parentf93887c0760e4530d3023b7682f2322ea312f3c5 (diff)
ARM: tegra: power: implement LP1 suspend/resume for Tegra3
Bug 862502 Change-Id: If70e54fb32ce14d5f13dde1d7fb4c1f1499a6722 Reviewed-on: http://git-master/r/47398 Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com> Tested-by: Daniel Willemsen <dwillemsen@nvidia.com> Rebase-Id: Ra77a54e6930692bca628a97bf1de10a30408cdef
Diffstat (limited to 'arch/arm/mach-tegra/pm.c')
-rw-r--r--arch/arm/mach-tegra/pm.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 688775531fe0..9211671984b0 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -66,6 +66,7 @@
#include "reset.h"
#include "sleep.h"
#include "timer.h"
+#include "reset.h"
struct suspend_context {
/*
@@ -99,6 +100,7 @@ static pgd_t *tegra_pgd;
static DEFINE_SPINLOCK(tegra_lp2_lock);
static cpumask_t tegra_in_lp2;
static cpumask_t *iram_cpu_lp2_mask;
+static unsigned long *iram_cpu_lp1_mask;
static u8 *iram_save;
static unsigned long iram_save_size;
static void __iomem *iram_code = IO_ADDRESS(TEGRA_IRAM_CODE_AREA);
@@ -664,8 +666,6 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
* scratch 41 to tegra_resume
*/
writel(0x0, pmc + PMC_SCRATCH39);
- __raw_writel(virt_to_phys(tegra_resume), pmc + PMC_SCRATCH41);
- wmb();
/* Enable DPD sample to trigger sampling pads data and direction
* in which pad will be driven during lp0 mode*/
@@ -678,8 +678,10 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
pmc_32kwritel(tegra_lp0_vec_start, PMC_SCRATCH1);
reg |= TEGRA_POWER_EFFECT_LP0;
- break;
+ /* No break here. LP0 code falls through to write SCRATCH41 */
case TEGRA_SUSPEND_LP1:
+ __raw_writel(virt_to_phys(tegra_resume), pmc + PMC_SCRATCH41);
+ wmb();
break;
case TEGRA_SUSPEND_LP2:
rate = clk_get_rate(tegra_pclk);
@@ -709,7 +711,7 @@ static int tegra_suspend_enter(suspend_state_t state)
if (pdata && pdata->board_suspend)
pdata->board_suspend(current_suspend_mode, TEGRA_SUSPEND_BEFORE_PERIPHERAL);
- ret = tegra_suspend_dram(current_suspend_mode);
+ ret = tegra_suspend_dram(current_suspend_mode, 0);
if (pdata && pdata->board_resume)
pdata->board_resume(current_suspend_mode, TEGRA_RESUME_AFTER_PERIPHERAL);
@@ -743,7 +745,7 @@ static void tegra_suspend_check_pwr_stats(void)
return;
}
-int tegra_suspend_dram(enum tegra_suspend_mode mode)
+int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
{
BUG_ON(mode < 0 || mode >= TEGRA_MAX_SUSPEND_MODE);
@@ -774,7 +776,11 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode)
tegra_lp0_suspend_mc();
}
- suspend_cpu_complex(0);
+ suspend_cpu_complex(flags);
+
+ if (mode == TEGRA_SUSPEND_LP1)
+ *iram_cpu_lp1_mask = 1;
+
flush_cache_all();
outer_flush_all();
outer_disable();
@@ -789,9 +795,10 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode)
if (mode == TEGRA_SUSPEND_LP0) {
tegra_lp0_resume_mc();
tegra_lp0_cpu_mode(false);
- }
+ } else if (mode == TEGRA_SUSPEND_LP1)
+ *iram_cpu_lp1_mask = 0;
- restore_cpu_complex(0);
+ restore_cpu_complex(flags);
cpu_complex_pm_exit();
cpu_pm_exit();
@@ -803,6 +810,8 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode)
tegra_common_resume();
+ pr_info("Exited suspend state %s\n", lp_state[mode]);
+
return 0;
}
@@ -1021,6 +1030,7 @@ out:
}
iram_cpu_lp2_mask = tegra_cpu_lp2_mask;
+ iram_cpu_lp1_mask = tegra_cpu_lp1_mask;
fail:
#endif
if (plat->suspend_mode == TEGRA_SUSPEND_NONE)