@@ -40,6 +40,7 @@ struct mtk_cpu_dvfs_info {
struct list_head list_head;
int intermediate_voltage;
bool need_voltage_tracking;
+ int old_vproc;
};
static LIST_HEAD(dvfs_info_list);
@@ -190,11 +191,17 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
{
+ int ret;
+
if (info->need_voltage_tracking)
- return mtk_cpufreq_voltage_tracking(info, vproc);
+ ret = mtk_cpufreq_voltage_tracking(info, vproc);
else
- return regulator_set_voltage(info->proc_reg, vproc,
- vproc + VOLT_TOL);
+ ret = regulator_set_voltage(info->proc_reg, vproc,
+ MAX_VOLT_LIMIT);
+ if (!ret)
+ info->old_vproc = vproc;
+
+ return ret;
}
static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
@@ -211,15 +218,7 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
inter_vproc = info->intermediate_voltage;
- old_freq_hz = clk_get_rate(cpu_clk);
- old_vproc = regulator_get_voltage(info->proc_reg);
- if (old_vproc < 0) {
- pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
- return old_vproc;
- }
-
freq_hz = freq_table[index].frequency * 1000;
-
opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
if (IS_ERR(opp)) {
pr_err("cpu%d: failed to find OPP for %ld\n",
@@ -229,6 +228,16 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
vproc = dev_pm_opp_get_voltage(opp);
dev_pm_opp_put(opp);
+ old_freq_hz = clk_get_rate(cpu_clk);
+ old_vproc = info->old_vproc;
+ if (old_vproc == 0)
+ old_vproc = regulator_get_voltage(info->proc_reg);
+ if (old_vproc < 0) {
+ dev_err(cpu_dev, "%s: invalid Vproc value: %d\n",
+ __func__, old_vproc);
+ return old_vproc;
+ }
+
/*
* If the new voltage or the intermediate voltage is higher than the
* current voltage, scale up voltage first.