drm/i915/skl: Program the DDB allocation
[deliverable/linux.git] / drivers / gpu / drm / i915 / i915_gem_context.c
index 0fdb357f8a5c0138dd045cab5daa4d89c041dedb..7d3257111737e7babdb37d48f4269172c62cec3d 100644 (file)
@@ -289,6 +289,12 @@ void i915_gem_context_reset(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
 
+       /* In execlists mode we will unreference the context when the execlist
+        * queue is cleared and the requests destroyed.
+        */
+       if (i915.enable_execlists)
+               return;
+
        for (i = 0; i < I915_NUM_RINGS; i++) {
                struct intel_engine_cs *ring = &dev_priv->ring[i];
                struct intel_context *lctx = ring->last_context;
@@ -397,6 +403,9 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
 
        BUG_ON(!dev_priv->ring[RCS].default_context);
 
+       if (i915.enable_execlists)
+               return 0;
+
        for_each_ring(ring, dev_priv, i) {
                ret = i915_switch_context(ring, ring->default_context);
                if (ret)
@@ -458,6 +467,7 @@ mi_set_context(struct intel_engine_cs *ring,
               struct intel_context *new_context,
               u32 hw_flags)
 {
+       u32 flags = hw_flags | MI_MM_SPACE_GTT;
        int ret;
 
        /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB
@@ -471,6 +481,10 @@ mi_set_context(struct intel_engine_cs *ring,
                        return ret;
        }
 
+       /* These flags are for resource streamer on HSW+ */
+       if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8)
+               flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN);
+
        ret = intel_ring_begin(ring, 6);
        if (ret)
                return ret;
@@ -484,10 +498,7 @@ mi_set_context(struct intel_engine_cs *ring,
        intel_ring_emit(ring, MI_NOOP);
        intel_ring_emit(ring, MI_SET_CONTEXT);
        intel_ring_emit(ring, i915_gem_obj_ggtt_offset(new_context->legacy_hw_ctx.rcs_state) |
-                       MI_MM_SPACE_GTT |
-                       MI_SAVE_EXT_STATE_EN |
-                       MI_RESTORE_EXT_STATE_EN |
-                       hw_flags);
+                       flags);
        /*
         * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP
         * WaMiSetContext_Hang:snb,ivb,vlv
@@ -511,6 +522,7 @@ static int do_switch(struct intel_engine_cs *ring,
        struct intel_context *from = ring->last_context;
        u32 hw_flags = 0;
        bool uninitialized = false;
+       struct i915_vma *vma;
        int ret, i;
 
        if (from != NULL && ring == &dev_priv->ring[RCS]) {
@@ -560,11 +572,10 @@ static int do_switch(struct intel_engine_cs *ring,
        if (ret)
                goto unpin_out;
 
-       if (!to->legacy_hw_ctx.rcs_state->has_global_gtt_mapping) {
-               struct i915_vma *vma = i915_gem_obj_to_vma(to->legacy_hw_ctx.rcs_state,
-                                                          &dev_priv->gtt.base);
-               vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level, GLOBAL_BIND);
-       }
+       vma = i915_gem_obj_to_ggtt(to->legacy_hw_ctx.rcs_state);
+       if (!(vma->bound & GLOBAL_BIND))
+               vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level,
+                               GLOBAL_BIND);
 
        if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
                hw_flags |= MI_RESTORE_INHIBIT;
@@ -617,6 +628,12 @@ done:
        ring->last_context = to;
 
        if (uninitialized) {
+               if (ring->init_context) {
+                       ret = ring->init_context(ring);
+                       if (ret)
+                               DRM_ERROR("ring init context: %d\n", ret);
+               }
+
                ret = i915_gem_render_state_init(ring);
                if (ret)
                        DRM_ERROR("init render state: %d\n", ret);
@@ -637,14 +654,19 @@ unpin_out:
  *
  * The context life cycle is simple. The context refcount is incremented and
  * decremented by 1 and create and destroy. If the context is in use by the GPU,
- * it will have a refoucnt > 1. This allows us to destroy the context abstract
+ * it will have a refcount > 1. This allows us to destroy the context abstract
  * object while letting the normal object tracking destroy the backing BO.
+ *
+ * This function should not be used in execlists mode.  Instead the context is
+ * switched by writing to the ELSP and requests keep a reference to their
+ * context.
  */
 int i915_switch_context(struct intel_engine_cs *ring,
                        struct intel_context *to)
 {
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
 
+       WARN_ON(i915.enable_execlists);
        WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
 
        if (to->legacy_hw_ctx.rcs_state == NULL) { /* We have the fake context */
This page took 0.028375 seconds and 5 git commands to generate.