Message ID | 445cbec0d3c353b6bdfe06d24288269a8c1354f6.1661941661.git.weijie.gao@mediatek.com |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Series | Add support for MediaTek MT7981/MT7986 SoCs - v2 | expand |
On Wed, Aug 31, 2022 at 07:05:06PM +0800, Weijie Gao wrote: > This patch adds support for a clock node to configure its parent clock > where possible. Tested on Bananapi BPi-R3 (MT7986A). Tested-by: Daniel Golle <daniel@makrotopia.org> > > Reviewed-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> > --- > v2 changes: none > --- > drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++-------------- > drivers/clk/mediatek/clk-mtk.h | 2 + > 2 files changed, 48 insertions(+), 33 deletions(-) > > diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c > index 7d145f4975..a537ff259f 100644 > --- a/drivers/clk/mediatek/clk-mtk.c > +++ b/drivers/clk/mediatek/clk-mtk.c > @@ -42,20 +42,14 @@ > * the accurate frequency. > */ > static ulong mtk_clk_find_parent_rate(struct clk *clk, int id, > - const struct driver *drv) > + struct udevice *pdev) > { > struct clk parent = { .id = id, }; > > - if (drv) { > - struct udevice *dev; > - > - if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev)) > - return -ENODEV; > - > - parent.dev = dev; > - } else { > + if (pdev) > + parent.dev = pdev; > + else > parent.dev = clk->dev; > - } > > return clk_get_rate(&parent); > } > @@ -296,7 +290,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk *clk, u32 off) > switch (fdiv->flags & CLK_PARENT_MASK) { > case CLK_PARENT_APMIXED: > rate = mtk_clk_find_parent_rate(clk, fdiv->parent, > - DM_DRIVER_GET(mtk_clk_apmixedsys)); > + priv->parent); > break; > case CLK_PARENT_TOPCKGEN: > rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); > @@ -321,9 +315,18 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) > > if (mux->parent[index] > 0 || > (mux->parent[index] == CLK_XTAL && > - priv->tree->flags & CLK_BYPASS_XTAL)) > - return mtk_clk_find_parent_rate(clk, mux->parent[index], > - NULL); > + priv->tree->flags & CLK_BYPASS_XTAL)) { > + switch (mux->flags & CLK_PARENT_MASK) { > + case CLK_PARENT_APMIXED: > + return mtk_clk_find_parent_rate(clk, mux->parent[index], > + priv->parent); > + break; > + default: > + return mtk_clk_find_parent_rate(clk, mux->parent[index], > + NULL); > + break; > + } > + } > > return priv->tree->xtal_rate; > } > @@ -342,7 +345,7 @@ static ulong mtk_topckgen_get_rate(struct clk *clk) > priv->tree->muxes_offs); > } > > -static int mtk_topckgen_enable(struct clk *clk) > +static int mtk_clk_mux_enable(struct clk *clk) > { > struct mtk_clk_priv *priv = dev_get_priv(clk->dev); > const struct mtk_composite *mux; > @@ -375,7 +378,7 @@ static int mtk_topckgen_enable(struct clk *clk) > return 0; > } > > -static int mtk_topckgen_disable(struct clk *clk) > +static int mtk_clk_mux_disable(struct clk *clk) > { > struct mtk_clk_priv *priv = dev_get_priv(clk->dev); > const struct mtk_composite *mux; > @@ -401,7 +404,7 @@ static int mtk_topckgen_disable(struct clk *clk) > return 0; > } > > -static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent) > +static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent) > { > struct mtk_clk_priv *priv = dev_get_priv(clk->dev); > > @@ -473,19 +476,7 @@ static ulong mtk_clk_gate_get_rate(struct clk *clk) > struct mtk_cg_priv *priv = dev_get_priv(clk->dev); > const struct mtk_gate *gate = &priv->gates[clk->id]; > > - switch (gate->flags & CLK_PARENT_MASK) { > - case CLK_PARENT_APMIXED: > - return mtk_clk_find_parent_rate(clk, gate->parent, > - DM_DRIVER_GET(mtk_clk_apmixedsys)); > - break; > - case CLK_PARENT_TOPCKGEN: > - return mtk_clk_find_parent_rate(clk, gate->parent, > - DM_DRIVER_GET(mtk_clk_topckgen)); > - break; > - > - default: > - return priv->tree->xtal_rate; > - } > + return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent); > } > > const struct clk_ops mtk_clk_apmixedsys_ops = { > @@ -496,10 +487,10 @@ const struct clk_ops mtk_clk_apmixedsys_ops = { > }; > > const struct clk_ops mtk_clk_topckgen_ops = { > - .enable = mtk_topckgen_enable, > - .disable = mtk_topckgen_disable, > + .enable = mtk_clk_mux_enable, > + .disable = mtk_clk_mux_disable, > .get_rate = mtk_topckgen_get_rate, > - .set_parent = mtk_topckgen_set_parent, > + .set_parent = mtk_common_clk_set_parent, > }; > > const struct clk_ops mtk_clk_gate_ops = { > @@ -512,11 +503,22 @@ int mtk_common_clk_init(struct udevice *dev, > const struct mtk_clk_tree *tree) > { > struct mtk_clk_priv *priv = dev_get_priv(dev); > + struct udevice *parent; > + int ret; > > priv->base = dev_read_addr_ptr(dev); > if (!priv->base) > return -ENOENT; > > + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); > + if (ret || !parent) { > + ret = uclass_get_device_by_driver(UCLASS_CLK, > + DM_DRIVER_GET(mtk_clk_apmixedsys), &parent); > + if (ret || !parent) > + return -ENOENT; > + } > + > + priv->parent = parent; > priv->tree = tree; > > return 0; > @@ -527,11 +529,22 @@ int mtk_common_clk_gate_init(struct udevice *dev, > const struct mtk_gate *gates) > { > struct mtk_cg_priv *priv = dev_get_priv(dev); > + struct udevice *parent; > + int ret; > > priv->base = dev_read_addr_ptr(dev); > if (!priv->base) > return -ENOENT; > > + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); > + if (ret || !parent) { > + ret = uclass_get_device_by_driver(UCLASS_CLK, > + DM_DRIVER_GET(mtk_clk_topckgen), &parent); > + if (ret || !parent) > + return -ENOENT; > + } > + > + priv->parent = parent; > priv->tree = tree; > priv->gates = gates; > > diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h > index e0c5550c80..41854879c6 100644 > --- a/drivers/clk/mediatek/clk-mtk.h > +++ b/drivers/clk/mediatek/clk-mtk.h > @@ -206,11 +206,13 @@ struct mtk_clk_tree { > }; > > struct mtk_clk_priv { > + struct udevice *parent; > void __iomem *base; > const struct mtk_clk_tree *tree; > }; > > struct mtk_cg_priv { > + struct udevice *parent; > void __iomem *base; > const struct mtk_clk_tree *tree; > const struct mtk_gate *gates; > -- > 2.17.1 >
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 7d145f4975..a537ff259f 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -42,20 +42,14 @@ * the accurate frequency. */ static ulong mtk_clk_find_parent_rate(struct clk *clk, int id, - const struct driver *drv) + struct udevice *pdev) { struct clk parent = { .id = id, }; - if (drv) { - struct udevice *dev; - - if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev)) - return -ENODEV; - - parent.dev = dev; - } else { + if (pdev) + parent.dev = pdev; + else parent.dev = clk->dev; - } return clk_get_rate(&parent); } @@ -296,7 +290,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk *clk, u32 off) switch (fdiv->flags & CLK_PARENT_MASK) { case CLK_PARENT_APMIXED: rate = mtk_clk_find_parent_rate(clk, fdiv->parent, - DM_DRIVER_GET(mtk_clk_apmixedsys)); + priv->parent); break; case CLK_PARENT_TOPCKGEN: rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); @@ -321,9 +315,18 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) if (mux->parent[index] > 0 || (mux->parent[index] == CLK_XTAL && - priv->tree->flags & CLK_BYPASS_XTAL)) - return mtk_clk_find_parent_rate(clk, mux->parent[index], - NULL); + priv->tree->flags & CLK_BYPASS_XTAL)) { + switch (mux->flags & CLK_PARENT_MASK) { + case CLK_PARENT_APMIXED: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + priv->parent); + break; + default: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + NULL); + break; + } + } return priv->tree->xtal_rate; } @@ -342,7 +345,7 @@ static ulong mtk_topckgen_get_rate(struct clk *clk) priv->tree->muxes_offs); } -static int mtk_topckgen_enable(struct clk *clk) +static int mtk_clk_mux_enable(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); const struct mtk_composite *mux; @@ -375,7 +378,7 @@ static int mtk_topckgen_enable(struct clk *clk) return 0; } -static int mtk_topckgen_disable(struct clk *clk) +static int mtk_clk_mux_disable(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); const struct mtk_composite *mux; @@ -401,7 +404,7 @@ static int mtk_topckgen_disable(struct clk *clk) return 0; } -static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent) +static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -473,19 +476,7 @@ static ulong mtk_clk_gate_get_rate(struct clk *clk) struct mtk_cg_priv *priv = dev_get_priv(clk->dev); const struct mtk_gate *gate = &priv->gates[clk->id]; - switch (gate->flags & CLK_PARENT_MASK) { - case CLK_PARENT_APMIXED: - return mtk_clk_find_parent_rate(clk, gate->parent, - DM_DRIVER_GET(mtk_clk_apmixedsys)); - break; - case CLK_PARENT_TOPCKGEN: - return mtk_clk_find_parent_rate(clk, gate->parent, - DM_DRIVER_GET(mtk_clk_topckgen)); - break; - - default: - return priv->tree->xtal_rate; - } + return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent); } const struct clk_ops mtk_clk_apmixedsys_ops = { @@ -496,10 +487,10 @@ const struct clk_ops mtk_clk_apmixedsys_ops = { }; const struct clk_ops mtk_clk_topckgen_ops = { - .enable = mtk_topckgen_enable, - .disable = mtk_topckgen_disable, + .enable = mtk_clk_mux_enable, + .disable = mtk_clk_mux_disable, .get_rate = mtk_topckgen_get_rate, - .set_parent = mtk_topckgen_set_parent, + .set_parent = mtk_common_clk_set_parent, }; const struct clk_ops mtk_clk_gate_ops = { @@ -512,11 +503,22 @@ int mtk_common_clk_init(struct udevice *dev, const struct mtk_clk_tree *tree) { struct mtk_clk_priv *priv = dev_get_priv(dev); + struct udevice *parent; + int ret; priv->base = dev_read_addr_ptr(dev); if (!priv->base) return -ENOENT; + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); + if (ret || !parent) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(mtk_clk_apmixedsys), &parent); + if (ret || !parent) + return -ENOENT; + } + + priv->parent = parent; priv->tree = tree; return 0; @@ -527,11 +529,22 @@ int mtk_common_clk_gate_init(struct udevice *dev, const struct mtk_gate *gates) { struct mtk_cg_priv *priv = dev_get_priv(dev); + struct udevice *parent; + int ret; priv->base = dev_read_addr_ptr(dev); if (!priv->base) return -ENOENT; + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); + if (ret || !parent) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(mtk_clk_topckgen), &parent); + if (ret || !parent) + return -ENOENT; + } + + priv->parent = parent; priv->tree = tree; priv->gates = gates; diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index e0c5550c80..41854879c6 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -206,11 +206,13 @@ struct mtk_clk_tree { }; struct mtk_clk_priv { + struct udevice *parent; void __iomem *base; const struct mtk_clk_tree *tree; }; struct mtk_cg_priv { + struct udevice *parent; void __iomem *base; const struct mtk_clk_tree *tree; const struct mtk_gate *gates;