drm/i915: Invalidate the guc ggtt TLB upon insertion
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 12 Jan 2017 11:00:49 +0000 (11:00 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 12 Jan 2017 16:47:04 +0000 (16:47 +0000)
Move the GuC invalidation of its ggtt TLB to where we perform the ggtt
modification rather than proliferate it into all the callers of the
insert (which may or may not in fact have to do the insertion).

v2: Just do the guc invalidate unconditionally, (afaict) it has no impact
without the guc loaded on gen8+
v3: Conditionally invalidate the guc - just in case that register has
not been validated for other modes.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170112110050.25333-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_gtt.h
drivers/gpu/drm/i915/i915_guc_submission.c
drivers/gpu/drm/i915/intel_guc_loader.c
drivers/gpu/drm/i915/intel_lrc.c

index 0ed99adfd0da56cb57d587486d7683eac8cedb8a..ed120a1e7f93d5a723f34d2d0161be1d0bec9663 100644 (file)
@@ -110,6 +110,30 @@ const struct i915_ggtt_view i915_ggtt_view_rotated = {
        .type = I915_GGTT_VIEW_ROTATED,
 };
 
+static void gen6_ggtt_invalidate(struct drm_i915_private *dev_priv)
+{
+       /* Note that as an uncached mmio write, this should flush the
+        * WCB of the writes into the GGTT before it triggers the invalidate.
+        */
+       I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
+}
+
+static void guc_ggtt_invalidate(struct drm_i915_private *dev_priv)
+{
+       gen6_ggtt_invalidate(dev_priv);
+       I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+}
+
+static void gmch_ggtt_invalidate(struct drm_i915_private *dev_priv)
+{
+       intel_gtt_chipset_flush();
+}
+
+static inline void i915_ggtt_invalidate(struct drm_i915_private *i915)
+{
+       i915->ggtt.invalidate(i915);
+}
+
 int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
                                int enable_ppgtt)
 {
@@ -2307,16 +2331,6 @@ void i915_check_and_clear_faults(struct drm_i915_private *dev_priv)
                POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
 }
 
-static void i915_ggtt_flush(struct drm_i915_private *dev_priv)
-{
-       if (INTEL_INFO(dev_priv)->gen < 6) {
-               intel_gtt_chipset_flush();
-       } else {
-               I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
-               POSTING_READ(GFX_FLSH_CNTL_GEN6);
-       }
-}
-
 void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv)
 {
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
@@ -2331,7 +2345,7 @@ void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv)
 
        ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total);
 
-       i915_ggtt_flush(dev_priv);
+       i915_ggtt_invalidate(dev_priv);
 }
 
 int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
@@ -2370,15 +2384,13 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm,
                                  enum i915_cache_level level,
                                  u32 unused)
 {
-       struct drm_i915_private *dev_priv = vm->i915;
+       struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
        gen8_pte_t __iomem *pte =
-               (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
-               (offset >> PAGE_SHIFT);
+               (gen8_pte_t __iomem *)ggtt->gsm + (offset >> PAGE_SHIFT);
 
        gen8_set_pte(pte, gen8_pte_encode(addr, level));
 
-       I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
-       POSTING_READ(GFX_FLSH_CNTL_GEN6);
+       ggtt->invalidate(vm->i915);
 }
 
 static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
@@ -2386,7 +2398,6 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
                                     uint64_t start,
                                     enum i915_cache_level level, u32 unused)
 {
-       struct drm_i915_private *dev_priv = vm->i915;
        struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
        struct sgt_iter sgt_iter;
        gen8_pte_t __iomem *gtt_entries;
@@ -2415,8 +2426,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
         * want to flush the TLBs only after we're certain all the PTE updates
         * have finished.
         */
-       I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
-       POSTING_READ(GFX_FLSH_CNTL_GEN6);
+       ggtt->invalidate(vm->i915);
 }
 
 struct insert_entries {
@@ -2451,15 +2461,13 @@ static void gen6_ggtt_insert_page(struct i915_address_space *vm,
                                  enum i915_cache_level level,
                                  u32 flags)
 {
-       struct drm_i915_private *dev_priv = vm->i915;
+       struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
        gen6_pte_t __iomem *pte =
-               (gen6_pte_t __iomem *)dev_priv->ggtt.gsm +
-               (offset >> PAGE_SHIFT);
+               (gen6_pte_t __iomem *)ggtt->gsm + (offset >> PAGE_SHIFT);
 
        iowrite32(vm->pte_encode(addr, level, flags), pte);
 
-       I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
-       POSTING_READ(GFX_FLSH_CNTL_GEN6);
+       ggtt->invalidate(vm->i915);
 }
 
 /*
@@ -2473,7 +2481,6 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
                                     uint64_t start,
                                     enum i915_cache_level level, u32 flags)
 {
-       struct drm_i915_private *dev_priv = vm->i915;
        struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
        struct sgt_iter sgt_iter;
        gen6_pte_t __iomem *gtt_entries;
@@ -2501,8 +2508,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
         * want to flush the TLBs only after we're certain all the PTE updates
         * have finished.
         */
-       I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
-       POSTING_READ(GFX_FLSH_CNTL_GEN6);
+       ggtt->invalidate(vm->i915);
 }
 
 static void nop_clear_range(struct i915_address_space *vm,
@@ -3062,6 +3068,8 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
        if (IS_CHERRYVIEW(dev_priv))
                ggtt->base.insert_entries = gen8_ggtt_insert_entries__BKL;
 
+       ggtt->invalidate = gen6_ggtt_invalidate;
+
        return ggtt_probe_common(ggtt, size);
 }
 
