diff options
Diffstat (limited to 'vmwgfx-Rework-device-initialization.patch')
-rw-r--r-- | vmwgfx-Rework-device-initialization.patch | 890 |
1 files changed, 0 insertions, 890 deletions
diff --git a/vmwgfx-Rework-device-initialization.patch b/vmwgfx-Rework-device-initialization.patch deleted file mode 100644 index 183ba9c28..000000000 --- a/vmwgfx-Rework-device-initialization.patch +++ /dev/null @@ -1,890 +0,0 @@ -From c1d9b32d8ee2e97e2867fa759eb84d436cca0311 Mon Sep 17 00:00:00 2001 -From: Thomas Hellstrom <thellstrom@vmware.com> -Date: Thu, 25 Jun 2015 10:47:43 -0700 -Subject: [PATCH 1/2] vmwgfx: Rework device initialization - -This commit reworks device initialization so that we always enable the -FIFO at driver load, deferring SVGA enable until either first modeset -or fbdev enable. -This should always leave the fifo properly enabled for render- and -control nodes. -In addition, -*) We disable the use of VRAM when SVGA is not enabled. -*) We simplify PM support so that we only throw out resources on hibernate, -not on suspend, since the device keeps its state on suspend. - -Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> -Reviewed-by: Sinclair Yeh <syeh@vmware.com> ---- - drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 8 +- - drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 337 ++++++++++++++++++-------------- - drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 19 +- - drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 4 + - drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 12 +- - drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 1 + - drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 6 +- - drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 1 + - drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 4 +- - drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 12 +- - 10 files changed, 230 insertions(+), 174 deletions(-) - -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c -index 5ac92874404d..a8e370a55e90 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c -@@ -140,7 +140,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) - cmd->body.cid = cpu_to_le32(res->id); - - vmw_fifo_commit(dev_priv, sizeof(*cmd)); -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - } - - static int vmw_gb_context_init(struct vmw_private *dev_priv, -@@ -220,7 +220,7 @@ static int vmw_context_init(struct vmw_private *dev_priv, - cmd->body.cid = cpu_to_le32(res->id); - - vmw_fifo_commit(dev_priv, sizeof(*cmd)); -- (void) vmw_3d_resource_inc(dev_priv, false); -+ vmw_fifo_resource_inc(dev_priv); - vmw_resource_activate(res, vmw_hw_context_destroy); - return 0; - -@@ -281,7 +281,7 @@ static int vmw_gb_context_create(struct vmw_resource *res) - cmd->header.size = sizeof(cmd->body); - cmd->body.cid = res->id; - vmw_fifo_commit(dev_priv, sizeof(*cmd)); -- (void) vmw_3d_resource_inc(dev_priv, false); -+ vmw_fifo_resource_inc(dev_priv); - - return 0; - -@@ -414,7 +414,7 @@ static int vmw_gb_context_destroy(struct vmw_resource *res) - if (dev_priv->query_cid == res->id) - dev_priv->query_cid_valid = false; - vmw_resource_release_id(res); -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - - return 0; - } -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c -index 620bb5cf617c..a4766acd0ea2 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c -@@ -339,24 +339,47 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) - return ret; - } - --static int vmw_request_device(struct vmw_private *dev_priv) -+/** -+ * vmw_request_device_late - Perform late device setup -+ * -+ * @dev_priv: Pointer to device private. -+ * -+ * This function performs setup of otables and enables large command -+ * buffer submission. These tasks are split out to a separate function -+ * because it reverts vmw_release_device_early and is intended to be used -+ * by an error path in the hibernation code. -+ */ -+static int vmw_request_device_late(struct vmw_private *dev_priv) - { - int ret; - -- ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); -- if (unlikely(ret != 0)) { -- DRM_ERROR("Unable to initialize FIFO.\n"); -- return ret; -- } -- vmw_fence_fifo_up(dev_priv->fman); - if (dev_priv->has_mob) { - ret = vmw_otables_setup(dev_priv); - if (unlikely(ret != 0)) { - DRM_ERROR("Unable to initialize " - "guest Memory OBjects.\n"); -- goto out_no_mob; -+ return ret; - } - } -+ -+ return 0; -+} -+ -+static int vmw_request_device(struct vmw_private *dev_priv) -+{ -+ int ret; -+ -+ ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); -+ if (unlikely(ret != 0)) { -+ DRM_ERROR("Unable to initialize FIFO.\n"); -+ return ret; -+ } -+ vmw_fence_fifo_up(dev_priv->fman); -+ -+ ret = vmw_request_device_late(dev_priv); -+ if (ret) -+ goto out_no_mob; -+ - ret = vmw_dummy_query_bo_create(dev_priv); - if (unlikely(ret != 0)) - goto out_no_query_bo; -@@ -364,15 +387,25 @@ static int vmw_request_device(struct vmw_private *dev_priv) - return 0; - - out_no_query_bo: -- if (dev_priv->has_mob) -+ if (dev_priv->has_mob) { -+ (void) ttm_bo_evict_mm(&dev_priv->bdev, VMW_PL_MOB); - vmw_otables_takedown(dev_priv); -+ } - out_no_mob: - vmw_fence_fifo_down(dev_priv->fman); - vmw_fifo_release(dev_priv, &dev_priv->fifo); - return ret; - } - --static void vmw_release_device(struct vmw_private *dev_priv) -+/** -+ * vmw_release_device_early - Early part of fifo takedown. -+ * -+ * @dev_priv: Pointer to device private struct. -+ * -+ * This is the first part of command submission takedown, to be called before -+ * buffer management is taken down. -+ */ -+static void vmw_release_device_early(struct vmw_private *dev_priv) - { - /* - * Previous destructions should've released -@@ -382,64 +415,24 @@ static void vmw_release_device(struct vmw_private *dev_priv) - BUG_ON(dev_priv->pinned_bo != NULL); - - ttm_bo_unref(&dev_priv->dummy_query_bo); -- if (dev_priv->has_mob) -+ if (dev_priv->has_mob) { -+ ttm_bo_evict_mm(&dev_priv->bdev, VMW_PL_MOB); - vmw_otables_takedown(dev_priv); -- vmw_fence_fifo_down(dev_priv->fman); -- vmw_fifo_release(dev_priv, &dev_priv->fifo); --} -- -- --/** -- * Increase the 3d resource refcount. -- * If the count was prevously zero, initialize the fifo, switching to svga -- * mode. Note that the master holds a ref as well, and may request an -- * explicit switch to svga mode if fb is not running, using @unhide_svga. -- */ --int vmw_3d_resource_inc(struct vmw_private *dev_priv, -- bool unhide_svga) --{ -- int ret = 0; -- -- mutex_lock(&dev_priv->release_mutex); -- if (unlikely(dev_priv->num_3d_resources++ == 0)) { -- ret = vmw_request_device(dev_priv); -- if (unlikely(ret != 0)) -- --dev_priv->num_3d_resources; -- } else if (unhide_svga) { -- vmw_write(dev_priv, SVGA_REG_ENABLE, -- vmw_read(dev_priv, SVGA_REG_ENABLE) & -- ~SVGA_REG_ENABLE_HIDE); - } -- -- mutex_unlock(&dev_priv->release_mutex); -- return ret; - } - - /** -- * Decrease the 3d resource refcount. -- * If the count reaches zero, disable the fifo, switching to vga mode. -- * Note that the master holds a refcount as well, and may request an -- * explicit switch to vga mode when it releases its refcount to account -- * for the situation of an X server vt switch to VGA with 3d resources -- * active. -+ * vmw_release_device_late - Late part of fifo takedown. -+ * -+ * @dev_priv: Pointer to device private struct. -+ * -+ * This is the last part of the command submission takedown, to be called when -+ * command submission is no longer needed. It may wait on pending fences. - */ --void vmw_3d_resource_dec(struct vmw_private *dev_priv, -- bool hide_svga) -+static void vmw_release_device_late(struct vmw_private *dev_priv) - { -- int32_t n3d; -- -- mutex_lock(&dev_priv->release_mutex); -- if (unlikely(--dev_priv->num_3d_resources == 0)) -- vmw_release_device(dev_priv); -- else if (hide_svga) -- vmw_write(dev_priv, SVGA_REG_ENABLE, -- vmw_read(dev_priv, SVGA_REG_ENABLE) | -- SVGA_REG_ENABLE_HIDE); -- -- n3d = (int32_t) dev_priv->num_3d_resources; -- mutex_unlock(&dev_priv->release_mutex); -- -- BUG_ON(n3d < 0); -+ vmw_fence_fifo_down(dev_priv->fman); -+ vmw_fifo_release(dev_priv, &dev_priv->fifo); - } - - /** -@@ -603,6 +596,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) - spin_lock_init(&dev_priv->hw_lock); - spin_lock_init(&dev_priv->waiter_lock); - spin_lock_init(&dev_priv->cap_lock); -+ spin_lock_init(&dev_priv->svga_lock); - - for (i = vmw_res_context; i < vmw_res_max; ++i) { - idr_init(&dev_priv->res_idr[i]); -@@ -714,17 +708,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) - dev_priv->active_master = &dev_priv->fbdev_master; - - -- ret = ttm_bo_device_init(&dev_priv->bdev, -- dev_priv->bo_global_ref.ref.object, -- &vmw_bo_driver, -- dev->anon_inode->i_mapping, -- VMWGFX_FILE_PAGE_OFFSET, -- false); -- if (unlikely(ret != 0)) { -- DRM_ERROR("Failed initializing TTM buffer object driver.\n"); -- goto out_err1; -- } -- - dev_priv->mmio_mtrr = arch_phys_wc_add(dev_priv->mmio_start, - dev_priv->mmio_size); - -@@ -787,13 +770,28 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) - goto out_no_fman; - } - -+ ret = ttm_bo_device_init(&dev_priv->bdev, -+ dev_priv->bo_global_ref.ref.object, -+ &vmw_bo_driver, -+ dev->anon_inode->i_mapping, -+ VMWGFX_FILE_PAGE_OFFSET, -+ false); -+ if (unlikely(ret != 0)) { -+ DRM_ERROR("Failed initializing TTM buffer object driver.\n"); -+ goto out_no_bdev; -+ } - -+ /* -+ * Enable VRAM, but initially don't use it until SVGA is enabled and -+ * unhidden. -+ */ - ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM, - (dev_priv->vram_size >> PAGE_SHIFT)); - if (unlikely(ret != 0)) { - DRM_ERROR("Failed initializing memory manager for VRAM.\n"); - goto out_no_vram; - } -+ dev_priv->bdev.man[TTM_PL_VRAM].use_type = false; - - dev_priv->has_gmr = true; - if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) || -@@ -814,18 +812,18 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) - } - } - -- vmw_kms_save_vga(dev_priv); -- -- /* Start kms and overlay systems, needs fifo. */ - ret = vmw_kms_init(dev_priv); - if (unlikely(ret != 0)) - goto out_no_kms; - vmw_overlay_init(dev_priv); - -+ ret = vmw_request_device(dev_priv); -+ if (ret) -+ goto out_no_fifo; -+ - if (dev_priv->enable_fb) { -- ret = vmw_3d_resource_inc(dev_priv, true); -- if (unlikely(ret != 0)) -- goto out_no_fifo; -+ vmw_fifo_resource_inc(dev_priv); -+ vmw_svga_enable(dev_priv); - vmw_fb_init(dev_priv); - } - -@@ -838,13 +836,14 @@ out_no_fifo: - vmw_overlay_close(dev_priv); - vmw_kms_close(dev_priv); - out_no_kms: -- vmw_kms_restore_vga(dev_priv); - if (dev_priv->has_mob) - (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); - if (dev_priv->has_gmr) - (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); - (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); - out_no_vram: -+ (void)ttm_bo_device_release(&dev_priv->bdev); -+out_no_bdev: - vmw_fence_manager_takedown(dev_priv->fman); - out_no_fman: - if (dev_priv->capabilities & SVGA_CAP_IRQMASK) -@@ -860,8 +859,6 @@ out_err4: - iounmap(dev_priv->mmio_virt); - out_err3: - arch_phys_wc_del(dev_priv->mmio_mtrr); -- (void)ttm_bo_device_release(&dev_priv->bdev); --out_err1: - vmw_ttm_global_release(dev_priv); - out_err0: - for (i = vmw_res_context; i < vmw_res_max; ++i) -@@ -883,18 +880,22 @@ static int vmw_driver_unload(struct drm_device *dev) - vfree(dev_priv->ctx.cmd_bounce); - if (dev_priv->enable_fb) { - vmw_fb_close(dev_priv); -- vmw_kms_restore_vga(dev_priv); -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); -+ vmw_svga_disable(dev_priv); - } -+ - vmw_kms_close(dev_priv); - vmw_overlay_close(dev_priv); - -- if (dev_priv->has_mob) -- (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); - if (dev_priv->has_gmr) - (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); - (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); - -+ vmw_release_device_early(dev_priv); -+ if (dev_priv->has_mob) -+ (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); -+ (void) ttm_bo_device_release(&dev_priv->bdev); -+ vmw_release_device_late(dev_priv); - vmw_fence_manager_takedown(dev_priv->fman); - if (dev_priv->capabilities & SVGA_CAP_IRQMASK) - drm_irq_uninstall(dev_priv->dev); -@@ -1148,27 +1149,13 @@ static int vmw_master_set(struct drm_device *dev, - struct vmw_master *vmaster = vmw_master(file_priv->master); - int ret = 0; - -- if (!dev_priv->enable_fb) { -- ret = vmw_3d_resource_inc(dev_priv, true); -- if (unlikely(ret != 0)) -- return ret; -- vmw_kms_save_vga(dev_priv); -- vmw_write(dev_priv, SVGA_REG_TRACES, 0); -- } -- - if (active) { - BUG_ON(active != &dev_priv->fbdev_master); - ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); - if (unlikely(ret != 0)) -- goto out_no_active_lock; -+ return ret; - - ttm_lock_set_kill(&active->lock, true, SIGTERM); -- ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); -- if (unlikely(ret != 0)) { -- DRM_ERROR("Unable to clean VRAM on " -- "master drop.\n"); -- } -- - dev_priv->active_master = NULL; - } - -@@ -1182,14 +1169,6 @@ static int vmw_master_set(struct drm_device *dev, - dev_priv->active_master = vmaster; - - return 0; -- --out_no_active_lock: -- if (!dev_priv->enable_fb) { -- vmw_kms_restore_vga(dev_priv); -- vmw_3d_resource_dec(dev_priv, true); -- vmw_write(dev_priv, SVGA_REG_TRACES, 1); -- } -- return ret; - } - - static void vmw_master_drop(struct drm_device *dev, -@@ -1214,16 +1193,9 @@ static void vmw_master_drop(struct drm_device *dev, - } - - ttm_lock_set_kill(&vmaster->lock, false, SIGTERM); -- vmw_execbuf_release_pinned_bo(dev_priv); - -- if (!dev_priv->enable_fb) { -- ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); -- if (unlikely(ret != 0)) -- DRM_ERROR("Unable to clean VRAM on master drop.\n"); -- vmw_kms_restore_vga(dev_priv); -- vmw_3d_resource_dec(dev_priv, true); -- vmw_write(dev_priv, SVGA_REG_TRACES, 1); -- } -+ if (!dev_priv->enable_fb) -+ vmw_svga_disable(dev_priv); - - dev_priv->active_master = &dev_priv->fbdev_master; - ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); -@@ -1233,6 +1205,74 @@ static void vmw_master_drop(struct drm_device *dev, - vmw_fb_on(dev_priv); - } - -+/** -+ * __vmw_svga_enable - Enable SVGA mode, FIFO and use of VRAM. -+ * -+ * @dev_priv: Pointer to device private struct. -+ * Needs the reservation sem to be held in non-exclusive mode. -+ */ -+void __vmw_svga_enable(struct vmw_private *dev_priv) -+{ -+ spin_lock(&dev_priv->svga_lock); -+ if (!dev_priv->bdev.man[TTM_PL_VRAM].use_type) { -+ vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE); -+ dev_priv->bdev.man[TTM_PL_VRAM].use_type = true; -+ } -+ spin_unlock(&dev_priv->svga_lock); -+} -+ -+/** -+ * vmw_svga_enable - Enable SVGA mode, FIFO and use of VRAM. -+ * -+ * @dev_priv: Pointer to device private struct. -+ */ -+void vmw_svga_enable(struct vmw_private *dev_priv) -+{ -+ ttm_read_lock(&dev_priv->reservation_sem, false); -+ __vmw_svga_enable(dev_priv); -+ ttm_read_unlock(&dev_priv->reservation_sem); -+} -+ -+/** -+ * __vmw_svga_disable - Disable SVGA mode and use of VRAM. -+ * -+ * @dev_priv: Pointer to device private struct. -+ * Needs the reservation sem to be held in exclusive mode. -+ * Will not empty VRAM. VRAM must be emptied by caller. -+ */ -+void __vmw_svga_disable(struct vmw_private *dev_priv) -+{ -+ spin_lock(&dev_priv->svga_lock); -+ if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) { -+ dev_priv->bdev.man[TTM_PL_VRAM].use_type = false; -+ vmw_write(dev_priv, SVGA_REG_ENABLE, -+ SVGA_REG_ENABLE_ENABLE_HIDE); -+ } -+ spin_unlock(&dev_priv->svga_lock); -+} -+ -+/** -+ * vmw_svga_disable - Disable SVGA_MODE, and use of VRAM. Keep the fifo -+ * running. -+ * -+ * @dev_priv: Pointer to device private struct. -+ * Will empty VRAM. -+ */ -+void vmw_svga_disable(struct vmw_private *dev_priv) -+{ -+ ttm_write_lock(&dev_priv->reservation_sem, false); -+ spin_lock(&dev_priv->svga_lock); -+ if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) { -+ dev_priv->bdev.man[TTM_PL_VRAM].use_type = false; -+ vmw_write(dev_priv, SVGA_REG_ENABLE, -+ SVGA_REG_ENABLE_ENABLE_HIDE); -+ spin_unlock(&dev_priv->svga_lock); -+ if (ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM)) -+ DRM_ERROR("Failed evicting VRAM buffers.\n"); -+ } else -+ spin_unlock(&dev_priv->svga_lock); -+ ttm_write_unlock(&dev_priv->reservation_sem); -+} - - static void vmw_remove(struct pci_dev *pdev) - { -@@ -1250,21 +1290,21 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, - - switch (val) { - case PM_HIBERNATION_PREPARE: -- case PM_SUSPEND_PREPARE: - ttm_suspend_lock(&dev_priv->reservation_sem); - -- /** -+ /* - * This empties VRAM and unbinds all GMR bindings. - * Buffer contents is moved to swappable memory. - */ - 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); - break; - case PM_POST_HIBERNATION: -- case PM_POST_SUSPEND: - case PM_POST_RESTORE: -+ vmw_fence_fifo_up(dev_priv->fman); - ttm_suspend_unlock(&dev_priv->reservation_sem); - - break; -@@ -1276,20 +1316,13 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, - return 0; - } - --/** -- * These might not be needed with the virtual SVGA device. -- */ -- - static int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state) - { - struct drm_device *dev = pci_get_drvdata(pdev); - struct vmw_private *dev_priv = vmw_priv(dev); - -- if (dev_priv->num_3d_resources != 0) { -- DRM_INFO("Can't suspend or hibernate " -- "while 3D resources are active.\n"); -+ if (dev_priv->refuse_hibernation) - return -EBUSY; -- } - - pci_save_state(pdev); - pci_disable_device(pdev); -@@ -1321,56 +1354,62 @@ static int vmw_pm_resume(struct device *kdev) - return vmw_pci_resume(pdev); - } - --static int vmw_pm_prepare(struct device *kdev) -+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); - -- /** -- * Release 3d reference held by fbdev and potentially -- * stop fifo. -- */ - dev_priv->suspended = true; - if (dev_priv->enable_fb) -- vmw_3d_resource_dec(dev_priv, true); -- -- if (dev_priv->num_3d_resources != 0) { -- -- DRM_INFO("Can't suspend or hibernate " -- "while 3D resources are active.\n"); -+ 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_3d_resource_inc(dev_priv, true); -+ vmw_fifo_resource_inc(dev_priv); -+ WARN_ON(vmw_request_device_late(dev_priv)); - dev_priv->suspended = false; - return -EBUSY; - } - -+ if (dev_priv->enable_fb) -+ __vmw_svga_disable(dev_priv); -+ -+ vmw_release_device_late(dev_priv); -+ - return 0; - } - --static void vmw_pm_complete(struct device *kdev) -+static int vmw_pm_restore(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; - - vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); - (void) vmw_read(dev_priv, SVGA_REG_ID); - -- /** -- * Reclaim 3d reference held by fbdev and potentially -- * start fifo. -- */ - if (dev_priv->enable_fb) -- vmw_3d_resource_inc(dev_priv, false); -+ vmw_fifo_resource_inc(dev_priv); -+ -+ ret = vmw_request_device(dev_priv); -+ if (ret) -+ return ret; -+ -+ if (dev_priv->enable_fb) -+ __vmw_svga_enable(dev_priv); - - dev_priv->suspended = false; -+ -+ return 0; - } - - static const struct dev_pm_ops vmw_pm_ops = { -- .prepare = vmw_pm_prepare, -- .complete = vmw_pm_complete, -+ .freeze = vmw_pm_freeze, -+ .thaw = vmw_pm_restore, -+ .restore = vmw_pm_restore, - .suspend = vmw_pm_suspend, - .resume = vmw_pm_resume, - }; -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -index d26a6daa9719..a5f221eaf076 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -@@ -484,6 +484,7 @@ struct vmw_private { - - bool stealth; - bool enable_fb; -+ spinlock_t svga_lock; - - /** - * Master management. -@@ -493,9 +494,10 @@ struct vmw_private { - struct vmw_master fbdev_master; - struct notifier_block pm_nb; - bool suspended; -+ bool refuse_hibernation; - - struct mutex release_mutex; -- uint32_t num_3d_resources; -+ atomic_t num_fifo_resources; - - /* - * Replace this with an rwsem as soon as we have down_xx_interruptible() -@@ -587,8 +589,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, - return val; - } - --int vmw_3d_resource_inc(struct vmw_private *dev_priv, bool unhide_svga); --void vmw_3d_resource_dec(struct vmw_private *dev_priv, bool hide_svga); -+extern void vmw_svga_enable(struct vmw_private *dev_priv); -+extern void vmw_svga_disable(struct vmw_private *dev_priv); -+ - - /** - * GMR utilities - vmwgfx_gmr.c -@@ -1116,4 +1119,14 @@ static inline struct ttm_mem_global *vmw_mem_glob(struct vmw_private *dev_priv) - { - return (struct ttm_mem_global *) dev_priv->mem_global_ref.object; - } -+ -+static inline void vmw_fifo_resource_inc(struct vmw_private *dev_priv) -+{ -+ atomic_inc(&dev_priv->num_fifo_resources); -+} -+ -+static inline void vmw_fifo_resource_dec(struct vmw_private *dev_priv) -+{ -+ atomic_dec(&dev_priv->num_fifo_resources); -+} - #endif -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c -index 0a474f391fad..0e062613a7db 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c -@@ -596,7 +596,10 @@ int vmw_fb_off(struct vmw_private *vmw_priv) - - info = vmw_priv->fb_info; - par = info->par; -+ if (!par->bo_ptr) -+ return 0; - -+ vmw_kms_save_vga(vmw_priv); - spin_lock_irqsave(&par->dirty.lock, flags); - par->dirty.active = false; - spin_unlock_irqrestore(&par->dirty.lock, flags); -@@ -648,6 +651,7 @@ int vmw_fb_on(struct vmw_private *vmw_priv) - spin_lock_irqsave(&par->dirty.lock, flags); - par->dirty.active = true; - spin_unlock_irqrestore(&par->dirty.lock, flags); -+ vmw_kms_restore_vga(vmw_priv); - - err_no_buffer: - vmw_fb_set_par(info); -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c -index 39f2b03888e7..cd5d9f3fe0e0 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c -@@ -98,7 +98,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) - __le32 __iomem *fifo_mem = dev_priv->mmio_virt; - uint32_t max; - uint32_t min; -- uint32_t dummy; - - fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE; - fifo->static_buffer = vmalloc(fifo->static_buffer_size); -@@ -112,10 +111,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) - mutex_init(&fifo->fifo_mutex); - init_rwsem(&fifo->rwsem); - -- /* -- * Allow mapping the first page read-only to user-space. -- */ -- - DRM_INFO("width %d\n", vmw_read(dev_priv, SVGA_REG_WIDTH)); - DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); - DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); -@@ -123,7 +118,9 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) - dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); - dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); - dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); -- vmw_write(dev_priv, SVGA_REG_ENABLE, 1); -+ -+ vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE_ENABLE_HIDE); -+ vmw_write(dev_priv, SVGA_REG_TRACES, 0); - - min = 4; - if (dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO) -@@ -155,7 +152,8 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) - atomic_set(&dev_priv->marker_seq, dev_priv->last_read_seqno); - iowrite32(dev_priv->last_read_seqno, fifo_mem + SVGA_FIFO_FENCE); - vmw_marker_queue_init(&fifo->marker_queue); -- return vmw_fifo_send_fence(dev_priv, &dummy); -+ -+ return 0; - } - - void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c -index 5c289f748ab4..53579f278b63 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c -@@ -280,6 +280,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) - } - - vmw_fb_off(dev_priv); -+ vmw_svga_enable(dev_priv); - - crtc->primary->fb = fb; - encoder->crtc = crtc; -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c -index 04a64b8cd3cd..f06d60f41fa7 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c -@@ -574,7 +574,7 @@ void vmw_mob_unbind(struct vmw_private *dev_priv, - vmw_fence_single_bo(bo, NULL); - ttm_bo_unreserve(bo); - } -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - } - - /* -@@ -627,7 +627,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv, - mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1; - } - -- (void) vmw_3d_resource_inc(dev_priv, false); -+ vmw_fifo_resource_inc(dev_priv); - - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { -@@ -648,7 +648,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv, - return 0; - - out_no_cmd_space: -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - if (pt_set_up) - ttm_bo_unref(&mob->pt_bo); - -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c -index 7dc591d04d9a..9e8eb364a6ac 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c -@@ -332,6 +332,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) - } - - vmw_fb_off(dev_priv); -+ vmw_svga_enable(dev_priv); - - if (mode->hdisplay != crtc->mode.hdisplay || - mode->vdisplay != crtc->mode.vdisplay) { -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c -index 6a4584a43aa6..6110a433ebfe 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c -@@ -165,7 +165,7 @@ static int vmw_gb_shader_create(struct vmw_resource *res) - cmd->body.type = shader->type; - cmd->body.sizeInBytes = shader->size; - vmw_fifo_commit(dev_priv, sizeof(*cmd)); -- (void) vmw_3d_resource_inc(dev_priv, false); -+ vmw_fifo_resource_inc(dev_priv); - - return 0; - -@@ -275,7 +275,7 @@ static int vmw_gb_shader_destroy(struct vmw_resource *res) - vmw_fifo_commit(dev_priv, sizeof(*cmd)); - mutex_unlock(&dev_priv->binding_mutex); - vmw_resource_release_id(res); -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - - return 0; - } -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -index 4ecdbf3e59da..4d0c98edeb6a 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -@@ -340,7 +340,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) - dev_priv->used_memory_size -= res->backup_size; - mutex_unlock(&dev_priv->cmdbuf_mutex); - } -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - } - - /** -@@ -576,14 +576,14 @@ static int vmw_surface_init(struct vmw_private *dev_priv, - - BUG_ON(res_free == NULL); - if (!dev_priv->has_mob) -- (void) vmw_3d_resource_inc(dev_priv, false); -+ vmw_fifo_resource_inc(dev_priv); - ret = vmw_resource_init(dev_priv, res, true, res_free, - (dev_priv->has_mob) ? &vmw_gb_surface_func : - &vmw_legacy_surface_func); - - if (unlikely(ret != 0)) { - if (!dev_priv->has_mob) -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - res_free(res); - return ret; - } -@@ -1028,7 +1028,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res) - if (likely(res->id != -1)) - return 0; - -- (void) vmw_3d_resource_inc(dev_priv, false); -+ vmw_fifo_resource_inc(dev_priv); - ret = vmw_resource_alloc_id(res); - if (unlikely(ret != 0)) { - DRM_ERROR("Failed to allocate a surface id.\n"); -@@ -1068,7 +1068,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res) - out_no_fifo: - vmw_resource_release_id(res); - out_no_id: -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - return ret; - } - -@@ -1213,7 +1213,7 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res) - vmw_fifo_commit(dev_priv, sizeof(*cmd)); - mutex_unlock(&dev_priv->binding_mutex); - vmw_resource_release_id(res); -- vmw_3d_resource_dec(dev_priv, false); -+ vmw_fifo_resource_dec(dev_priv); - - return 0; - } --- -2.4.3 - |