Merge airlied/drm-next into drm-intel-next-queued
[muen/linux.git] / drivers / gpu / drm / i915 / i915_drv.c
index 4c96a72..25de4a9 100644 (file)
@@ -237,17 +237,17 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
                                        !IS_KABYLAKE(dev_priv));
                        } else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
                                dev_priv->pch_type = PCH_KBP;
-                               DRM_DEBUG_KMS("Found KabyPoint PCH\n");
+                               DRM_DEBUG_KMS("Found Kaby Lake PCH (KBP)\n");
                                WARN_ON(!IS_SKYLAKE(dev_priv) &&
                                        !IS_KABYLAKE(dev_priv));
                        } else if (id == INTEL_PCH_CNP_DEVICE_ID_TYPE) {
                                dev_priv->pch_type = PCH_CNP;
-                               DRM_DEBUG_KMS("Found CannonPoint PCH\n");
+                               DRM_DEBUG_KMS("Found Cannon Lake PCH (CNP)\n");
                                WARN_ON(!IS_CANNONLAKE(dev_priv) &&
                                        !IS_COFFEELAKE(dev_priv));
                        } else if (id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
                                dev_priv->pch_type = PCH_CNP;
-                               DRM_DEBUG_KMS("Found CannonPoint LP PCH\n");
+                               DRM_DEBUG_KMS("Found Cannon Lake LP PCH (CNP-LP)\n");
                                WARN_ON(!IS_CANNONLAKE(dev_priv) &&
                                        !IS_COFFEELAKE(dev_priv));
                        } else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
@@ -596,7 +596,8 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
 
 static void i915_gem_fini(struct drm_i915_private *dev_priv)
 {
-       flush_workqueue(dev_priv->wq);
+       /* Flush any outstanding unpin_work. */
+       i915_gem_drain_workqueue(dev_priv);
 
        mutex_lock(&dev_priv->drm.struct_mutex);
        intel_uc_fini_hw(dev_priv);
@@ -875,7 +876,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
        spin_lock_init(&dev_priv->uncore.lock);
 
        spin_lock_init(&dev_priv->mm.object_stat_lock);
-       spin_lock_init(&dev_priv->mmio_flip_lock);
        mutex_init(&dev_priv->sb_lock);
        mutex_init(&dev_priv->modeset_restore_lock);
        mutex_init(&dev_priv->av_mutex);
@@ -1240,6 +1240,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
  */
 static void i915_driver_unregister(struct drm_i915_private *dev_priv)
 {
+       intel_fbdev_unregister(dev_priv);
        intel_audio_deinit(dev_priv);
 
        intel_gpu_ips_teardown();
@@ -1371,7 +1372,7 @@ void i915_driver_unload(struct drm_device *dev)
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct pci_dev *pdev = dev_priv->drm.pdev;
 
-       intel_fbdev_fini(dev);
+       i915_driver_unregister(dev_priv);
 
        if (i915_gem_suspend(dev_priv))
                DRM_ERROR("failed to idle hardware; continuing to unload!\n");
@@ -1382,8 +1383,6 @@ void i915_driver_unload(struct drm_device *dev)
 
        intel_gvt_cleanup(dev_priv);
 
-       i915_driver_unregister(dev_priv);
-
        intel_modeset_cleanup(dev);
 
        /*
@@ -1409,9 +1408,6 @@ void i915_driver_unload(struct drm_device *dev)
        cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
        i915_reset_error_state(dev_priv);
 
-       /* Flush any outstanding unpin_work. */
-       drain_workqueue(dev_priv->wq);
-
        i915_gem_fini(dev_priv);
        intel_uc_fini_fw(dev_priv);
        intel_fbc_cleanup_cfb(dev_priv);
@@ -1835,7 +1831,8 @@ static int i915_resume_switcheroo(struct drm_device *dev)
 
 /**
  * i915_reset - reset chip after a hang
- * @dev_priv: device private to reset
+ * @i915: #drm_i915_private to reset
+ * @flags: Instructions
  *
  * Reset the chip.  Useful if a hang is detected. Marks the device as wedged
  * on failure.
@@ -1850,33 +1847,34 @@ static int i915_resume_switcheroo(struct drm_device *dev)
  *   - re-init interrupt state
  *   - re-init display
  */
-void i915_reset(struct drm_i915_private *dev_priv)
+void i915_reset(struct drm_i915_private *i915, unsigned int flags)
 {
-       struct i915_gpu_error *error = &dev_priv->gpu_error;
+       struct i915_gpu_error *error = &i915->gpu_error;
        int ret;
 
-       lockdep_assert_held(&dev_priv->drm.struct_mutex);
+       lockdep_assert_held(&i915->drm.struct_mutex);
        GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags));
 
        if (!test_bit(I915_RESET_HANDOFF, &error->flags))
                return;
 
        /* Clear any previous failed attempts at recovery. Time to try again. */
-       if (!i915_gem_unset_wedged(dev_priv))
+       if (!i915_gem_unset_wedged(i915))
                goto wakeup;
 
+       if (!(flags & I915_RESET_QUIET))
+               dev_notice(i915->drm.dev, "Resetting chip after gpu hang\n");
        error->reset_count++;
 
-       pr_notice("drm/i915: Resetting chip after gpu hang\n");
-       disable_irq(dev_priv->drm.irq);
-       ret = i915_gem_reset_prepare(dev_priv);
+       disable_irq(i915->drm.irq);
+       ret = i915_gem_reset_prepare(i915);
        if (ret) {
                DRM_ERROR("GPU recovery failed\n");
-               intel_gpu_reset(dev_priv, ALL_ENGINES);
+               intel_gpu_reset(i915, ALL_ENGINES);
                goto error;
        }
 
-       ret = intel_gpu_reset(dev_priv, ALL_ENGINES);
+       ret = intel_gpu_reset(i915, ALL_ENGINES);
        if (ret) {
                if (ret != -ENODEV)
                        DRM_ERROR("Failed to reset chip: %i\n", ret);
@@ -1885,8 +1883,8 @@ void i915_reset(struct drm_i915_private *dev_priv)
                goto error;
        }
 
-       i915_gem_reset(dev_priv);
-       intel_overlay_reset(dev_priv);
+       i915_gem_reset(i915);
+       intel_overlay_reset(i915);
 
        /* Ok, now get things going again... */
 
@@ -1902,17 +1900,17 @@ void i915_reset(struct drm_i915_private *dev_priv)
         * was running at the time of the reset (i.e. we weren't VT
         * switched away).
         */
-       ret = i915_gem_init_hw(dev_priv);
+       ret = i915_gem_init_hw(i915);
        if (ret) {
                DRM_ERROR("Failed hw init on reset %d\n", ret);
                goto error;
        }
 
-       i915_queue_hangcheck(dev_priv);
+       i915_queue_hangcheck(i915);
 
 finish:
-       i915_gem_reset_finish(dev_priv);
-       enable_irq(dev_priv->drm.irq);
+       i915_gem_reset_finish(i915);
+       enable_irq(i915->drm.irq);
 
 wakeup:
        clear_bit(I915_RESET_HANDOFF, &error->flags);
@@ -1920,14 +1918,15 @@ wakeup:
        return;
 
 error:
-       i915_gem_set_wedged(dev_priv);
-       i915_gem_retire_requests(dev_priv);
+       i915_gem_set_wedged(i915);
+       i915_gem_retire_requests(i915);
        goto finish;
 }
 
 /**
  * i915_reset_engine - reset GPU engine to recover from a hang
  * @engine: engine to reset
+ * @flags: options
  *
  * Reset a specific GPU engine. Useful if a hang is detected.
  * Returns zero on successful reset or otherwise an error code.
@@ -1937,7 +1936,7 @@ error:
  *  - reset engine (which will force the engine to idle)
  *  - re-init/configure engine
  */
