Add handling for gates in the topckgen clk drivers. This avoids the need
to have separate topckgen-cg drivers and devicetree nodes for the same
address space and clock ID range.

Signed-off-by: David Lechner <[email protected]>
---
 drivers/clk/mediatek/clk-mtk.c | 61 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index e370d304c03..82306ae285c 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -582,7 +582,7 @@ static const int mtk_topckgen_of_xlate(struct clk *clk,
        if (ret)
                return ret;
 
-       /* topckgen only uses fclks, fdivs and muxes. */
+       /* topckgen only uses fclks, fdivs, muxes and gates. */
 
        if (tree->fclks && clk->id < tree->num_fclks)
                return 0;
@@ -595,6 +595,10 @@ static const int mtk_topckgen_of_xlate(struct clk *clk,
            clk->id < tree->muxes_offs + tree->num_muxes)
                return 0;
 
+       if (tree->gates && clk->id >= tree->gates_offs &&
+           clk->id < tree->gates_offs + tree->num_gates)
+               return 0;
+
        return -ENOENT;
 }
 
@@ -696,6 +700,14 @@ static ulong mtk_find_parent_rate(struct mtk_clk_priv 
*priv, struct clk *clk,
 static ulong mtk_topckgen_get_rate(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+       const struct mtk_clk_tree *tree = priv->tree;
+
+       if (tree->gates && clk->id >= tree->gates_offs &&
+           clk->id < tree->gates_offs + tree->num_gates) {
+               const struct mtk_gate *gate = &tree->gates[clk->id - 
tree->gates_offs];
+
+               return mtk_clk_find_parent_rate(clk, gate->parent, NULL);
+       }
 
        if (clk->id < priv->tree->fdivs_offs)
                return priv->tree->fclks[clk->id].rate;
@@ -740,6 +752,21 @@ static int mtk_clk_mux_enable(struct clk *clk)
        return 0;
 }
 
+static int mtk_topckgen_enable(struct clk *clk)
+{
+       struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+       const struct mtk_clk_tree *tree = priv->tree;
+
+       if (tree->gates && clk->id >= tree->gates_offs &&
+           clk->id < tree->gates_offs + tree->num_gates) {
+               const struct mtk_gate *gate = &tree->gates[clk->id - 
tree->gates_offs];
+
+               return mtk_gate_enable(priv->base, gate);
+       }
+
+       return mtk_clk_mux_enable(clk);
+}
+
 static int mtk_clk_mux_disable(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
@@ -766,13 +793,29 @@ static int mtk_clk_mux_disable(struct clk *clk)
        return 0;
 }
 
+static int mtk_topckgen_disable(struct clk *clk)
+{
+       struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+       const struct mtk_clk_tree *tree = priv->tree;
+
+       if (tree->gates && clk->id >= tree->gates_offs &&
+           clk->id < tree->gates_offs + tree->num_gates) {
+               const struct mtk_gate *gate = &tree->gates[clk->id - 
tree->gates_offs];
+
+               return mtk_gate_disable(priv->base, gate);
+       }
+
+       return mtk_clk_mux_disable(clk);
+}
+
 static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent)
 {
        struct mtk_clk_priv *parent_priv = dev_get_priv(parent->dev);
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
        u32 parent_type;
 
-       if (clk->id < priv->tree->muxes_offs)
+       if (!priv->tree->muxes || clk->id < priv->tree->muxes_offs ||
+           clk->id >= priv->tree->muxes_offs + priv->tree->num_muxes)
                return 0;
 
        if (!parent_priv)
@@ -821,6 +864,16 @@ static void mtk_topckgen_dump(struct udevice *dev)
                mtk_clk_print_mux_parents(priv, mux);
                printf("\n");
        }
+
+       for (i = 0; i < tree->num_gates; i++) {
+               const struct mtk_gate *gate = &tree->gates[i];
+
+               printf("[GATE%u] DT: %u", i, gate->id);
+               mtk_clk_print_mapped_id(gate->id, i + tree->gates_offs, 
tree->id_offs_map);
+               mtk_clk_print_rate(dev, i + tree->gates_offs);
+               mtk_clk_print_single_parent(gate->parent, gate->flags);
+               printf("\n");
+       }
 }
 #endif
 
@@ -1124,8 +1177,8 @@ const struct clk_ops mtk_clk_fixed_pll_ops = {
 
 const struct clk_ops mtk_clk_topckgen_ops = {
        .of_xlate = mtk_topckgen_of_xlate,
-       .enable = mtk_clk_mux_enable,
-       .disable = mtk_clk_mux_disable,
+       .enable = mtk_topckgen_enable,
+       .disable = mtk_topckgen_disable,
        .get_rate = mtk_topckgen_get_rate,
        .set_parent = mtk_common_clk_set_parent,
 #if CONFIG_IS_ENABLED(CMD_CLK)

-- 
2.43.0

Reply via email to