]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
clk: add CONFIG_CLK_AUTO_ID
authorPatrick Delaunay <patrick.delaunay@foss.st.com>
Tue, 27 May 2025 13:27:46 +0000 (15:27 +0200)
committerPatrice Chotard <patrice.chotard@foss.st.com>
Wed, 11 Jun 2025 07:42:55 +0000 (09:42 +0200)
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@foss.st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Cc: Lukasz Majewski <lukma@denx.de>
Cc: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
drivers/clk/Kconfig
drivers/clk/clk-uclass.c
drivers/clk/stm32/clk-stm32-core.c
include/clk.h
include/linux/clk-provider.h

index 19aa2ffa5396f0364bfbccd1e79b326a3dd0ff21..8dbcc35335f78b7153d68084a028381dd9b6c281 100644 (file)
@@ -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
index 2167cd5ad0fe6482bece6c4fa79ba2f48a5bc238..7262e89b5128927796d81e880dc043cfbe13aa91 100644 (file)
@@ -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;
 
index 358ee56682a12ae162bb44dbd50114852b442402..df3b35b10031e10dd482e00d7609474328fd290d 100644 (file)
@@ -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;
index a6ef4e02692252f9ec4b94c274af847a1ecdc1d0..f94135ff778a1247694b1252380801ab828b61c7 100644 (file)
 #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) */
 
 /**
index 267757939e0e98f9a804d0332ad7d329be763076..2d754fa4287188b83c0f1d9a0430a63f1f9fc5a7 100644 (file)
 
 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);
 }
 
 /*