aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Hilman <khilman@ti.com>2012-03-02 17:08:57 -0500
committerKevin Hilman <khilman@ti.com>2012-03-06 20:37:14 -0500
commitc15f1d84bb3ddd668593e9bca53221a2f82e9e99 (patch)
tree96e4bbcab2b9c470b0e3a27e2d8b62f9cb9b254b
parente160dda0f49f54deddd62e943e449a13430c2e8b (diff)
ARM: OMAP2+: voltage: ensure voltage used is exact voltage from OPP table
When using the SMPS regulators to scale voltages, the regulator framework may pass a minimum voltage that is not an exact OPP voltage. For the VC/VP controlled voltage domains, we must ensure that the voltage requested is the exact voltage from the OPP table. This is especially critical when using SR. To fix, voltdm_scale() uses the target voltage passed to walk through the OPP voltages until it finds a voltage that is >= one of the OPP voltages. Cc: Tero Kristo <t-kristo@ti.com> Cc: Nishanth Menon <nm@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
-rw-r--r--arch/arm/mach-omap2/voltage.c21
1 files changed, 18 insertions, 3 deletions
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}