Commit 5142cbce authored by Sascha Hauer's avatar Sascha Hauer Committed by Stephen Boyd

clk: si5351: Wait for bit clear after PLL reset

Documentation states that SI5351_PLL_RESET_B and SI5351_PLL_RESET_A bits
are self clearing bits, so wait until they are cleared before
continuing.
This fixes a case when the clock doesn't come up properly after a PLL
reset. It worked properly when the frequency was below 900MHz, but with
900MHz it only works when we are waiting for the bit to clear.
Signed-off-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
Link: https://lore.kernel.org/r/20201130091033.1687-1-s.hauer@pengutronix.deSigned-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 3650b228
...@@ -902,6 +902,10 @@ static int _si5351_clkout_set_disable_state( ...@@ -902,6 +902,10 @@ static int _si5351_clkout_set_disable_state(
static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num) static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num)
{ {
u8 val = si5351_reg_read(drvdata, SI5351_CLK0_CTRL + num); u8 val = si5351_reg_read(drvdata, SI5351_CLK0_CTRL + num);
u8 mask = val & SI5351_CLK_PLL_SELECT ? SI5351_PLL_RESET_B :
SI5351_PLL_RESET_A;
unsigned int v;
int err;
switch (val & SI5351_CLK_INPUT_MASK) { switch (val & SI5351_CLK_INPUT_MASK) {
case SI5351_CLK_INPUT_XTAL: case SI5351_CLK_INPUT_XTAL:
...@@ -909,9 +913,12 @@ static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num ...@@ -909,9 +913,12 @@ static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num
return; /* pll not used, no need to reset */ return; /* pll not used, no need to reset */
} }
si5351_reg_write(drvdata, SI5351_PLL_RESET, si5351_reg_write(drvdata, SI5351_PLL_RESET, mask);
val & SI5351_CLK_PLL_SELECT ? SI5351_PLL_RESET_B :
SI5351_PLL_RESET_A); err = regmap_read_poll_timeout(drvdata->regmap, SI5351_PLL_RESET, v,
!(v & mask), 0, 20000);
if (err < 0)
dev_err(&drvdata->client->dev, "Reset bit didn't clear\n");
dev_dbg(&drvdata->client->dev, "%s - %s: pll = %d\n", dev_dbg(&drvdata->client->dev, "%s - %s: pll = %d\n",
__func__, clk_hw_get_name(&drvdata->clkout[num].hw), __func__, clk_hw_get_name(&drvdata->clkout[num].hw),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment