diff options
author | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2011-01-09 00:29:09 +0300 |
---|---|---|
committer | Kevin Hilman <khilman@ti.com> | 2011-12-08 23:29:01 +0400 |
commit | 5e94c6e33e7c4726ef09f46c267e9ca232c5148a (patch) | |
tree | ea13686167925b0a3f9e67ae02817cbb6986e0fc /arch/arm/mach-omap2/omap-mpuss-lowpower.c | |
parent | 0f3cf2ec81aeb4747624954bae2cc8decc48e12f (diff) | |
download | linux-5e94c6e33e7c4726ef09f46c267e9ca232c5148a.tar.xz |
ARM: OMAP4: PM: Add L2X0 cache lowpower support
When MPUSS hits off-mode, L2 cache is lost. This patch adds L2X0
necessary maintenance operations and context restoration in the
low power code.
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Jean Pihet <j-pihet@ti.com>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Tested-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap-mpuss-lowpower.c')
-rw-r--r-- | arch/arm/mach-omap2/omap-mpuss-lowpower.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index f9bb2b3d977b..907a048fe5e9 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -49,6 +49,7 @@ #include <asm/system.h> #include <asm/pgalloc.h> #include <asm/suspend.h> +#include <asm/hardware/cache-l2x0.h> #include <plat/omap44xx.h> @@ -63,10 +64,12 @@ struct omap4_cpu_pm_info { struct powerdomain *pwrdm; void __iomem *scu_sar_addr; void __iomem *wkup_sar_addr; + void __iomem *l2x0_sar_addr; }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); static struct powerdomain *mpuss_pd; +static void __iomem *sar_base; /* * Program the wakeup routine address for the CPU0 and CPU1 @@ -135,6 +138,36 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) __raw_writel(scu_pwr_st, pm_info->scu_sar_addr); } +/* + * Store the CPU cluster state for L2X0 low power operations. + */ +static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + __raw_writel(save_state, pm_info->l2x0_sar_addr); +} + +/* + * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to + * in every restore MPUSS OFF path. + */ +#ifdef CONFIG_CACHE_L2X0 +static void save_l2x0_context(void) +{ + u32 val; + void __iomem *l2x0_base = omap4_get_l2cache_base(); + + val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); + __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); + val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); + __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); +} +#else +static void save_l2x0_context(void) +{} +#endif + /** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming @@ -182,6 +215,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) set_cpu_next_pwrst(cpu, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); scu_pwrst_prepare(cpu, power_state); + l2x0_pwrst_prepare(cpu, save_state); /* * Call low level function with targeted low power state. @@ -239,17 +273,19 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) int __init omap4_mpuss_init(void) { struct omap4_cpu_pm_info *pm_info; - void __iomem *sar_base = omap4_get_sar_ram_base(); if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); return -ENODEV; } + sar_base = omap4_get_sar_ram_base(); + /* Initilaise per CPU PM information */ pm_info = &per_cpu(omap4_pm_info, 0x0); pm_info->scu_sar_addr = sar_base + SCU_OFFSET0; pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0; pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm"); if (!pm_info->pwrdm) { pr_err("Lookup failed for CPU0 pwrdm\n"); @@ -265,6 +301,7 @@ int __init omap4_mpuss_init(void) pm_info = &per_cpu(omap4_pm_info, 0x1); pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { pr_err("Lookup failed for CPU1 pwrdm\n"); @@ -290,6 +327,8 @@ int __init omap4_mpuss_init(void) else __raw_writel(0, sar_base + OMAP_TYPE_OFFSET); + save_l2x0_context(); + return 0; } |