clk: si5351: fix PLL reset
authorRussell King <rmk+kernel@armlinux.org.uk>
Wed, 26 Jul 2017 08:18:08 +0000 (09:18 +0100)
committerStephen Boyd <sboyd@codeaurora.org>
Fri, 1 Sep 2017 23:00:54 +0000 (16:00 -0700)
Changing the audio sample rate on the SolidRun Cubox disrupts the video
output.  The Si5351 provides both the video clock (using PLLA on output
0) and the audio clock (using PLLB on output 2).

When the rate of clock output 2 is changed, it reconfigures PLLB, which
results in both PLLA and PLLB being reset.  The reset of PLLA causes
clock output 0 to be disrupted, thereby causing a loss of sync by the
attached display device.

Hence, each time the audio sample rate changes (eg, when a video player
starts up, or when starting to play music) the video display momentarily
blanks while the Si5351 settles down.  Prior to the commit below, this
behaviour did not happen.

Fix this by only resetting only the PLL which has been changed.

Fixes: 6dc669a22c77 ("clk: si5351: Add PLL soft reset")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/clk-si5351.c

index 2492442eea77aa0c5abcf540e9bedb81e36d62d3..20d90769cceda980a0e198919c226e1d86d80c9e 100644 (file)
@@ -519,6 +519,11 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
                SI5351_CLK_INTEGER_MODE,
                (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);
 
+       /* Do a pll soft reset on the affected pll */
+       si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET,
+                        hwdata->num == 0 ? SI5351_PLL_RESET_A :
+                                           SI5351_PLL_RESET_B);
+
        dev_dbg(&hwdata->drvdata->client->dev,
                "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
                __func__, clk_hw_get_name(hw),
@@ -1091,13 +1096,6 @@ static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
        si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
                        SI5351_CLK_POWERDOWN, 0);
 
-       /*
-        * Do a pll soft reset on both plls, needed in some cases to get
-        * all outputs running.
-        */
-       si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET,
-                        SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
-
        dev_dbg(&hwdata->drvdata->client->dev,
                "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
                __func__, clk_hw_get_name(hw), (1 << rdiv),