The DCLK reparenting logic in vop2_crtc_atomic_enable() is gated only on
the presence of an HDMI PHY PLL on the SoC.
This condition is true on any board that wires up an HDMI PHY, even when
the CRTC is currently driving a non-HDMI output such as DSI or LVDS.
Those encoders do not set vcstate->output_bpc, so it stays 0, hence the
subsequent DIV_ROUND_CLOSEST_ULL() then divides by zero.
Note this division happens before the drm_for_each_encoder_mask() loop
that would establish whether the pipe is actually driven by HDMI, so the
loop provides no protection.
Default bpc to 8 when it would otherwise be 0. The resulting max_dclk
value is a don't-care on the non-HDMI paths that trigger this, since the
encoder loop will not select the PHY PLL as the DCLK source there.
Fixes: b0362c45c401 ("drm/rockchip: vop2: Check bpc before switching DCLK
source")
Reported-by: Sashiko <[email protected]>
Closes: https://lore.kernel.org/all/[email protected]/
Signed-off-by: Cristian Ciocaltea <[email protected]>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index c2328b35466d..e966c0a0266e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1920,8 +1920,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
* to 4K@60Hz, if available, otherwise keep using the system CRU.
*/
if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) {
- unsigned long max_dclk =
DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8,
-
vcstate->output_bpc);
+ unsigned int bpc = vcstate->output_bpc ?: 8;
+ unsigned long max_dclk =
DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev,
crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder =
to_rockchip_encoder(encoder);
--
2.54.0