Commit 2a87c0c9 authored by Steve Longerbeam's avatar Steve Longerbeam Committed by Mauro Carvalho Chehab

media: imx-csi: Double crop height for alternate fields at sink

If the incoming sink field type is alternate, the reset crop height
and crop height bounds must be set to twice the incoming height,
because in alternate field mode, upstream will report only the
lines for a single field, and the CSI captures the whole frame.
Signed-off-by: default avatarSteve Longerbeam <slongerbeam@gmail.com>
Reviewed-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent d969291d
...@@ -1142,6 +1142,8 @@ static void csi_try_crop(struct csi_priv *priv, ...@@ -1142,6 +1142,8 @@ static void csi_try_crop(struct csi_priv *priv,
struct v4l2_mbus_framefmt *infmt, struct v4l2_mbus_framefmt *infmt,
struct v4l2_fwnode_endpoint *upstream_ep) struct v4l2_fwnode_endpoint *upstream_ep)
{ {
u32 in_height;
crop->width = min_t(__u32, infmt->width, crop->width); crop->width = min_t(__u32, infmt->width, crop->width);
if (crop->left + crop->width > infmt->width) if (crop->left + crop->width > infmt->width)
crop->left = infmt->width - crop->width; crop->left = infmt->width - crop->width;
...@@ -1149,6 +1151,10 @@ static void csi_try_crop(struct csi_priv *priv, ...@@ -1149,6 +1151,10 @@ static void csi_try_crop(struct csi_priv *priv,
crop->left &= ~0x3; crop->left &= ~0x3;
crop->width &= ~0x7; crop->width &= ~0x7;
in_height = infmt->height;
if (infmt->field == V4L2_FIELD_ALTERNATE)
in_height *= 2;
/* /*
* FIXME: not sure why yet, but on interlaced bt.656, * FIXME: not sure why yet, but on interlaced bt.656,
* changing the vertical cropping causes loss of vertical * changing the vertical cropping causes loss of vertical
...@@ -1158,12 +1164,12 @@ static void csi_try_crop(struct csi_priv *priv, ...@@ -1158,12 +1164,12 @@ static void csi_try_crop(struct csi_priv *priv,
if (upstream_ep->bus_type == V4L2_MBUS_BT656 && if (upstream_ep->bus_type == V4L2_MBUS_BT656 &&
(V4L2_FIELD_HAS_BOTH(infmt->field) || (V4L2_FIELD_HAS_BOTH(infmt->field) ||
infmt->field == V4L2_FIELD_ALTERNATE)) { infmt->field == V4L2_FIELD_ALTERNATE)) {
crop->height = infmt->height; crop->height = in_height;
crop->top = (infmt->height == 480) ? 2 : 0; crop->top = (in_height == 480) ? 2 : 0;
} else { } else {
crop->height = min_t(__u32, infmt->height, crop->height); crop->height = min_t(__u32, in_height, crop->height);
if (crop->top + crop->height > infmt->height) if (crop->top + crop->height > in_height)
crop->top = infmt->height - crop->height; crop->top = in_height - crop->height;
} }
} }
...@@ -1403,6 +1409,8 @@ static void csi_try_fmt(struct csi_priv *priv, ...@@ -1403,6 +1409,8 @@ static void csi_try_fmt(struct csi_priv *priv,
crop->top = 0; crop->top = 0;
crop->width = sdformat->format.width; crop->width = sdformat->format.width;
crop->height = sdformat->format.height; crop->height = sdformat->format.height;
if (sdformat->format.field == V4L2_FIELD_ALTERNATE)
crop->height *= 2;
csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep); csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep);
compose->left = 0; compose->left = 0;
compose->top = 0; compose->top = 0;
...@@ -1530,6 +1538,8 @@ static int csi_get_selection(struct v4l2_subdev *sd, ...@@ -1530,6 +1538,8 @@ static int csi_get_selection(struct v4l2_subdev *sd,
sel->r.top = 0; sel->r.top = 0;
sel->r.width = infmt->width; sel->r.width = infmt->width;
sel->r.height = infmt->height; sel->r.height = infmt->height;
if (infmt->field == V4L2_FIELD_ALTERNATE)
sel->r.height *= 2;
break; break;
case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_CROP:
sel->r = *crop; sel->r = *crop;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment