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.
Signed-off-by: Murali Nalajala <mnalajal@codeaurora.org>
(cherry picked from commit ff723ece018452e722155daa67ff0fdd65cc5c96)
Change-Id: Ideb6300ce1afe9976853e47ab9f1eec2ef22c77e
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 5e6b0cc..866e777 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1229,6 +1229,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
@@ -1307,6 +1308,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 b441412..fbba857 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -1157,6 +1157,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 1fcf7dc..72b1535 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -501,6 +501,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 c722ff6..21491c2 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);
@@ -124,4 +129,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,