]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/msm: Compute dumb-buffer sizes with drm_mode_size_dumb()
authorThomas Zimmermann <tzimmermann@suse.de>
Thu, 21 Aug 2025 08:17:20 +0000 (10:17 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Mon, 29 Sep 2025 12:00:57 +0000 (14:00 +0200)
Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch
and buffer size. Alignment is specified in bytes, but the hardware
requires the scanline pitch to be a multiple of 32 pixels. Therefore
compute the byte size of 32 pixels in the given color mode and align
the pitch accordingly. This replaces the existing code in the driver's
align_pitch() helper.

v3:
- clarify pitch alignment in commit message (Dmitry)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: Sean Paul <sean@poorly.run>
Cc: Marijn Suijten <marijn.suijten@somainline.org>
Link: https://lore.kernel.org/r/20250821081918.79786-14-tzimmermann@suse.de
drivers/gpu/drm/msm/msm_gem.c

index e7631f4ef530931f8ed46435c8160680ce0276a4..a6635ba426d48d51960a26d1d84bf04a25dd97b9 100644 (file)
 #include <linux/shmem_fs.h>
 #include <linux/dma-buf.h>
 
+#include <drm/drm_dumb_buffers.h>
 #include <drm/drm_prime.h>
 #include <drm/drm_file.h>
+#include <drm/drm_fourcc.h>
 
 #include <trace/events/gpu_mem.h>
 
@@ -698,8 +700,29 @@ void msm_gem_unpin_iova(struct drm_gem_object *obj, struct drm_gpuvm *vm)
 int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
                struct drm_mode_create_dumb *args)
 {
-       args->pitch = align_pitch(args->width, args->bpp);
-       args->size  = PAGE_ALIGN(args->pitch * args->height);
+       u32 fourcc;
+       const struct drm_format_info *info;
+       u64 pitch_align;
+       int ret;
+
+       /*
+        * Adreno needs pitch aligned to 32 pixels. Compute the number
+        * of bytes for a block of 32 pixels at the given color format.
+        * Use the result as pitch alignment.
+        */
+       fourcc = drm_driver_color_mode_format(dev, args->bpp);
+       if (fourcc == DRM_FORMAT_INVALID)
+               return -EINVAL;
+       info = drm_format_info(fourcc);
+       if (!info)
+               return -EINVAL;
+       pitch_align = drm_format_info_min_pitch(info, 0, SZ_32);
+       if (!pitch_align || pitch_align > U32_MAX)
+               return -EINVAL;
+       ret = drm_mode_size_dumb(dev, args, pitch_align, 0);
+       if (ret)
+               return ret;
+
        return msm_gem_new_handle(dev, file, args->size,
                        MSM_BO_SCANOUT | MSM_BO_WC, &args->handle, "dumb");
 }