aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2011-07-08 01:45:47 -0700
committerNishanth Menon <nm@ti.com>2011-07-10 23:20:34 -0700
commit6a2b03494e9cab723836442dc7f31e5b905a0009 (patch)
tree5a53bea6c6416ae2d6d837084189e230ecb296bf /arch
parent5ee70d0fa6dba7a9dd1ec642a977cd032ffcae88 (diff)
downloadkernel_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.h4
-rw-r--r--arch/arm/mach-omap2/vc.c60
-rw-r--r--arch/arm/mach-omap2/vc.h28
-rw-r--r--arch/arm/mach-omap2/vc3xxx_data.c16
-rw-r--r--arch/arm/mach-omap2/vc44xx_data.c17
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,
};