diff options
author | Ian Forbes <ian.forbes@broadcom.com> | 2024-05-31 23:33:58 +0300 |
---|---|---|
committer | Zack Rusin <zack.rusin@broadcom.com> | 2024-06-06 05:11:42 +0300 |
commit | 7ef91dcba172441582962602ff6899bfec6078b7 (patch) | |
tree | 7a0fbd143865f603b404d036ed0526770fe65f60 /drivers/gpu | |
parent | a54a200f3dc710db0572aba45c5c06b12b74489a (diff) | |
download | linux-7ef91dcba172441582962602ff6899bfec6078b7.tar.xz |
drm/vmwgfx: Don't destroy Screen Target when CRTC is enabled but inactive
drm_crtc_helper_funcs::atomic_disable can be called even when the CRTC is
still enabled. This can occur when the mode changes or the CRTC is set as
inactive.
In the case where the CRTC is being set as inactive we only want to
blank the screen. The Screen Target should remain intact as long as the
mode has not changed and CRTC is enabled.
This fixes a bug with GDM where locking the screen results in a permanent
black screen because the Screen Target is no longer defined.
Fixes: 7b0062036c3b ("drm/vmwgfx: Implement virtual crc generation")
Signed-off-by: Ian Forbes <ian.forbes@broadcom.com>
Reviewed-by: Martin Krastev <martin.krastev@broadcom.com>
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240531203358.26677-1-ian.forbes@broadcom.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 52e8ec3b2357..afc0bc4ef4e1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -421,6 +421,7 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc, { struct vmw_private *dev_priv; struct vmw_screen_target_display_unit *stdu; + struct drm_crtc_state *new_crtc_state; int ret; if (!crtc) { @@ -430,6 +431,7 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc, stdu = vmw_crtc_to_stdu(crtc); dev_priv = vmw_priv(crtc->dev); + new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); if (dev_priv->vkms_enabled) drm_crtc_vblank_off(crtc); @@ -441,6 +443,14 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc, (void) vmw_stdu_update_st(dev_priv, stdu); + /* Don't destroy the Screen Target if we are only setting the + * display as inactive + */ + if (new_crtc_state->enable && + !new_crtc_state->active && + !new_crtc_state->mode_changed) + return; + ret = vmw_stdu_destroy_st(dev_priv, stdu); if (ret) DRM_ERROR("Failed to destroy Screen Target\n"); |