@@ -117,6 +117,17 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
RWPF_MIN_WIDTH, rwpf->entity.max_width);
format->height = clamp_t(unsigned int, fmt->format.height,
RWPF_MIN_HEIGHT, rwpf->entity.max_height);
+
+ /*
+ * For YUV formats on the RPF, restrict the size to multiples of 2 to
+ * avoid shifting the color plane.
+ */
+ if (rwpf->entity.type == VSP1_ENTITY_RPF &&
+ format->code == MEDIA_BUS_FMT_AYUV8_1X32) {
+ format->width = ALIGN(format->width, 2);
+ format->height = ALIGN(format->height, 2);
+ }
+
format->field = V4L2_FIELD_NONE;
format->colorspace = fmt->format.colorspace;
@@ -231,23 +242,23 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
/* Make sure the crop rectangle is entirely contained in the image. */
format = v4l2_subdev_state_get_format(state, RWPF_PAD_SINK);
- /*
- * Restrict the crop rectangle coordinates to multiples of 2 to avoid
- * shifting the color plane.
- */
- if (format->code == MEDIA_BUS_FMT_AYUV8_1X32) {
- sel->r.left = ALIGN(sel->r.left, 2);
- sel->r.top = ALIGN(sel->r.top, 2);
- sel->r.width = round_down(sel->r.width, 2);
- sel->r.height = round_down(sel->r.height, 2);
- }
-
sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2);
sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2);
- sel->r.width = min_t(unsigned int, sel->r.width,
- format->width - sel->r.left);
- sel->r.height = min_t(unsigned int, sel->r.height,
- format->height - sel->r.top);
+ sel->r.width = clamp_t(unsigned int, sel->r.width, RWPF_MIN_WIDTH,
+ format->width - sel->r.left);
+ sel->r.height = clamp_t(unsigned int, sel->r.height, RWPF_MIN_HEIGHT,
+ format->height - sel->r.top);
+
+ /*
+ * For YUV formats, restrict the crop rectangle coordinates to multiples
+ * of 2 to avoid shifting the color plane.
+ */
+ if (format->code == MEDIA_BUS_FMT_AYUV8_1X32) {
+ sel->r.left = round_down(sel->r.left, 2);
+ sel->r.top = round_down(sel->r.top, 2);
+ sel->r.width = ALIGN(sel->r.width, 2);
+ sel->r.height = ALIGN(sel->r.height, 2);
+ }
crop = v4l2_subdev_state_get_crop(state, RWPF_PAD_SINK);
*crop = sel->r;
When reading YUV formats from memory, the hardware requires the crop rectangle size and position to be aligned to multiples of two, depending on the horizontal and vertical subsampling factors. The driver doesn't enforce this, leading to incorrect operation. As the crop rectangle is implemented on the RPF subdev's sink pad, enforcing the constraint conditionally based on the subsampling factors is difficult, as those are only known by the RPF video device. We could perform the check at pipeline validation time, but that could lead to confusing -EPIPE errors. As there is very few use cases for odd crop offsets and sizes with non-subsampled YUV, take the easier and more user-friendly route of enforcing the constraint on all YUV formats. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> --- .../media/platform/renesas/vsp1/vsp1_rwpf.c | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-)