aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2012-04-30 10:08:29 -0700
committerTony Lindgren <tony@atomide.com>2012-04-30 10:08:29 -0700
commita8822e2d570bc265c9fa0347710fbcc7bef8b327 (patch)
tree4a5b198d5ab6bdde620f9dbe8282a10604a204a4
parent69964ea4c7b68c9399f7977aa5b9aa6539a6a98a (diff)
parent39358f2b57f37fe079eff4159307c844a0bfb176 (diff)
Merge branch 'for_3.4/pm/smps-regulator' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into pm-regulatoromap-pm-regulator-for-v3.5
Conflicts: arch/arm/mach-omap2/twl-common.c
-rw-r--r--arch/arm/mach-omap2/twl-common.c147
-rw-r--r--arch/arm/mach-omap2/vc3xxx_data.c1
-rw-r--r--arch/arm/mach-omap2/voltage.c21
3 files changed, 166 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 7a7b89304c48..ee6596b45214 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -31,6 +31,7 @@
#include "twl-common.h"
#include "pm.h"
+#include "voltage.h"
static struct i2c_board_info __initdata pmic_i2c_board_info = {
.addr = 0x48,
@@ -47,6 +48,18 @@ static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
},
};
+static int twl_set_voltage(void *data, int target_uV)
+{
+ struct voltagedomain *voltdm = (struct voltagedomain *)data;
+ return voltdm_scale(voltdm, target_uV);
+}
+
+static int twl_get_voltage(void *data)
+{
+ struct voltagedomain *voltdm = (struct voltagedomain *)data;
+ return voltdm_get_voltage(voltdm);
+}
+
void __init omap_pmic_init(int bus, u32 clkrate,
const char *pmic_type, int pmic_irq,
struct twl4030_platform_data *pmic_data)
@@ -153,6 +166,48 @@ static struct regulator_init_data omap3_vpll2_idata = {
.consumer_supplies = omap3_vpll2_supplies,
};
+static struct regulator_consumer_supply omap3_vdd1_supply[] = {
+ REGULATOR_SUPPLY("vcc", "mpu.0"),
+};
+
+static struct regulator_consumer_supply omap3_vdd2_supply[] = {
+ REGULATOR_SUPPLY("vcc", "l3_main.0"),
+};
+
+static struct regulator_init_data omap3_vdd1 = {
+ .constraints = {
+ .name = "vdd_mpu_iva",
+ .min_uV = 600000,
+ .max_uV = 1450000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3_vdd1_supply),
+ .consumer_supplies = omap3_vdd1_supply,
+};
+
+static struct regulator_init_data omap3_vdd2 = {
+ .constraints = {
+ .name = "vdd_core",
+ .min_uV = 600000,
+ .max_uV = 1450000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3_vdd2_supply),
+ .consumer_supplies = omap3_vdd2_supply,
+};
+
+static struct twl_regulator_driver_data omap3_vdd1_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+static struct twl_regulator_driver_data omap3_vdd2_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags)
{
@@ -160,6 +215,16 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
pmic_data->irq_base = TWL4030_IRQ_BASE;
if (!pmic_data->irq_end)
pmic_data->irq_end = TWL4030_IRQ_END;
+ if (!pmic_data->vdd1) {
+ omap3_vdd1.driver_data = &omap3_vdd1_drvdata;
+ omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva");
+ pmic_data->vdd1 = &omap3_vdd1;
+ }
+ if (!pmic_data->vdd2) {
+ omap3_vdd2.driver_data = &omap3_vdd2_drvdata;
+ omap3_vdd2_drvdata.data = voltdm_lookup("core");
+ pmic_data->vdd2 = &omap3_vdd2;
+ }
/* Common platform data configurations */
if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
@@ -310,6 +375,70 @@ static struct regulator_init_data omap4_clk32kg_idata = {
},
};
+static struct regulator_consumer_supply omap4_vdd1_supply[] = {
+ REGULATOR_SUPPLY("vcc", "mpu.0"),
+};
+
+static struct regulator_consumer_supply omap4_vdd2_supply[] = {
+ REGULATOR_SUPPLY("vcc", "iva.0"),
+};
+
+static struct regulator_consumer_supply omap4_vdd3_supply[] = {
+ REGULATOR_SUPPLY("vcc", "l3_main.0"),
+};
+
+static struct regulator_init_data omap4_vdd1 = {
+ .constraints = {
+ .name = "vdd_mpu",
+ .min_uV = 500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vdd1_supply),
+ .consumer_supplies = omap4_vdd1_supply,
+};
+
+static struct regulator_init_data omap4_vdd2 = {
+ .constraints = {
+ .name = "vdd_iva",
+ .min_uV = 500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vdd2_supply),
+ .consumer_supplies = omap4_vdd2_supply,
+};
+
+static struct regulator_init_data omap4_vdd3 = {
+ .constraints = {
+ .name = "vdd_core",
+ .min_uV = 500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vdd3_supply),
+ .consumer_supplies = omap4_vdd3_supply,
+};
+
+
+static struct twl_regulator_driver_data omap4_vdd1_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+static struct twl_regulator_driver_data omap4_vdd2_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
+static struct twl_regulator_driver_data omap4_vdd3_drvdata = {
+ .get_voltage = twl_get_voltage,
+ .set_voltage = twl_set_voltage,
+};
+
void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags)
{
@@ -318,6 +447,24 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
if (!pmic_data->irq_end)
pmic_data->irq_end = TWL6030_IRQ_END;
+ if (!pmic_data->vdd1) {
+ omap4_vdd1.driver_data = &omap4_vdd1_drvdata;
+ omap4_vdd1_drvdata.data = voltdm_lookup("mpu");
+ pmic_data->vdd1 = &omap4_vdd1;
+ }
+
+ if (!pmic_data->vdd2) {
+ omap4_vdd2.driver_data = &omap4_vdd2_drvdata;
+ omap4_vdd2_drvdata.data = voltdm_lookup("iva");
+ pmic_data->vdd2 = &omap4_vdd2;
+ }
+
+ if (!pmic_data->vdd3) {
+ omap4_vdd3.driver_data = &omap4_vdd3_drvdata;
+ omap4_vdd3_drvdata.data = voltdm_lookup("core");
+ pmic_data->vdd3 = &omap4_vdd3;
+ }
+
/* Common platform data configurations */
if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
pmic_data->usb = &omap4_usb_pdata;
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index a5ec7f8f2ea8..5d8eaf31569c 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -46,6 +46,7 @@ static struct omap_vc_common omap3_vc_common = {
};
struct omap_vc_channel omap3_vc_mpu = {
+ .flags = OMAP_VC_CHANNEL_DEFAULT,
.common = &omap3_vc_common,
.smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 8a36342e60d2..4dc60e83e00d 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -73,7 +73,8 @@ unsigned long voltdm_get_voltage(struct voltagedomain *voltdm)
int voltdm_scale(struct voltagedomain *voltdm,
unsigned long target_volt)
{
- int ret;
+ int ret, i;
+ unsigned long volt = 0;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
@@ -86,9 +87,23 @@ int voltdm_scale(struct voltagedomain *voltdm,
return -ENODATA;
}
- ret = voltdm->scale(voltdm, target_volt);
+ /* Adjust voltage to the exact voltage from the OPP table */
+ for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {
+ if (voltdm->volt_data[i].volt_nominal >= target_volt) {
+ volt = voltdm->volt_data[i].volt_nominal;
+ break;
+ }
+ }
+
+ if (!volt) {
+ pr_warning("%s: not scaling. OPP voltage for %lu, not found.\n",
+ __func__, target_volt);
+ return -EINVAL;
+ }
+
+ ret = voltdm->scale(voltdm, volt);
if (!ret)
- voltdm->nominal_volt = target_volt;
+ voltdm->nominal_volt = volt;
return ret;
}