[Intel-gfx] [PATCH v2] drm/i915: DMA map DSM [stolen memory]
Chris Wilson
chris at chris-wilson.co.uk
Mon Oct 12 14:35:09 UTC 2020
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 at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 29 +++++++++++++++++++++-
drivers/gpu/drm/i915/i915_drv.h | 5 ++++
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 0be5e8683337..376b9ecd405a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -162,6 +162,12 @@ static void i915_gem_cleanup_stolen(struct drm_i915_private *i915)
if (!drm_mm_initialized(&i915->mm.stolen))
return;
+ if (i915->dsm_dma != i915->dsm.start)
+ 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);
}
@@ -372,6 +378,18 @@ static void icl_get_stolen_reserved(struct drm_i915_private *i915,
}
}
+static dma_addr_t remap_stolen(struct drm_i915_private *i915)
+{
+ if (pfn_valid(PHYS_PFN(i915->dsm.start)))
+ return (dma_addr_t)i915->dsm.start;
+
+ return 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);
+}
+
static int i915_gem_init_stolen(struct drm_i915_private *i915)
{
struct intel_uncore *uncore = &i915->uncore;
@@ -489,6 +507,14 @@ static int i915_gem_init_stolen(struct drm_i915_private *i915)
i915->stolen_usable_size =
resource_size(&i915->dsm) - reserved_total;
+ i915->dsm_dma = remap_stolen(i915);
+ 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 +530,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 +550,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.
--
2.20.1
More information about the Intel-gfx
mailing list