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>
int voltdm_scale(struct voltagedomain *voltdm,
unsigned long target_volt)
{
int voltdm_scale(struct voltagedomain *voltdm,
unsigned long target_volt)
{
+ int ret, i;
+ unsigned long volt = 0;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
- 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);
- voltdm->nominal_volt = target_volt;
+ voltdm->nominal_volt = volt;