summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/mediatek/clk-mtk.c34
-rw-r--r--drivers/clk/mediatek/clk-mtk.h17
2 files changed, 50 insertions, 1 deletions
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 9d0a6cd79cf..da584aba0c3 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -34,6 +34,27 @@
#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,
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index b39a62edc43..ce0685b830e 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -32,6 +32,15 @@
#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,