drm/vmwgfx: Refactor resource management
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / vmwgfx / vmwgfx_drv.c
index 56973cd417358633ca109702d10968c71521d410..91581fd5004b1141059b9ff00aa7d4c999bea6d9 100644 (file)
@@ -432,6 +432,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
        struct vmw_private *dev_priv;
        int ret;
        uint32_t svga_id;
+       enum vmw_res_type i;
 
        dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
        if (unlikely(dev_priv == NULL)) {
@@ -448,15 +449,18 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
        mutex_init(&dev_priv->cmdbuf_mutex);
        mutex_init(&dev_priv->release_mutex);
        rwlock_init(&dev_priv->resource_lock);
-       idr_init(&dev_priv->context_idr);
-       idr_init(&dev_priv->surface_idr);
-       idr_init(&dev_priv->stream_idr);
+
+       for (i = vmw_res_context; i < vmw_res_max; ++i) {
+               idr_init(&dev_priv->res_idr[i]);
+               INIT_LIST_HEAD(&dev_priv->res_lru[i]);
+       }
+
        mutex_init(&dev_priv->init_mutex);
        init_waitqueue_head(&dev_priv->fence_queue);
        init_waitqueue_head(&dev_priv->fifo_queue);
        dev_priv->fence_queue_waiters = 0;
        atomic_set(&dev_priv->fifo_queue_waiters, 0);
-       INIT_LIST_HEAD(&dev_priv->surface_lru);
+
        dev_priv->used_memory_size = 0;
 
        dev_priv->io_start = pci_resource_start(dev->pdev, 0);
@@ -670,9 +674,9 @@ out_err2:
 out_err1:
        vmw_ttm_global_release(dev_priv);
 out_err0:
-       idr_destroy(&dev_priv->surface_idr);
-       idr_destroy(&dev_priv->context_idr);
-       idr_destroy(&dev_priv->stream_idr);
+       for (i = vmw_res_context; i < vmw_res_max; ++i)
+               idr_destroy(&dev_priv->res_idr[i]);
+
        kfree(dev_priv);
        return ret;
 }
@@ -680,9 +684,12 @@ out_err0:
 static int vmw_driver_unload(struct drm_device *dev)
 {
        struct vmw_private *dev_priv = vmw_priv(dev);
+       enum vmw_res_type i;
 
        unregister_pm_notifier(&dev_priv->pm_nb);
 
+       if (dev_priv->ctx.res_ht_initialized)
+               drm_ht_remove(&dev_priv->ctx.res_ht);
        if (dev_priv->ctx.cmd_bounce)
                vfree(dev_priv->ctx.cmd_bounce);
        if (dev_priv->enable_fb) {
@@ -709,9 +716,9 @@ static int vmw_driver_unload(struct drm_device *dev)
        (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
        (void)ttm_bo_device_release(&dev_priv->bdev);
        vmw_ttm_global_release(dev_priv);
-       idr_destroy(&dev_priv->surface_idr);
-       idr_destroy(&dev_priv->context_idr);
-       idr_destroy(&dev_priv->stream_idr);
+
+       for (i = vmw_res_context; i < vmw_res_max; ++i)
+               idr_destroy(&dev_priv->res_idr[i]);
 
        kfree(dev_priv);
 
@@ -935,7 +942,7 @@ static void vmw_master_drop(struct drm_device *dev,
 
        vmw_fp->locked_master = drm_master_get(file_priv->master);
        ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile);
-       vmw_execbuf_release_pinned_bo(dev_priv, false, 0);
+       vmw_execbuf_release_pinned_bo(dev_priv);
 
        if (unlikely((ret != 0))) {
                DRM_ERROR("Unable to lock TTM at VT switch.\n");
@@ -987,7 +994,8 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
                 * This empties VRAM and unbinds all GMR bindings.
                 * Buffer contents is moved to swappable memory.
                 */
-               vmw_execbuf_release_pinned_bo(dev_priv, false, 0);
+               vmw_execbuf_release_pinned_bo(dev_priv);
+               vmw_resource_evict_all(dev_priv);
                ttm_bo_swapout_all(&dev_priv->bdev);
 
                break;