Commit 8db82563 authored by Gregory CLEMENT's avatar Gregory CLEMENT Committed by Viresh Kumar

cpufreq: armada-37xx: fix frequency calculation for opp

The frequency calculation was based on the current(max) frequency of the
CPU. However for low frequency, the value used was already the parent
frequency divided by a factor of 2.

Instead of using this frequency, this fix directly get the frequency from
the parent clock.

Fixes: 92ce45fb ("cpufreq: Add DVFS support for Armada 37xx")
Cc: <stable@vger.kernel.org>
Reported-by: default avatarChristian Neubert <christian.neubert.86@gmail.com>
Signed-off-by: default avatarGregory CLEMENT <gregory.clement@bootlin.com>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent c1d1090c
...@@ -359,11 +359,11 @@ static int __init armada37xx_cpufreq_driver_init(void) ...@@ -359,11 +359,11 @@ static int __init armada37xx_cpufreq_driver_init(void)
struct armada_37xx_dvfs *dvfs; struct armada_37xx_dvfs *dvfs;
struct platform_device *pdev; struct platform_device *pdev;
unsigned long freq; unsigned long freq;
unsigned int cur_frequency; unsigned int cur_frequency, base_frequency;
struct regmap *nb_pm_base, *avs_base; struct regmap *nb_pm_base, *avs_base;
struct device *cpu_dev; struct device *cpu_dev;
int load_lvl, ret; int load_lvl, ret;
struct clk *clk; struct clk *clk, *parent;
nb_pm_base = nb_pm_base =
syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm"); syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
...@@ -399,6 +399,22 @@ static int __init armada37xx_cpufreq_driver_init(void) ...@@ -399,6 +399,22 @@ static int __init armada37xx_cpufreq_driver_init(void)
return PTR_ERR(clk); return PTR_ERR(clk);
} }
parent = clk_get_parent(clk);
if (IS_ERR(parent)) {
dev_err(cpu_dev, "Cannot get parent clock for CPU0\n");
clk_put(clk);
return PTR_ERR(parent);
}
/* Get parent CPU frequency */
base_frequency = clk_get_rate(parent);
if (!base_frequency) {
dev_err(cpu_dev, "Failed to get parent clock rate for CPU\n");
clk_put(clk);
return -EINVAL;
}
/* Get nominal (current) CPU frequency */ /* Get nominal (current) CPU frequency */
cur_frequency = clk_get_rate(clk); cur_frequency = clk_get_rate(clk);
if (!cur_frequency) { if (!cur_frequency) {
...@@ -431,7 +447,7 @@ static int __init armada37xx_cpufreq_driver_init(void) ...@@ -431,7 +447,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR; for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
load_lvl++) { load_lvl++) {
unsigned long u_volt = avs_map[dvfs->avs[load_lvl]] * 1000; unsigned long u_volt = avs_map[dvfs->avs[load_lvl]] * 1000;
freq = cur_frequency / dvfs->divider[load_lvl]; freq = base_frequency / dvfs->divider[load_lvl];
ret = dev_pm_opp_add(cpu_dev, freq, u_volt); ret = dev_pm_opp_add(cpu_dev, freq, u_volt);
if (ret) if (ret)
goto remove_opp; goto remove_opp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment