diff options
author | Nishanth Menon <nm@ti.com> | 2011-07-08 01:45:47 -0700 |
---|---|---|
committer | Nishanth Menon <nm@ti.com> | 2011-07-10 23:20:34 -0700 |
commit | 6a2b03494e9cab723836442dc7f31e5b905a0009 (patch) | |
tree | 5a53bea6c6416ae2d6d837084189e230ecb296bf /arch | |
parent | 5ee70d0fa6dba7a9dd1ec642a977cd032ffcae88 (diff) | |
download | kernel_samsung_tuna-6a2b03494e9cab723836442dc7f31e5b905a0009.zip kernel_samsung_tuna-6a2b03494e9cab723836442dc7f31e5b905a0009.tar.gz kernel_samsung_tuna-6a2b03494e9cab723836442dc7f31e5b905a0009.tar.bz2 |
OMAP3+: VC: add ability for auto transition
Auto transition is an ability on OMAP3+ devices with SmartReflex
capability to be able to automatically command a specific voltage
in reaction to a device/domain wide power state transition. In order
to support this variance in OMAP3 and OMAP4 devices, we provide a
new API to allow SoC specific OMAP PM code to program required
domain transition as they are detected.
Signed-off-by: Nishanth Menon <nm@ti.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/prm-regbits-44xx.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc.h | 28 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc3xxx_data.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc44xx_data.c | 17 |
5 files changed, 125 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h index 175412a..d9b8320 100644 --- a/arch/arm/mach-omap2/prm-regbits-44xx.h +++ b/arch/arm/mach-omap2/prm-regbits-44xx.h @@ -92,6 +92,10 @@ #define OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT 2 #define OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK (0x3 << 2) +/* Used by PRM_VOLTCTRL */ +#define OMAP4430_AUTO_CTRL_VDD_RET_MASK (1 << 1) +#define OMAP4430_AUTO_CTRL_VDD_SLEEP_MASK (1 << 0) + /* Used by PRM_VC_ERRST */ #define OMAP4430_BYPS_RA_ERR_SHIFT 25 #define OMAP4430_BYPS_RA_ERR_MASK (1 << 25) diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 2cf520d..1b0562a 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -132,6 +132,66 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm, return 0; } +/** + * omap_vc_set_auto_trans() - set auto transition parameters for a domain + * @voltdm: voltage domain we are interested in + * @flag: which state should we program this to + */ +int omap_vc_set_auto_trans(struct voltagedomain *voltdm, u8 flag) +{ + struct omap_vc_channel *vc; + const struct omap_vc_auto_trans *auto_trans; + u8 val = OMAP_VC_CHANNEL_AUTO_TRANSITION_UNSUPPORTED; + + if (!voltdm) { + pr_err("%s: NULL Voltage domain!\n", __func__); + return -ENOENT; + } + vc = voltdm->vc; + if (!vc) { + pr_err("%s: NULL VC Voltage domain %s!\n", __func__, + voltdm->name); + return -ENOENT; + } + + auto_trans = vc->auto_trans; + if (!auto_trans) { + pr_debug("%s: No auto trans %s!\n", __func__, voltdm->name); + return 0; + } + + /* Handle value and masks per silicon data */ + switch (flag) { + case OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE: + val = 0x0; + break; + case OMAP_VC_CHANNEL_AUTO_TRANSITION_SLEEP: + val = auto_trans->sleep_val; + break; + case OMAP_VC_CHANNEL_AUTO_TRANSITION_RETENTION: + val = auto_trans->retention_val; + break; + case OMAP_VC_CHANNEL_AUTO_TRANSITION_OFF: + val = auto_trans->off_val; + break; + default: + pr_err("%s: Voltdm %s invalid flag %d\n", __func__, + voltdm->name, flag); + return -EINVAL; + } + + if (val == OMAP_VC_CHANNEL_AUTO_TRANSITION_UNSUPPORTED) { + pr_err("%s: transition to %d on %s is NOT supported\n", + __func__, flag, voltdm->name); + return -EINVAL; + } + + /* All ready - set it and move on.. */ + voltdm->rmw(vc->auto_trans_mask, val << __ffs(vc->auto_trans_mask), + auto_trans->reg); + return 0; +} + void omap_vc_post_scale(struct voltagedomain *voltdm, unsigned long target_volt, u8 target_vsel, u8 current_vsel) diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h index cf20f47..fc042e4 100644 --- a/arch/arm/mach-omap2/vc.h +++ b/arch/arm/mach-omap2/vc.h @@ -62,6 +62,20 @@ struct omap_vc_common { u8 i2c_mcode_mask; }; +/** + * struct omap_vc_auto_trans - describe the auto transition for the domain + * @reg: register to modify (usually PRM_VOLTCTRL) + * @sleep_val: value to set for enabling sleep transition + * @retention_val: value to set for enabling retention transition + * @off_val: value to set for enabling off transition + */ +struct omap_vc_auto_trans { + u8 reg; + u8 sleep_val; + u8 retention_val; + u8 off_val; +}; + /* omap_vc_channel.flags values */ #define OMAP_VC_CHANNEL_DEFAULT BIT(0) #define OMAP_VC_CHANNEL_CFG_MUTANT BIT(1) @@ -72,6 +86,8 @@ struct omap_vc_common { * @common: pointer to VC common data for this platform * @smps_sa_mask: i2c slave address bitmask in the PRM_VC_SMPS_SA register * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register + * @auto_trans: Auto transition information + * @auto_trans_mask: Auto transition mask for this channel */ struct omap_vc_channel { u8 flags; @@ -91,6 +107,9 @@ struct omap_vc_channel { u32 smps_cmdra_mask; u8 cmdval_reg; u8 cfg_channel_sa_shift; + + const struct omap_vc_auto_trans *auto_trans; + u32 auto_trans_mask; }; extern struct omap_vc_channel omap3_vc_mpu; @@ -107,6 +126,15 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm, void omap_vc_post_scale(struct voltagedomain *voltdm, unsigned long target_volt, u8 target_vsel, u8 current_vsel); + +/* Auto transition flags for users */ +#define OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE 0 +#define OMAP_VC_CHANNEL_AUTO_TRANSITION_SLEEP 1 +#define OMAP_VC_CHANNEL_AUTO_TRANSITION_RETENTION 2 +#define OMAP_VC_CHANNEL_AUTO_TRANSITION_OFF 3 +/* For silicon data to mark unsupported transition */ +#define OMAP_VC_CHANNEL_AUTO_TRANSITION_UNSUPPORTED 0xff +int omap_vc_set_auto_trans(struct voltagedomain *voltdm, u8 flag); int omap_vc_bypass_scale_voltage(struct voltagedomain *voltdm, unsigned long target_volt); int omap_vc_bypass_send_i2c_msg(struct voltagedomain *voltdm, diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c index 95d7701..c21d3f5 100644 --- a/arch/arm/mach-omap2/vc3xxx_data.c +++ b/arch/arm/mach-omap2/vc3xxx_data.c @@ -49,6 +49,18 @@ static struct omap_vc_common omap3_vc_common = { .i2c_mcode_mask = OMAP3430_MCODE_MASK, }; +/* + * VC auto transition settings for OMAP3. On OMAP3, we just have a single + * device wide state that is achieved on core, so we shall use this data + * only for core domain transition + */ +static const struct omap_vc_auto_trans omap3_vc_auto_trans = { + .reg = OMAP3_PRM_VOLTCTRL_OFFSET, + .sleep_val = OMAP3430_AUTO_SLEEP_MASK, + .retention_val = OMAP3430_AUTO_RET_MASK, + .off_val = OMAP3430_AUTO_OFF_MASK, +}; + struct omap_vc_channel omap3_vc_mpu = { .common = &omap3_vc_common, .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET, @@ -65,4 +77,8 @@ struct omap_vc_channel omap3_vc_core = { .smps_volra_mask = OMAP3430_VOLRA1_MASK, .smps_cmdra_mask = OMAP3430_CMDRA1_MASK, .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT, + + .auto_trans = &omap3_vc_auto_trans, + .auto_trans_mask = OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK | + OMAP3430_AUTO_SLEEP_MASK, }; diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c index 0a4fc37..3757d4f 100644 --- a/arch/arm/mach-omap2/vc44xx_data.c +++ b/arch/arm/mach-omap2/vc44xx_data.c @@ -50,6 +50,14 @@ static const struct omap_vc_common omap4_vc_common = { .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, }; +/* VC auto transition settings for OMAP4. */ +static const struct omap_vc_auto_trans omap4_vc_auto_trans = { + .reg = OMAP4_PRM_VOLTCTRL_OFFSET, + .sleep_val = OMAP4430_AUTO_CTRL_VDD_SLEEP_MASK, + .retention_val = OMAP4430_AUTO_CTRL_VDD_RET_MASK, + .off_val = OMAP_VC_CHANNEL_AUTO_TRANSITION_UNSUPPORTED, +}; + /* VC instance data for each controllable voltage line */ struct omap_vc_channel omap4_vc_mpu = { .flags = OMAP_VC_CHANNEL_DEFAULT | OMAP_VC_CHANNEL_CFG_MUTANT, @@ -59,6 +67,9 @@ 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, + + .auto_trans = &omap4_vc_auto_trans, + .auto_trans_mask = OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK, }; struct omap_vc_channel omap4_vc_iva = { @@ -68,6 +79,9 @@ 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, + + .auto_trans = &omap4_vc_auto_trans, + .auto_trans_mask = OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK, }; struct omap_vc_channel omap4_vc_core = { @@ -77,5 +91,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, + + .auto_trans = &omap4_vc_auto_trans, + .auto_trans_mask = OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK, }; |