mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
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: 92ce45fb87
("cpufreq: Add DVFS support for Armada 37xx")
Cc: <stable@vger.kernel.org>
Reported-by: Christian Neubert <christian.neubert.86@gmail.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
This commit is contained in:
parent
c1d1090c3c
commit
8db8256345
1 changed files with 19 additions and 3 deletions
|
@ -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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue