On 12.09.25 13:11, Srinivasan Shanmugam wrote:
> MMIO_REMAP (HDP flush page) exposes a hardware MMIO register window via a PCI 
> BAR.
> 
> Handle it as fixed I/O:
> - map(): if MMIO_REMAP, require P2P, compute the BAR address (bus_addr + page
>   offset), and build a 1-entry sg_table with dma_map_resource().
> - unmap(): if MMIO_REMAP, call dma_unmap_resource() and return.
> 
> 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 | 39 +++++++++++++++++++--
>  1 file changed, 37 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 33fa17a927ce..f85e16be438f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -151,7 +151,7 @@ static void amdgpu_dma_buf_unpin(struct 
> dma_buf_attachment *attach)
>  }
>  
>  /* Map a BAR-backed I/O span as a 1-entry sg_table via dma_map_resource(). */
> -static __maybe_unused struct sg_table *
> +static struct sg_table *
>  amdgpu_dmabuf_map_iomem(struct device *dev, resource_size_t phys,
>                       size_t size, enum dma_data_direction dir)
>  {
> @@ -183,7 +183,7 @@ amdgpu_dmabuf_map_iomem(struct device *dev, 
> resource_size_t phys,
>       return sgt;
>  }
>  
> -static __maybe_unused void
> +static void
>  amdgpu_dmabuf_unmap_iomem(struct device *dev, struct sg_table *sgt,
>                         enum dma_data_direction dir)
>  {
> @@ -218,6 +218,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct 
> dma_buf_attachment *attach,
>       struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
>       struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>       struct sg_table *sgt;
> +     resource_size_t phys;
> +     u64 off;
> +     size_t len;
>       long r;
>  
>       if (!bo->tbo.pin_count) {
> @@ -261,6 +264,29 @@ static struct sg_table *amdgpu_dma_buf_map(struct 
> dma_buf_attachment *attach,
>               if (r)
>                       return ERR_PTR(r);
>               break;
> +
> +     case AMDGPU_PL_MMIO_REMAP:
> +             /* Only allow when importer can reach exporter via P2P. */
> +             if (!attach->peer2peer ||
> +                 pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
> +                     return ERR_PTR(-EOPNOTSUPP);
> +

> +             if (!adev->rmmio_remap.bus_addr)
> +                     return ERR_PTR(-ENODEV);
> +
> +             if (bo->tbo.base.size != AMDGPU_GPU_PAGE_SIZE)
> +                     return ERR_PTR(-EINVAL);

I think you can drop those checks.

> +
> +             /* TTM start is in pages → convert to byte offset. */
> +             off  = (u64)bo->tbo.resource->start << PAGE_SHIFT;

Please don't use resource->start for that. Instead use the functions in 
amdgpu_res_cursor.h.

> +             len  = AMDGPU_GPU_PAGE_SIZE;
> +             phys = adev->rmmio_remap.bus_addr + off;
> +
> +             sgt = amdgpu_dmabuf_map_iomem(attach->dev, phys, len, dir);

Move the amdgpu_dmabuf_map_iomem() function as well as the off and length 
calculation into amdgpu_ttm.c.

That is still not an ideal placement, but better than here.

Apart from that looks good to me.

Regards,
Christian.

> +             if (IS_ERR(sgt))
> +                     return sgt;
> +             break;
> +
>       default:
>               return ERR_PTR(-EINVAL);
>       }
> @@ -286,6 +312,15 @@ static void amdgpu_dma_buf_unmap(struct 
> dma_buf_attachment *attach,
>                                struct sg_table *sgt,
>                                enum dma_data_direction dir)
>  {
> +     struct drm_gem_object *obj = attach->dmabuf->priv;
> +     struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
> +
> +     if (bo->tbo.resource &&
> +         bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP) {
> +             amdgpu_dmabuf_unmap_iomem(attach->dev, sgt, dir);
> +             return;
> +     }
> +
>       if (sg_page(sgt->sgl)) {
>               dma_unmap_sgtable(attach->dev, sgt, dir, 0);
>               sg_free_table(sgt);

Reply via email to