[PATCH 2/2] clk: imx95-blk-ctrl: Resolve scmi clk before using it
Peng Fan (OSS)
peng.fan at oss.nxp.com
Thu Dec 11 09:31:44 CET 2025
From: Peng Fan <peng.fan at nxp.com>
With commit 3547e315c188 ("clk: scmi: Defer issue of SCMI_CLOCK_ATTRIBUTES"),
there is error log:
imx95_blkctrl_clk syscon at 4c0100c0: Failed to resolve clk hsiopll
clk_register use parent name "hsiopll", however this name does not
exist. The valid name at the moment is "scmi-[0-9*]". So need to first
resolve the scmi clk before using it.
Fixes: 3547e315c188 ("clk: scmi: Defer issue of SCMI_CLOCK_ATTRIBUTES")
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
drivers/clk/imx/Makefile | 6 ++++-
drivers/clk/imx/clk-imx95-blkctrl.c | 48 ++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index f2fd6ff8ca0..619a523cf96 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -25,4 +25,8 @@ obj-$(CONFIG_$(PHASE_)CLK_IMX93) += clk-imx93.o clk-fracn-gppll.o \
obj-$(CONFIG_$(PHASE_)CLK_IMXRT1020) += clk-imxrt1020.o
obj-$(CONFIG_$(PHASE_)CLK_IMXRT1050) += clk-imxrt1050.o
obj-$(CONFIG_$(PHASE_)CLK_IMXRT1170) += clk-imxrt1170.o
-obj-$(CONFIG_CLK_IMX95_BLKCTRL) += clk-imx95-blkctrl.o
+
+ifdef CONFIG_CLK_IMX95_BLKCTRL
+ccflags-y += -I$(srctree)/dts/upstream/src/arm64/freescale/
+obj-y += clk-imx95-blkctrl.o
+endif
diff --git a/drivers/clk/imx/clk-imx95-blkctrl.c b/drivers/clk/imx/clk-imx95-blkctrl.c
index 3e6f53b4a16..f6563539402 100644
--- a/drivers/clk/imx/clk-imx95-blkctrl.c
+++ b/drivers/clk/imx/clk-imx95-blkctrl.c
@@ -6,9 +6,11 @@
#include <asm/io.h>
#include <clk-uclass.h>
+#include <clk/scmi.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dt-bindings/clock/nxp,imx95-clock.h>
+#include <imx95-clock.h>
#include <linux/clk-provider.h>
#include "clk.h"
@@ -19,9 +21,11 @@ enum {
CLK_MUX,
};
+#define MAX_NUM_PARENTS 4
struct imx95_blk_ctl_clk_dev_data {
const char *name;
const char * const *parent_names;
+ u32 clk_parent_ids[4];
u32 num_parents;
u32 reg;
u32 bit_idx;
@@ -41,6 +45,7 @@ static const struct imx95_blk_ctl_clk_dev_data hsio_blk_ctl_clk_dev_data[] = {
[0] = {
.name = "hsio_blk_ctl_clk",
.parent_names = (const char *[]){ "hsiopll", },
+ .clk_parent_ids = { IMX95_CLK_HSIOPLL, },
.num_parents = 1,
.reg = 0,
.bit_idx = 6,
@@ -59,6 +64,7 @@ static const struct imx95_blk_ctl_clk_dev_data imx95_lvds_clk_dev_data[] = {
[IMX95_CLK_DISPMIX_LVDS_PHY_DIV] = {
.name = "ldb_phy_div",
.parent_names = (const char *[]){ "ldbpll", },
+ .clk_parent_ids = { IMX95_CLK_LDBPLL, },
.num_parents = 1,
.reg = 0,
.bit_idx = 0,
@@ -69,6 +75,7 @@ static const struct imx95_blk_ctl_clk_dev_data imx95_lvds_clk_dev_data[] = {
[IMX95_CLK_DISPMIX_LVDS_CH0_GATE] = {
.name = "lvds_ch0_gate",
.parent_names = (const char *[]){ "ldb_phy_div", },
+ .clk_parent_ids = { ~0U, },
.num_parents = 1,
.reg = 0,
.bit_idx = 1,
@@ -79,6 +86,7 @@ static const struct imx95_blk_ctl_clk_dev_data imx95_lvds_clk_dev_data[] = {
[IMX95_CLK_DISPMIX_LVDS_CH1_GATE] = {
.name = "lvds_ch1_gate",
.parent_names = (const char *[]){ "ldb_phy_div", },
+ .clk_parent_ids = { ~0U, },
.num_parents = 1,
.reg = 0,
.bit_idx = 2,
@@ -89,6 +97,7 @@ static const struct imx95_blk_ctl_clk_dev_data imx95_lvds_clk_dev_data[] = {
[IMX95_CLK_DISPMIX_PIX_DI0_GATE] = {
.name = "lvds_di0_gate",
.parent_names = (const char *[]){ "ldb_pll_div7", },
+ .clk_parent_ids = { ~0U, },
.num_parents = 1,
.reg = 0,
.bit_idx = 3,
@@ -99,6 +108,7 @@ static const struct imx95_blk_ctl_clk_dev_data imx95_lvds_clk_dev_data[] = {
[IMX95_CLK_DISPMIX_PIX_DI1_GATE] = {
.name = "lvds_di1_gate",
.parent_names = (const char *[]){ "ldb_pll_div7", },
+ .clk_parent_ids = { ~0U, },
.num_parents = 1,
.reg = 0,
.bit_idx = 4,
@@ -116,10 +126,11 @@ static const struct imx95_blk_ctl_dev_data imx95_lvds_csr_dev_data = {
static int imx95_blkctrl_clk_probe(struct udevice *dev)
{
- int i;
+ int i, j, ret;
void __iomem *addr;
struct imx95_blk_ctl_dev_data *dev_data = (void *)dev_get_driver_data(dev);
const struct imx95_blk_ctl_clk_dev_data *clk_dev_data;
+ struct udevice *scmi_clk_dev;
addr = dev_read_addr_ptr(dev);
if (addr == (void *)FDT_ADDR_T_NONE) {
@@ -132,7 +143,42 @@ static int imx95_blkctrl_clk_probe(struct udevice *dev)
return -EINVAL;
}
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol at 14", &scmi_clk_dev);
+ if (ret) {
+ dev_err(dev, "Failed to find procotol at 14\n");
+ return ret;
+ }
+
clk_dev_data = dev_data->clk_dev_data;
+ for (i = 0; i < dev_data->num_clks; i++) {
+ ulong id;
+ if (clk_dev_data[i].clk_type == CLK_GATE ||
+ clk_dev_data[i].clk_type == CLK_DIVIDER) {
+ if (clk_dev_data[i].clk_parent_ids[0] == ~0U)
+ continue;
+
+ id = CLK_ID(scmi_clk_dev, clk_dev_data[i].clk_parent_ids[0]);
+ ret = scmi_clk_resolve_attr(id, NULL);
+ if (ret) {
+ dev_err(dev, "Failed to resolve clk %s\n",
+ clk_dev_data[i].parent_names[0]);
+ return ret;
+ }
+ } else if (clk_dev_data[i].clk_type == CLK_MUX) {
+ for (j = 0; j < clk_dev_data[i].num_parents; j++) {
+ if (clk_dev_data[i].clk_parent_ids[j] == ~0U)
+ continue;
+ id = CLK_ID(scmi_clk_dev, clk_dev_data[i].clk_parent_ids[j]);
+ ret = scmi_clk_resolve_attr(id, NULL);
+ if (ret) {
+ dev_err(dev, "Failed to resolve clk %s\n",
+ clk_dev_data[i].parent_names[0]);
+ return ret;
+ }
+ }
+ }
+ }
+
for (i = 0; i < dev_data->num_clks; i++) {
if (clk_dev_data[i].clk_type == CLK_GATE) {
dev_clk_dm(dev, i,
--
2.51.0
More information about the U-Boot
mailing list