summaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorOctavian Purdila <octavian.purdila@nxp.com>2017-04-07 13:29:43 +0300
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commitfce5c2488a41234420ecf51297b35c89f7f9a359 (patch)
tree00cf1df5676314e0b1c3a2649a716a89dd6f3cdc /drivers/cpufreq
parentb4f04971ae03af636de9307c66df276912dcdcd8 (diff)
MLK-14653 cpufreq: imx6q: reparent pll1_sys to pll1_bypass before changing it's rate
Make sure we reparent pll1_sys to pll1_bypass before changing it's rate. Otherwise, it may happen that pll1_sys is "parented" to pll1_bypass_src like this: osc pll1 0 0 996000000 0 0 pll1_bypass_src 0 0 24000000 0 0 pll1_bypass 0 0 24000000 0 0 pll1_sys 0 0 24000000 0 0 in which case changing the rate of pll1_sys won't propagate up to pll1 and we will end up with a different pll1_sys rate than requested. This fixes an issue where cpufreq can't properly switch to 792Mhz: $ cpufreq-set -f 996000 $ cpufreq-set -f 396000 $ cpufreq-set -f 792000 $ cat /sys/kernel/debug/clk/clk_summary pll1 1 1 996000000 0 0 pll1_bypass 1 1 996000000 0 0 pll1_sys 1 1 996000000 0 0 pll1_sw 1 1 996000000 0 0 arm 2 2 498000000 0 0 Signed-off-by: Octavian Purdila <octavian.purdila@nxp.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 850601e207ac..6d4a7bba7b7f 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -170,10 +170,13 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
clk_set_parent(step_clk, pll2_pfd2_396m_clk);
clk_set_parent(pll1_sw_clk, step_clk);
if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
- clk_set_rate(pll1_sys_clk, new_freq * 1000);
-
- /* Ensure pll1_bypass is set back to pll1. */
+ /* Ensure that pll1_bypass is set back to
+ * pll1. We have to do this first so that the
+ * change rate done to pll1_sys_clk done below
+ * can propagate up to pll1.
+ */
clk_set_parent(pll1_bypass, pll1);
+ clk_set_rate(pll1_sys_clk, new_freq * 1000);
clk_set_parent(pll1_sw_clk, pll1_sys_clk);
} else {
/*