On Thu, Mar 26, 2026 at 6:03 PM Chen-Yu Tsai <[email protected]> wrote: > > From: Rob Herring <[email protected]> > > Add support in DMA helpers to handle callers specifying > DRM_MODE_DUMB_KERNEL_MAP flag. Existing behavior is maintained with this > change. drm_gem_dma_dumb_create() always creates a kernel mapping as > before. drm_gem_dma_dumb_create_internal() lets the caller set the flags > as desired. > > drm_gem_dma_dumb_create_internal() users have DRM_MODE_DUMB_KERNEL_MAP > added to preserve existing behavior. > > A dumb buffer allocated from these devices can be shared (exported) to > another device. The consuming device may require the kernel mapping to > scan out the buffer to its own display. Such devices include DisplayLink > and various MIPI DBI based displays. Therefore altering the behavior > should be given much consideration. > > Signed-off-by: Rob Herring <[email protected]> > [[email protected]: Rebase onto renamed GEM DMA helpers] > [[email protected]: show "vaddr=(no mapping)" in drm_gem_dma_print_info()] > [[email protected]: Add DRM_MODE_DUMB_KERNEL_MAP to new drivers] > [[email protected]: Add flags field to drm_gem_dma_create_with_handle() > kerneldoc] > Signed-off-by: Chen-Yu Tsai <[email protected]> > --- > Changes since v2: > - Added back DRM_MODE_DUMB_KERNEL_MAP flag to all drivers calling > drm_gem_dma_dumb_create_internal() > - Expanded commit message to cover display drivers needing the kernel > mapping to do scan out > > Changes since v1: > - Rebased onto renamed GEM DMA helpers > - Added check in drm_fb_dma_get_scanout_buffer() and drm_gem_dma_vmap(). > - Made drm_gem_dma_print_info() show "vaddr=(no mapping)" for objects > allocated without kernel mapping > - Dropped existing DRM_MODE_DUMB_KERNEL_MAP flag addition in various > drivers > - Added DRM_MODE_DUMB_KERNEL_MAP flag to adp_drm_gem_dumb_create() > - Added flags field kerneldoc for drm_gem_dma_create_with_handle() > > Cc: Sasha Finkelstein <[email protected]> > Cc: Janne Grunau <[email protected]> > Cc: Liviu Dudau <[email protected]> > Cc: Paul Kocialkowski <[email protected]> > Cc: Neil Armstrong <[email protected]> > Cc: Laurent Pinchart <[email protected]> > Cc: Tomi Valkeinen <[email protected]> > Cc: Kieran Bingham <[email protected]> > Cc: Biju Das <[email protected]> > Cc: Yannick Fertre <[email protected]> > Cc: Raphael Gallais-Pou <[email protected]> > Cc: Philippe Cornu <[email protected]> > Cc: Jernej Skrabec <[email protected]> > Cc: Maxime Ripard <[email protected]> > Cc: Dave Stevenson <[email protected]> > Cc: "Maíra Canal" <[email protected]> > Cc: Raspberry Pi Kernel Maintenance <[email protected]> > Cc: Icenowy Zheng <[email protected]> > Cc: Laurent Pinchart <[email protected]> > Cc: Tomi Valkeinen <[email protected]> > --- > drivers/gpu/drm/adp/adp_drv.c | 1 + > .../gpu/drm/arm/display/komeda/komeda_kms.c | 1 + > drivers/gpu/drm/arm/malidp_drv.c | 1 + > drivers/gpu/drm/drm_fb_dma_helper.c | 4 ++ > drivers/gpu/drm/drm_gem_dma_helper.c | 67 ++++++++++++------- > drivers/gpu/drm/logicvc/logicvc_drm.c | 1 + > drivers/gpu/drm/meson/meson_drv.c | 1 + > drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 2 + > drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 1 + > drivers/gpu/drm/stm/drv.c | 3 +- > drivers/gpu/drm/sun4i/sun4i_drv.c | 1 + > drivers/gpu/drm/vc4/vc4_drv.c | 2 + > drivers/gpu/drm/verisilicon/vs_drm.c | 2 + > drivers/gpu/drm/xlnx/zynqmp_kms.c | 2 + > 14 files changed, 63 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/adp/adp_drv.c b/drivers/gpu/drm/adp/adp_drv.c > index 4554cf75565e..c549b44b3814 100644 > --- a/drivers/gpu/drm/adp/adp_drv.c > +++ b/drivers/gpu/drm/adp/adp_drv.c > @@ -95,6 +95,7 @@ static int adp_drm_gem_dumb_create(struct drm_file > *file_priv, > { > args->height = ALIGN(args->height, 64); > args->size = args->pitch * args->height; > + args->flags = DRM_MODE_DUMB_KERNEL_MAP; > > return drm_gem_dma_dumb_create_internal(file_priv, drm, args); > } > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c > b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c > index 6ed504099188..2c096ebaea33 100644 > --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c > @@ -29,6 +29,7 @@ static int komeda_gem_dma_dumb_create(struct drm_file *file, > struct komeda_dev *mdev = dev->dev_private; > u32 pitch = DIV_ROUND_UP(args->width * args->bpp, 8); > > + args->flags = DRM_MODE_DUMB_KERNEL_MAP; > args->pitch = ALIGN(pitch, mdev->chip.bus_width); > > return drm_gem_dma_dumb_create_internal(file, dev, args); > diff --git a/drivers/gpu/drm/arm/malidp_drv.c > b/drivers/gpu/drm/arm/malidp_drv.c > index b765f6c9eea4..5519f48a27c0 100644 > --- a/drivers/gpu/drm/arm/malidp_drv.c > +++ b/drivers/gpu/drm/arm/malidp_drv.c > @@ -464,6 +464,7 @@ static int malidp_dumb_create(struct drm_file *file_priv, > /* allocate for the worst case scenario, i.e. rotated buffers */ > u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 1); > > + args->flags = DRM_MODE_DUMB_KERNEL_MAP; > args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), > alignment); > > return drm_gem_dma_dumb_create_internal(file_priv, drm, args); > diff --git a/drivers/gpu/drm/drm_fb_dma_helper.c > b/drivers/gpu/drm/drm_fb_dma_helper.c > index fd71969d2fb1..12a44accc48c 100644 > --- a/drivers/gpu/drm/drm_fb_dma_helper.c > +++ b/drivers/gpu/drm/drm_fb_dma_helper.c > @@ -187,6 +187,10 @@ int drm_fb_dma_get_scanout_buffer(struct drm_plane > *plane, > if (!dma_obj->vaddr) > return -ENODEV; > > + /* Buffer was allocated with NO_KERNEL_MAPPING */ > + if (dma_obj->dma_attrs & DMA_ATTR_NO_KERNEL_MAPPING) > + return -ENODEV; > + > iosys_map_set_vaddr(&sb->map[0], dma_obj->vaddr); > sb->format = fb->format; > sb->height = fb->height; > diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c > b/drivers/gpu/drm/drm_gem_dma_helper.c > index 9722c9fc86f3..281fb563f061 100644 > --- a/drivers/gpu/drm/drm_gem_dma_helper.c > +++ b/drivers/gpu/drm/drm_gem_dma_helper.c > @@ -116,26 +116,8 @@ __drm_gem_dma_create(struct drm_device *drm, size_t > size, bool private) > return ERR_PTR(ret); > } > > -/** > - * drm_gem_dma_create - allocate an object with the given size > - * @drm: DRM device > - * @size: size of the object to allocate > - * > - * This function creates a DMA GEM object and allocates memory as backing > store. > - * The allocated memory will occupy a contiguous chunk of bus address space. > - * > - * For devices that are directly connected to the memory bus then the > allocated > - * memory will be physically contiguous. For devices that access through an > - * IOMMU, then the allocated memory is not expected to be physically > contiguous > - * because having contiguous IOVAs is sufficient to meet a devices DMA > - * requirements. > - * > - * Returns: > - * A struct drm_gem_dma_object * on success or an ERR_PTR()-encoded negative > - * error code on failure. > - */ > -struct drm_gem_dma_object *drm_gem_dma_create(struct drm_device *drm, > - size_t size) > +static struct drm_gem_dma_object * > +drm_gem_dma_create_flags(struct drm_device *drm, size_t size, u32 flags) > { > struct drm_gem_dma_object *dma_obj; > int ret; > @@ -146,6 +128,9 @@ struct drm_gem_dma_object *drm_gem_dma_create(struct > drm_device *drm, > if (IS_ERR(dma_obj)) > return dma_obj; > > + if (!(flags & DRM_MODE_DUMB_KERNEL_MAP)) > + dma_obj->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING; > + > if (dma_obj->map_noncoherent) { > dma_obj->vaddr = dma_alloc_noncoherent(drm_dev_dma_dev(drm), > size, > @@ -171,6 +156,30 @@ struct drm_gem_dma_object *drm_gem_dma_create(struct > drm_device *drm, > drm_gem_object_put(&dma_obj->base); > return ERR_PTR(ret); > } > + > +/** > + * drm_gem_dma_create - allocate an object with the given size > + * @drm: DRM device > + * @size: size of the object to allocate > + * > + * This function creates a DMA GEM object and allocates memory as backing > store. > + * The allocated memory will occupy a contiguous chunk of bus address space. > + * > + * For devices that are directly connected to the memory bus then the > allocated > + * memory will be physically contiguous. For devices that access through an > + * IOMMU, then the allocated memory is not expected to be physically > contiguous > + * because having contiguous IOVAs is sufficient to meet a devices DMA > + * requirements. > + * > + * Returns: > + * A struct drm_gem_dma_object * on success or an ERR_PTR()-encoded negative > + * error code on failure. > + */ > +struct drm_gem_dma_object *drm_gem_dma_create(struct drm_device *drm, > + size_t size) > +{ > + return drm_gem_dma_create_flags(drm, size, DRM_MODE_DUMB_KERNEL_MAP); > +} > EXPORT_SYMBOL_GPL(drm_gem_dma_create); > > /** > @@ -179,6 +188,7 @@ EXPORT_SYMBOL_GPL(drm_gem_dma_create); > * @file_priv: DRM file-private structure to register the handle for > * @drm: DRM device > * @size: size of the object to allocate > + * @flags: DRM_MODE_DUMB_* flags if any > * @handle: return location for the GEM handle > * > * This function creates a DMA GEM object, allocating a chunk of memory as > @@ -194,14 +204,14 @@ EXPORT_SYMBOL_GPL(drm_gem_dma_create); > */ > static struct drm_gem_dma_object * > drm_gem_dma_create_with_handle(struct drm_file *file_priv, > - struct drm_device *drm, size_t size, > + struct drm_device *drm, size_t size, u32 flags, > uint32_t *handle) > { > struct drm_gem_dma_object *dma_obj; > struct drm_gem_object *gem_obj; > int ret; > > - dma_obj = drm_gem_dma_create(drm, size); > + dma_obj = drm_gem_dma_create_flags(drm, size, > DRM_MODE_DUMB_KERNEL_MAP);
Sashiko pointed out an obvious (to me now) error here: this should pass `flags`, not the flag directly. ChenYu
