diff options
-rw-r--r-- | vmwgfx_drv.c | 13 | ||||
-rw-r--r-- | vmwgfx_drv.h | 1 | ||||
-rw-r--r-- | vmwgfx_kms.c | 11 | ||||
-rw-r--r-- | vmwgfx_kms.h | 1 |
4 files changed, 25 insertions, 1 deletions
diff --git a/vmwgfx_drv.c b/vmwgfx_drv.c index a70d499..49c2fb1 100644 --- a/vmwgfx_drv.c +++ b/vmwgfx_drv.c @@ -1369,6 +1369,19 @@ static void __vmw_svga_disable(struct vmw_private *dev_priv) */ void vmw_svga_disable(struct vmw_private *dev_priv) { + /* + * Disabling SVGA will turn off device modesetting capabilities, so + * notify KMS about that so that it doesn't cache atomic state that + * isn't valid anymore, for example crtcs turned on. + * Strictly we'd want to do this under the SVGA lock (or an SVGA mutex), + * but vmw_kms_lost_device() takes the reservation sem and thus we'll + * end up with lock order reversal. Thus, a master may actually perform + * a new modeset just after we call vmw_kms_lost_device() and race with + * vmw_svga_disable(), but that should at worst cause atomic KMS state + * to be inconsistent with the device, causing modesetting problems. + * + */ + vmw_kms_lost_device(dev_priv->dev); ttm_write_lock(&dev_priv->reservation_sem, false); spin_lock(&dev_priv->svga_lock); if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) { diff --git a/vmwgfx_drv.h b/vmwgfx_drv.h index dda8813..e55b749 100644 --- a/vmwgfx_drv.h +++ b/vmwgfx_drv.h @@ -944,6 +944,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv); void vmw_kms_legacy_hotspot(struct drm_device *dev, struct drm_file *file_priv, int crtc_id, __s32 *hot_x, __s32 *hot_y); +void vmw_kms_lost_device(struct drm_device *dev); int vmw_dumb_create(struct drm_file *file_priv, struct drm_device *dev, diff --git a/vmwgfx_kms.c b/vmwgfx_kms.c index a33b056..1ae22ca 100644 --- a/vmwgfx_kms.c +++ b/vmwgfx_kms.c @@ -2903,3 +2903,14 @@ int vmw_kms_set_config(struct drm_mode_set *set, return drm_atomic_helper_set_config(set, ctx); } + + +/** + * vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost + * + * @dev: Pointer to the drm device + */ +void vmw_kms_lost_device(struct drm_device *dev) +{ + drm_atomic_helper_shutdown(dev); +} diff --git a/vmwgfx_kms.h b/vmwgfx_kms.h index 2446c48..73e428c 100644 --- a/vmwgfx_kms.h +++ b/vmwgfx_kms.h @@ -447,5 +447,4 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv, int vmw_kms_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx); - #endif |