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@xxxxxxxxxxxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx