On 05/03/2019 06:05, Weiyi Lu wrote: > From: Owen Chen <owen.chen@xxxxxxxxxxxx> > > PLLs with tuner_en bit, such as APLL1, need to disable > tuner_en before apply new frequency settings, or the new frequency > settings (pcw) will not be applied. > The tuner_en bit will be disabled during changing PLL rate > and be restored after new settings applied. > > Fixes: e2f744a82d725 (clk: mediatek: Add MT2712 clock support) > Cc: <stable@xxxxxxxxxxxxxxx> > Signed-off-by: Owen Chen <owen.chen@xxxxxxxxxxxx> > Signed-off-by: Weiyi Lu <weiyi.lu@xxxxxxxxxxxx> Reviewed-by: Matthias Brugger <matthias.bgg@xxxxxxxxx> > --- > drivers/clk/mediatek/clk-pll.c | 48 ++++++++++++++++++++++++---------- > 1 file changed, 34 insertions(+), 14 deletions(-) > > diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c > index f54e4015b0b1..18842d660317 100644 > --- a/drivers/clk/mediatek/clk-pll.c > +++ b/drivers/clk/mediatek/clk-pll.c > @@ -88,6 +88,32 @@ static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin, > return ((unsigned long)vco + postdiv - 1) / postdiv; > } > > +static void __mtk_pll_tuner_enable(struct mtk_clk_pll *pll) > +{ > + u32 r; > + > + if (pll->tuner_en_addr) { > + r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit); > + writel(r, pll->tuner_en_addr); > + } else if (pll->tuner_addr) { > + r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN; > + writel(r, pll->tuner_addr); > + } > +} > + > +static void __mtk_pll_tuner_disable(struct mtk_clk_pll *pll) > +{ > + u32 r; > + > + if (pll->tuner_en_addr) { > + r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit); > + writel(r, pll->tuner_en_addr); > + } else if (pll->tuner_addr) { > + r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN; > + writel(r, pll->tuner_addr); > + } > +} > + > static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw, > int postdiv) > { > @@ -96,6 +122,9 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw, > > pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN; > > + /* disable tuner */ > + __mtk_pll_tuner_disable(pll); > + > /* set postdiv */ > val = readl(pll->pd_addr); > val &= ~(POSTDIV_MASK << pll->data->pd_shift); > @@ -122,6 +151,9 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw, > if (pll->tuner_addr) > writel(con1 + 1, pll->tuner_addr); > > + /* restore tuner_en */ > + __mtk_pll_tuner_enable(pll); > + > if (pll_en) > udelay(20); > } > @@ -228,13 +260,7 @@ static int mtk_pll_prepare(struct clk_hw *hw) > r |= pll->data->en_mask; > writel(r, pll->base_addr + REG_CON0); > > - if (pll->tuner_en_addr) { > - r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit); > - writel(r, pll->tuner_en_addr); > - } else if (pll->tuner_addr) { > - r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN; > - writel(r, pll->tuner_addr); > - } > + __mtk_pll_tuner_enable(pll); > > udelay(20); > > @@ -258,13 +284,7 @@ static void mtk_pll_unprepare(struct clk_hw *hw) > writel(r, pll->base_addr + REG_CON0); > } > > - if (pll->tuner_en_addr) { > - r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit); > - writel(r, pll->tuner_en_addr); > - } else if (pll->tuner_addr) { > - r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN; > - writel(r, pll->tuner_addr); > - } > + __mtk_pll_tuner_disable(pll); > > r = readl(pll->base_addr + REG_CON0); > r &= ~CON0_BASE_EN; >