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/mediatek: Set dedicated DMA device and drop custom GEM callbacks

In commit 9b54a32c7c6a ("drm/mediatek: mtk_gem: Partial refactor and
use drm_gem_dma_object") the MediaTek DRM driver was refactored to use
drm_gem_dma_object, but custom callbacks were still needed to deal with
using the first device of the pipeline as the DMA device, instead of
the MMSYS device that the DRM driver binds to.

Turns out there is already partial support for dedicated DMA devices in
the DRM subsystem for PRIME imports. The preceding patches add support
for dedicated DMA devices to the GEM DMA helpers.

This allows us to just set the dedicated DMA device for the DRM device,
and drop all the custom GEM callbacks. Also drop the .dma_dev field
from the driver private data as it is no longer needed.

There are slight differences in the mmap helper: the VM_DONTDUMP and
VM_IO flags are no longer set. Both were lifted from drm_gem_mmap_obj().
VM_IO probably doesn't make sense since the buffer is allocated using
dma_alloc_attrs().

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20260311094929.3393338-4-wenst@chromium.org
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>

+3 -269
-1
drivers/gpu/drm/mediatek/Makefile
··· 14 14 mtk_dsi.o \ 15 15 mtk_dpi.o \ 16 16 mtk_ethdr.o \ 17 - mtk_gem.o \ 18 17 mtk_mdp_rdma.o \ 19 18 mtk_padding.o \ 20 19 mtk_plane.o
-1
drivers/gpu/drm/mediatek/mtk_crtc.c
··· 23 23 #include "mtk_crtc.h" 24 24 #include "mtk_ddp_comp.h" 25 25 #include "mtk_drm_drv.h" 26 - #include "mtk_gem.h" 27 26 #include "mtk_plane.h" 28 27 29 28 /*
+3 -18
drivers/gpu/drm/mediatek/mtk_drm_drv.c
··· 19 19 #include <drm/drm_fbdev_dma.h> 20 20 #include <drm/drm_fourcc.h> 21 21 #include <drm/drm_gem.h> 22 + #include <drm/drm_gem_dma_helper.h> 22 23 #include <drm/drm_gem_framebuffer_helper.h> 23 24 #include <drm/drm_ioctl.h> 24 25 #include <drm/drm_of.h> ··· 30 29 #include "mtk_ddp_comp.h" 31 30 #include "mtk_disp_drv.h" 32 31 #include "mtk_drm_drv.h" 33 - #include "mtk_gem.h" 34 32 35 33 #define DRIVER_NAME "mediatek" 36 34 #define DRIVER_DESC "Mediatek SoC DRM" ··· 565 565 goto err_component_unbind; 566 566 } 567 567 568 - for (i = 0; i < private->data->mmsys_dev_num; i++) 569 - private->all_drm_private[i]->dma_dev = dma_dev; 568 + drm_dev_set_dma_dev(drm, dma_dev); 570 569 571 570 /* 572 571 * Configure the DMA segment size to make sure we get contiguous IOVA ··· 599 600 600 601 DEFINE_DRM_GEM_FOPS(mtk_drm_fops); 601 602 602 - /* 603 - * We need to override this because the device used to import the memory is 604 - * not dev->dev, as drm_gem_prime_import() expects. 605 - */ 606 - static struct drm_gem_object *mtk_gem_prime_import(struct drm_device *dev, 607 - struct dma_buf *dma_buf) 608 - { 609 - struct mtk_drm_private *private = dev->dev_private; 610 - 611 - return drm_gem_prime_import_dev(dev, dma_buf, private->dma_dev); 612 - } 613 - 614 603 static const struct drm_driver mtk_drm_driver = { 615 604 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, 616 605 617 - .dumb_create = mtk_gem_dumb_create, 606 + DRM_GEM_DMA_DRIVER_OPS, 618 607 DRM_FBDEV_DMA_DRIVER_OPS, 619 608 620 - .gem_prime_import = mtk_gem_prime_import, 621 - .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, 622 609 .fops = &mtk_drm_fops, 623 610 624 611 .name = DRIVER_NAME,
-1
drivers/gpu/drm/mediatek/mtk_drm_drv.h
··· 54 54 55 55 struct mtk_drm_private { 56 56 struct drm_device *drm; 57 - struct device *dma_dev; 58 57 bool mtk_drm_bound; 59 58 bool drm_master; 60 59 struct device *dev;
-231
drivers/gpu/drm/mediatek/mtk_gem.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (c) 2015 MediaTek Inc. 4 - * Copyright (c) 2025 Collabora Ltd. 5 - * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 6 - */ 7 - 8 - #include <linux/dma-buf.h> 9 - #include <linux/vmalloc.h> 10 - 11 - #include <drm/drm.h> 12 - #include <drm/drm_device.h> 13 - #include <drm/drm_gem.h> 14 - #include <drm/drm_gem_dma_helper.h> 15 - #include <drm/drm_prime.h> 16 - #include <drm/drm_print.h> 17 - 18 - #include "mtk_drm_drv.h" 19 - #include "mtk_gem.h" 20 - 21 - static int mtk_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); 22 - 23 - static void mtk_gem_free_object(struct drm_gem_object *obj) 24 - { 25 - struct drm_gem_dma_object *dma_obj = to_drm_gem_dma_obj(obj); 26 - struct mtk_drm_private *priv = obj->dev->dev_private; 27 - 28 - if (dma_obj->sgt) 29 - drm_prime_gem_destroy(obj, dma_obj->sgt); 30 - else 31 - dma_free_wc(priv->dma_dev, dma_obj->base.size, 32 - dma_obj->vaddr, dma_obj->dma_addr); 33 - 34 - /* release file pointer to gem object. */ 35 - drm_gem_object_release(obj); 36 - 37 - kfree(dma_obj); 38 - } 39 - 40 - /* 41 - * Allocate a sg_table for this GEM object. 42 - * Note: Both the table's contents, and the sg_table itself must be freed by 43 - * the caller. 44 - * Returns a pointer to the newly allocated sg_table, or an ERR_PTR() error. 45 - */ 46 - static struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj) 47 - { 48 - struct drm_gem_dma_object *dma_obj = to_drm_gem_dma_obj(obj); 49 - struct mtk_drm_private *priv = obj->dev->dev_private; 50 - struct sg_table *sgt; 51 - int ret; 52 - 53 - sgt = kzalloc_obj(*sgt); 54 - if (!sgt) 55 - return ERR_PTR(-ENOMEM); 56 - 57 - ret = dma_get_sgtable(priv->dma_dev, sgt, dma_obj->vaddr, 58 - dma_obj->dma_addr, obj->size); 59 - if (ret) { 60 - DRM_ERROR("failed to allocate sgt, %d\n", ret); 61 - kfree(sgt); 62 - return ERR_PTR(ret); 63 - } 64 - 65 - return sgt; 66 - } 67 - 68 - static const struct drm_gem_object_funcs mtk_gem_object_funcs = { 69 - .free = mtk_gem_free_object, 70 - .print_info = drm_gem_dma_object_print_info, 71 - .get_sg_table = mtk_gem_prime_get_sg_table, 72 - .vmap = drm_gem_dma_object_vmap, 73 - .mmap = mtk_gem_object_mmap, 74 - .vm_ops = &drm_gem_dma_vm_ops, 75 - }; 76 - 77 - static struct drm_gem_dma_object *mtk_gem_init(struct drm_device *dev, 78 - unsigned long size, bool private) 79 - { 80 - struct drm_gem_dma_object *dma_obj; 81 - int ret; 82 - 83 - size = round_up(size, PAGE_SIZE); 84 - 85 - if (size == 0) 86 - return ERR_PTR(-EINVAL); 87 - 88 - dma_obj = kzalloc_obj(*dma_obj); 89 - if (!dma_obj) 90 - return ERR_PTR(-ENOMEM); 91 - 92 - dma_obj->base.funcs = &mtk_gem_object_funcs; 93 - 94 - if (private) { 95 - ret = 0; 96 - drm_gem_private_object_init(dev, &dma_obj->base, size); 97 - } else { 98 - ret = drm_gem_object_init(dev, &dma_obj->base, size); 99 - } 100 - if (ret) { 101 - DRM_ERROR("failed to initialize gem object\n"); 102 - kfree(dma_obj); 103 - return ERR_PTR(ret); 104 - } 105 - 106 - return dma_obj; 107 - } 108 - 109 - static struct drm_gem_dma_object *mtk_gem_create(struct drm_device *dev, size_t size) 110 - { 111 - struct mtk_drm_private *priv = dev->dev_private; 112 - struct drm_gem_dma_object *dma_obj; 113 - struct drm_gem_object *obj; 114 - int ret; 115 - 116 - dma_obj = mtk_gem_init(dev, size, false); 117 - if (IS_ERR(dma_obj)) 118 - return ERR_CAST(dma_obj); 119 - 120 - obj = &dma_obj->base; 121 - 122 - dma_obj->vaddr = dma_alloc_wc(priv->dma_dev, obj->size, 123 - &dma_obj->dma_addr, 124 - GFP_KERNEL | __GFP_NOWARN); 125 - if (!dma_obj->vaddr) { 126 - DRM_ERROR("failed to allocate %zx byte dma buffer", obj->size); 127 - ret = -ENOMEM; 128 - goto err_gem_free; 129 - } 130 - 131 - DRM_DEBUG_DRIVER("vaddr = %p dma_addr = %pad size = %zu\n", 132 - dma_obj->vaddr, &dma_obj->dma_addr, 133 - size); 134 - 135 - return dma_obj; 136 - 137 - err_gem_free: 138 - drm_gem_object_release(obj); 139 - kfree(dma_obj); 140 - return ERR_PTR(ret); 141 - } 142 - 143 - int mtk_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, 144 - struct drm_mode_create_dumb *args) 145 - { 146 - struct drm_gem_dma_object *dma_obj; 147 - int ret; 148 - 149 - args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8); 150 - 151 - /* 152 - * Multiply 2 variables of different types, 153 - * for example: args->size = args->spacing * args->height; 154 - * may cause coverity issue with unintentional overflow. 155 - */ 156 - args->size = args->pitch; 157 - args->size *= args->height; 158 - 159 - dma_obj = mtk_gem_create(dev, args->size); 160 - if (IS_ERR(dma_obj)) 161 - return PTR_ERR(dma_obj); 162 - 163 - /* 164 - * allocate a id of idr table where the obj is registered 165 - * and handle has the id what user can see. 166 - */ 167 - ret = drm_gem_handle_create(file_priv, &dma_obj->base, &args->handle); 168 - if (ret) 169 - goto err_handle_create; 170 - 171 - /* drop reference from allocate - handle holds it now. */ 172 - drm_gem_object_put(&dma_obj->base); 173 - 174 - return 0; 175 - 176 - err_handle_create: 177 - mtk_gem_free_object(&dma_obj->base); 178 - return ret; 179 - } 180 - 181 - static int mtk_gem_object_mmap(struct drm_gem_object *obj, 182 - struct vm_area_struct *vma) 183 - 184 - { 185 - struct drm_gem_dma_object *dma_obj = to_drm_gem_dma_obj(obj); 186 - struct mtk_drm_private *priv = obj->dev->dev_private; 187 - int ret; 188 - 189 - /* 190 - * Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the 191 - * whole buffer from the start. 192 - */ 193 - vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); 194 - 195 - /* 196 - * dma_alloc_attrs() allocated a struct page table for mtk_gem, so clear 197 - * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap(). 198 - */ 199 - vm_flags_mod(vma, VM_IO | VM_DONTEXPAND | VM_DONTDUMP, VM_PFNMAP); 200 - 201 - vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); 202 - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); 203 - 204 - ret = dma_mmap_wc(priv->dma_dev, vma, dma_obj->vaddr, 205 - dma_obj->dma_addr, obj->size); 206 - if (ret) 207 - drm_gem_vm_close(vma); 208 - 209 - return ret; 210 - } 211 - 212 - struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, 213 - struct dma_buf_attachment *attach, struct sg_table *sgt) 214 - { 215 - struct drm_gem_dma_object *dma_obj; 216 - 217 - /* check if the entries in the sg_table are contiguous */ 218 - if (drm_prime_get_contiguous_size(sgt) < attach->dmabuf->size) { 219 - DRM_ERROR("sg_table is not contiguous"); 220 - return ERR_PTR(-EINVAL); 221 - } 222 - 223 - dma_obj = mtk_gem_init(dev, attach->dmabuf->size, true); 224 - if (IS_ERR(dma_obj)) 225 - return ERR_CAST(dma_obj); 226 - 227 - dma_obj->dma_addr = sg_dma_address(sgt->sgl); 228 - dma_obj->sgt = sgt; 229 - 230 - return &dma_obj->base; 231 - }
-17
drivers/gpu/drm/mediatek/mtk_gem.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (c) 2015 MediaTek Inc. 4 - */ 5 - 6 - #ifndef _MTK_GEM_H_ 7 - #define _MTK_GEM_H_ 8 - 9 - #include <drm/drm_gem.h> 10 - #include <drm/drm_gem_dma_helper.h> 11 - 12 - int mtk_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, 13 - struct drm_mode_create_dumb *args); 14 - struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, 15 - struct dma_buf_attachment *attach, struct sg_table *sg); 16 - 17 - #endif