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@xxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html