aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2012-04-30 13:08:29 -0400
committerTony Lindgren <tony@atomide.com>2012-04-30 13:08:29 -0400
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-regulator
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 @@
31 31
32#include "twl-common.h" 32#include "twl-common.h"
33#include "pm.h" 33#include "pm.h"
34#include "voltage.h"
34 35
35static struct i2c_board_info __initdata pmic_i2c_board_info = { 36static struct i2c_board_info __initdata pmic_i2c_board_info = {
36 .addr = 0x48, 37 .addr = 0x48,
@@ -47,6 +48,18 @@ static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
47 }, 48 },
48}; 49};
49 50
51static int twl_set_voltage(void *data, int target_uV)
52{
53 struct voltagedomain *voltdm = (struct voltagedomain *)data;
54 return voltdm_scale(voltdm, target_uV);
55}
56
57static int twl_get_voltage(void *data)
58{
59 struct voltagedomain *voltdm = (struct voltagedomain *)data;
60 return voltdm_get_voltage(voltdm);
61}
62
50void __init omap_pmic_init(int bus, u32 clkrate, 63void __init omap_pmic_init(int bus, u32 clkrate,
51 const char *pmic_type, int pmic_irq, 64 const char *pmic_type, int pmic_irq,
52 struct twl4030_platform_data *pmic_data) 65 struct twl4030_platform_data *pmic_data)
@@ -153,6 +166,48 @@ static struct regulator_init_data omap3_vpll2_idata = {
153 .consumer_supplies = omap3_vpll2_supplies, 166 .consumer_supplies = omap3_vpll2_supplies,
154}; 167};
155 168
169static struct regulator_consumer_supply omap3_vdd1_supply[] = {
170 REGULATOR_SUPPLY("vcc", "mpu.0"),
171};
172
173static struct regulator_consumer_supply omap3_vdd2_supply[] = {
174 REGULATOR_SUPPLY("vcc", "l3_main.0"),
175};
176
177static struct regulator_init_data omap3_vdd1 = {
178 .constraints = {
179 .name = "vdd_mpu_iva",
180 .min_uV = 600000,
181 .max_uV = 1450000,
182 .valid_modes_mask = REGULATOR_MODE_NORMAL,
183 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
184 },
185 .num_consumer_supplies = ARRAY_SIZE(omap3_vdd1_supply),
186 .consumer_supplies = omap3_vdd1_supply,
187};
188
189static struct regulator_init_data omap3_vdd2 = {
190 .constraints = {
191 .name = "vdd_core",
192 .min_uV = 600000,
193 .max_uV = 1450000,
194 .valid_modes_mask = REGULATOR_MODE_NORMAL,
195 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
196 },
197 .num_consumer_supplies = ARRAY_SIZE(omap3_vdd2_supply),
198 .consumer_supplies = omap3_vdd2_supply,
199};
200
201static struct twl_regulator_driver_data omap3_vdd1_drvdata = {
202 .get_voltage = twl_get_voltage,
203 .set_voltage = twl_set_voltage,
204};
205
206static struct twl_regulator_driver_data omap3_vdd2_drvdata = {
207 .get_voltage = twl_get_voltage,
208 .set_voltage = twl_set_voltage,
209};
210
156void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, 211void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
157 u32 pdata_flags, u32 regulators_flags) 212 u32 pdata_flags, u32 regulators_flags)
158{ 213{
@@ -160,6 +215,16 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
160 pmic_data->irq_base = TWL4030_IRQ_BASE; 215 pmic_data->irq_base = TWL4030_IRQ_BASE;
161 if (!pmic_data->irq_end) 216 if (!pmic_data->irq_end)
162 pmic_data->irq_end = TWL4030_IRQ_END; 217 pmic_data->irq_end = TWL4030_IRQ_END;
218 if (!pmic_data->vdd1) {
219 omap3_vdd1.driver_data = &omap3_vdd1_drvdata;
220 omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva");
221 pmic_data->vdd1 = &omap3_vdd1;
222 }
223 if (!pmic_data->vdd2) {
224 omap3_vdd2.driver_data = &omap3_vdd2_drvdata;
225 omap3_vdd2_drvdata.data = voltdm_lookup("core");
226 pmic_data->vdd2 = &omap3_vdd2;
227 }
163 228
164 /* Common platform data configurations */ 229 /* Common platform data configurations */
165 if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) 230 if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
@@ -310,6 +375,70 @@ static struct regulator_init_data omap4_clk32kg_idata = {
310 }, 375 },
311}; 376};
312 377
378static struct regulator_consumer_supply omap4_vdd1_supply[] = {
379 REGULATOR_SUPPLY("vcc", "mpu.0"),
380};
381
382static struct regulator_consumer_supply omap4_vdd2_supply[] = {
383 REGULATOR_SUPPLY("vcc", "iva.0"),
384};
385
386static struct regulator_consumer_supply omap4_vdd3_supply[] = {
387 REGULATOR_SUPPLY("vcc", "l3_main.0"),
388};
389
390static struct regulator_init_data omap4_vdd1 = {
391 .constraints = {
392 .name = "vdd_mpu",
393 .min_uV = 500000,
394 .max_uV = 1500000,
395 .valid_modes_mask = REGULATOR_MODE_NORMAL,
396 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
397 },
398 .num_consumer_supplies = ARRAY_SIZE(omap4_vdd1_supply),
399 .consumer_supplies = omap4_vdd1_supply,
400};
401
402static struct regulator_init_data omap4_vdd2 = {
403 .constraints = {
404 .name = "vdd_iva",
405 .min_uV = 500000,
406 .max_uV = 1500000,
407 .valid_modes_mask = REGULATOR_MODE_NORMAL,
408 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
409 },
410 .num_consumer_supplies = ARRAY_SIZE(omap4_vdd2_supply),
411 .consumer_supplies = omap4_vdd2_supply,
412};
413
414static struct regulator_init_data omap4_vdd3 = {
415 .constraints = {
416 .name = "vdd_core",
417 .min_uV = 500000,
418 .max_uV = 1500000,
419 .valid_modes_mask = REGULATOR_MODE_NORMAL,
420 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
421 },
422 .num_consumer_supplies = ARRAY_SIZE(omap4_vdd3_supply),
423 .consumer_supplies = omap4_vdd3_supply,
424};
425
426
427static struct twl_regulator_driver_data omap4_vdd1_drvdata = {
428 .get_voltage = twl_get_voltage,
429 .set_voltage = twl_set_voltage,
430};
431
432static struct twl_regulator_driver_data omap4_vdd2_drvdata = {
433 .get_voltage = twl_get_voltage,
434 .set_voltage = twl_set_voltage,
435};
436
437static struct twl_regulator_driver_data omap4_vdd3_drvdata = {
438 .get_voltage = twl_get_voltage,
439 .set_voltage = twl_set_voltage,
440};
441
313void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, 442void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
314 u32 pdata_flags, u32 regulators_flags) 443 u32 pdata_flags, u32 regulators_flags)
315{ 444{
@@ -318,6 +447,24 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
318 if (!pmic_data->irq_end) 447 if (!pmic_data->irq_end)
319 pmic_data->irq_end = TWL6030_IRQ_END; 448 pmic_data->irq_end = TWL6030_IRQ_END;
320 449
450 if (!pmic_data->vdd1) {
451 omap4_vdd1.driver_data = &omap4_vdd1_drvdata;
452 omap4_vdd1_drvdata.data = voltdm_lookup("mpu");
453 pmic_data->vdd1 = &omap4_vdd1;
454 }
455
456 if (!pmic_data->vdd2) {
457 omap4_vdd2.driver_data = &omap4_vdd2_drvdata;
458 omap4_vdd2_drvdata.data = voltdm_lookup("iva");
459 pmic_data->vdd2 = &omap4_vdd2;
460 }
461
462 if (!pmic_data->vdd3) {
463 omap4_vdd3.driver_data = &omap4_vdd3_drvdata;
464 omap4_vdd3_drvdata.data = voltdm_lookup("core");
465 pmic_data->vdd3 = &omap4_vdd3;
466 }
467
321 /* Common platform data configurations */ 468 /* Common platform data configurations */
322 if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) 469 if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
323 pmic_data->usb = &omap4_usb_pdata; 470 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 = {
46}; 46};
47 47
48struct omap_vc_channel omap3_vc_mpu = { 48struct omap_vc_channel omap3_vc_mpu = {
49 .flags = OMAP_VC_CHANNEL_DEFAULT,
49 .common = &omap3_vc_common, 50 .common = &omap3_vc_common,
50 .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET, 51 .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
51 .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET, 52 .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)
73int voltdm_scale(struct voltagedomain *voltdm, 73int voltdm_scale(struct voltagedomain *voltdm,
74 unsigned long target_volt) 74 unsigned long target_volt)
75{ 75{
76 int ret; 76 int ret, i;
77 unsigned long volt = 0;
77 78
78 if (!voltdm || IS_ERR(voltdm)) { 79 if (!voltdm || IS_ERR(voltdm)) {
79 pr_warning("%s: VDD specified does not exist!\n", __func__); 80 pr_warning("%s: VDD specified does not exist!\n", __func__);
@@ -86,9 +87,23 @@ int voltdm_scale(struct voltagedomain *voltdm,
86 return -ENODATA; 87 return -ENODATA;
87 } 88 }
88 89
89 ret = voltdm->scale(voltdm, target_volt); 90 /* Adjust voltage to the exact voltage from the OPP table */
91 for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {
92 if (voltdm->volt_data[i].volt_nominal >= target_volt) {
93 volt = voltdm->volt_data[i].volt_nominal;
94 break;
95 }
96 }
97
98 if (!volt) {
99 pr_warning("%s: not scaling. OPP voltage for %lu, not found.\n",
100 __func__, target_volt);
101 return -EINVAL;
102 }
103
104 ret = voltdm->scale(voltdm, volt);
90 if (!ret) 105 if (!ret)
91 voltdm->nominal_volt = target_volt; 106 voltdm->nominal_volt = volt;
92 107
93 return ret; 108 return ret;
94} 109}