From 6477bb1492b7ac89678891447f3d794e4fdb6df6 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Tue, 23 Apr 2019 19:25:24 +0800 Subject: [PATCH] MLK-21525 drm/imx: dpu: kms: Disallow primary plane on-the-fly disablement The below commit introduced in v4.16 reveals the fact that the DPU KMS driver doesn't support primary plane on-the-fly disablement. This may cause display issue when we restart weston with 4kp60 display for i.MX8QM. To support this, we need considerable driver change, but doesn't make too much sense, because disabling primary plane on an active CRTC doesn't often happen for real graphics update. In order not to run into this problem, we can explicitly disallow this use case in ->atomic_check(). This rejection makes us fall back to disable CRTC when removing the primary plane's framebuffer according to the below commit's rationale, which is the original behavior of atomic_remove_fb(). commit 846c7dfc1193 ("drm/atomic: Try to preserve the crtc enabled state in drm_atomic_remove_fb, v2.") Signed-off-by: Liu Ying --- drivers/gpu/drm/imx/dpu/dpu-kms.c | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpu/drm/imx/dpu/dpu-kms.c b/drivers/gpu/drm/imx/dpu/dpu-kms.c index 07e68bc34dcc..f120ab7bbfc4 100644 --- a/drivers/gpu/drm/imx/dpu/dpu-kms.c +++ b/drivers/gpu/drm/imx/dpu/dpu-kms.c @@ -521,6 +521,40 @@ dpu_atomic_put_possible_states_per_crtc(struct drm_crtc_state *crtc_state) dpu_atomic_put_crtc_state(state, crtc); } +/* primary plane on-the-fly disablement? */ +static bool +dpu_primary_plane_is_disabling_otf_per_crtc(struct drm_crtc_state *crtc_state) +{ + struct drm_atomic_state *state = crtc_state->state; + struct drm_plane *plane; + struct drm_plane_state *old_plane_state, *new_plane_state; + int i; + + if (!crtc_state->enable) + return false; + + if (drm_atomic_crtc_needs_modeset(crtc_state)) + return false; + + for_each_oldnew_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) { + if (plane->type != DRM_PLANE_TYPE_PRIMARY) + continue; + + if (!old_plane_state->crtc) + continue; + + if (old_plane_state->crtc != crtc_state->crtc) + continue; + + if (drm_atomic_plane_disabling(old_plane_state, + new_plane_state)) + return true; + } + + return false; +} + static int dpu_drm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { @@ -580,6 +614,10 @@ static int dpu_drm_atomic_check(struct drm_device *dev, imx_crtc_state = to_imx_crtc_state(crtc_state); dcstate = to_dpu_crtc_state(imx_crtc_state); + /* disallow primary plane on-the-fly disablement */ + if (dpu_primary_plane_is_disabling_otf_per_crtc(crtc_state)) + return -EINVAL; + if (crtc_state->enable) { if (use_pc[dpu_crtc->crtc_grp_id]) return -EINVAL; -- 2.17.1