summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-03-23 06:18:48 +1000
committerDave Airlie <airlied@redhat.com>2018-03-23 06:18:48 +1000
commit2a2553cc45c889f15a1df0355891a809f17ca43d (patch)
treee5664857265d4c1d47c5191ea0b71d569ba69613 /drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
parentf3924ae723d84746546bd74bdefc99c17da2a467 (diff)
parent43bfefedd0281ef476f8154397cd283a710d8baf (diff)
Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm-next
A relative large set of various improvements for vmwgfx. Some of them have been around for a while, some are relatively new, but functionality should have been tested in our standalone repo. * 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux: drm/vmwgfx: Bump version patchlevel and date drm/vmwgfx: use monotonic event timestamps drm/vmwgfx: Unpin the screen object backup buffer when not used drm/vmwgfx: Stricter count of legacy surface device resources drm/vmwgfx: Use kasprintf drm/vmwgfx: Get rid of the device-private suspended member drm/vmwgfx: Improve on hibernation drm/vmwgfx: Avoid pinning fbdev framebuffers drm/vmwgfx: Fix multiple command buffer context use drm/vmwgfx: Use the cpu blit utility for framebuffer to screen target blits drm/vmwgfx: Add a cpu blit utility that can be used for page-backed bos drm/ttm: Export the ttm_k[un]map_atomic_prot API. drm/ttm: Clean up kmap_atomic_prot selection code drm/vmwgfx: Cursor update fixes drm/vmwgfx: Send the correct nonblock option for atomic_commit drm/vmwgfx: Move the stdu vblank event to atomic function drm/vmwgfx: Move screen object page flip to atomic function drm/vmwgfx: Remove drm_crtc_arm_vblank_event from atomic flush drm/vmwgfx: Move surface copy cmd to atomic function drm/vmwgfx: Avoid iterating over display unit if crtc is available
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c80
1 files changed, 54 insertions, 26 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 184340d486c3..61a03ac90f8c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -301,6 +301,8 @@ static void vmw_print_capabilities(uint32_t capabilities)
DRM_INFO(" Guest Backed Resources.\n");
if (capabilities & SVGA_CAP_DX)
DRM_INFO(" DX Features.\n");
+ if (capabilities & SVGA_CAP_HP_CMD_QUEUE)
+ DRM_INFO(" HP Command Queue.\n");
}
/**
@@ -1277,8 +1279,7 @@ static void vmw_master_drop(struct drm_device *dev,
ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
ttm_vt_unlock(&dev_priv->fbdev_master.lock);
- if (dev_priv->enable_fb)
- vmw_fb_on(dev_priv);
+ vmw_fb_refresh(dev_priv);
}
/**
@@ -1368,28 +1369,23 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
switch (val) {
case PM_HIBERNATION_PREPARE:
- if (dev_priv->enable_fb)
- vmw_fb_off(dev_priv);
- ttm_suspend_lock(&dev_priv->reservation_sem);
-
/*
- * This empties VRAM and unbinds all GMR bindings.
- * Buffer contents is moved to swappable memory.
+ * Take the reservation sem in write mode, which will make sure
+ * there are no other processes holding a buffer object
+ * reservation, meaning we should be able to evict all buffer
+ * objects if needed.
+ * Once user-space processes have been frozen, we can release
+ * the lock again.
*/
- vmw_execbuf_release_pinned_bo(dev_priv);
- vmw_resource_evict_all(dev_priv);
- vmw_release_device_early(dev_priv);
- ttm_bo_swapout_all(&dev_priv->bdev);
- vmw_fence_fifo_down(dev_priv->fman);
+ ttm_suspend_lock(&dev_priv->reservation_sem);
+ dev_priv->suspend_locked = true;
break;
case PM_POST_HIBERNATION:
case PM_POST_RESTORE:
- vmw_fence_fifo_up(dev_priv->fman);
- ttm_suspend_unlock(&dev_priv->reservation_sem);
- if (dev_priv->enable_fb)
- vmw_fb_on(dev_priv);
- break;
- case PM_RESTORE_PREPARE:
+ if (READ_ONCE(dev_priv->suspend_locked)) {
+ dev_priv->suspend_locked = false;
+ ttm_suspend_unlock(&dev_priv->reservation_sem);
+ }
break;
default:
break;
@@ -1440,25 +1436,48 @@ static int vmw_pm_freeze(struct device *kdev)
struct pci_dev *pdev = to_pci_dev(kdev);
struct drm_device *dev = pci_get_drvdata(pdev);
struct vmw_private *dev_priv = vmw_priv(dev);
+ int ret;
- dev_priv->suspended = true;
+ /*
+ * Unlock for vmw_kms_suspend.
+ * No user-space processes should be running now.
+ */
+ ttm_suspend_unlock(&dev_priv->reservation_sem);
+ ret = vmw_kms_suspend(dev_priv->dev);
+ if (ret) {
+ ttm_suspend_lock(&dev_priv->reservation_sem);
+ DRM_ERROR("Failed to freeze modesetting.\n");
+ return ret;
+ }
if (dev_priv->enable_fb)
- vmw_fifo_resource_dec(dev_priv);
+ vmw_fb_off(dev_priv);
+ ttm_suspend_lock(&dev_priv->reservation_sem);
+ vmw_execbuf_release_pinned_bo(dev_priv);
+ vmw_resource_evict_all(dev_priv);
+ vmw_release_device_early(dev_priv);
+ ttm_bo_swapout_all(&dev_priv->bdev);
+ if (dev_priv->enable_fb)
+ vmw_fifo_resource_dec(dev_priv);
if (atomic_read(&dev_priv->num_fifo_resources) != 0) {
DRM_ERROR("Can't hibernate while 3D resources are active.\n");
if (dev_priv->enable_fb)
vmw_fifo_resource_inc(dev_priv);
WARN_ON(vmw_request_device_late(dev_priv));
- dev_priv->suspended = false;
+ dev_priv->suspend_locked = false;
+ ttm_suspend_unlock(&dev_priv->reservation_sem);
+ if (dev_priv->suspend_state)
+ vmw_kms_resume(dev);
+ if (dev_priv->enable_fb)
+ vmw_fb_on(dev_priv);
+ vmw_fb_refresh(dev_priv);
return -EBUSY;
}
- if (dev_priv->enable_fb)
- __vmw_svga_disable(dev_priv);
+ vmw_fence_fifo_down(dev_priv->fman);
+ __vmw_svga_disable(dev_priv);
vmw_release_device_late(dev_priv);
-
return 0;
}
@@ -1482,7 +1501,16 @@ static int vmw_pm_restore(struct device *kdev)
if (dev_priv->enable_fb)
__vmw_svga_enable(dev_priv);
- dev_priv->suspended = false;
+ vmw_fence_fifo_up(dev_priv->fman);
+ dev_priv->suspend_locked = false;
+ ttm_suspend_unlock(&dev_priv->reservation_sem);
+ if (dev_priv->suspend_state)
+ vmw_kms_resume(dev_priv->dev);
+
+ if (dev_priv->enable_fb)
+ vmw_fb_on(dev_priv);
+
+ vmw_fb_refresh(dev_priv);
return 0;
}