diff options
author | Nishanth Menon <nm@ti.com> | 2012-08-01 20:53:03 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2012-08-01 20:53:03 +0800 |
commit | 54c74ae99930268f90d8e4b20147133337229741 (patch) | |
tree | e15ffb3a1f14098d15691864d7c1e55ab1b8b4e3 | |
parent | fc3d6b60d862603b69d6f4b44ee969ef4295f65d (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.c | 8 |
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) { |