[PATCHv7 21/21] ARM: OMAP4: vc: auto retention support
Tero Kristo
t-kristo at ti.com
Tue Sep 25 12:33:53 EDT 2012
This patch adds callbacks for the voltdm sleep / wakeups, which are now
used for enabling / disabling auto retention voltage control. Once a
voltage domain is ready to idle, its auto retention mode is enabled.
Signed-off-by: Tero Kristo <t-kristo at ti.com>
---
arch/arm/mach-omap2/prm-regbits-44xx.h | 5 +++
arch/arm/mach-omap2/vc.c | 52 ++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/vc.h | 4 ++
arch/arm/mach-omap2/vc44xx_data.c | 6 ++++
4 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h
index 3cb247b..15b9599 100644
--- a/arch/arm/mach-omap2/prm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-44xx.h
@@ -81,6 +81,11 @@
#define OMAP4430_AIPOFF_MASK (1 << 8)
/* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_DISABLED 0
+#define OMAP4430_AUTO_CTRL_VDD_SLEEP 1
+#define OMAP4430_AUTO_CTRL_VDD_RET 2
+
+/* Used by PRM_VOLTCTRL */
#define OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT 0
#define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK (0x3 << 0)
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index d217bbf..c607a0c 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -568,11 +568,63 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
}
+/**
+ * omap4_vc_sleep - voltagedomain sleep entry callback
+ * @voltdm: domain which is entering idle
+ *
+ * This function is called once a voltagedomain is ready to enter idle.
+ * Sets up AUTO_RET / AUTO_SLEEP command to be sent through the I2C
+ * to the PMIC.
+ */
+static void omap4_vc_sleep(struct voltagedomain *voltdm)
+{
+ u32 val;
+ u32 voltctrl;
+
+ switch (voltdm->target_state) {
+ case PWRDM_POWER_OFF:
+ case PWRDM_POWER_RET:
+ val = OMAP4430_AUTO_CTRL_VDD_RET;
+ break;
+ default:
+ val = OMAP4430_AUTO_CTRL_VDD_SLEEP;
+ break;
+ }
+ voltctrl = voltdm->read(OMAP4_PRM_VOLTCTRL_OFFSET);
+
+ voltctrl &= ~(u32)voltdm->vc->voltctrl_mask;
+
+ voltctrl |= val << voltdm->vc->voltctrl_shift;
+
+ voltdm->write(voltctrl, OMAP4_PRM_VOLTCTRL_OFFSET);
+}
+
+/**
+ * omap4_vc_wakeup - voltagedomain wakeup callback
+ * @voltdm: domain which is leaving idle
+ *
+ * This function is called once a voltagedomain is becoming active.
+ * Disables AUTO_RET / AUTO_SLEEP for the domain.
+ */
+static void omap4_vc_wakeup(struct voltagedomain *voltdm)
+{
+ u32 voltctrl;
+
+ voltctrl = voltdm->read(OMAP4_PRM_VOLTCTRL_OFFSET);
+
+ voltctrl &= ~(u32)voltdm->vc->voltctrl_mask;
+
+ voltdm->write(voltctrl, OMAP4_PRM_VOLTCTRL_OFFSET);
+}
+
/* OMAP4 specific voltage init functions */
static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
{
omap4_set_timings(voltdm, true);
omap4_set_timings(voltdm, false);
+
+ voltdm->sleep = omap4_vc_sleep;
+ voltdm->wakeup = omap4_vc_wakeup;
}
struct i2c_init_data {
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index 91c8d75..8357d57 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -79,6 +79,8 @@ struct omap_vc_common {
* @smps_cmdra_reg: Offset of PRM_VC_SMPS_CMD_RA reg from PRM start
* @cfg_channel_reg: VC channel configuration register
* @cfg_channel_sa_shift: bit shift for slave address cfg_channel register
+ * @voltctrl_shift: bit shift for voltctrl register field
+ * @voltctrl_mask: bit mask for voltctrl register field
* @flags: VC channel-specific flags (optional)
*/
struct omap_vc_channel {
@@ -100,6 +102,8 @@ struct omap_vc_channel {
u8 smps_cmdra_reg;
u8 cfg_channel_reg;
u8 cfg_channel_sa_shift;
+ u8 voltctrl_shift;
+ u8 voltctrl_mask;
u8 flags;
};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
index 085e5d6..a003a1f 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -59,6 +59,8 @@ struct omap_vc_channel omap4_vc_mpu = {
.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK,
.cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT,
+ .voltctrl_shift = OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT,
+ .voltctrl_mask = OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK,
};
struct omap_vc_channel omap4_vc_iva = {
@@ -72,6 +74,8 @@ struct omap_vc_channel omap4_vc_iva = {
.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK,
.cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT,
+ .voltctrl_shift = OMAP4430_AUTO_CTRL_VDD_IVA_L_SHIFT,
+ .voltctrl_mask = OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK,
};
struct omap_vc_channel omap4_vc_core = {
@@ -85,6 +89,8 @@ struct omap_vc_channel omap4_vc_core = {
.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK,
.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
+ .voltctrl_shift = OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT,
+ .voltctrl_mask = OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK,
};
/*
--
1.7.4.1
More information about the linux-arm-kernel
mailing list