Message ID | 20191223092829.11017-3-mingming.lee@mediatek.com |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Series | Add support for MediaTek MT8512 Soc | expand |
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.lee@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;
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.lee@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.
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;
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 Signed-off-by: mingming lee <mingming.lee@mediatek.com> --- drivers/clk/mediatek/clk-mtk.c | 72 ++++++++++++++++++++++++---------- drivers/clk/mediatek/clk-mtk.h | 26 ++++++++++++ 2 files changed, 77 insertions(+), 21 deletions(-)