]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
clk: mediatek: add registration function for clock tree types
authorDavid Lechner <dlechner@baylibre.com>
Fri, 10 Jul 2026 18:56:18 +0000 (13:56 -0500)
committerDavid Lechner <dlechner@baylibre.com>
Wed, 22 Jul 2026 17:01:17 +0000 (12:01 -0500)
Add a new enum, field and function for registering clock tree types.
These types will be later used when looking up parent clocks. This
will replace fragile code that depends on lookup up devices by driver
names or ops.

We also need a way to ensure that any parent clock trees are probed
before trying to use a clock tree that depends on them. Since the
devicetree does not provide these relationships and there are only
a small number of clock parent providers (2 or 3 per SoC) vs. a large
number of clock trees that depend on them, it will simpler to just
always probe the parent clock trees on bind rather than trying to
add device info to all of the clocks to describe their parent
relations. For this, a mtk_common_clk_parent_bind() is added that the
drivers will use to set DM_FLAG_PROBE_AFTER_BIND.

Link: https://patch.msgid.link/20260710-mtk-clk-parent-lookup-improvements-v2-2-f3f3a4a28dca@baylibre.com
Signed-off-by: David Lechner <dlechner@baylibre.com>
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-mtk.h

index 9d0a6cd79cf7204ff772b46ff9902ef80e650912..da584aba0c3ba2550ae6b2c41a98590766f2e678 100644 (file)
 #define SCP_AXICK_DCM_DIS_EN           BIT(0)
 #define SCP_AXICK_26M_SEL_EN           BIT(4)
 
+static struct udevice *mtk_clk_providers[MTK_CLK_TREE_NUM_TYPES];
+
+static bool mtk_clk_tree_type_is_provider(enum mtk_clk_tree_type type)
+{
+       return type != MTK_CLK_TREE_NONE && type < MTK_CLK_TREE_NUM_TYPES;
+}
+
+static int mtk_clk_tree_register_provider(struct udevice *dev,
+                                         const struct mtk_clk_tree *tree)
+{
+       if (!mtk_clk_tree_type_is_provider(tree->type))
+               return 0;
+
+       if (mtk_clk_providers[tree->type])
+               return -EEXIST;
+
+       mtk_clk_providers[tree->type] = dev;
+
+       return 0;
+}
+
 /* shared functions */
 
 static const int mtk_common_clk_of_xlate(struct clk *clk,
@@ -1182,6 +1203,17 @@ const struct clk_ops mtk_clk_gate_ops = {
 #endif
 };
 
+int mtk_common_clk_parent_bind(struct udevice *dev)
+{
+       /*
+        * Clock trees that provide parent clocks need to be probed right away
+        * so that any clock depending on them will work correctly.
+        */
+       dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+
+       return 0;
+}
+
 static int mtk_common_clk_init_drv(struct udevice *dev,
                                   const struct mtk_clk_tree *tree,
                                   const struct driver *drv)
@@ -1204,7 +1236,7 @@ static int mtk_common_clk_init_drv(struct udevice *dev,
        priv->parent = parent;
        priv->tree = tree;
 
-       return 0;
+       return mtk_clk_tree_register_provider(dev, tree);
 }
 
 int mtk_common_clk_init(struct udevice *dev,
index b39a62edc4331ba78c5524de463b9ce60e15611d..ce0685b830e995db79fd6507fb23e24677b92cd5 100644 (file)
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS     0x34
 
+/* These get matched to CLK_PARENT_* when looking up parent clocks. */
+enum mtk_clk_tree_type {
+       MTK_CLK_TREE_NONE,
+       MTK_CLK_TREE_APMIXED,
+       MTK_CLK_TREE_TOPCKGEN,
+       MTK_CLK_TREE_INFRASYS,
+       MTK_CLK_TREE_NUM_TYPES
+};
+
 /* struct mtk_pll_data - hardware-specific PLLs data */
 struct mtk_pll_data {
        /* unmapped ID of clock */
@@ -261,6 +270,13 @@ struct mtk_clk_tree {
        const int num_muxes;
        const int num_gates;
        u32 flags;
+       /*
+        * Set this if this tree provides a specific type for parent lookup.
+        * Devices that set this should also include mtk_common_clk_parent_bind()
+        * in the driver bind function to ensure that it will be registered as
+        * a provider.
+        */
+       enum mtk_clk_tree_type type;
 };
 
 struct mtk_clk_priv {
@@ -284,6 +300,7 @@ extern const struct clk_ops mtk_clk_topckgen_ops;
 extern const struct clk_ops mtk_clk_infrasys_ops;
 extern const struct clk_ops mtk_clk_gate_ops;
 
+int mtk_common_clk_parent_bind(struct udevice *dev);
 int mtk_common_clk_init(struct udevice *dev,
                        const struct mtk_clk_tree *tree);
 int mtk_common_clk_infrasys_init(struct udevice *dev,