If IDMAC interweaving is enabled in a write channel, the channel must write the odd chroma rows for 4:2:0 formats. Skipping writing the odd chroma rows produces corrupted captured 4:2:0 images when interweave is enabled. Signed-off-by: Steve Longerbeam <steve_longerbeam@xxxxxxxxxx> --- drivers/staging/media/imx/imx-ic-prpencvf.c | 18 +++++++++++++----- drivers/staging/media/imx/imx-media-csi.c | 18 ++++++++++++------ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index ae453fd..b63b3f4 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -353,6 +353,7 @@ static int prp_setup_channel(struct prp_priv *priv, struct v4l2_mbus_framefmt *infmt; unsigned int burst_size; struct ipu_image image; + bool interweave; int ret; infmt = &priv->format_mbus[PRPENCVF_SINK_PAD]; @@ -365,6 +366,10 @@ static int prp_setup_channel(struct prp_priv *priv, image.rect.width = image.pix.width; image.rect.height = image.pix.height; + interweave = (image.pix.field == V4L2_FIELD_NONE && + V4L2_FIELD_HAS_BOTH(infmt->field) && + channel == priv->out_ch); + if (rot_swap_width_height) { swap(image.pix.width, image.pix.height); swap(image.rect.width, image.rect.height); @@ -377,12 +382,17 @@ static int prp_setup_channel(struct prp_priv *priv, image.phys0 = addr0; image.phys1 = addr1; - if (channel == priv->out_ch || channel == priv->rot_out_ch) { + /* + * Skip writing U and V components to odd rows in the output + * channels for planar 4:2:0 (but not when enabling IDMAC + * interweaving, they are incompatible). + */ + if (!interweave && (channel == priv->out_ch || + channel == priv->rot_out_ch)) { switch (image.pix.pixelformat) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: case V4L2_PIX_FMT_NV12: - /* Skip writing U and V components to odd rows */ ipu_cpmem_skip_odd_chroma_rows(channel); break; } @@ -405,9 +415,7 @@ static int prp_setup_channel(struct prp_priv *priv, if (rot_mode) ipu_cpmem_set_rotation(channel, rot_mode); - if (image.pix.field == V4L2_FIELD_NONE && - V4L2_FIELD_HAS_BOTH(infmt->field) && - channel == priv->out_ch) + if (interweave) ipu_cpmem_interlaced_scan(channel, image.pix.bytesperline); ret = ipu_ic_task_idma_init(priv->ic, channel, diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 6829c08..ab2de71 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -368,10 +368,10 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) { struct imx_media_video_dev *vdev = priv->vdev; struct v4l2_mbus_framefmt *infmt; + bool passthrough, interweave; struct ipu_image image; u32 passthrough_bits; dma_addr_t phys[2]; - bool passthrough; u32 burst_size; int ret; @@ -389,6 +389,10 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) image.phys0 = phys[0]; image.phys1 = phys[1]; + interweave = (image.pix.field == V4L2_FIELD_NONE && + (V4L2_FIELD_HAS_BOTH(infmt->field) || + infmt->field == V4L2_FIELD_ALTERNATE)); + /* * Check for conditions that require the IPU to handle the * data internally as generic data, aka passthrough mode: @@ -422,8 +426,12 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) ((image.pix.width & 0xf) ? 8 : 16) : 32) : 64; passthrough = is_parallel_16bit_bus(&priv->upstream_ep); passthrough_bits = 16; - /* Skip writing U and V components to odd rows */ - ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch); + /* + * Skip writing U and V components to odd rows (but not + * when enabling IDMAC interweaving, they are incompatible). + */ + if (!interweave) + ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch); break; case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: @@ -477,9 +485,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) ipu_smfc_set_burstsize(priv->smfc, burst_size); - if (image.pix.field == V4L2_FIELD_NONE && - (V4L2_FIELD_HAS_BOTH(infmt->field) || - infmt->field == V4L2_FIELD_ALTERNATE)) + if (interweave) ipu_cpmem_interlaced_scan(priv->idmac_ch, image.pix.bytesperline); -- 2.7.4