diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/dvfs.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm44xx.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/smartreflex-class3.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/voltage.c | 32 | ||||
-rw-r--r-- | arch/arm/mach-omap2/voltage.h | 20 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vp.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vp.h | 2 |
10 files changed, 87 insertions, 32 deletions
diff --git a/arch/arm/mach-omap2/dvfs.c b/arch/arm/mach-omap2/dvfs.c index 953ed9b..4659e92 100644 --- a/arch/arm/mach-omap2/dvfs.c +++ b/arch/arm/mach-omap2/dvfs.c @@ -729,6 +729,8 @@ static int _dvfs_scale(struct device *req_dev, struct device *target_dev, int ret = 0; struct voltagedomain *voltdm; struct omap_vdd_info *vdd; + struct omap_volt_data *new_vdata; + struct omap_volt_data *curr_vdata; voltdm = tdvfs_info->voltdm; if (IS_ERR_OR_NULL(voltdm)) { @@ -741,9 +743,22 @@ static int _dvfs_scale(struct device *req_dev, struct device *target_dev, node = plist_last(&tdvfs_info->vdd_user_list); new_volt = node->prio; + new_vdata = omap_voltage_get_voltdata(voltdm, new_volt); + if (IS_ERR_OR_NULL(new_vdata)) { + pr_err("%s:%s: Bad New voltage data for %ld\n", + __func__, voltdm->name, new_volt); + return PTR_ERR(new_vdata); + } + new_volt = omap_get_operation_voltage(new_vdata); + curr_vdata = omap_voltage_get_curr_vdata(voltdm); + if (IS_ERR_OR_NULL(curr_vdata)) { + pr_err("%s:%s: Bad Current voltage data\n", + __func__, voltdm->name); + return PTR_ERR(curr_vdata); + } curr_volt = omap_vp_get_curr_volt(voltdm); if (!curr_volt) - curr_volt = omap_voltage_get_nom_volt(voltdm); + curr_volt = omap_get_operation_voltage(curr_vdata); /* Disable smartreflex module across voltage and frequency scaling */ omap_sr_disable(voltdm); @@ -760,7 +775,7 @@ static int _dvfs_scale(struct device *req_dev, struct device *target_dev, goto fail; } - ret = voltdm_scale(voltdm, new_volt); + ret = voltdm_scale(voltdm, new_vdata); if (ret) { dev_err(target_dev, "%s: Unable to scale the %s to %ld volt\n", @@ -817,7 +832,7 @@ static int _dvfs_scale(struct device *req_dev, struct device *target_dev, goto fail; if (DVFS_VOLT_SCALE_DOWN == volt_scale_dir) { - voltdm_scale(voltdm, new_volt); + voltdm_scale(voltdm, new_vdata); _dep_scale_domains(target_dev, vdd); } diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 9cba649..1afb2f6 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -370,7 +370,8 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, */ if (freq_cur < freq_valid) { - ret = voltdm_scale(voltdm, bootup_volt); + ret = voltdm_scale(voltdm, + omap_voltage_get_voltdata(voltdm, bootup_volt)); if (ret) { pr_err("%s: Fail set voltage-%s(f=%ld v=%ld)on vdd%s\n", __func__, vdd_name, freq_valid, @@ -391,7 +392,8 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, } if (freq_cur >= freq_valid) { - ret = voltdm_scale(voltdm, bootup_volt); + ret = voltdm_scale(voltdm, + omap_voltage_get_voltdata(voltdm, bootup_volt)); if (ret) { pr_err("%s: Fail set voltage-%s(f=%ld v=%ld)on vdd%s\n", __func__, clk_name, freq_valid, diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index ffc79ee4..6f011e0 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -21,6 +21,7 @@ #include <plat/cpu.h> #include <plat/prcm.h> +#include "voltage.h" #include "vp.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c index 5bc7ef0..44be57a 100644 --- a/arch/arm/mach-omap2/smartreflex-class3.c +++ b/arch/arm/mach-omap2/smartreflex-class3.c @@ -15,13 +15,15 @@ static int sr_class3_enable(struct voltagedomain *voltdm) { - unsigned long volt = omap_voltage_get_nom_volt(voltdm); + struct omap_volt_data *v = omap_voltage_get_curr_vdata(voltdm); + unsigned long volt; - if (!volt) { + if (IS_ERR_OR_NULL(v)) { pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n", __func__, voltdm->name); return -ENODATA; } + volt = omap_get_operation_voltage(v); omap_vp_enable(voltdm); return sr_enable(voltdm, volt); diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index cbf9a3b..162ee9f 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -197,6 +197,7 @@ int omap_vc_set_auto_trans(struct voltagedomain *voltdm, u8 flag) void omap_vc_post_scale(struct voltagedomain *voltdm, unsigned long target_volt, + struct omap_volt_data *target_vdata, u8 target_vsel, u8 current_vsel) { struct omap_vc_channel *vc; @@ -221,7 +222,7 @@ void omap_vc_post_scale(struct voltagedomain *voltdm, voltdm->pmic->slew_rate) + 2; udelay(smps_delay); - voltdm->curr_volt = target_volt; + voltdm->curr_volt = target_vdata; /* Set up the on voltage for wakeup from lp and OFF */ on_vsel = voltdm->pmic->uv_to_vsel(target_volt); @@ -281,11 +282,12 @@ static int omap_vc_bypass_send_value(struct voltagedomain *voltdm, /* vc_bypass_scale_voltage - VC bypass method of voltage scaling */ int omap_vc_bypass_scale_voltage(struct voltagedomain *voltdm, - unsigned long target_volt) + struct omap_volt_data *target_v) { struct omap_vc_channel *vc; u8 target_vsel, current_vsel; int ret; + unsigned long target_volt = omap_get_operation_voltage(target_v); if (IS_ERR_OR_NULL(voltdm)) { pr_err("%s bad voldm\n", __func__); @@ -308,7 +310,8 @@ int omap_vc_bypass_scale_voltage(struct voltagedomain *voltdm, if (ret) return ret; - omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel); + omap_vc_post_scale(voltdm, target_volt, target_v, target_vsel, + current_vsel); return 0; } diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h index a5f25fa..473375f 100644 --- a/arch/arm/mach-omap2/vc.h +++ b/arch/arm/mach-omap2/vc.h @@ -144,6 +144,7 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm, u8 *target_vsel, u8 *current_vsel); void omap_vc_post_scale(struct voltagedomain *voltdm, unsigned long target_volt, + struct omap_volt_data *target_vdata, u8 target_vsel, u8 current_vsel); /* Auto transition flags for users */ @@ -155,7 +156,7 @@ void omap_vc_post_scale(struct voltagedomain *voltdm, #define OMAP_VC_CHANNEL_AUTO_TRANSITION_UNSUPPORTED 0xff int omap_vc_set_auto_trans(struct voltagedomain *voltdm, u8 flag); int omap_vc_bypass_scale_voltage(struct voltagedomain *voltdm, - unsigned long target_volt); + struct omap_volt_data *target_volt); int omap_vc_bypass_send_i2c_msg(struct voltagedomain *voltdm, u8 slave_addr, u8 reg_addr, u8 data); #endif diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index 57a153c..60fcdae 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -88,17 +88,16 @@ ovdc_out: /* Public functions */ /** - * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage + * omap_voltage_get_curr_vdata() - Gets the current voltage data * @voltdm: pointer to the VDD for which current voltage info is needed * - * API to get the current non-auto-compensated voltage for a VDD. - * Returns 0 in case of error else returns the current voltage for the VDD. + * API to get the current voltage data pointer for a VDD, returns NULL on error */ -unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm) +struct omap_volt_data *omap_voltage_get_curr_vdata(struct voltagedomain *voltdm) { if (!voltdm || IS_ERR(voltdm)) { pr_warning("%s: VDD specified does not exist!\n", __func__); - return 0; + return NULL; } return voltdm->curr_volt; @@ -113,10 +112,11 @@ unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm) * for a particular voltage domain during DVFS. */ int voltdm_scale(struct voltagedomain *voltdm, - unsigned long target_volt) + struct omap_volt_data *target_v) { int ret = 0; struct omap_voltage_notifier notify; + unsigned long target_volt = omap_get_operation_voltage(target_v); if (!voltdm || IS_ERR(voltdm)) { pr_warning("%s: VDD specified does not exist!\n", __func__); @@ -145,14 +145,15 @@ int voltdm_scale(struct voltagedomain *voltdm, } if (!ret) { - ret = voltdm->scale(voltdm, target_volt); + ret = voltdm->scale(voltdm, target_v); if (ret) pr_err("%s: voltage scale failed for vdd%s: %d\n", __func__, voltdm->name, ret); if (voltdm->abb) { - ret = omap_ldo_abb_post_scale(voltdm, - voltdm->curr_volt); + unsigned long cv; + cv = omap_get_operation_voltage(voltdm->curr_volt); + ret = omap_ldo_abb_post_scale(voltdm, cv); if (ret) pr_err("%s: ABB postscale fail for vdd%s:%d\n", __func__, voltdm->name, ret); @@ -179,14 +180,14 @@ int voltdm_scale(struct voltagedomain *voltdm, */ void voltdm_reset(struct voltagedomain *voltdm) { - unsigned long target_volt; + struct omap_volt_data *target_volt; if (!voltdm || IS_ERR(voltdm)) { pr_warning("%s: VDD specified does not exist!\n", __func__); return; } - target_volt = omap_voltage_get_nom_volt(voltdm); + target_volt = omap_voltage_get_curr_vdata(voltdm); if (!target_volt) { pr_err("%s: unable to find current voltage for vdd_%s\n", __func__, voltdm->name); @@ -339,13 +340,20 @@ DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n"); static int nom_volt_debug_get(void *data, u64 *val) { struct voltagedomain *voltdm = (struct voltagedomain *) data; + struct omap_volt_data *vdata; if (!voltdm) { pr_warning("Wrong paramater passed\n"); return -EINVAL; } - *val = omap_voltage_get_nom_volt(voltdm); + vdata = omap_voltage_get_curr_vdata(voltdm); + if (IS_ERR_OR_NULL(vdata)) { + pr_warning("%s: unable to get volt for vdd_%s\n", + __func__, voltdm->name); + return -ENODEV; + } + *val = vdata->volt_nominal; return 0; } diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h index 0a9f529..2931983 100644 --- a/arch/arm/mach-omap2/voltage.h +++ b/arch/arm/mach-omap2/voltage.h @@ -17,6 +17,8 @@ #include <linux/notifier.h> #include <linux/err.h> +struct omap_volt_data; + #include "vc.h" #include "vp.h" #include "ldo.h" @@ -90,8 +92,8 @@ struct voltagedomain { } sys_clk; int (*scale) (struct voltagedomain *voltdm, - unsigned long target_volt); - u32 curr_volt; + struct omap_volt_data *target_volt); + struct omap_volt_data *curr_volt; struct omap_vdd_info *vdd; struct srcu_notifier_head change_notify_list; @@ -266,7 +268,7 @@ void omap_voltage_get_volttable(struct voltagedomain *voltdm, struct omap_volt_data **volt_data); struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, unsigned long volt); -unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm); +struct omap_volt_data *omap_voltage_get_curr_vdata(struct voltagedomain *voldm); #ifdef CONFIG_PM int omap_voltage_register_pmic(struct voltagedomain *voltdm, struct omap_voltdm_pmic *pmic); @@ -299,7 +301,8 @@ int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user), int voltdm_for_each_pwrdm(struct voltagedomain *voltdm, int (*fn)(struct voltagedomain *voltdm, struct powerdomain *pwrdm)); -int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt); +int voltdm_scale(struct voltagedomain *voltdm, + struct omap_volt_data *target_volt); void voltdm_reset(struct voltagedomain *voltdm); static inline int voltdm_register_notifier(struct voltagedomain *voltdm, @@ -314,4 +317,13 @@ static inline int voltdm_unregister_notifier(struct voltagedomain *voltdm, return srcu_notifier_chain_unregister(&voltdm->change_notify_list, nb); } +/* convert volt data to the voltage for the voltage data */ +static inline unsigned long omap_get_operation_voltage( + struct omap_volt_data *vdata) +{ + if (!vdata) + return 0; + return vdata->volt_nominal; +} + #endif diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index d3d9791..7ccf0a3 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -13,11 +13,17 @@ static void vp_latch_vsel(struct voltagedomain *voltdm) { struct omap_vp_instance *vp = voltdm->vp; + struct omap_volt_data *v = omap_voltage_get_curr_vdata(voltdm); u32 vpconfig; unsigned long uvdc; char vsel; - uvdc = omap_voltage_get_nom_volt(voltdm); + if (IS_ERR_OR_NULL(v)) { + pr_warning("%s: unable to get voltage for vdd_%s\n", + __func__, voltdm->name); + return; + } + uvdc = omap_get_operation_voltage(v); if (!uvdc) { pr_warning("%s: unable to find current voltage for vdd_%s\n", __func__, voltdm->name); @@ -106,8 +112,11 @@ int omap_vp_update_errorgain(struct voltagedomain *voltdm, /* Get volt_data corresponding to target_volt */ volt_data = omap_voltage_get_voltdata(voltdm, target_volt); - if (IS_ERR(volt_data)) + if (IS_ERR(volt_data)) { + pr_err("%s: vdm %s no voltage data for %ld\n", __func__, + voltdm->name, target_volt); return -EINVAL; + } /* Setting vp errorgain based on the voltage */ voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask, @@ -143,12 +152,13 @@ static u8 __vp_recover_count = _MAX_RETRIES_BEFORE_RECOVER; /* VP force update method of voltage scaling */ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, - unsigned long target_volt) + struct omap_volt_data *target_v) { struct omap_vp_instance *vp = voltdm->vp; u32 vpconfig; u8 target_vsel, current_vsel; int ret, timeout = 0; + unsigned long target_volt = omap_get_operation_voltage(target_v); /* * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us @@ -220,7 +230,8 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, __func__, voltdm->name, target_volt, target_vsel, current_vsel); - omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel); + omap_vc_post_scale(voltdm, target_volt, target_v, + target_vsel, current_vsel); /* * Disable TransactionDone interrupt , clear all status, clear diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h index e5f65fd..c3a1e69 100644 --- a/arch/arm/mach-omap2/vp.h +++ b/arch/arm/mach-omap2/vp.h @@ -114,7 +114,7 @@ void omap_vp_enable(struct voltagedomain *voltdm); void omap_vp_disable(struct voltagedomain *voltdm); unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm); int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, - unsigned long target_volt); + struct omap_volt_data *target_v); int omap_vp_update_errorgain(struct voltagedomain *voltdm, unsigned long target_volt); |