Add helpers to map/unmap a hardware MMIO register window (PCI BAR) as a 1-entry sg_table using dma_map_resource()/dma_unmap_resource(). This will be used by MMIO_REMAP.
Cc: Christian König <[email protected]> Cc: Alex Deucher <[email protected]> Signed-off-by: Srinivasan Shanmugam <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index ff98c87b2e0b..33fa17a927ce 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -37,11 +37,15 @@ #include "amdgpu_dma_buf.h" #include "amdgpu_xgmi.h" #include "amdgpu_vm.h" +#include "amdgpu_object.h" #include <drm/amdgpu_drm.h> #include <drm/ttm/ttm_tt.h> #include <linux/dma-buf.h> #include <linux/dma-fence-array.h> #include <linux/pci-p2pdma.h> +#include <linux/dma-mapping.h> +#include <linux/scatterlist.h> +#include <linux/slab.h> static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops; @@ -146,6 +150,53 @@ static void amdgpu_dma_buf_unpin(struct dma_buf_attachment *attach) amdgpu_bo_unpin(bo); } +/* Map a BAR-backed I/O span as a 1-entry sg_table via dma_map_resource(). */ +static __maybe_unused struct sg_table * +amdgpu_dmabuf_map_iomem(struct device *dev, resource_size_t phys, + size_t size, enum dma_data_direction dir) +{ + struct sg_table *sgt; + unsigned long attrs = DMA_ATTR_SKIP_CPU_SYNC; /* no P2PDMA attr */ + dma_addr_t dma; + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) + return ERR_PTR(-ENOMEM); + + if (sg_alloc_table(sgt, 1, GFP_KERNEL)) { + kfree(sgt); + return ERR_PTR(-ENOMEM); + } + + /* No struct page backing for I/O regions. */ + sg_set_page(sgt->sgl, NULL, size, 0); + + dma = dma_map_resource(dev, phys, size, dir, attrs); + if (dma_mapping_error(dev, dma)) { + sg_free_table(sgt); + kfree(sgt); + return ERR_PTR(-EIO); + } + + sg_dma_address(sgt->sgl) = dma; + sg_dma_len(sgt->sgl) = size; + return sgt; +} + +static __maybe_unused void +amdgpu_dmabuf_unmap_iomem(struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir) +{ + /* attrs must match map side; we only used SKIP_CPU_SYNC above */ + dma_unmap_resource(dev, + sg_dma_address(sgt->sgl), + sg_dma_len(sgt->sgl), + dir, + 0); + sg_free_table(sgt); + kfree(sgt); +} + /** * amdgpu_dma_buf_map - &dma_buf_ops.map_dma_buf implementation * @attach: DMA-buf attachment -- 2.34.1
