aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/dvfs.c21
-rw-r--r--arch/arm/mach-omap2/pm.c6
-rw-r--r--arch/arm/mach-omap2/prm44xx.c1
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c6
-rw-r--r--arch/arm/mach-omap2/vc.c9
-rw-r--r--arch/arm/mach-omap2/vc.h3
-rw-r--r--arch/arm/mach-omap2/voltage.c32
-rw-r--r--arch/arm/mach-omap2/voltage.h20
-rw-r--r--arch/arm/mach-omap2/vp.c19
-rw-r--r--arch/arm/mach-omap2/vp.h2
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);