diff mbox series

[07/12] clk: mediatek: add support for gate clock to reference topckgen clock

Message ID 20240628174114.8675-8-ansuelsmth@gmail.com
State Accepted
Commit a38cf1b2db46643aaa02ce11ed4665f6117fcbf5
Delegated to: Sean Anderson
Headers show
Series clk: mediatek: add OPs to support OF_UPSTREAM | expand

Commit Message

Christian Marangi June 28, 2024, 5:40 p.m. UTC
Add support for gate clock get_rate to reference topckgen clock for
infracfg-ao implementation.

In infracfg-ao implementation topckgen is on second level of parent with
infracfg in the middle.
To correctly detect this, check the driver of the dev parent and use the
second level parent if it's not mtk_clk_topckgen.

Due to all the dependency, parent tree must be filled before a gate is
used, hence is safe to assume it will be there.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/clk/mediatek/clk-mtk.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 790b92eaf86..4a057059407 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -651,20 +651,33 @@  static int mtk_clk_infrasys_disable(struct clk *clk)
 static ulong mtk_clk_gate_get_rate(struct clk *clk)
 {
 	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+	struct udevice *parent = priv->parent;
 	const struct mtk_gate *gate;
 
 	if (clk->id < priv->tree->gates_offs)
 		return -EINVAL;
 
 	gate = &priv->gates[clk->id - priv->tree->gates_offs];
+	/*
+	 * With requesting a TOPCKGEN parent, make sure the dev parent
+	 * is actually topckgen. This might not be the case for an
+	 * infracfg-ao implementation where:
+	 * parent = infracfg
+	 * parent->parent = topckgen
+	 */
+	if (gate->flags & CLK_PARENT_TOPCKGEN &&
+	    parent->driver != DM_DRIVER_GET(mtk_clk_topckgen)) {
+		priv = dev_get_priv(parent);
+		parent = priv->parent;
 	/*
 	 * Assume xtal_rate to be declared if some gates have
 	 * XTAL as parent
 	 */
-	if (gate->flags & CLK_PARENT_XTAL)
+	} else if (gate->flags & CLK_PARENT_XTAL) {
 		return priv->tree->xtal_rate;
+	}
 
-	return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent);
+	return mtk_clk_find_parent_rate(clk, gate->parent, parent);
 }
 
 const struct clk_ops mtk_clk_apmixedsys_ops = {