:p
atchew
Login
Dear All, While testing ov5645 + RZ/G3E we found out that the UYVY8_2X8/2592x1944 is broken. The issue is that the CRU DMA engine requires the line stride to be a multiple of 128 bytes (RZG2L_CRU_STRIDE_ALIGN). v4l2_fill_pixfmt() sets bytesperline as width * bytes_per_pixel with no alignment, so for widths whose natural stride is not 128-byte aligned the hardware silently rounds up, causing a mismatch that produces visible horizontal banding in the captured image. Tested using: media-ctl -d /dev/media0 --set-v4l2 '"ov5645 0-003c":0[fmt:UYVY8_2X8/2592x1944 field:none]' media-ctl -d /dev/media0 --set-v4l2 '"csi-16000400.csi2":0[fmt:UYVY8_2X8/2592x1944]' media-ctl -d /dev/media0 --set-v4l2 '"cru-ip-16000000.video":0[fmt:UYVY8_2X8/2592x1944]' v4l2-ctl -d /dev/video0 --verbose --set-fmt-video=width=2592,height=1944,pixelformat=UYVY --stream-mmap --stream-count=100 --stream-to=./frame.raw gst-launch-1.0 v4l2src device=/dev/video0 blocksize=76800 io-mode=dmabuf num-buffers=200 ! video/x-raw,format=UYVY,width=2592,height=1944 ! videoconvert ! queue ! waylandsink sync=false This patch fix the issue. Kind Regards, Tommaso v2->v3: - PATCH 2/4: No changes, just moved to from PATCH 3/4 to PATCH 2/4 - PATCH 3/4: Moved to PATCH 3/4, from PATCH 2/4. Fixed documentation as suggested by Sven Püschel v1->v2: - PATCH 3/4: Move v4l2_fill_pixfmt() into v4l2-common.h as inline wrapper Add v4l2_fill_pixfmt_aligned() helper documentation. - PATCH 4/4: Collected tag, add missing Cc stable, fix s/commit/Commit/ into commit body. Tommaso Merciai (4): media: v4l2-common: Convert v4l2_fill_pixfmt_mp() to static inline wrapper media: v4l2-common: Add v4l2_fill_pixfmt_aligned() helper media: v4l2-common: Add kernel-doc for v4l2_fill_pixfmt_mp_aligned() media: rzg2l-cru: Align bytesperline to hardware DMA stride requirement .../platform/renesas/rzg2l-cru/rzg2l-video.c | 3 +- drivers/media/v4l2-core/v4l2-common.c | 20 ++--- include/media/v4l2-common.h | 75 +++++++++++++++++-- 3 files changed, 79 insertions(+), 19 deletions(-) -- 2.54.0
Convert v4l2_fill_pixfmt_mp() to static inline wrapper: drop the exported v4l2_fill_pixfmt_mp() function from v4l2-common.c and replace it with an equivalent static inline in the header that delegates to v4l2_fill_pixfmt_mp_aligned() with stride_alignment=1. Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v2->v3: - No changes v1->v2: - New patch drivers/media/v4l2-core/v4l2-common.c | 8 -------- include/media/v4l2-common.h | 9 +++++++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -XXX,XX +XXX,XX @@ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, } EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp_aligned); -int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, - u32 pixelformat, u32 width, u32 height) -{ - return v4l2_fill_pixfmt_mp_aligned(pixfmt, pixelformat, - width, height, 1); -} -EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp); - int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, u32 width, u32 height) { diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index XXXXXXX..XXXXXXX 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -XXX,XX +XXX,XX @@ void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, const struct v4l2_frmsize_stepwise *frmsize); int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, u32 width, u32 height); -int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, - u32 width, u32 height); + /* @stride_alignment is a power of 2 value in bytes */ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, u32 width, u32 height, u8 stride_alignment); +static inline int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, + u32 pixelformat, u32 width, u32 height) +{ + return v4l2_fill_pixfmt_mp_aligned(pixfmt, pixelformat, width, height, 1); +} + /** * v4l2_get_link_freq - Get link rate from transmitter * -- 2.54.0
Add v4l2_fill_pixfmt_aligned(), a variant of v4l2_fill_pixfmt() that accepts a stride_alignment parameter, mirroring the existing v4l2_fill_pixfmt_mp() / v4l2_fill_pixfmt_mp_aligned() pair. v4l2_fill_pixfmt() is refactored to call v4l2_fill_pixfmt_aligned() with stride_alignment=1, preserving its existing behaviour. The new helper is needed by drivers whose DMA engine requires the line stride to be a multiple of a specific value, such as the Renesas RZ/G3E CRU which requires 128-byte alignment. Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v2->v3: - No changes, just moved to from PATCH 3/4 to PATCH 2/4 v1->v2: - Move v4l2_fill_pixfmt() into v4l2-common.h as inline wrapper - Add v4l2_fill_pixfmt_aligned() helper documentation. drivers/media/v4l2-core/v4l2-common.c | 12 +++++---- include/media/v4l2-common.h | 38 +++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -XXX,XX +XXX,XX @@ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, } EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp_aligned); -int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, - u32 width, u32 height) +int v4l2_fill_pixfmt_aligned(struct v4l2_pix_format *pixfmt, u32 pixelformat, + u32 width, u32 height, u8 stride_alignment) { const struct v4l2_format_info *info; int i; @@ -XXX,XX +XXX,XX @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, pixfmt->width = width; pixfmt->height = height; pixfmt->pixelformat = pixelformat; - pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width, 1); + pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width, + stride_alignment); pixfmt->sizeimage = 0; for (i = 0; i < info->comp_planes; i++) pixfmt->sizeimage += - v4l2_format_plane_size(info, i, width, height, 1); + v4l2_format_plane_size(info, i, width, height, + stride_alignment); return 0; } -EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); +EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_aligned); #ifdef CONFIG_MEDIA_CONTROLLER static s64 v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler, diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index XXXXXXX..XXXXXXX 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -XXX,XX +XXX,XX @@ static inline bool v4l2_is_format_bayer(const struct v4l2_format_info *f) const struct v4l2_format_info *v4l2_format_info(u32 format); void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, const struct v4l2_frmsize_stepwise *frmsize); -int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, - u32 width, u32 height); + +/** + * v4l2_fill_pixfmt_aligned - Fill in a &struct v4l2_pix_format with stride + * alignment requirements. + * + * @pixfmt: pointer to the &struct v4l2_pix_format to be filled + * @pixelformat: the V4L2 pixel format (V4L2_PIX_FMT_*) + * @width: image width in pixels + * @height: image height in pixels + * @stride_alignment: stride alignment in bytes, must be a power of 2 + * + * Fills all fields of @pixfmt for the given pixel format, dimensions, and + * stride alignment. Only formats stored in a single memory plane are + * supported; returns -EINVAL for multi-memory-plane formats. + * + * @pixfmt->bytesperline is set to the stride of the primary (plane 0) plane, + * rounded up to a multiple of @stride_alignment. For formats that store + * multiple component planes in a single memory buffer (e.g. NV12), the + * alignment applied to each component plane's stride is scaled relative to + * @stride_alignment so that the chroma stride remains consistently derivable + * from the luma stride. @pixfmt->bytesperline therefore reflects only the + * primary plane stride. + * + * @pixfmt->sizeimage is set to the total size in bytes of all component planes. + * + * Return: 0 on success, -EINVAL if @pixelformat is unknown or uses multiple + * memory planes. + */ +int v4l2_fill_pixfmt_aligned(struct v4l2_pix_format *pixfmt, u32 pixelformat, + u32 width, u32 height, u8 stride_alignment); + +static inline int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, + u32 pixelformat, u32 width, u32 height) +{ + return v4l2_fill_pixfmt_aligned(pixfmt, pixelformat, width, height, 1); +} /* @stride_alignment is a power of 2 value in bytes */ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, -- 2.54.0
Replace the bare placeholder comment with a full kernel-doc block documenting all parameters, the function behaviour for both single memory plane (mem_planes == 1) and multiple memory plane (mem_planes > 1) formats, and the return value. Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v2->v3: - Moved to PATCH 3/4 - Fixed documentation as suggested by Sven Püschel v1->v2: - New patch include/media/v4l2-common.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index XXXXXXX..XXXXXXX 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -XXX,XX +XXX,XX @@ static inline int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, return v4l2_fill_pixfmt_aligned(pixfmt, pixelformat, width, height, 1); } -/* @stride_alignment is a power of 2 value in bytes */ +/** + * v4l2_fill_pixfmt_mp_aligned - Fill in a &struct v4l2_pix_format_mplane with + * stride alignment requirements. + * + * @pixfmt: pointer to the &struct v4l2_pix_format_mplane to be filled + * @pixelformat: the V4L2 pixel format (V4L2_PIX_FMT_*) + * @width: image width in pixels + * @height: image height in pixels + * @stride_alignment: stride alignment in bytes; must be a power of 2 + * + * Fills all fields of @pixfmt for the given pixel format, dimensions, and + * stride alignment. + * + * For formats stored in a single memory plane (mem_planes == 1), the + * behaviour matches v4l2_fill_pixfmt_aligned(): plane_fmt[0].bytesperline + * is set to the primary plane stride. The strides of all components are + * aligned to the @stride_alignment. To keep the chroma strides consistently + * derivable from the luma stride, strides may be aligned to a multiple of + * the @stride_alignment instead. plane_fmt[0].sizeimage covers all + * component planes. + * + * For formats with multiple memory planes (mem_planes > 1), each plane's + * bytesperline is independently rounded up to @stride_alignment, and + * sizeimage is set to bytesperline multiplied by the plane height. + * + * Return: 0 on success, -EINVAL if @pixelformat is unknown. + */ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, u32 width, u32 height, u8 stride_alignment); -- 2.54.0
The RZ/G3E CRU programs the line stride via the AMnIS register, whose IS field encodes the value in units of 128 bytes. If bytesperline is not a multiple of 128, the division truncates and the hardware uses a wrong stride, causing horizontal banding. Commit ace92ccef0c9 ("media: platform: rzg2l-cru: Use v4l2_fill_pixfmt()") replaced the open-coded aligned calculation with v4l2_fill_pixfmt(), which sets no alignment, reintroducing the issue. Switch to v4l2_fill_pixfmt_aligned() with RZG2L_CRU_STRIDE_ALIGN when info->has_stride is set. RZ/G2L has no AMnIS register and keeps using v4l2_fill_pixfmt() unchanged. Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Cc: stable@vger.kernel.org Fixes: ace92ccef0c9 ("media: platform: rzg2l-cru: Use v4l2_fill_pixfmt()") Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v2->v3: - No changes. v1->v2: - Collected tag - Add missing Cc stable - Fix s/commit/Commit/ into commit body drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -XXX,XX +XXX,XX @@ static void rzg2l_cru_format_align(struct rzg2l_cru_dev *cru, v4l_bound_align_image(&pix->width, 320, info->max_width, 1, &pix->height, 240, info->max_height, 0, 0); - v4l2_fill_pixfmt(pix, pix->pixelformat, pix->width, pix->height); + v4l2_fill_pixfmt_aligned(pix, pix->pixelformat, pix->width, pix->height, + info->has_stride ? RZG2L_CRU_STRIDE_ALIGN : 1); dev_dbg(cru->dev, "Format %ux%u bpl: %u size: %u\n", pix->width, pix->height, pix->bytesperline, pix->sizeimage); -- 2.54.0
Dear All, While testing ov5645 + RZ/G3E we found out that the UYVY8_2X8/2592x1944 is broken. The issue is that the CRU DMA engine requires the line stride to be a multiple of 128 bytes (RZG2L_CRU_STRIDE_ALIGN). v4l2_fill_pixfmt() sets bytesperline as width * bytes_per_pixel with no alignment, so for widths whose natural stride is not 128-byte aligned the hardware silently rounds up, causing a mismatch that produces visible horizontal banding in the captured image. Tested using: media-ctl -d /dev/media0 --set-v4l2 '"ov5645 0-003c":0[fmt:UYVY8_2X8/2592x1944 field:none]' media-ctl -d /dev/media0 --set-v4l2 '"csi-16000400.csi2":0[fmt:UYVY8_2X8/2592x1944]' media-ctl -d /dev/media0 --set-v4l2 '"cru-ip-16000000.video":0[fmt:UYVY8_2X8/2592x1944]' v4l2-ctl -d /dev/video0 --verbose --set-fmt-video=width=2592,height=1944,pixelformat=UYVY --stream-mmap --stream-count=100 --stream-to=./frame.raw gst-launch-1.0 v4l2src device=/dev/video0 blocksize=76800 io-mode=dmabuf num-buffers=200 ! video/x-raw,format=UYVY,width=2592,height=1944 ! videoconvert ! queue ! waylandsink sync=false This patch fix the issue. Kind Regards, Tommaso v3->v4: - Rebased on top of media-committers/next - PATCH 1/4: Collected tag. - PATCH 2/4: Collected Jacopo tag. Removed "." at the end of the function's brief description. Removed "component" from @pixfmt->sizeimage line Removed wrong tab. Fixed example (e.g NV12) -> (e.g. YUV420) into function description - PATCH 3/4: Collected Jacopo tag. Fixed into "and each plane's sizeimage is" - PATCH 4/4: Collected tag. v2->v3: - PATCH 2/4: No changes, just moved to from PATCH 3/4 to PATCH 2/4 - PATCH 3/4: Moved to PATCH 3/4, from PATCH 2/4. Fixed documentation as suggested by Sven Püschel v1->v2: - PATCH 3/4: Move v4l2_fill_pixfmt() into v4l2-common.h as inline wrapper Add v4l2_fill_pixfmt_aligned() helper documentation. - PATCH 4/4: Collected tag, add missing Cc stable, fix s/commit/Commit/ into commit body. Tommaso Merciai (4): media: v4l2-common: Convert v4l2_fill_pixfmt_mp() to static inline wrapper media: v4l2-common: Add v4l2_fill_pixfmt_aligned() helper media: v4l2-common: Add kernel-doc for v4l2_fill_pixfmt_mp_aligned() media: rzg2l-cru: Align bytesperline to hardware DMA stride requirement .../platform/renesas/rzg2l-cru/rzg2l-video.c | 3 +- drivers/media/v4l2-core/v4l2-common.c | 20 ++--- include/media/v4l2-common.h | 75 +++++++++++++++++-- 3 files changed, 79 insertions(+), 19 deletions(-) -- 2.54.0
Convert v4l2_fill_pixfmt_mp() to static inline wrapper: drop the exported v4l2_fill_pixfmt_mp() function from v4l2-common.c and replace it with an equivalent static inline in the header that delegates to v4l2_fill_pixfmt_mp_aligned() with stride_alignment=1. Reviewed-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v3->v4: - Collected tag. v2->v3: - No changes v1->v2: - New patch drivers/media/v4l2-core/v4l2-common.c | 8 -------- include/media/v4l2-common.h | 9 +++++++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -XXX,XX +XXX,XX @@ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, } EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp_aligned); -int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, - u32 pixelformat, u32 width, u32 height) -{ - return v4l2_fill_pixfmt_mp_aligned(pixfmt, pixelformat, - width, height, 1); -} -EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp); - int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, u32 width, u32 height) { diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index XXXXXXX..XXXXXXX 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -XXX,XX +XXX,XX @@ void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, const struct v4l2_frmsize_stepwise *frmsize); int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, u32 width, u32 height); -int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, - u32 width, u32 height); + /* @stride_alignment is a power of 2 value in bytes */ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, u32 width, u32 height, u8 stride_alignment); +static inline int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, + u32 pixelformat, u32 width, u32 height) +{ + return v4l2_fill_pixfmt_mp_aligned(pixfmt, pixelformat, width, height, 1); +} + /** * v4l2_get_link_freq - Get link rate from transmitter * -- 2.54.0
Add v4l2_fill_pixfmt_aligned(), a variant of v4l2_fill_pixfmt() that accepts a stride_alignment parameter, mirroring the existing v4l2_fill_pixfmt_mp() / v4l2_fill_pixfmt_mp_aligned() pair. v4l2_fill_pixfmt() is refactored to call v4l2_fill_pixfmt_aligned() with stride_alignment=1, preserving its existing behaviour. The new helper is needed by drivers whose DMA engine requires the line stride to be a multiple of a specific value, such as the Renesas RZ/G3E CRU which requires 128-byte alignment. Reviewed-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v3->v4: - Collected tag. - Removed "." at the end of the function's brief description - Removed "component" from @pixfmt->sizeimage line - Removed wrong tab - Fixed example (e.g NV12) -> (e.g. YUV420) into function description v2->v3: - No changes, just moved to from PATCH 3/4 to PATCH 2/4 v1->v2: - Move v4l2_fill_pixfmt() into v4l2-common.h as inline wrapper - Add v4l2_fill_pixfmt_aligned() helper documentation. drivers/media/v4l2-core/v4l2-common.c | 12 +++++---- include/media/v4l2-common.h | 38 +++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -XXX,XX +XXX,XX @@ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, } EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp_aligned); -int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, - u32 width, u32 height) +int v4l2_fill_pixfmt_aligned(struct v4l2_pix_format *pixfmt, u32 pixelformat, + u32 width, u32 height, u8 stride_alignment) { const struct v4l2_format_info *info; int i; @@ -XXX,XX +XXX,XX @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, pixfmt->width = width; pixfmt->height = height; pixfmt->pixelformat = pixelformat; - pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width, 1); + pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width, + stride_alignment); pixfmt->sizeimage = 0; for (i = 0; i < info->comp_planes; i++) pixfmt->sizeimage += - v4l2_format_plane_size(info, i, width, height, 1); + v4l2_format_plane_size(info, i, width, height, + stride_alignment); return 0; } -EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); +EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_aligned); #ifdef CONFIG_MEDIA_CONTROLLER static s64 v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler, diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index XXXXXXX..XXXXXXX 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -XXX,XX +XXX,XX @@ static inline bool v4l2_is_format_bayer(const struct v4l2_format_info *f) const struct v4l2_format_info *v4l2_format_info(u32 format); void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, const struct v4l2_frmsize_stepwise *frmsize); -int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, - u32 width, u32 height); + +/** + * v4l2_fill_pixfmt_aligned - Fill in a &struct v4l2_pix_format with stride + * alignment requirements + * + * @pixfmt: pointer to the &struct v4l2_pix_format to be filled + * @pixelformat: the V4L2 pixel format (V4L2_PIX_FMT_*) + * @width: image width in pixels + * @height: image height in pixels + * @stride_alignment: stride alignment in bytes, must be a power of 2 + * + * Fills all fields of @pixfmt for the given pixel format, dimensions, and + * stride alignment. Only formats stored in a single memory plane are + * supported; returns -EINVAL for multi-memory-plane formats. + * + * @pixfmt->bytesperline is set to the stride of the primary (plane 0) plane, + * rounded up to a multiple of @stride_alignment. For formats that store + * multiple component planes in a single memory buffer (e.g. YUV420), the + * alignment applied to each component plane's stride is scaled relative to + * @stride_alignment so that the chroma stride remains consistently derivable + * from the luma stride. @pixfmt->bytesperline therefore reflects only the + * primary plane stride. + * + * @pixfmt->sizeimage is set to the total size in bytes of all planes. + * + * Return: 0 on success, -EINVAL if @pixelformat is unknown or uses multiple + * memory planes. + */ +int v4l2_fill_pixfmt_aligned(struct v4l2_pix_format *pixfmt, u32 pixelformat, + u32 width, u32 height, u8 stride_alignment); + +static inline int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, + u32 pixelformat, u32 width, u32 height) +{ + return v4l2_fill_pixfmt_aligned(pixfmt, pixelformat, width, height, 1); +} /* @stride_alignment is a power of 2 value in bytes */ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, -- 2.54.0
Replace the bare placeholder comment with a full kernel-doc block documenting all parameters, the function behaviour for both single memory plane (mem_planes == 1) and multiple memory plane (mem_planes > 1) formats, and the return value. Reviewed-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v3->v4: - Collected tag. - Fixed function documentation. v2->v3: - Moved to PATCH 3/4 - Fixed documentation as suggested by Sven Püschel v1->v2: - New patch include/media/v4l2-common.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index XXXXXXX..XXXXXXX 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -XXX,XX +XXX,XX @@ static inline int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, return v4l2_fill_pixfmt_aligned(pixfmt, pixelformat, width, height, 1); } -/* @stride_alignment is a power of 2 value in bytes */ +/** + * v4l2_fill_pixfmt_mp_aligned - Fill in a &struct v4l2_pix_format_mplane with + * stride alignment requirements. + * + * @pixfmt: pointer to the &struct v4l2_pix_format_mplane to be filled + * @pixelformat: the V4L2 pixel format (V4L2_PIX_FMT_*) + * @width: image width in pixels + * @height: image height in pixels + * @stride_alignment: stride alignment in bytes; must be a power of 2 + * + * Fills all fields of @pixfmt for the given pixel format, dimensions, and + * stride alignment. + * + * For formats stored in a single memory plane (mem_planes == 1), the + * behaviour matches v4l2_fill_pixfmt_aligned(): plane_fmt[0].bytesperline + * is set to the primary plane stride. The strides of all components are + * aligned to the @stride_alignment. To keep the chroma strides consistently + * derivable from the luma stride, strides may be aligned to a multiple of + * the @stride_alignment instead. plane_fmt[0].sizeimage covers all + * component planes. + * + * For formats with multiple memory planes (mem_planes > 1), each plane's + * bytesperline is independently rounded up to @stride_alignment, and each + * plane's sizeimage is set to bytesperline multiplied by the plane height. + * + * Return: 0 on success, -EINVAL if @pixelformat is unknown. + */ int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, u32 width, u32 height, u8 stride_alignment); -- 2.54.0
The RZ/G3E CRU programs the line stride via the AMnIS register, whose IS field encodes the value in units of 128 bytes. If bytesperline is not a multiple of 128, the division truncates and the hardware uses a wrong stride, causing horizontal banding. Commit ace92ccef0c9 ("media: platform: rzg2l-cru: Use v4l2_fill_pixfmt()") replaced the open-coded aligned calculation with v4l2_fill_pixfmt(), which sets no alignment, reintroducing the issue. Switch to v4l2_fill_pixfmt_aligned() with RZG2L_CRU_STRIDE_ALIGN when info->has_stride is set. RZ/G2L has no AMnIS register and keeps using v4l2_fill_pixfmt() unchanged. Cc: stable@vger.kernel.org Fixes: ace92ccef0c9 ("media: platform: rzg2l-cru: Use v4l2_fill_pixfmt()") Reviewed-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> --- v3->v4: - Collected tag. - Rebased on top of media-committers/next v2->v3: - No changes. v1->v2: - Collected tag - Add missing Cc stable - Fix s/commit/Commit/ into commit body drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -XXX,XX +XXX,XX @@ static void rzg2l_cru_format_align(struct rzg2l_cru_dev *cru, v4l_bound_align_image(&pix->width, 320, info->max_width, 1, &pix->height, 240, info->max_height, 2, 0); - v4l2_fill_pixfmt(pix, pix->pixelformat, pix->width, pix->height); + v4l2_fill_pixfmt_aligned(pix, pix->pixelformat, pix->width, pix->height, + info->has_stride ? RZG2L_CRU_STRIDE_ALIGN : 1); dev_dbg(cru->dev, "Format %ux%u bpl: %u size: %u\n", pix->width, pix->height, pix->bytesperline, pix->sizeimage); -- 2.54.0