[PATCH v6 08/15] drm/rockchip: vop2: Consolidate HDMI PHY PLL clock parent switch
From: Cristian Ciocaltea
Date: Wed Nov 04 2026 - 20:52:27 EST
The DCLK parent switch logic for HDMI0 and HDMI1 PHY PLLs was
duplicated, with each endpoint repeating the same clk_get_parent(),
clk_set_parent() and error handling calls.
Refactor this by first selecting the appropriate PHY PLL clock handle
based on the active HDMI endpoint, then performing the parent switch in
a single shared code path.
While at it, retrieve the original DCLK parent at init time, along with
the rest of the clocks, instead of lazily on the first switch to a PHY
PLL.
Tested-by: Igor Paunovic <royalnet026@xxxxxxxxx>
Reviewed-by: Daniel Stone <daniels@xxxxxxxxxxxxx>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@xxxxxxxxxxxxx>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 35 +++++++++++-----------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 98430587a7ab..ab6ced49ae40 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1956,42 +1956,31 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) {
unsigned int bpc = vcstate->output_bpc ?: 8;
unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+ struct clk *pll_hdmiphy = NULL;
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
- if (!vop2->pll_hdmiphy0)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI0 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy0;
break;
}
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI1) {
- if (!vop2->pll_hdmiphy1)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy1);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI1 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy1;
break;
}
}
}
+
+ if (pll_hdmiphy) {
+ ret = clk_set_parent(vp->dclk, pll_hdmiphy);
+ if (ret < 0)
+ drm_warn(vop2->drm,
+ "Failed to switch DCLK to HDMI PHY PLL: %d\n",
+ ret);
+ }
}
clk_set_rate(vp->dclk, clock);
@@ -2610,6 +2599,8 @@ static int vop2_create_crtcs(struct vop2 *vop2)
return dev_err_probe(drm->dev, PTR_ERR(vp->dclk),
"failed to get %s\n", dclk_name);
+ vp->dclk_src = clk_get_parent(vp->dclk);
+
vp->dclk_rst = devm_reset_control_get_optional_exclusive(vop2->dev,
dclk_name);
if (IS_ERR(vp->dclk_rst))
--
2.55.0