[PATCH 5/5] ppgtt + fake local-memory

Matthew Auld matthew.auld at intel.com
Fri Nov 29 10:49:32 UTC 2019


---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 81 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  5 +-
 2 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cf061160e920..1994532a1f04 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -37,6 +37,8 @@
 #include <drm/i915_drm.h>
 
 #include "display/intel_frontbuffer.h"
+#include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_region.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 
@@ -576,6 +578,76 @@ static void i915_address_space_init(struct i915_address_space *vm, int subclass)
 	INIT_LIST_HEAD(&vm->bound_list);
 }
 
+static struct i915_buddy_block *vm_alloc_lm(struct drm_i915_private *i915)
+{
+	struct intel_memory_region *mem = i915->mm.regions[INTEL_REGION_LMEM];
+
+	return __intel_memory_region_get_block_buddy(mem,
+						     mem->mm.chunk_size,
+						     I915_ALLOC_CONTIGUOUS);
+}
+
+static void vm_free_lm(struct i915_buddy_block *block)
+{
+	__intel_memory_region_put_block_buddy(block);
+}
+
+static inline dma_addr_t vm_daddr_lm(struct i915_buddy_block *block)
+{
+	struct intel_memory_region *mem = block->private;
+
+	return mem->region.start + i915_buddy_block_offset(block);
+}
+
+static inline void __iomem *vm_kmap_lm(struct i915_buddy_block *block)
+{
+	struct intel_memory_region *mem = block->private;
+
+	return io_mapping_map_atomic_wc(&mem->iomap,
+					i915_buddy_block_offset(block));
+}
+
+static inline void vm_kunmap_lm(void *vaddr)
+{
+	io_mapping_unmap_atomic(vaddr);
+}
+
+static void *kmap_page_dma_local(const struct i915_page_dma *p)
+{
+	return vm_kmap_lm(p->block_lm);
+}
+
+static void kunmap_page_dma_local(void *vaddr)
+{
+	vm_kunmap_lm(vaddr);
+}
+
+static int setup_page_dma_local(struct i915_address_space *vm,
+				struct i915_page_dma *p,
+				gfp_t unused)
+{
+	struct drm_i915_private *i915 = vm->i915;
+	struct i915_buddy_block *block_lm;
+
+	block_lm = vm_alloc_lm(i915);
+	if (IS_ERR(block_lm))
+		return PTR_ERR(block_lm);
+
+	p->block_lm = block_lm;
+	p->daddr = vm_daddr_lm(block_lm);
+
+	p->kmap = kmap_page_dma_local;
+	p->kunmap = kunmap_page_dma_local;
+
+	return 0;
+}
+
+static void cleanup_page_dma_local(struct i915_address_space *vm,
+				   struct i915_page_dma *p)
+{
+	vm_free_lm(p->block_lm);
+}
+
 static void *kmap_page_dma_system(const struct i915_page_dma *p)
 {
 	return kmap_atomic(p->page);
@@ -1546,8 +1618,13 @@ static struct i915_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915)
 	if (IS_CHERRYVIEW(i915) || IS_BROXTON(i915))
 		ppgtt->vm.pt_kmap_wc = true;
 
-	ppgtt->vm.setup_page_dma = setup_page_dma_system;
-	ppgtt->vm.cleanup_page_dma = cleanup_page_dma_system;
+	if (HAS_LMEM(i915)) {
+		ppgtt->vm.setup_page_dma = setup_page_dma_local;
+		ppgtt->vm.cleanup_page_dma = cleanup_page_dma_local;
+	} else {
+		ppgtt->vm.setup_page_dma = setup_page_dma_system;
+		ppgtt->vm.cleanup_page_dma = cleanup_page_dma_system;
+	}
 
 	err = gen8_init_scratch(&ppgtt->vm);
 	if (err)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 4356cd546796..a920c3006dc2 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -217,7 +217,10 @@ enum i915_cache_level;
 struct i915_vma;
 
 struct i915_page_dma {
-	struct page *page;
+	union {
+		struct i915_buddy_block *block_lm;
+		struct page *page;
+	};
 	union {
 		dma_addr_t daddr;
 
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list