msm: pm2: Add CPR specific function callbacks to PM driver
CPR(Core Power Reduction) is a new h/w block added in 8x25
2.0 revision. This block reduce the power consumption of
SOC using sensors inside the SOC. Add function callbacks to
PM driver to perform disable, enable, save and restore of
CPR context data when the core do an IdlePC.
Change-Id: I4f9ba9a06919c58c6fe2cbc8ce60267be5ce7f22
Signed-off-by: Murali Nalajala <mnalajal@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index e00f150..cf7faf1 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1187,6 +1187,7 @@
ARRAY_SIZE(msm8625_pm_data));
BUG_ON(msm_pm_boot_init(&msm_pm_8625_boot_pdata));
msm8x25_spm_device_init();
+ msm_pm_register_cpr_ops();
}
#define UART1DM_RX_GPIO 45
@@ -1265,6 +1266,7 @@
ARRAY_SIZE(msm8625_pm_data));
BUG_ON(msm_pm_boot_init(&msm_pm_8625_boot_pdata));
msm8x25_spm_device_init();
+ msm_pm_register_cpr_ops();
} else {
msm_pm_set_platform_data(msm7x27a_pm_data,
ARRAY_SIZE(msm7x27a_pm_data));
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 1da9ede..fc476fb 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -1115,6 +1115,7 @@
ARRAY_SIZE(msm8625_pm_data));
BUG_ON(msm_pm_boot_init(&msm_pm_8625_boot_pdata));
msm8x25_spm_device_init();
+ msm_pm_register_cpr_ops();
}
}
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 27de697..2de0215 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -509,6 +509,19 @@
}
+static struct msm_pm_cpr_ops msm8625_pm_cpr_ops = {
+ .cpr_suspend = msm_cpr_pm_suspend,
+ .cpr_resume = msm_cpr_pm_resume,
+};
+
+void __init msm_pm_register_cpr_ops(void)
+{
+ /* CPR presents on revision >= v2.0 chipsets */
+ if (cpu_is_msm8625() &&
+ SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
+ msm_pm_set_cpr_ops(&msm8625_pm_cpr_ops);
+}
+
#define MSM_SDC1_BASE 0xA0400000
#define MSM_SDC2_BASE 0xA0500000
#define MSM_SDC3_BASE 0xA0600000
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index 8febe26..8b59b14 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -31,6 +31,7 @@
void __init msm8625_map_io(void);
int ar600x_wlan_power(bool on);
void __init msm8x25_spm_device_init(void);
+void __init msm_pm_register_cpr_ops(void);
void __init msm8x25_kgsl_3d0_init(void);
void __iomem *core1_reset_base(void);
extern void setup_mm_for_reboot(void);
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 4dd6df3..552fb16 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -80,6 +80,11 @@
bool notify_rpm, bool collapsed);
};
+struct msm_pm_cpr_ops {
+ void (*cpr_suspend)(void);
+ void (*cpr_resume)(void);
+};
+
void msm_pm_set_platform_data(struct msm_pm_platform_data *data, int count);
int msm_pm_idle_prepare(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index);
@@ -125,4 +130,6 @@
static inline void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t) {}
#endif
+void msm_pm_set_cpr_ops(struct msm_pm_cpr_ops *ops);
+
#endif /* __ARCH_ARM_MACH_MSM_PM_H */
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 8fccda4..10c5445 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -152,6 +152,7 @@
static struct msm_pm_platform_data *msm_pm_modes;
static struct msm_pm_irq_calls *msm_pm_irq_extns;
+static struct msm_pm_cpr_ops *msm_cpr_ops;
struct msm_pm_kobj_attribute {
unsigned int cpu;
@@ -415,6 +416,11 @@
msm_pm_irq_extns = irq_calls;
}
+void __init msm_pm_set_cpr_ops(struct msm_pm_cpr_ops *ops)
+{
+ msm_cpr_ops = ops;
+}
+
/******************************************************************************
* Sleep Limitations
*****************************************************************************/
@@ -876,6 +882,10 @@
WARN_ON(ret);
}
+ /* Call CPR suspend only for "idlePC" case */
+ if (msm_cpr_ops && from_idle)
+ msm_cpr_ops->cpr_suspend();
+
msm_pm_irq_extns->enter_sleep1(true, from_idle,
&msm_pm_smem_data->irq_mask);
msm_sirc_enter_sleep();
@@ -1113,6 +1123,10 @@
WARN_ON(ret);
}
+ /* Call CPR resume only for "idlePC" case */
+ if (msm_cpr_ops && from_idle)
+ msm_cpr_ops->cpr_resume();
+
return 0;
power_collapse_early_exit:
@@ -1165,6 +1179,10 @@
if (collapsed)
smd_sleep_exit();
+ /* Call CPR resume only for "idlePC" case */
+ if (msm_cpr_ops && from_idle)
+ msm_cpr_ops->cpr_resume();
+
power_collapse_bail:
if (cpu_is_msm8625()) {
ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING,