Hi Thomas, On Fri, Feb 28, 2025 at 10:32:51AM +0100, Thomas Zimmermann wrote: > Importing dma-bufs via PRIME requires a DMA-capable device. Devices on > peripheral busses, such as USB, often cannot perform DMA by themselves. > Without DMA-capable device PRIME import fails. DRM drivers for USB > devices already use a separate DMA device for dma-buf imports. Make the > mechanism generally available. > > Add the field dma_dev to struct drm_device to refer to the device's DMA > device. For USB this should be the USB controller. Use dma_dev in the > PRIME import helpers, if set. > > Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> > --- > drivers/gpu/drm/drm_drv.c | 2 ++ > drivers/gpu/drm/drm_prime.c | 2 +- > include/drm/drm_device.h | 37 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 40 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 17fc5dc708f4..f8c3c9f77d22 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -654,6 +654,8 @@ static void drm_dev_init_release(struct drm_device *dev, void *res) > { > drm_fs_inode_free(dev->anon_inode); > > + put_device(dev->dma_dev); > + dev->dma_dev = NULL; > put_device(dev->dev); > /* Prevent use-after-free in drm_managed_release when debugging is > * enabled. Slightly awkward, but can't really be helped. */ > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > index 32a8781cfd67..258858f2f8dd 100644 > --- a/drivers/gpu/drm/drm_prime.c > +++ b/drivers/gpu/drm/drm_prime.c > @@ -1004,7 +1004,7 @@ EXPORT_SYMBOL(drm_gem_prime_import_dev); > struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, > struct dma_buf *dma_buf) > { > - return drm_gem_prime_import_dev(dev, dma_buf, dev->dev); > + return drm_gem_prime_import_dev(dev, dma_buf, drm_dev_dma_dev(dev)); > } > EXPORT_SYMBOL(drm_gem_prime_import); > > diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h > index 6ea54a578cda..a24cac4b2077 100644 > --- a/include/drm/drm_device.h > +++ b/include/drm/drm_device.h > @@ -64,6 +64,23 @@ struct drm_device { > /** @dev: Device structure of bus-device */ > struct device *dev; > > + /** > + * @dma_dev: > + * > + * Device for DMA operations. Only required if the device @dev > + * cannot perform DMA by itself. Should be NULL otherwise. > + * > + * Devices on USB and other peripheral busses cannot perform DMA > + * by themselves. The @dma_dev field should point the bus controller > + * that does DMA on behalve of such a device. Required for importing > + * buffers via dma-buf. > + * > + * If set, the DRM driver has to acquire a reference on the DMA > + * device, which will be owned and released automatically by the > + * DRM core. > + */ > + struct device *dma_dev; > + It looks good to me in general, but this is also useful with ARM platform is general. On those, the DRM device is bound to a virtual device (and thus can't do DMA), but the HW accesses will be done by one or more HW controllers that are part of the overall DRM driver. Thus, we typically have to make hacks to copy to the virtual device DMA setup from the actual device doing the DMA accesses. See for example https://elixir.bootlin.com/linux/v6.13.5/source/drivers/gpu/drm/vc4/vc4_drv.c#L313 https://elixir.bootlin.com/linux/v6.13.5/source/drivers/gpu/drm/sun4i/sun4i_backend.c#L797 It's probably worth documenting. Maxime
Attachment:
signature.asc
Description: PGP signature