summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2012-08-01 20:53:03 +0800
committerAndy Green <andy.green@linaro.org>2012-08-01 20:53:03 +0800
commit54c74ae99930268f90d8e4b20147133337229741 (patch)
treee15ffb3a1f14098d15691864d7c1e55ab1b8b4e3
parentfc3d6b60d862603b69d6f4b44ee969ef4295f65d (diff)
OMAP3+: PM: DVFS: fix making wrong scale direction decision
In most cases with SmartReflex AVS class 3 and Class 1.5 calibration, the SR adjusted voltage(Vsr) is usually lower than Vnom, However, at times, the Vsr for a higher OPP may even be lower than a couple of lower OPPs. For example, on a specific sample silicon on OMAP4430: MPU OPP Vsr Vnom OPP50 0.862249970436096 1.025 OPP100 1.03509700298309 1.2 OPPTurbo 1.09257805347443 1.325 OPPNitro 1.18703103065491 1.388 OPPNitroSB 1.29427194595337 1.398 Consider in the above case where we transition from OPPTurbo to OPP100 We are attempting to transition from 1.325V to 1.09V, if we pickup voltage while SmartReflex AVS convergence is taking place, we might pickup 1.21V which in effect is a scale down decision flag for DVFS. however, since SR was active, it could make a jump of upto 8steps (100mV) lowering the voltage to 1.1V after s/w sampled the voltage, which in reality should have made SR to do a scale up operation. This wrong scale direction can result in either dependent domain scale combination to be performed wrongly OR even scale with lower voltage for a given transition frequency resulting in device instability. Fix the same by sampling the voltage only after stopping SmartReflex AVS convergence. Change-Id: I119a22b7060f30d123c4fe3bcabfadb6d7d71419 Signed-off-by: Nishanth Menon <nm@ti.com>
-rw-r--r--arch/arm/mach-omap2/dvfs.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/dvfs.c b/arch/arm/mach-omap2/dvfs.c
index 24c1e3ffd51..5e9bd7bcf21 100644
--- a/arch/arm/mach-omap2/dvfs.c
+++ b/arch/arm/mach-omap2/dvfs.c
@@ -774,13 +774,15 @@ static int _dvfs_scale(struct device *req_dev, struct device *target_dev,
__func__, voltdm->name);
return PTR_ERR(curr_vdata);
}
- curr_volt = omap_vp_get_curr_volt(voltdm);
- if (!curr_volt)
- curr_volt = omap_get_operation_voltage(curr_vdata);
/* Disable smartreflex module across voltage and frequency scaling */
omap_sr_disable(voltdm);
+ /* Pick up the current voltage ONLY after ensuring no changes occur */
+ curr_volt = omap_vp_get_curr_volt(voltdm);
+ if (!curr_volt)
+ curr_volt = omap_get_operation_voltage(curr_vdata);
+
if (curr_volt == new_volt) {
volt_scale_dir = DVFS_VOLT_SCALE_NONE;
} else if (curr_volt < new_volt) {