On Tue, 2019-12-24 at 03:50 +0800, Ryder Lee wrote: > On Mon, 2019-12-23 at 17:28 +0800, mingming lee wrote: > > Update mtk common clock driver to support mt8512 > > 1. add new set_clr_upd mux type and related operation > > 2. add configurable pcw_chg_reg/ibits/fmin to mtk_pll > > 3. fix mtk_clk_find_parent_rate data overflow. > > I think these should be split into different patches. Also, Sam has sent a > fixup for overflow problem > > > Signed-off-by: mingming lee <mingming....@mediatek.com> > > --- > > drivers/clk/mediatek/clk-mtk.c | 72 ++++++++++++++++++++++++---------- > > drivers/clk/mediatek/clk-mtk.h | 26 ++++++++++++ > > 2 files changed, 77 insertions(+), 21 deletions(-) > > > diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c > > index 6c6b500d9b..5a2b77e4ae 100644 > > --- a/drivers/clk/mediatek/clk-mtk.c > > +++ b/drivers/clk/mediatek/clk-mtk.c > > @@ -39,8 +39,8 @@ > > * this function is recursively called to find the parent to calculate > > * the accurate frequency. > > */ > > -static int mtk_clk_find_parent_rate(struct clk *clk, int id, > > - const struct driver *drv) > > +static ulong mtk_clk_find_parent_rate(struct clk *clk, int id, > > + const struct driver *drv) > > { > > struct clk parent = { .id = id, }; > > > > @@ -67,12 +67,23 @@ static int mtk_clk_mux_set_parent(void __iomem *base, > > u32 parent, > > if (++index == mux->num_parents) > > return -EINVAL; > > > > - /* switch mux to a select parent */ > > - val = readl(base + mux->mux_reg); > > - val &= ~(mux->mux_mask << mux->mux_shift); > > + if (mux->flags & CLK_MUX_SETCLR_UPD) { > > + val = (mux->mux_mask << mux->mux_shift); > > + writel(val, base + mux->mux_clr_reg); > > > > - val |= index << mux->mux_shift; > > - writel(val, base + mux->mux_reg); > > + val = (index << mux->mux_shift); > > + writel(val, base + mux->mux_set_reg); > > + > > + if (mux->upd_shift >= 0) > > + writel(BIT(mux->upd_shift), base + mux->upd_reg); > > + } else { > > + /* switch mux to a select parent */ > > + val = readl(base + mux->mux_reg); > > + val &= ~(mux->mux_mask << mux->mux_shift); > > + > > + val |= index << mux->mux_shift; > > + writel(val, base + mux->mux_reg); > > + } > > > > return 0; > > } > > @@ -84,11 +95,13 @@ static unsigned long __mtk_pll_recalc_rate(const struct > > mtk_pll_data *pll, > > { > > int pcwbits = pll->pcwbits; > > int pcwfbits; > > + int ibits; > > u64 vco; > > u8 c = 0; > > > > /* The fractional part of the PLL divider. */ > > - pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0; > > + ibits = pll->pcwibits ? pll->pcwibits : INTEGER_BITS; > > + pcwfbits = pcwbits > ibits ? pcwbits - ibits : 0; > > > > vco = (u64)fin * pcw; > > > > @@ -113,7 +126,7 @@ static void mtk_pll_set_rate_regs(struct clk *clk, u32 > > pcw, int postdiv) > > { > > struct mtk_clk_priv *priv = dev_get_priv(clk->dev); > > const struct mtk_pll_data *pll = &priv->tree->plls[clk->id]; > > - u32 val; > > + u32 val, chg; > > > > /* set postdiv */ > > val = readl(priv->base + pll->pd_reg); > > @@ -129,11 +142,16 @@ static void mtk_pll_set_rate_regs(struct clk *clk, > > u32 pcw, int postdiv) > > /* set pcw */ > > val &= ~GENMASK(pll->pcw_shift + pll->pcwbits - 1, pll->pcw_shift); > > val |= pcw << pll->pcw_shift; > > - val &= ~CON1_PCW_CHG; > > - writel(val, priv->base + pll->pcw_reg); > > > > - val |= CON1_PCW_CHG; > > - writel(val, priv->base + pll->pcw_reg); > > + if (pll->pcw_chg_reg) { > > + chg = readl(priv->base + pll->pcw_chg_reg); > > + chg |= CON1_PCW_CHG; > > + writel(val, priv->base + pll->pcw_reg); > > + writel(chg, priv->base + pll->pcw_chg_reg); > > + } else { > > + val |= CON1_PCW_CHG; > > + writel(val, priv->base + pll->pcw_reg); > > + } > > > > udelay(20); > > } > > @@ -150,8 +168,9 @@ static void mtk_pll_calc_values(struct clk *clk, u32 > > *pcw, u32 *postdiv, > > { > > struct mtk_clk_priv *priv = dev_get_priv(clk->dev); > > const struct mtk_pll_data *pll = &priv->tree->plls[clk->id]; > > - unsigned long fmin = 1000 * MHZ; > > + unsigned long fmin = pll->fmin ? pll->fmin : 1000 * MHZ; > > u64 _pcw; > > + int ibits; > > u32 val; > > > > if (freq > pll->fmax) > > @@ -164,7 +183,8 @@ static void mtk_pll_calc_values(struct clk *clk, u32 > > *pcw, u32 *postdiv, > > } > > > > /* _pcw = freq * postdiv / xtal_rate * 2^pcwfbits */ > > - _pcw = ((u64)freq << val) << (pll->pcwbits - INTEGER_BITS); > > + ibits = pll->pcwibits ? pll->pcwibits : INTEGER_BITS; > > + _pcw = ((u64)freq << val) << (pll->pcwbits - ibits); > > do_div(_pcw, priv->tree->xtal2_rate); > > > > *pcw = (u32)_pcw; > > @@ -332,9 +352,14 @@ static int mtk_topckgen_enable(struct clk *clk) > > return 0; > > > > /* enable clock gate */ > > - val = readl(priv->base + mux->gate_reg); > > - val &= ~BIT(mux->gate_shift); > > - writel(val, priv->base + mux->gate_reg); > > + if (mux->flags & CLK_MUX_SETCLR_UPD) { > > + val = BIT(mux->gate_shift); > > + writel(val, priv->base + mux->mux_clr_reg); > > + } else { > > + val = readl(priv->base + mux->gate_reg); > > + val &= ~BIT(mux->gate_shift); > > + writel(val, priv->base + mux->gate_reg); > > + } > > > > if (mux->flags & CLK_DOMAIN_SCPSYS) { > > /* enable scpsys clock off control */ > > @@ -360,9 +385,14 @@ static int mtk_topckgen_disable(struct clk *clk) > > return 0; > > > > /* disable clock gate */ > > - val = readl(priv->base + mux->gate_reg); > > - val |= BIT(mux->gate_shift); > > - writel(val, priv->base + mux->gate_reg); > > + if (mux->flags & CLK_MUX_SETCLR_UPD) { > > + val = BIT(mux->gate_shift); > > + writel(val, priv->base + mux->mux_set_reg); > > + } else { > > + val = readl(priv->base + mux->gate_reg); > > + val |= BIT(mux->gate_shift); > > + writel(val, priv->base + mux->gate_reg); > > + } > > > > return 0; > > } > > diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h > > index dce93253ad..c7dc980861 100644 > > --- a/drivers/clk/mediatek/clk-mtk.h > > +++ b/drivers/clk/mediatek/clk-mtk.h > > @@ -12,6 +12,7 @@ > > > > #define HAVE_RST_BAR BIT(0) > > #define CLK_DOMAIN_SCPSYS BIT(0) > > +#define CLK_MUX_SETCLR_UPD BIT(1) > > > > #define CLK_GATE_SETCLR BIT(0) > > #define CLK_GATE_SETCLR_INV BIT(1) > > @@ -36,9 +37,12 @@ struct mtk_pll_data { > > u32 flags; > > u32 rst_bar_mask; > > u64 fmax; > > + u64 fmin; > > int pcwbits; > > + int pcwibits; > > u32 pcw_reg; > > int pcw_shift; > > + u32 pcw_chg_reg; > > }; > > > > /** > > @@ -102,9 +106,13 @@ struct mtk_composite { > > const int id; > > const int *parent; > > u32 mux_reg; > > + u32 mux_set_reg; > > + u32 mux_clr_reg; > > + u32 upd_reg; > > u32 gate_reg; > > u32 mux_mask; > > signed char mux_shift; > > + signed char upd_shift; > > signed char gate_shift; > > signed char num_parents; > > u16 flags; > > @@ -137,6 +145,24 @@ struct mtk_composite { > > .flags = 0, \ > > } > > > > +#define MUX_CLR_SET_UPD_FLAGS(_id, _parents, _mux_ofs, _mux_set_ofs,\ > > + _mux_clr_ofs, _shift, _width, _gate, \ > > + _upd_ofs, _upd, _flags) { \ > > + .id = _id, \ > > + .mux_reg = _mux_ofs, \ > > + .mux_set_reg = _mux_set_ofs, \ > > + .mux_clr_reg = _mux_clr_ofs, \ > > + .upd_reg = _upd_ofs, \ > > + .upd_shift = _upd, \ > > + .mux_shift = _shift, \ > > + .mux_mask = BIT(_width) - 1, \ > > + .gate_reg = _mux_ofs, \ > > + .gate_shift = _gate, \ > > + .parent = _parents, \ > > + .num_parents = ARRAY_SIZE(_parents), \ > > + .flags = _flags, \ > > + } > > + > > struct mtk_gate_regs { > > u32 sta_ofs; > > u32 clr_ofs; > >
OK,I will split it. Also, Sam has sent a fixup for overflow problem ------->And do you mean I could not care this in my patch.