From: Jon Bloomfield <[email protected]>

Hook up the flags to allow read-only ppGTT mappings for gen8+

Signed-off-by: Jon Bloomfield <[email protected]>
Signed-off-by: Chris Wilson <[email protected]>
Cc: Joonas Lahtinen <[email protected]>
Cc: Matthew Auld <[email protected]>
Reviewed-by: Joonas Lahtinen <[email protected]>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c     | 45 ++++++++++++++++---------
 drivers/gpu/drm/i915/i915_gem_gtt.h     |  7 +++-
 drivers/gpu/drm/i915/intel_ringbuffer.c | 11 ++++--
 3 files changed, 44 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 5936f0bfdd19..1ac626cacc8d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -204,7 +204,7 @@ static int ppgtt_bind_vma(struct i915_vma *vma,
                        return ret;
        }
 
-       /* Currently applicable only to VLV */
+       /* Applicable to VLV, and gen8+ */
        pte_flags = 0;
        if (vma->obj->gt_ro)
                pte_flags |= PTE_READ_ONLY;
@@ -1008,10 +1008,11 @@ gen8_ppgtt_insert_pte_entries(struct i915_hw_ppgtt 
*ppgtt,
                              struct i915_page_directory_pointer *pdp,
                              struct sgt_dma *iter,
                              struct gen8_insert_pte *idx,
-                             enum i915_cache_level cache_level)
+                             enum i915_cache_level cache_level,
+                             u32 flags)
 {
        struct i915_page_directory *pd;
-       const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, 0);
+       const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags);
        gen8_pte_t *vaddr;
        bool ret;
 
@@ -1062,14 +1063,14 @@ gen8_ppgtt_insert_pte_entries(struct i915_hw_ppgtt 
*ppgtt,
 static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm,
                                   struct i915_vma *vma,
                                   enum i915_cache_level cache_level,
-                                  u32 unused)
+                                  u32 flags)
 {
        struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
        struct sgt_dma iter = sgt_dma(vma);
        struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
 
        gen8_ppgtt_insert_pte_entries(ppgtt, &ppgtt->pdp, &iter, &idx,
-                                     cache_level);
+                                     cache_level, flags);
 
        vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
 }
@@ -1077,9 +1078,10 @@ static void gen8_ppgtt_insert_3lvl(struct 
i915_address_space *vm,
 static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
                                           struct i915_page_directory_pointer 
**pdps,
                                           struct sgt_dma *iter,
-                                          enum i915_cache_level cache_level)
+                                          enum i915_cache_level cache_level,
+                                          u32 flags)
 {
-       const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, 0);
+       const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags);
        u64 start = vma->node.start;
        dma_addr_t rem = iter->sg->length;
 
@@ -1195,19 +1197,21 @@ static void gen8_ppgtt_insert_huge_entries(struct 
i915_vma *vma,
 static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm,
                                   struct i915_vma *vma,
                                   enum i915_cache_level cache_level,
-                                  u32 unused)
+                                  u32 flags)
 {
        struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
        struct sgt_dma iter = sgt_dma(vma);
        struct i915_page_directory_pointer **pdps = ppgtt->pml4.pdps;
 
        if (vma->page_sizes.sg > I915_GTT_PAGE_SIZE) {
-               gen8_ppgtt_insert_huge_entries(vma, pdps, &iter, cache_level);
+               gen8_ppgtt_insert_huge_entries(vma, pdps, &iter, cache_level,
+                                              flags);
        } else {
                struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
 
                while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++],
-                                                    &iter, &idx, cache_level))
+                                                    &iter, &idx, cache_level,
+                                                    flags))
                        GEM_BUG_ON(idx.pml4e >= GEN8_PML4ES_PER_PML4);
 
                vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
@@ -1614,6 +1618,9 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
                1ULL << 48 :
                1ULL << 32;
 
+       /* From bdw, there is support for read-only pages in the PPGTT */
+       ppgtt->base.has_read_only = true;
+
        /* There are only few exceptions for gen >=6. chv and bxt.
         * And we are not sure about the latter so play safe for now.
         */
