drm/rockchip: drv: Only set clk loader protect when route node exist

rockchip_clocks_loader_protect() always call in arch_initcall_sync().
However, rockchip_clocks_loader_unprotect() is not called when the
DRM driver is not loaded, which assumes that these clocks will always
be enabled.

This may cause the clock to be turned on accidentally. In the case of
ebc, for example, when the ebc driver is enabled and the DRM driver
is not loaded, rockchip_clocks_loader_protect() will enable ebc clk.
In addition, rockchip_clocks_loader_unprotect() will not be called,
meaning that the ebc clock will always be on. However, the ebc driver
will also control the ebc clk, but it will not be able to actually
turn off the clk. The dmc driver will check the status of the clk in
the CRU while working, and it will always find that the clk is on.
This will cause a wrong judgment on the working status of the ebc.

This patch adds constraints to rockchip_clocks_loader_protect() to
protect clocks only when route nodes are available, which means that
the logo is already enabled during the u-boot stage, so it makes
sense to perform clock loader protect.

Change-Id: Ib9efbade547181e86516d19637995569a751fade
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
This commit is contained in:
Chaoyi Chen
2025-05-20 16:55:11 +08:00
committed by Tao Huang
parent 5b24af833e
commit ceea326d94

View File

@@ -1319,13 +1319,36 @@ static const char *const loader_protect_clocks[] __initconst = {
static struct clk **loader_clocks;
static int __init rockchip_clocks_loader_protect(void)
{
struct device_node *np, *route_np, *route_child_np;
int nclocks = ARRAY_SIZE(loader_protect_clocks);
struct clk *clk;
int i;
int ret = 0;
/* Check for available route nodes and enable protect only when node is available. */
np = of_find_compatible_node(NULL, NULL, "rockchip,display-subsystem");
if (!np || !of_device_is_available(np)) {
ret = -ENODEV;
goto err_np;
}
route_np = of_get_child_by_name(np, "route");
if (!route_np) {
ret = -ENODEV;
goto err_route_np;
}
route_child_np = of_get_next_available_child(route_np, NULL);
if (!route_child_np) {
ret = -ENODEV;
goto err_route_child_np;
}
loader_clocks = kcalloc(nclocks, sizeof(void *), GFP_KERNEL);
if (!loader_clocks)
return -ENOMEM;
if (!loader_clocks) {
ret = -ENOMEM;
goto err_route_child_np;
}
for (i = 0; i < nclocks; i++) {
clk = __clk_lookup(loader_protect_clocks[i]);
@@ -1336,7 +1359,14 @@ static int __init rockchip_clocks_loader_protect(void)
}
}
return 0;
err_route_child_np:
of_node_put(route_child_np);
err_route_np:
of_node_put(route_np);
err_np:
of_node_put(np);
return ret;
}
arch_initcall_sync(rockchip_clocks_loader_protect);