In order to do the full context switch with address space, it's
convenient to have a way to switch the address space. We already have
this in our code - just pull it out to be called by the context switch
code later.

Signed-off-by: Ben Widawsky <b...@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_drv.h     |  2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c | 79 +++++++++++++++++++++----------------
 2 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 883d314..7865618 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -534,6 +534,8 @@ struct i915_hw_ppgtt {
        gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr,
                                     enum i915_cache_level level);
        int (*enable)(struct i915_hw_ppgtt *ppgtt);
+       int (*switch_mm)(struct i915_hw_ppgtt *ppgtt,
+                        struct intel_ring_buffer *ring);
        void (*cleanup)(struct i915_hw_ppgtt *ppgtt);
 };
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index be5c7a9..646e8ef 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -122,11 +122,54 @@ static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
        readl(pd_addr);
 }
 
+static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt,
+                         struct intel_ring_buffer *ring)
+{
+       struct drm_device *dev = ppgtt->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       uint32_t pd_offset = ppgtt->pd_offset;
+       int ret;
+
+       pd_offset /= 64; /* in cachelines, */
+       pd_offset <<= 16;
+
+       /* If we're in reset, we can assume the GPU is sufficiently idle
+        * to manually frob these bits. Ideally we could use the ring
+        * functions, except our error handling makes it quite difficult
+        * (can't use intel_ring_begin, ring->flush, or
+        * intel_ring_advance)
+        */
+       if (i915_reset_in_progress(&dev_priv->gpu_error)) {
+               WARN_ON(ppgtt != dev_priv->gtt.aliasing_ppgtt);
+               I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
+               I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset);
+               return 0;
+       }
+
+       /* NB: TLBs must be flushed and invalidated before a switch */
+       ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
+       if (ret)
+               return ret;
+
+       ret = intel_ring_begin(ring, 6);
+       if (ret)
+               return ret;
+
+       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(2));
+       intel_ring_emit(ring, RING_PP_DIR_DCLV(ring));
+       intel_ring_emit(ring, PP_DIR_DCLV_2G);
+       intel_ring_emit(ring, RING_PP_DIR_BASE(ring));
+       intel_ring_emit(ring, pd_offset);
+       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_advance(ring);
+
+       return 0;
+}
+
 static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
 {
        struct drm_device *dev = ppgtt->base.dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       uint32_t pd_offset;
        struct intel_ring_buffer *ring;
        int i;
 
@@ -134,10 +177,6 @@ static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
 
        gen6_write_pdes(ppgtt);
 
-       pd_offset = ppgtt->pd_offset;
-       pd_offset /= 64; /* in cachelines, */
-       pd_offset <<= 16;
-
        if (INTEL_INFO(dev)->gen == 6) {
                uint32_t ecochk, gab_ctl, ecobits;
 
@@ -179,36 +218,9 @@ static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
                        I915_WRITE(RING_MODE_GEN7(ring),
                                   _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
 
-               /* If we're in reset, we can assume the GPU is sufficiently idle
-                * to manually frob these bits. Ideally we could use the ring
-                * functions, except our error handling makes it quite difficult
-                * (can't use intel_ring_begin, ring->flush, or
-                * intel_ring_advance)
-                */
-               if (i915_reset_in_progress(&dev_priv->gpu_error)) {
-                       WARN_ON(ppgtt != dev_priv->gtt.aliasing_ppgtt);
-                       I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
-                       I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset);
-                       return 0;
-               }
-
-               /* NB: TLBs must be flushed and invalidated before a switch */
-               ret = ring->flush(ring, I915_GEM_GPU_DOMAINS,
-                                 I915_GEM_GPU_DOMAINS);
+               ret = ppgtt->switch_mm(ppgtt, ring);
                if (ret)
                        return ret;
-
-               ret = intel_ring_begin(ring, 6);
-               if (ret)
-                       return ret;
-
-               intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(2));
-               intel_ring_emit(ring, RING_PP_DIR_DCLV(ring));
-               intel_ring_emit(ring, PP_DIR_DCLV_2G);
-               intel_ring_emit(ring, RING_PP_DIR_BASE(ring));
-               intel_ring_emit(ring, pd_offset);
-               intel_ring_emit(ring, MI_NOOP);
-               intel_ring_advance(ring);
        }
        return 0;
 }
@@ -375,6 +387,7 @@ alloc:
 
        ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES;
        ppgtt->enable = gen6_ppgtt_enable;
+       ppgtt->switch_mm = gen6_mm_switch;
        ppgtt->cleanup = gen6_ppgtt_cleanup;
 
        vm->clear_range = gen6_ppgtt_clear_range;
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to