81 lines
2.5 KiB
Plaintext
81 lines
2.5 KiB
Plaintext
diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
|
|
index 75491fc84..c2adf380b 100644
|
|
--- a/drivers/cpufreq/armada-37xx-cpufreq.c
|
|
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
|
|
@@ -162,11 +162,25 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
|
|
}
|
|
|
|
/*
|
|
- * Set cpu clock source, for all the level we keep the same
|
|
- * clock source that the one already configured. For this one
|
|
- * we need to use the clock framework
|
|
- */
|
|
+ * Set CPU clock source, for all the level we keep the same
|
|
+ * clock source that the one already configured with DVS
|
|
+ * disabled. For this one we need to use the clock framewor
|
|
+ */
|
|
parent = clk_get_parent(clk);
|
|
+
|
|
+ /*
|
|
+ * Unset parent clock to force the clock framework setting again
|
|
+ * the clock parent
|
|
+ */
|
|
+ clk_set_parent(clk, NULL);
|
|
+
|
|
+ /*
|
|
+ * For the Armada 37xx CPU clocks, setting the parent will
|
|
+ * actually configure the parent when DVFS is enabled. At
|
|
+ * hardware level it will be a different register from the one
|
|
+ * read when doing clk_get_parent that will be set with
|
|
+ * clk_set_parent.
|
|
+ */
|
|
clk_set_parent(clk, parent);
|
|
}
|
|
|
|
@@ -359,11 +373,11 @@ static int __init armada37xx_cpufreq_driver_init(void)
|
|
struct armada_37xx_dvfs *dvfs;
|
|
struct platform_device *pdev;
|
|
unsigned long freq;
|
|
- unsigned int cur_frequency;
|
|
+ unsigned int cur_frequency, base_frequency;
|
|
struct regmap *nb_pm_base, *avs_base;
|
|
struct device *cpu_dev;
|
|
int load_lvl, ret;
|
|
- struct clk *clk;
|
|
+ struct clk *clk, *parent;
|
|
|
|
nb_pm_base =
|
|
syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
|
|
@@ -399,6 +413,22 @@ static int __init armada37xx_cpufreq_driver_init(void)
|
|
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 */
|
|
cur_frequency = clk_get_rate(clk);
|
|
if (!cur_frequency) {
|
|
@@ -431,7 +461,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
|
|
for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
|
|
load_lvl++) {
|
|
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);
|
|
if (ret)
|
|
goto remove_opp;
|