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 be large enough to support this. Therefore compute the byte size of 8 pixels in the given color mode and align the pitch accordingly. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> Cc: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> Cc: Shawn Guo <shawnguo@xxxxxxxxxx> Cc: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> Cc: Pengutronix Kernel Team <kernel@xxxxxxxxxxxxxx> Cc: Fabio Estevam <festevam@xxxxxxxxx> --- drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 31 ++++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c index e7025df7b978..465b5a6ad5bb 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c @@ -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(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 = { -- 2.47.1