@@ -2430,7 +2437,7 @@ static void gen8_ggtt_insert_page(struct 
i915_address_space *vm,
 static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
                                     struct i915_vma *vma,
                                     enum i915_cache_level level,
-                                    u32 unused)
+                                    u32 flags)
 {
        struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
        struct sgt_iter sgt_iter;
@@ -2438,6 +2445,9 @@ static void gen8_ggtt_insert_entries(struct 
i915_address_space *vm,
        const gen8_pte_t pte_encode = gen8_pte_encode(0, level, 0);
        dma_addr_t addr;
 
+       /* The GTT does not support read-only mappings */
+       GEM_BUG_ON(flags & PTE_READ_ONLY);
+
        gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm;
        gtt_entries += vma->node.start >> PAGE_SHIFT;
        for_each_sgt_dma(addr, sgt_iter, vma->pages)
@@ -2564,13 +2574,14 @@ struct insert_entries {
        struct i915_address_space *vm;
        struct i915_vma *vma;
        enum i915_cache_level level;
+       u32 flags;
 };
 
 static int bxt_vtd_ggtt_insert_entries__cb(void *_arg)
 {
        struct insert_entries *arg = _arg;
 
-       gen8_ggtt_insert_entries(arg->vm, arg->vma, arg->level, 0);
+       gen8_ggtt_insert_entries(arg->vm, arg->vma, arg->level, arg->flags);
        bxt_vtd_ggtt_wa(arg->vm);
 
        return 0;
@@ -2579,9 +2590,9 @@ static int bxt_vtd_ggtt_insert_entries__cb(void *_arg)
 static void bxt_vtd_ggtt_insert_entries__BKL(struct i915_address_space *vm,
                                             struct i915_vma *vma,
                                             enum i915_cache_level level,
-                                            u32 unused)
+                                            u32 flags)
 {
-       struct insert_entries arg = { vm, vma, level };
+       struct insert_entries arg = { vm, vma, level, flags };
 
        stop_machine(bxt_vtd_ggtt_insert_entries__cb, &arg, NULL);
 }
@@ -2672,7 +2683,7 @@ static int ggtt_bind_vma(struct i915_vma *vma,
        struct drm_i915_gem_object *obj = vma->obj;
        u32 pte_flags;
 
-       /* Currently applicable only to VLV */
+       /* Applicable to VLV (gen8+ do not support RO in the GGTT) */
        pte_flags = 0;
        if (obj->gt_ro)
                pte_flags |= PTE_READ_ONLY;
@@ -3555,6 +3566,10 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
         */
        mutex_lock(&dev_priv->drm.struct_mutex);
        i915_address_space_init(&ggtt->base, dev_priv, "[global]");
+
+       /* Only VLV supports read-only GGTT mappings */
+       ggtt->base.has_read_only = IS_VALLEYVIEW(dev_priv);
+
        if (!HAS_LLC(dev_priv) && !USES_PPGTT(dev_priv))
                ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
        mutex_unlock(&dev_priv->drm.struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index aec4f73574f4..b0929b547846 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -309,7 +309,12 @@ struct i915_address_space {
        struct list_head unbound_list;
 
        struct pagevec free_pages;
-       bool pt_kmap_wc;
+
+       /* Some systems require uncached updates of the page directories */
+       bool pt_kmap_wc:1;
+
+       /* Some systems support read-only mappings for GGTT and/or PPGTT */
+       bool has_read_only:1;
 
        /* FIXME: Need a more generic return type */
        gen6_pte_t (*pte_encode)(dma_addr_t addr,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 97b38bbb7ce2..6cac4ce59438 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1111,6 +1111,7 @@ void intel_ring_unpin(struct intel_ring *ring)
 static struct i915_vma *
 intel_ring_create_vma(struct drm_i915_private *dev_priv, int size)
 {
+       struct i915_address_space *vm = &dev_priv->ggtt.base;
        struct drm_i915_gem_object *obj;
        struct i915_vma *vma;
 
@@ -1120,10 +1121,14 @@ intel_ring_create_vma(struct drm_i915_private 
*dev_priv, int size)
        if (IS_ERR(obj))
                return ERR_CAST(obj);
 
-       /* mark ring buffers as read-only from GPU side by default */
-       obj->gt_ro = 1;
+       /*
+        * Mark ring buffers as read-only from GPU side (so no stray overwrites)
+        * if supported by the platform's GGTT.
+        */
+       if (vm->has_read_only)
+               obj->gt_ro = 1;
 
-       vma = i915_vma_instance(obj, &dev_priv->ggtt.base, NULL);
+       vma = i915_vma_instance(obj, vm, NULL);
        if (IS_ERR(vma))
                goto err;
 
-- 
2.17.1

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to