diff --git a/drivers/video/adf/adf.c b/drivers/video/adf/adf.c index 589baaa5fbcd..e6ef144136c2 100644 --- a/drivers/video/adf/adf.c +++ b/drivers/video/adf/adf.c @@ -1073,6 +1073,7 @@ int adf_format_validate_yuv(struct adf_device *dev, struct adf_buffer *buf, u32 width = buf->w / (i != 0 ? hsub : 1); u32 height = buf->h / (i != 0 ? vsub : 1); u8 cpp = adf_format_plane_cpp(buf->format, i); + u32 last_line_size; if (buf->pitch[i] < (u64) width * cpp) { dev_err(&dev->base.dev, "plane %u pitch is shorter than buffer width (pitch = %u, width = %u, bpp = %u)\n", @@ -1080,8 +1081,21 @@ int adf_format_validate_yuv(struct adf_device *dev, struct adf_buffer *buf, return -EINVAL; } - if ((u64) height * buf->pitch[i] + buf->offset[i] > - buf->dma_bufs[i]->size) { + switch (dev->ops->quirks.buffer_padding) { + case ADF_BUFFER_PADDED_TO_PITCH: + last_line_size = buf->pitch[i]; + break; + + case ADF_BUFFER_UNPADDED: + last_line_size = width * cpp; + break; + + default: + BUG(); + } + + if ((u64) (height - 1) * buf->pitch[i] + last_line_size + + buf->offset[i] > buf->dma_bufs[i]->size) { dev_err(&dev->base.dev, "plane %u buffer too small (height = %u, pitch = %u, offset = %u, size = %zu)\n", i, height, buf->pitch[i], buf->offset[i], buf->dma_bufs[i]->size); diff --git a/include/video/adf.h b/include/video/adf.h index 2b742ab463dd..34f10e538f9e 100644 --- a/include/video/adf.h +++ b/include/video/adf.h @@ -192,11 +192,27 @@ struct adf_obj { int minor; }; +/** + * struct adf_device_quirks - common display device quirks + * + * @buffer_padding: whether the last scanline of a buffer extends to the + * buffer's pitch (@ADF_BUFFER_PADDED_TO_PITCH) or just to the visible + * width (@ADF_BUFFER_UNPADDED) + */ +struct adf_device_quirks { + /* optional, defaults to ADF_BUFFER_PADDED_TO_PITCH */ + enum { + ADF_BUFFER_PADDED_TO_PITCH = 0, + ADF_BUFFER_UNPADDED = 1, + } buffer_padding; +}; + /** * struct adf_device_ops - display device implementation ops * * @owner: device's module * @base: common operations (see &struct adf_obj_ops) + * @quirks: device's quirks (see &struct adf_device_quirks) * * @attach: attach overlay engine @eng to interface @intf. Return 0 on success * or error code (<0) on failure. @@ -228,6 +244,8 @@ struct adf_device_ops { /* required */ struct module *owner; const struct adf_obj_ops base; + /* optional */ + const struct adf_device_quirks quirks; /* optional */ int (*attach)(struct adf_device *dev, struct adf_overlay_engine *eng,