diff mbox series

drm/i915: DMA map DSM [stolen memory]

Message ID 20201012133641.5658-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series drm/i915: DMA map DSM [stolen memory] | expand

Commit Message

Chris Wilson Oct. 12, 2020, 1:36 p.m. UTC
Pass the physical address of our BIOS reserved stolen memory to the dma
mapper so we convert it into a proper dma_addr_t and track access with
the iommu.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 21 ++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_drv.h            |  5 +++++
 2 files changed, 25 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 0be5e8683337..ecb4ee6ac19d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -162,6 +162,11 @@  static void i915_gem_cleanup_stolen(struct drm_i915_private *i915)
 	if (!drm_mm_initialized(&i915->mm.stolen))
 		return;
 
+	dma_unmap_resource(i915->drm.dev,
+			   i915->dsm_dma, resource_size(&i915->dsm),
+			   DMA_BIDIRECTIONAL,
+			   DMA_ATTR_NO_WARN);
+
 	drm_mm_takedown(&i915->mm.stolen);
 }
 
@@ -489,6 +494,19 @@  static int i915_gem_init_stolen(struct drm_i915_private *i915)
 	i915->stolen_usable_size =
 		resource_size(&i915->dsm) - reserved_total;
 
+	i915->dsm_dma =
+		dma_map_resource(i915->drm.dev,
+				 i915->dsm.start, resource_size(&i915->dsm),
+				 DMA_BIDIRECTIONAL,
+				 DMA_ATTR_NO_KERNEL_MAPPING |
+				 DMA_ATTR_SKIP_CPU_SYNC);
+	if (dma_mapping_error(i915->drm.dev, i915->dsm_dma)) {
+		drm_err(&i915->drm,
+			"Failed to map stolen memory %pR for use with DMA\n",
+			&i915->dsm);
+		return 0; /* bail; continue to load the driver without stolen */
+	}
+
 	/* Basic memrange allocator for stolen space. */
 	drm_mm_init(&i915->mm.stolen, 0, i915->stolen_usable_size);
 
@@ -504,6 +522,7 @@  i915_pages_create_for_stolen(struct drm_device *dev,
 	struct scatterlist *sg;
 
 	GEM_BUG_ON(range_overflows(offset, size, resource_size(&i915->dsm)));
+	GEM_BUG_ON(dma_mapping_error(dev->dev, i915->dsm_dma));
 
 	/* We hide that we have no struct page backing our stolen object
 	 * by wrapping the contiguous physical allocation with a fake
@@ -523,7 +542,7 @@  i915_pages_create_for_stolen(struct drm_device *dev,
 	sg->offset = 0;
 	sg->length = size;
 
-	sg_dma_address(sg) = (dma_addr_t)i915->dsm.start + offset;
+	sg_dma_address(sg) = i915->dsm_dma + offset;
 	sg_dma_len(sg) = size;
 
 	return st;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9c2672c56cc1..44972eda7fb8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -836,6 +836,11 @@  struct drm_i915_private {
 	 */
 	struct resource dsm_reserved;
 
+	/**
+	 * dma-mapping of the Data Stolen Memory.
+	 */
+	dma_addr_t dsm_dma;
+
 	/*
 	 * Stolen memory is segmented in hardware with different portions
 	 * offlimits to certain functions.