From ceea326d94eb93317b009b96e510a6f7b49ecab9 Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Tue, 20 May 2025 16:55:11 +0800 Subject: [PATCH] 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 --- drivers/gpu/drm/rockchip/rockchip_drm_logo.c | 36 ++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c index 2b7076fac108..79f39cd371bf 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c @@ -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);