Commit 0f8b7137 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'omap-pm-regulator-for-v3.5' of...

Merge tag 'omap-pm-regulator-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/pm

Add support for vdd1 and vdd2 regulators and make voltage code to use them

By Tero Kristo (4) and Kevin Hilman (1)
via Kevin Hilman (3) and Tony Lindgren (1)
* tag 'omap-pm-regulator-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP2+: voltage: ensure voltage used is exact voltage from OPP table
  arm: omap4: add common twl configurations for vdd1, vdd2 and vdd3
  arm: omap3: twl: add external controllers for core voltage regulators
  arm: omap3: add common twl configurations for vdd1 and vdd2
  arm: omap3: voltage: fix channel configuration
parents 69964ea4 a8822e2d
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "twl-common.h" #include "twl-common.h"
#include "pm.h" #include "pm.h"
#include "voltage.h"
static struct i2c_board_info __initdata pmic_i2c_board_info = { static struct i2c_board_info __initdata pmic_i2c_board_info = {
.addr = 0x48, .addr = 0x48,
...@@ -47,6 +48,18 @@ static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { ...@@ -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, void __init omap_pmic_init(int bus, u32 clkrate,
const char *pmic_type, int pmic_irq, const char *pmic_type, int pmic_irq,
struct twl4030_platform_data *pmic_data) struct twl4030_platform_data *pmic_data)
...@@ -153,6 +166,48 @@ static struct regulator_init_data omap3_vpll2_idata = { ...@@ -153,6 +166,48 @@ static struct regulator_init_data omap3_vpll2_idata = {
.consumer_supplies = omap3_vpll2_supplies, .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, void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags) u32 pdata_flags, u32 regulators_flags)
{ {
...@@ -160,6 +215,16 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, ...@@ -160,6 +215,16 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
pmic_data->irq_base = TWL4030_IRQ_BASE; pmic_data->irq_base = TWL4030_IRQ_BASE;
if (!pmic_data->irq_end) if (!pmic_data->irq_end)
pmic_data->irq_end = TWL4030_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 */ /* Common platform data configurations */
if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
...@@ -310,6 +375,70 @@ static struct regulator_init_data omap4_clk32kg_idata = { ...@@ -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, void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags) u32 pdata_flags, u32 regulators_flags)
{ {
...@@ -318,6 +447,24 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, ...@@ -318,6 +447,24 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
if (!pmic_data->irq_end) if (!pmic_data->irq_end)
pmic_data->irq_end = TWL6030_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 */ /* Common platform data configurations */
if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
pmic_data->usb = &omap4_usb_pdata; pmic_data->usb = &omap4_usb_pdata;
......
...@@ -46,6 +46,7 @@ static struct omap_vc_common omap3_vc_common = { ...@@ -46,6 +46,7 @@ static struct omap_vc_common omap3_vc_common = {
}; };
struct omap_vc_channel omap3_vc_mpu = { struct omap_vc_channel omap3_vc_mpu = {
.flags = OMAP_VC_CHANNEL_DEFAULT,
.common = &omap3_vc_common, .common = &omap3_vc_common,
.smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET, .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET, .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
......
...@@ -73,7 +73,8 @@ unsigned long voltdm_get_voltage(struct voltagedomain *voltdm) ...@@ -73,7 +73,8 @@ unsigned long voltdm_get_voltage(struct voltagedomain *voltdm)
int voltdm_scale(struct voltagedomain *voltdm, int voltdm_scale(struct voltagedomain *voltdm,
unsigned long target_volt) unsigned long target_volt)
{ {
int ret; int ret, i;
unsigned long volt = 0;
if (!voltdm || IS_ERR(voltdm)) { if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__); pr_warning("%s: VDD specified does not exist!\n", __func__);
...@@ -86,9 +87,23 @@ int voltdm_scale(struct voltagedomain *voltdm, ...@@ -86,9 +87,23 @@ int voltdm_scale(struct voltagedomain *voltdm,
return -ENODATA; 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) if (!ret)
voltdm->nominal_volt = target_volt; voltdm->nominal_volt = volt;
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment