diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 07db8b5c3000..467dc8b61a37 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -289,25 +289,6 @@ static int meson_clk_pll_wait_lock(struct clk_hw *hw) return -ETIMEDOUT; } -static int meson_clk_pll_init(struct clk_hw *hw) -{ - struct clk_regmap *clk = to_clk_regmap(hw); - struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); - - if (pll->init_count) { - if (MESON_PARM_APPLICABLE(&pll->rst)) - meson_parm_write(clk->map, &pll->rst, 1); - - regmap_multi_reg_write(clk->map, pll->init_regs, - pll->init_count); - - if (MESON_PARM_APPLICABLE(&pll->rst)) - meson_parm_write(clk->map, &pll->rst, 0); - } - - return 0; -} - static int meson_clk_pll_is_enabled(struct clk_hw *hw) { struct clk_regmap *clk = to_clk_regmap(hw); @@ -324,6 +305,33 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw) return 1; } +static int meson_clk_pll_init(struct clk_hw *hw) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); + + /* + * Keep the clock running, which was already initialized and enabled + * from the bootloader stage, to avoid any glitches. + */ + if ((pll->flags & CLK_MESON_PLL_NOINIT_ENABLED) && + meson_clk_pll_is_enabled(hw)) + return 0; + + if (pll->init_count) { + if (MESON_PARM_APPLICABLE(&pll->rst)) + meson_parm_write(clk->map, &pll->rst, 1); + + regmap_multi_reg_write(clk->map, pll->init_regs, + pll->init_count); + + if (MESON_PARM_APPLICABLE(&pll->rst)) + meson_parm_write(clk->map, &pll->rst, 0); + } + + return 0; +} + static int meson_clk_pcie_pll_enable(struct clk_hw *hw) { int retries = 10; diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h index a2228c0fdce5..7b6b87274073 100644 --- a/drivers/clk/meson/clk-pll.h +++ b/drivers/clk/meson/clk-pll.h @@ -28,6 +28,7 @@ struct pll_mult_range { } #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) +#define CLK_MESON_PLL_NOINIT_ENABLED BIT(1) struct meson_clk_pll_data { struct parm en;