MLK-14653 cpufreq: imx6q: reparent pll1_sys to pll1_bypass before changing it's rate
authorOctavian Purdila <octavian.purdila@nxp.com>
Fri, 7 Apr 2017 10:29:43 +0000 (13:29 +0300)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:21:53 +0000 (15:21 -0500)
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>
drivers/cpufreq/imx6q-cpufreq.c

index 850601e..6d4a7bb 100644 (file)
@@ -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 {
                        /*