diff options
| -rw-r--r-- | drivers/clk/mediatek/clk-mtk.c | 34 | ||||
| -rw-r--r-- | drivers/clk/mediatek/clk-mtk.h | 17 |
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, |