@@ -3099,6 +3107,8 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
        ggtt->base.unbind_vma = ggtt_unbind_vma;
        ggtt->base.cleanup = gen6_gmch_remove;
 
+       ggtt->invalidate = gen6_ggtt_invalidate;
+
        if (HAS_EDRAM(dev_priv))
                ggtt->base.pte_encode = iris_pte_encode;
        else if (IS_HASWELL(dev_priv))
@@ -3142,6 +3152,8 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
        ggtt->base.unbind_vma = ggtt_unbind_vma;
        ggtt->base.cleanup = i915_gmch_remove;
 
+       ggtt->invalidate = gmch_ggtt_invalidate;
+
        if (unlikely(ggtt->do_idle_maps))
                DRM_INFO("applying Ironlake quirks for intel_iommu\n");
 
@@ -3260,6 +3272,16 @@ int i915_ggtt_enable_hw(struct drm_i915_private *dev_priv)
        return 0;
 }
 
+void i915_ggtt_enable_guc(struct drm_i915_private *i915)
+{
+       i915->ggtt.invalidate = guc_ggtt_invalidate;
+}
+
+void i915_ggtt_disable_guc(struct drm_i915_private *i915)
+{
+       i915->ggtt.invalidate = gen6_ggtt_invalidate;
+}
+
 void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv)
 {
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
@@ -3323,7 +3345,7 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv)
                }
        }
 
-       i915_ggtt_flush(dev_priv);
+       i915_ggtt_invalidate(dev_priv);
 }
 
 struct i915_vma *
index 3e031a057f78cce381e5563fec63b5d1c10a9d7c..6c40088f8cf43c2f30a0deacb927ad22473c16ea 100644 (file)
@@ -336,6 +336,7 @@ struct i915_ggtt {
 
        /** "Graphics Stolen Memory" holds the global PTEs */
        void __iomem *gsm;
+       void (*invalidate)(struct drm_i915_private *dev_priv);
 
        bool do_idle_maps;
 
@@ -504,6 +505,8 @@ i915_vm_to_ggtt(struct i915_address_space *vm)
 int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv);
 int i915_ggtt_init_hw(struct drm_i915_private *dev_priv);
 int i915_ggtt_enable_hw(struct drm_i915_private *dev_priv);
+void i915_ggtt_enable_guc(struct drm_i915_private *i915);
+void i915_ggtt_disable_guc(struct drm_i915_private *i915);
 int i915_gem_init_ggtt(struct drm_i915_private *dev_priv);
 void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv);
 
index 710fbb9fc63fe567ab10ada8c6423205f7dbf59f..913d873589728f3f841aaae202525e65bd04184e 100644 (file)
@@ -579,9 +579,6 @@ static struct i915_vma *guc_allocate_vma(struct intel_guc *guc, u32 size)
                goto err;
        }
 
-       /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
-       I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
-
        return vma;
 
 err:
index 5a6ab8728d48c505dada8ad727577ee620cd45d1..b8891914287ee8f2bfdc8079b56c9c262116d42a 100644 (file)
@@ -367,9 +367,6 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
                return PTR_ERR(vma);
        }
 
-       /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
-       I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
-
        intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
        /* init WOPCM */
@@ -487,6 +484,9 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
        guc_interrupts_release(dev_priv);
        gen9_reset_guc_interrupts(dev_priv);
 
+       /* We need to notify the guc whenever we change the GGTT */
+       i915_ggtt_enable_guc(dev_priv);
+
        guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;
 
        DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
@@ -548,6 +548,7 @@ fail:
        guc_interrupts_release(dev_priv);
        i915_guc_submission_disable(dev_priv);
        i915_guc_submission_fini(dev_priv);
+       i915_ggtt_disable_guc(dev_priv);
 
        /*
         * We've failed to load the firmware :(
index 8acab875fcfc49919fc903864d2d8ecce9090c99..8f8dcd9a9524c770aa557193c9e60f016277b71e 100644 (file)
@@ -811,12 +811,6 @@ static int execlists_context_pin(struct intel_engine_cs *engine,
 
        ce->state->obj->mm.dirty = true;
 
-       /* Invalidate GuC TLB. */
-       if (i915.enable_guc_submission) {
-               struct drm_i915_private *dev_priv = ctx->i915;
-               I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
-       }
-
        i915_gem_context_get(ctx);
        return 0;