[PATCH v1 04/13] clk: add CONFIG_CLK_AUTO_ID
Patrice Chotard
patrice.chotard at foss.st.com
Wed May 21 15:41:08 CEST 2025
From: Patrick Delaunay <patrick.delaunay at foss.st.com>
Add a new config CONFIG_CLK_AUTO_ID to support a unique clk id
for all the clock providers, managed by clk uclass, when the clock
reference arg[0] is the same.
When the CONFIG is activated, the clock id is limited to the lower
CLK_ID_SZ = 24 bits in default clock xlate function
and the sequence number + 1 of the clk provider device is
added for the 8 higher bits.
We use sequence number + 1 to avoid the "dummy" clock id = 0,
used for invalid clock when CCF is activated.
When this config is activated, the new function clk_get_id()
should be used to get back the internal reference to clock
for the each clock provider.
Signed-off-by: Patrick Delaunay <patrick.delaunay at foss.st.com>
Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Lukasz Majewski <lukma at denx.de>
Cc: Sean Anderson <seanga2 at gmail.com>
---
drivers/clk/Kconfig | 10 ++++++++++
drivers/clk/clk-uclass.c | 9 +++++++--
drivers/clk/stm32/clk-stm32-core.c | 3 ++-
include/clk.h | 24 ++++++++++++++++++++++++
include/linux/clk-provider.h | 9 ++++++++-
5 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 18bd640a68b..b2e53fe325e 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -10,6 +10,16 @@ config CLK
feed into other clocks in a tree structure, with multiplexers to
choose the source for each clock.
+config CLK_AUTO_ID
+ bool "Enable support of an unique clock id with several provider"
+ depends on CLK
+ help
+ Add the uclass sequence number of clock provider in the 8 higher bits
+ of the clk id to guaranty an unique clock identifier in clk uclass
+ when several clock providers are present on the device and when
+ default xlate are used.
+ This feature limit each identifier for each clock providers (24 bits).
+
config SPL_CLK
bool "Enable clock support in SPL"
depends on CLK && SPL && SPL_DM
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 2167cd5ad0f..7262e89b512 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -34,6 +34,11 @@ struct clk *dev_get_clk_ptr(struct udevice *dev)
return (struct clk *)dev_get_uclass_priv(dev);
}
+ulong clk_get_id(const struct clk *clk)
+{
+ return (ulong)(clk->id & CLK_ID_MSK);
+}
+
#if CONFIG_IS_ENABLED(OF_PLATDATA)
int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells,
struct clk *clk)
@@ -43,7 +48,7 @@ int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells,
ret = device_get_by_ofplat_idx(cells->idx, &clk->dev);
if (ret)
return ret;
- clk->id = cells->arg[0];
+ clk->id = CLK_ID(dev, cells->arg[0]);
return 0;
}
@@ -61,7 +66,7 @@ static int clk_of_xlate_default(struct clk *clk,
}
if (args->args_count)
- clk->id = args->args[0];
+ clk->id = CLK_ID(clk->dev, args->args[0]);
else
clk->id = 0;
diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c
index 358ee56682a..df3b35b1003 100644
--- a/drivers/clk/stm32/clk-stm32-core.c
+++ b/drivers/clk/stm32/clk-stm32-core.c
@@ -46,7 +46,8 @@ int stm32_rcc_init(struct udevice *dev,
if (cfg->setup) {
clk = cfg->setup(dev, cfg);
- clk->id = cfg->id;
+ /* set identifier of clock provider*/
+ dev_clk_dm(dev, cfg->id, clk);
} else {
dev_err(dev, "failed to register clock %s\n", cfg->name);
return -ENOENT;
diff --git a/include/clk.h b/include/clk.h
index a6ef4e02692..f94135ff778 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -13,6 +13,15 @@
#include <linux/errno.h>
#include <linux/types.h>
+#ifdef CONFIG_CLK_AUTO_ID
+#define CLK_ID_SZ 24
+#define CLK_ID_MSK GENMASK(23, 0)
+#define CLK_ID(dev, id) (((dev_seq(dev) + 1) << CLK_ID_SZ) | ((id) & CLK_ID_MSK))
+#else
+#define CLK_ID_MSK (~0UL)
+#define CLK_ID(dev, id) id
+#endif
+
/**
* DOC: Overview
*
@@ -570,6 +579,16 @@ int clk_get_by_id(ulong id, struct clk **clkp);
*/
bool clk_dev_binded(struct clk *clk);
+/**
+ * clk_get_id - get clk id
+ *
+ * @clk: A clock struct
+ *
+ * Return: the clock identifier as it is defined by the clock provider in
+ * device tree or in platdata
+ */
+ulong clk_get_id(const struct clk *clk);
+
#else /* CONFIG_IS_ENABLED(CLK) */
static inline int clk_request(struct udevice *dev, struct clk *clk)
@@ -641,6 +660,11 @@ static inline bool clk_dev_binded(struct clk *clk)
{
return false;
}
+
+static inline ulong clk_get_id(const struct clk *clk)
+{
+ return 0;
+}
#endif /* CONFIG_IS_ENABLED(CLK) */
/**
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 267757939e0..2d754fa4287 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -15,10 +15,17 @@
struct udevice;
+/* update clock ID for the dev = clock provider, compatible with CLK_AUTO_ID */
+static inline void dev_clk_dm(const struct udevice *dev, ulong id, struct clk *clk)
+{
+ if (!IS_ERR(clk))
+ clk->id = CLK_ID(dev, id);
+}
+
static inline void clk_dm(ulong id, struct clk *clk)
{
if (!IS_ERR(clk))
- clk->id = id;
+ clk->id = CLK_ID(clk->dev, id);
}
/*
--
2.25.1
More information about the U-Boot
mailing list