diff options
author | Nishanth Menon <nm@ti.com> | 2012-08-01 20:54:02 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2012-08-01 20:54:02 +0800 |
commit | 4eb6e70d9176f05712ba650b30a9a0d50c4c02f5 (patch) | |
tree | a4ab6776b60c9fd0021aea6187413940fecc55b5 | |
parent | cd5d320333bbe7742e2196df5b896ec9931b031f (diff) |
OMAP3+: VP/VC: ensure vp errgen is configured for the right OPP
Since target_volt converted by omap_voltage_get_voltdata to get to
vp_errgain for the OPP voltage level, we can have a scenario as follows:
OPP100 Vnom=1.2V, Vcalib = 0V(not calibrated) vp_errgain=0x16
OPPNitro Vnom=1.375, Vcalib = 1.2V vp_errgain=0x27
When a request to vc_bypass or vp_forceupdate is provided to OPPNitro
volt_data pointer, it in turn calls vc_prescale with 1.2V, this gets
passed down to vp_errgen_configure, who converts it back into vdata
using omap_voltage_get_voltdata
However, omap_voltage_get_voltdata walks through the volt_data array
and finds the first match of OPP100 where Vnom = 1.2V and returns
the volt_data pointer for OPP100, this causes 0x16 to be selected
for VP errgain instead of 0x27, causing instability for voltage scale
operation.
Instead, pass the volt_data pointer straight to vc_prescale and down
to vp_errgen_configure to ensure that the right configuration parameters
are used.
Change-Id: I96c697175fb5d16c53de9891ec5c008101c0550b
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Conflicts:
arch/arm/mach-omap2/vc.c
arch/arm/mach-omap2/vp.c
arch/arm/mach-omap2/vp.h
Signed-off-by: Sebastien Jan <s-jan@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/vp.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vp.h | 2 |
2 files changed, 9 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 453c05074f5..ec24999cf90 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -138,11 +138,17 @@ void __init omap_vp_init(struct voltagedomain *voltdm) } int omap_vp_update_errorgain(struct voltagedomain *voltdm, - struct omap_volt_data *target_volt) + struct omap_volt_data *volt_data) { + if (IS_ERR_OR_NULL(volt_data)) { + pr_err("%s: vdm %s bad voltage data %p\n", __func__, + voltdm->name, volt_data); + return -EINVAL; + } + /* Setting vp errorgain based on the voltage */ voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask, - target_volt->vp_errgain << + volt_data->vp_errgain << __ffs(voltdm->vp->common->vpconfig_errorgain_mask), voltdm->vp->vpconfig); diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h index 834bab9d77a..afd231f1fcb 100644 --- a/arch/arm/mach-omap2/vp.h +++ b/arch/arm/mach-omap2/vp.h @@ -133,7 +133,7 @@ void omap_vp_disable(struct voltagedomain *voltdm); int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, struct omap_volt_data *target_volt); int omap_vp_update_errorgain(struct voltagedomain *voltdm, - struct omap_volt_data *target_volt); + struct omap_volt_data *volt_data); unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm); #endif |