clk: add CONFIG_CLK_AUTO_ID

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>
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 19aa2ff..8dbcc35 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -10,6 +10,16 @@
 	  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 2167cd5..7262e89 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -34,6 +34,11 @@
 	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 @@
 	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 @@
 	}
 
 	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 358ee56..df3b35b 100644
--- a/drivers/clk/stm32/clk-stm32-core.c
+++ b/drivers/clk/stm32/clk-stm32-core.c
@@ -46,7 +46,8 @@
 
 		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;