-int i915_reset_engine(struct intel_engine_cs *engine)
+int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags)
 {
        struct i915_gpu_error *error = &engine->i915->gpu_error;
        struct drm_i915_gem_request *active_request;
@@ -1945,7 +1944,11 @@ int i915_reset_engine(struct intel_engine_cs *engine)
 
        GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
 
-       DRM_DEBUG_DRIVER("resetting %s\n", engine->name);
+       if (!(flags & I915_RESET_QUIET)) {
+               dev_notice(engine->i915->drm.dev,
+                          "Resetting %s after gpu hang\n", engine->name);
+       }
+       error->reset_engine_count[engine->id]++;
 
        active_request = i915_gem_reset_prepare_engine(engine);
        if (IS_ERR(active_request)) {
@@ -1954,18 +1957,7 @@ int i915_reset_engine(struct intel_engine_cs *engine)
                goto out;
        }
 
-       /*
-        * The request that caused the hang is stuck on elsp, we know the
-        * active request and can drop it, adjust head to skip the offending
-        * request to resume executing remaining requests in the queue.
-        */
-       i915_gem_reset_engine(engine, active_request);
-
-       /* Finally, reset just this engine. */
        ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));
-
-       i915_gem_reset_finish_engine(engine);
-
        if (ret) {
                /* If we fail here, we expect to fallback to a global reset */
                DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
@@ -1973,6 +1965,13 @@ int i915_reset_engine(struct intel_engine_cs *engine)
                goto out;
        }
 
+       /*
+        * The request that caused the hang is stuck on elsp, we know the
+        * active request and can drop it, adjust head to skip the offending
+        * request to resume executing remaining requests in the queue.
+        */
+       i915_gem_reset_engine(engine, active_request);
+
        /*
         * The engine and its registers (and workarounds in case of render)
         * have been reset to their default values. Follow the init_ring
@@ -1982,8 +1981,8 @@ int i915_reset_engine(struct intel_engine_cs *engine)
        if (ret)
                goto out;
 
-       error->reset_engine_count[engine->id]++;
 out:
+       i915_gem_reset_finish_engine(engine);
        return ret;
 }
 
@@ -2730,6 +2729,8 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_PERF_ADD_CONFIG, i915_perf_add_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_PERF_REMOVE_CONFIG, i915_perf_remove_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 };
 
 static struct drm_driver driver = {