|
@@ -71,10 +71,43 @@ struct omap4_cpu_pm_info {
|
|
|
void (*secondary_startup)(void);
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * struct cpu_pm_ops - CPU pm operations
|
|
|
+ * @finish_suspend: CPU suspend finisher function pointer
|
|
|
+ * @resume: CPU resume function pointer
|
|
|
+ * @scu_prepare: CPU Snoop Control program function pointer
|
|
|
+ *
|
|
|
+ * Structure holds functions pointer for CPU low power operations like
|
|
|
+ * suspend, resume and scu programming.
|
|
|
+ */
|
|
|
+struct cpu_pm_ops {
|
|
|
+ int (*finish_suspend)(unsigned long cpu_state);
|
|
|
+ void (*resume)(void);
|
|
|
+ void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
|
|
|
+};
|
|
|
+
|
|
|
static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
|
|
|
static struct powerdomain *mpuss_pd;
|
|
|
static void __iomem *sar_base;
|
|
|
|
|
|
+static int default_finish_suspend(unsigned long cpu_state)
|
|
|
+{
|
|
|
+ omap_do_wfi();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void dummy_cpu_resume(void)
|
|
|
+{}
|
|
|
+
|
|
|
+static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
|
|
|
+{}
|
|
|
+
|
|
|
+struct cpu_pm_ops omap_pm_ops = {
|
|
|
+ .finish_suspend = default_finish_suspend,
|
|
|
+ .resume = dummy_cpu_resume,
|
|
|
+ .scu_prepare = dummy_scu_prepare,
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* Program the wakeup routine address for the CPU0 and CPU1
|
|
|
* used for OFF or DORMANT wakeup.
|
|
@@ -158,11 +191,12 @@ 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);
|
|
|
+ if (l2x0_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)
|
|
@@ -225,14 +259,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
|
|
|
|
|
|
cpu_clear_prev_logic_pwrst(cpu);
|
|
|
pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
|
|
|
- set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
|
|
|
- scu_pwrst_prepare(cpu, power_state);
|
|
|
+ set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume));
|
|
|
+ omap_pm_ops.scu_prepare(cpu, power_state);
|
|
|
l2x0_pwrst_prepare(cpu, save_state);
|
|
|
|
|
|
/*
|
|
|
* Call low level function with targeted low power state.
|
|
|
*/
|
|
|
- cpu_suspend(save_state, omap4_finish_suspend);
|
|
|
+ if (save_state)
|
|
|
+ cpu_suspend(save_state, omap_pm_ops.finish_suspend);
|
|
|
+ else
|
|
|
+ omap_pm_ops.finish_suspend(save_state);
|
|
|
|
|
|
/*
|
|
|
* Restore the CPUx power state to ON otherwise CPUx
|
|
@@ -268,14 +305,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
|
|
|
pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
|
|
|
pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
|
|
|
set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
|
|
|
- scu_pwrst_prepare(cpu, power_state);
|
|
|
+ omap_pm_ops.scu_prepare(cpu, power_state);
|
|
|
|
|
|
/*
|
|
|
* CPU never retuns back if targeted power state is OFF mode.
|
|
|
* CPU ONLINE follows normal CPU ONLINE ptah via
|
|
|
- * omap_secondary_startup().
|
|
|
+ * omap4_secondary_startup().
|
|
|
*/
|
|
|
- omap4_finish_suspend(cpu_state);
|
|
|
+ omap_pm_ops.finish_suspend(cpu_state);
|
|
|
|
|
|
pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
|
|
|
return 0;
|
|
@@ -319,9 +356,9 @@ int __init omap4_mpuss_init(void)
|
|
|
pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
|
|
|
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
|
|
|
if (cpu_is_omap446x())
|
|
|
- pm_info->secondary_startup = omap_secondary_startup_4460;
|
|
|
+ pm_info->secondary_startup = omap4460_secondary_startup;
|
|
|
else
|
|
|
- pm_info->secondary_startup = omap_secondary_startup;
|
|
|
+ pm_info->secondary_startup = omap4_secondary_startup;
|
|
|
|
|
|
pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
|
|
|
if (!pm_info->pwrdm) {
|
|
@@ -352,6 +389,12 @@ int __init omap4_mpuss_init(void)
|
|
|
|
|
|
save_l2x0_context();
|
|
|
|
|
|
+ if (cpu_is_omap44xx()) {
|
|
|
+ omap_pm_ops.finish_suspend = omap4_finish_suspend;
|
|
|
+ omap_pm_ops.resume = omap4_cpu_resume;
|
|
|
+ omap_pm_ops.scu_prepare = scu_pwrst_prepare;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|