* [PATCH v3 2/4] clk: scmi: Factor out clock control flags resolution
2025-11-09 1:35 [PATCH v3 1/4] clk: scmi: Bulk allocate all sub-driver instance data Marek Vasut
@ 2025-11-09 1:35 ` Marek Vasut
2025-11-09 1:35 ` [PATCH v3 3/4] clk: scmi: Postpone clock name resolution Marek Vasut
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Marek Vasut @ 2025-11-09 1:35 UTC (permalink / raw)
To: u-boot
Cc: Marek Vasut, Peng Fan, Alice Guo, Patrice Chotard,
Patrick Delaunay, Sean Anderson, Tom Rini, Valentin Caron,
Vinh Nguyen
Pull clock control flags resolution into dedicated function and
call it from each site that does access clock control flags. No
functional change.
This is a preparatory patch for deferred issue of SCMI_CLOCK_ATTRIBUTES.
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Alice Guo <alice.guo@nxp.com>
Cc: Patrice Chotard <patrice.chotard@foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sean Anderson <seanga2@gmail.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Valentin Caron <valentin.caron@foss.st.com>
Cc: Vinh Nguyen <vinh.nguyen.xz@renesas.com>
Cc: u-boot@lists.denx.de
---
V2: Add RB from Peng
V3: No change
---
drivers/clk/clk_scmi.c | 51 +++++++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 23 deletions(-)
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 548bbfe14de..1a6a6ae464c 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -163,22 +163,36 @@ static int scmi_clk_gate(struct clk *clk, int enable)
return scmi_to_linux_errno(out.status);
}
-static int scmi_clk_enable(struct clk *clk)
+static int scmi_clk_get_ctrl_flags(struct clk *clk, u32 *ctrl_flags)
{
struct clk_scmi *clkscmi;
struct clk *c;
int ret;
- if (!CONFIG_IS_ENABLED(CLK_CCF))
- return scmi_clk_gate(clk, 1);
-
ret = clk_get_by_id(clk->id, &c);
if (ret)
return ret;
clkscmi = container_of(c, struct clk_scmi, clk);
- if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL)
+ *ctrl_flags = clkscmi->ctrl_flags;
+
+ return 0;
+}
+
+static int scmi_clk_enable(struct clk *clk)
+{
+ u32 ctrl_flags;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(CLK_CCF))
+ return scmi_clk_gate(clk, 1);
+
+ ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags);
+ if (ret)
+ return ret;
+
+ if (ctrl_flags & SUPPORT_CLK_STAT_CONTROL)
return scmi_clk_gate(clk, 1);
/* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
@@ -188,20 +202,17 @@ static int scmi_clk_enable(struct clk *clk)
static int scmi_clk_disable(struct clk *clk)
{
- struct clk_scmi *clkscmi;
- struct clk *c;
+ u32 ctrl_flags;
int ret;
if (!CONFIG_IS_ENABLED(CLK_CCF))
return scmi_clk_gate(clk, 0);
- ret = clk_get_by_id(clk->id, &c);
+ ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags);
if (ret)
return ret;
- clkscmi = container_of(c, struct clk_scmi, clk);
-
- if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL)
+ if (ctrl_flags & SUPPORT_CLK_STAT_CONTROL)
return scmi_clk_gate(clk, 0);
/* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
@@ -259,20 +270,17 @@ static ulong __scmi_clk_set_rate(struct clk *clk, ulong rate)
static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
{
- struct clk_scmi *clkscmi;
- struct clk *c;
+ u32 ctrl_flags;
int ret;
if (!CONFIG_IS_ENABLED(CLK_CCF))
return __scmi_clk_set_rate(clk, rate);
- ret = clk_get_by_id(clk->id, &c);
+ ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags);
if (ret)
return ret;
- clkscmi = container_of(c, struct clk_scmi, clk);
-
- if (clkscmi->ctrl_flags & SUPPORT_CLK_RATE_CONTROL)
+ if (ctrl_flags & SUPPORT_CLK_RATE_CONTROL)
return __scmi_clk_set_rate(clk, rate);
/* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
@@ -375,20 +383,17 @@ static int __scmi_clk_set_parent(struct clk *clk, struct clk *parent)
static int scmi_clk_set_parent(struct clk *clk, struct clk *parent)
{
- struct clk_scmi *clkscmi;
- struct clk *c;
+ u32 ctrl_flags;
int ret;
if (!CONFIG_IS_ENABLED(CLK_CCF))
return __scmi_clk_set_parent(clk, parent);
- ret = clk_get_by_id(clk->id, &c);
+ ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags);
if (ret)
return ret;
- clkscmi = container_of(c, struct clk_scmi, clk);
-
- if (clkscmi->ctrl_flags & SUPPORT_CLK_PARENT_CONTROL)
+ if (ctrl_flags & SUPPORT_CLK_PARENT_CONTROL)
return __scmi_clk_set_parent(clk, parent);
/* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v3 3/4] clk: scmi: Postpone clock name resolution
2025-11-09 1:35 [PATCH v3 1/4] clk: scmi: Bulk allocate all sub-driver instance data Marek Vasut
2025-11-09 1:35 ` [PATCH v3 2/4] clk: scmi: Factor out clock control flags resolution Marek Vasut
@ 2025-11-09 1:35 ` Marek Vasut
2025-11-09 1:35 ` [PATCH v3 4/4] clk: scmi: Defer issue of SCMI_CLOCK_ATTRIBUTES Marek Vasut
2025-11-10 14:02 ` [PATCH v3 1/4] clk: scmi: Bulk allocate all sub-driver instance data Peng Fan
3 siblings, 0 replies; 5+ messages in thread
From: Marek Vasut @ 2025-11-09 1:35 UTC (permalink / raw)
To: u-boot
Cc: Marek Vasut, Peng Fan, Alice Guo, Patrice Chotard,
Patrick Delaunay, Sean Anderson, Tom Rini, Valentin Caron,
Vinh Nguyen
The clock names are retrived via SCMI_CLOCK_ATTRIBUTES, called for each
clock ID. This may take a lot of time to complete and is not strictly
necessary. Register each clock as "scmi-%zu" instead, and let the first
call of SCMI_CLOCK_ATTRIBUTES fill in the actual clock name.
This has a side effect, which can be considered both an upside and also
a downside. Unused clock are never renamed and retain their placeholder
"scmi-%zu" name, which avoids empty clock names for nameless SCMI clock,
and avoids the name resolution and improves boot time. But for those
SCMI clock which do have name, that name is not listed until the clock
are used.
This is a preparatory patch for deferred issue of SCMI_CLOCK_ATTRIBUTES.
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Alice Guo <alice.guo@nxp.com>
Cc: Patrice Chotard <patrice.chotard@foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sean Anderson <seanga2@gmail.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Valentin Caron <valentin.caron@foss.st.com>
Cc: Vinh Nguyen <vinh.nguyen.xz@renesas.com>
Cc: u-boot@lists.denx.de
---
V2: Add RB from Peng
V3: No change
---
drivers/clk/clk_scmi.c | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 1a6a6ae464c..9bb41eddbba 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -17,6 +17,7 @@
struct clk_scmi {
struct clk clk;
+ char name[SCMI_CLOCK_NAME_LENGTH_MAX];
u32 ctrl_flags;
};
@@ -325,25 +326,21 @@ static int scmi_clk_probe(struct udevice *dev)
return -ENOMEM;
for (i = 0; i < num_clocks; i++) {
- char *clock_name;
+ clk_scmi = clk_scmi_bulk + i;
+ char *clock_name = clk_scmi->name;
u32 attributes;
- if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) {
- clk_scmi = clk_scmi_bulk + i;
- if (!clock_name)
- ret = -ENOMEM;
- else
- ret = clk_register(&clk_scmi->clk, dev->driver->name,
- clock_name, dev->name);
-
- if (ret) {
- free(clock_name);
- return ret;
- }
+ snprintf(clock_name, SCMI_CLOCK_NAME_LENGTH_MAX, "scmi-%zu", i);
+
+ ret = clk_register(&clk_scmi->clk, dev->driver->name,
+ clock_name, dev->name);
+ if (ret)
+ return ret;
- dev_clk_dm(dev, i, &clk_scmi->clk);
- dev_set_parent_priv(clk_scmi->clk.dev, priv);
+ dev_clk_dm(dev, i, &clk_scmi->clk);
+ dev_set_parent_priv(clk_scmi->clk.dev, priv);
+ if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) {
if (CLK_HAS_RESTRICTIONS(attributes)) {
u32 perm;
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v3 4/4] clk: scmi: Defer issue of SCMI_CLOCK_ATTRIBUTES
2025-11-09 1:35 [PATCH v3 1/4] clk: scmi: Bulk allocate all sub-driver instance data Marek Vasut
2025-11-09 1:35 ` [PATCH v3 2/4] clk: scmi: Factor out clock control flags resolution Marek Vasut
2025-11-09 1:35 ` [PATCH v3 3/4] clk: scmi: Postpone clock name resolution Marek Vasut
@ 2025-11-09 1:35 ` Marek Vasut
2025-11-10 14:02 ` [PATCH v3 1/4] clk: scmi: Bulk allocate all sub-driver instance data Peng Fan
3 siblings, 0 replies; 5+ messages in thread
From: Marek Vasut @ 2025-11-09 1:35 UTC (permalink / raw)
To: u-boot
Cc: Marek Vasut, Peng Fan, Alice Guo, Patrice Chotard,
Patrick Delaunay, Sean Anderson, Tom Rini, Valentin Caron,
Vinh Nguyen
Instead of resolving clock control flags using SCMI_CLOCK_ATTRIBUTES
during probe for each and every clock, resolve the clock control
flags using SCMI_CLOCK_ATTRIBUTES when the clock control flags are
first used. Because most clock are never used by U-Boot, this allows
reducing the amount of SCMI_CLOCK_ATTRIBUTES considerably, and this
improve probe time of the scmi clock driver and U-Boot start up time.
On Renesas X5H, with 1700+ SCMI clock, the boot time improved by 1.7s .
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Alice Guo <alice.guo@nxp.com>
Cc: Patrice Chotard <patrice.chotard@foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sean Anderson <seanga2@gmail.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Valentin Caron <valentin.caron@foss.st.com>
Cc: Vinh Nguyen <vinh.nguyen.xz@renesas.com>
Cc: u-boot@lists.denx.de
---
V2: Add RB from Peng
V3: Use clk_get_by_id() clock 'c' device parent instead of clk->dev->parent
---
drivers/clk/clk_scmi.c | 52 +++++++++++++++++++++++++++---------------
1 file changed, 33 insertions(+), 19 deletions(-)
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 9bb41eddbba..683ac822a01 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -19,6 +19,7 @@ struct clk_scmi {
struct clk clk;
char name[SCMI_CLOCK_NAME_LENGTH_MAX];
u32 ctrl_flags;
+ bool attrs_resolved;
};
struct scmi_clock_priv {
@@ -86,7 +87,7 @@ static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks)
return 0;
}
-static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name,
+static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char *name,
u32 *attr)
{
struct scmi_clock_priv *priv = dev_get_priv(dev);
@@ -110,7 +111,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name,
if (ret)
return ret;
- *name = strdup(out.clock_name);
+ strncpy(name, out.clock_name, SCMI_CLOCK_NAME_LENGTH_MAX);
*attr = out.attributes;
} else {
struct scmi_clk_attribute_out out;
@@ -127,7 +128,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name,
if (ret)
return ret;
- *name = strdup(out.clock_name);
+ strncpy(name, out.clock_name, SCMI_CLOCK_NAME_LENGTH_MAX);
*attr = out.attributes;
}
@@ -167,6 +168,8 @@ static int scmi_clk_gate(struct clk *clk, int enable)
static int scmi_clk_get_ctrl_flags(struct clk *clk, u32 *ctrl_flags)
{
struct clk_scmi *clkscmi;
+ struct udevice *dev;
+ u32 attributes;
struct clk *c;
int ret;
@@ -174,8 +177,35 @@ static int scmi_clk_get_ctrl_flags(struct clk *clk, u32 *ctrl_flags)
if (ret)
return ret;
+ dev = c->dev->parent;
+
clkscmi = container_of(c, struct clk_scmi, clk);
+ if (!clkscmi->attrs_resolved) {
+ char name[SCMI_CLOCK_NAME_LENGTH_MAX];
+ ret = scmi_clk_get_attibute(dev, clk->id & CLK_ID_MSK,
+ name, &attributes);
+ if (ret)
+ return ret;
+
+ strncpy(clkscmi->name, name, SCMI_CLOCK_NAME_LENGTH_MAX);
+ if (CLK_HAS_RESTRICTIONS(attributes)) {
+ u32 perm;
+
+ ret = scmi_clk_get_permissions(dev, clk->id & CLK_ID_MSK, &perm);
+ if (ret < 0)
+ clkscmi->ctrl_flags = 0;
+ else
+ clkscmi->ctrl_flags = perm;
+ } else {
+ clkscmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL |
+ SUPPORT_CLK_PARENT_CONTROL |
+ SUPPORT_CLK_RATE_CONTROL;
+ }
+
+ clkscmi->attrs_resolved = true;
+ }
+
*ctrl_flags = clkscmi->ctrl_flags;
return 0;
@@ -328,7 +358,6 @@ static int scmi_clk_probe(struct udevice *dev)
for (i = 0; i < num_clocks; i++) {
clk_scmi = clk_scmi_bulk + i;
char *clock_name = clk_scmi->name;
- u32 attributes;
snprintf(clock_name, SCMI_CLOCK_NAME_LENGTH_MAX, "scmi-%zu", i);
@@ -339,21 +368,6 @@ static int scmi_clk_probe(struct udevice *dev)
dev_clk_dm(dev, i, &clk_scmi->clk);
dev_set_parent_priv(clk_scmi->clk.dev, priv);
-
- if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) {
- if (CLK_HAS_RESTRICTIONS(attributes)) {
- u32 perm;
-
- ret = scmi_clk_get_permissions(dev, i, &perm);
- if (ret < 0)
- clk_scmi->ctrl_flags = 0;
- else
- clk_scmi->ctrl_flags = perm;
- } else {
- clk_scmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL | SUPPORT_CLK_PARENT_CONTROL |
- SUPPORT_CLK_RATE_CONTROL;
- }
- }
}
return 0;
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v3 1/4] clk: scmi: Bulk allocate all sub-driver instance data
2025-11-09 1:35 [PATCH v3 1/4] clk: scmi: Bulk allocate all sub-driver instance data Marek Vasut
` (2 preceding siblings ...)
2025-11-09 1:35 ` [PATCH v3 4/4] clk: scmi: Defer issue of SCMI_CLOCK_ATTRIBUTES Marek Vasut
@ 2025-11-10 14:02 ` Peng Fan
3 siblings, 0 replies; 5+ messages in thread
From: Peng Fan @ 2025-11-10 14:02 UTC (permalink / raw)
To: Marek Vasut
Cc: u-boot, Peng Fan, Alice Guo, Patrice Chotard, Patrick Delaunay,
Sean Anderson, Tom Rini, Valentin Caron, Vinh Nguyen
Hi Marek,
I have applied this patchset to fsl-qoriq/next for CI.
After CI pass, the PR to Tom for RC2 should be soon.
Thanks,
Peng
^ permalink raw reply [flat|nested] 5+ messages in thread