Commit b1d0e470 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/imx/ipuv3: Compute dumb-buffer sizes with drm_mode_size_dumb()



Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch and
buffer size. The hardware requires the framebuffer width to be a
multiple of 8. The scanline pitch has to be large enough to support
this. Therefore compute the byte size of 8 pixels in the given color
mode and align the pitch accordingly.

v5:
- fix typo in commit description

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Link: https://lore.kernel.org/r/20250821081918.79786-11-tzimmermann@suse.de
parent ecf29357
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_dumb_buffers.h>
#include <drm/drm_fbdev_dma.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_managed.h>
@@ -141,19 +143,32 @@ static int imx_drm_dumb_create(struct drm_file *file_priv,
			       struct drm_device *drm,
			       struct drm_mode_create_dumb *args)
{
	u32 width = args->width;
	u32 fourcc;
	const struct drm_format_info *info;
	u64 pitch_align;
	int ret;

	args->width = ALIGN(width, 8);
	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
	args->size = args->pitch * args->height;

	ret = drm_gem_dma_dumb_create_internal(file_priv, drm, args);
	/*
	 * Hardware requires the framebuffer width to be aligned to
	 * multiples of 8. The mode-setting code handles this, but
	 * the buffer pitch has to be aligned as well. Set the pitch
	 * alignment accordingly, so that the each scanline fits into
	 * the allocated buffer.
	 */
	fourcc = drm_driver_color_mode_format(drm, 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_8);
	if (!pitch_align || pitch_align > U32_MAX)
		return -EINVAL;
	ret = drm_mode_size_dumb(drm, args, pitch_align, 0);
	if (ret)
		return ret;

	args->width = width;
	return ret;
	return drm_gem_dma_dumb_create(file_priv, drm, args);
}

static const struct drm_driver imx_drm_driver = {