OSDN Git Service

drm/i915: Reset request handling for gen8+
[android-x86/kernel.git] / drivers / gpu / drm / i915 / intel_uncore.c
index 4a86cf0..160a47a 100644 (file)
@@ -1455,9 +1455,50 @@ static int gen6_do_reset(struct drm_device *dev)
        return ret;
 }
 
+static int wait_for_register(struct drm_i915_private *dev_priv,
+                            const u32 reg,
+                            const u32 mask,
+                            const u32 value,
+                            const unsigned long timeout_ms)
+{
+       return wait_for((I915_READ(reg) & mask) == value, timeout_ms);
+}
+
+static int gen8_do_reset(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_engine_cs *engine;
+       int i;
+
+       for_each_ring(engine, dev_priv, i) {
+               I915_WRITE(RING_RESET_CTL(engine->mmio_base),
+                          _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET));
+
+               if (wait_for_register(dev_priv,
+                                     RING_RESET_CTL(engine->mmio_base),
+                                     RESET_CTL_READY_TO_RESET,
+                                     RESET_CTL_READY_TO_RESET,
+                                     700)) {
+                       DRM_ERROR("%s: reset request timeout\n", engine->name);
+                       goto not_ready;
+               }
+       }
+
+       return gen6_do_reset(dev);
+
+not_ready:
+       for_each_ring(engine, dev_priv, i)
+               I915_WRITE(RING_RESET_CTL(engine->mmio_base),
+                          _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET));
+
+       return -EIO;
+}
+
 static int (*intel_get_gpu_reset(struct drm_device *dev))(struct drm_device *)
 {
-       if (INTEL_INFO(dev)->gen >= 6)
+       if (INTEL_INFO(dev)->gen >= 8)
+               return gen8_do_reset;
+       else if (INTEL_INFO(dev)->gen >= 6)
                return gen6_do_reset;
        else if (IS_GEN5(dev))
                return ironlake_do_reset;