Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/gem-dma: Support dedicated DMA device for allocation and mapping

Support for a dedicated DMA device for prime imports was added in commit
143ec8d3f939 ("drm/prime: Support dedicated DMA device for dma-buf imports").
This allowed the DRM driver to provide a dedicated DMA device when its
own underlying device was not capable of DMA, for example when it is a
USB device (the original target) or a virtual device. The latter case is
common on embedded SoCs, on which the display pipeline is composed of
various fixed function blocks, and the DRM device is simply a made-up
device, an address space managing the routing between the blocks, or
whichever block the implementor thought made sense at the time. The
point is that the chosen device is often not the actual device doing
the DMA. Various drivers have used workarounds or reimplemented the
GEM DMA helpers to get the DMA addresses and IOMMUs to work correctly.

Add support for the dedicated DMA device to the GEM DMA helpers.

No existing driver currently uses the GEM DMA helpers and calls
drm_dev_set_dma_dev() to set a dedicated DMA device, so no existing
users should be affected.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20260311094929.3393338-3-wenst@chromium.org
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>

+12 -9
+12 -9
drivers/gpu/drm/drm_gem_dma_helper.c
··· 146 146 return dma_obj; 147 147 148 148 if (dma_obj->map_noncoherent) { 149 - dma_obj->vaddr = dma_alloc_noncoherent(drm->dev, size, 149 + dma_obj->vaddr = dma_alloc_noncoherent(drm_dev_dma_dev(drm), 150 + size, 150 151 &dma_obj->dma_addr, 151 152 DMA_TO_DEVICE, 152 153 GFP_KERNEL | __GFP_NOWARN); 153 154 } else { 154 - dma_obj->vaddr = dma_alloc_wc(drm->dev, size, 155 + dma_obj->vaddr = dma_alloc_wc(drm_dev_dma_dev(drm), size, 155 156 &dma_obj->dma_addr, 156 157 GFP_KERNEL | __GFP_NOWARN); 157 158 } ··· 237 236 drm_prime_gem_destroy(gem_obj, dma_obj->sgt); 238 237 } else if (dma_obj->vaddr) { 239 238 if (dma_obj->map_noncoherent) 240 - dma_free_noncoherent(gem_obj->dev->dev, dma_obj->base.size, 239 + dma_free_noncoherent(drm_dev_dma_dev(gem_obj->dev), 240 + dma_obj->base.size, 241 241 dma_obj->vaddr, dma_obj->dma_addr, 242 242 DMA_TO_DEVICE); 243 243 else 244 - dma_free_wc(gem_obj->dev->dev, dma_obj->base.size, 245 - dma_obj->vaddr, dma_obj->dma_addr); 244 + dma_free_wc(drm_dev_dma_dev(gem_obj->dev), 245 + dma_obj->base.size, dma_obj->vaddr, 246 + dma_obj->dma_addr); 246 247 } 247 248 248 249 drm_gem_object_release(gem_obj); ··· 435 432 if (!sgt) 436 433 return ERR_PTR(-ENOMEM); 437 434 438 - ret = dma_get_sgtable(obj->dev->dev, sgt, dma_obj->vaddr, 435 + ret = dma_get_sgtable(drm_dev_dma_dev(obj->dev), sgt, dma_obj->vaddr, 439 436 dma_obj->dma_addr, obj->size); 440 437 if (ret < 0) 441 438 goto out; ··· 542 539 if (dma_obj->map_noncoherent) { 543 540 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 544 541 545 - ret = dma_mmap_pages(dma_obj->base.dev->dev, 542 + ret = dma_mmap_pages(drm_dev_dma_dev(dma_obj->base.dev), 546 543 vma, vma->vm_end - vma->vm_start, 547 544 virt_to_page(dma_obj->vaddr)); 548 545 } else { 549 - ret = dma_mmap_wc(dma_obj->base.dev->dev, vma, dma_obj->vaddr, 550 - dma_obj->dma_addr, 546 + ret = dma_mmap_wc(drm_dev_dma_dev(dma_obj->base.dev), vma, 547 + dma_obj->vaddr, dma_obj->dma_addr, 551 548 vma->vm_end - vma->vm_start); 552 549 } 553 550 if (ret)