media: gpu: ipu-v3: Add planar support to interlaced scan
To support interlaced scan with planar formats, cpmem SLUV must be programmed with the correct chroma line stride. For full and partial planar 4:2:2 (YUV422P, NV16), chroma line stride must be doubled. For full and partial planar 4:2:0 (YUV420, YVU420, NV12), chroma line stride must _not_ be doubled, since a single chroma line is shared by two luma lines. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
fc8c723852
commit
9b5c8d5ffb
|
@ -277,9 +277,10 @@ void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(ipu_cpmem_set_uv_offset);
|
||||
|
||||
void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride)
|
||||
void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride,
|
||||
u32 pixelformat)
|
||||
{
|
||||
u32 ilo, sly;
|
||||
u32 ilo, sly, sluv;
|
||||
|
||||
if (stride < 0) {
|
||||
stride = -stride;
|
||||
|
@ -290,9 +291,30 @@ void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride)
|
|||
|
||||
sly = (stride * 2) - 1;
|
||||
|
||||
switch (pixelformat) {
|
||||
case V4L2_PIX_FMT_YUV420:
|
||||
case V4L2_PIX_FMT_YVU420:
|
||||
sluv = stride / 2 - 1;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
sluv = stride - 1;
|
||||
break;
|
||||
case V4L2_PIX_FMT_YUV422P:
|
||||
sluv = stride - 1;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV16:
|
||||
sluv = stride * 2 - 1;
|
||||
break;
|
||||
default:
|
||||
sluv = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1);
|
||||
ipu_ch_param_write_field(ch, IPU_FIELD_ILO, ilo);
|
||||
ipu_ch_param_write_field(ch, IPU_FIELD_SLY, sly);
|
||||
if (sluv)
|
||||
ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, sluv);
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ipu_cpmem_interlaced_scan);
|
||||
|
||||
|
|
|
@ -412,7 +412,8 @@ static int prp_setup_channel(struct prp_priv *priv,
|
|||
if (image.pix.field == V4L2_FIELD_NONE &&
|
||||
V4L2_FIELD_HAS_BOTH(infmt->field) &&
|
||||
channel == priv->out_ch)
|
||||
ipu_cpmem_interlaced_scan(channel, image.pix.bytesperline);
|
||||
ipu_cpmem_interlaced_scan(channel, image.pix.bytesperline,
|
||||
image.pix.pixelformat);
|
||||
|
||||
ret = ipu_ic_task_idma_init(priv->ic, channel,
|
||||
image.pix.width, image.pix.height,
|
||||
|
|
|
@ -512,7 +512,8 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
|
|||
if (image.pix.field == V4L2_FIELD_NONE &&
|
||||
V4L2_FIELD_HAS_BOTH(infmt->field))
|
||||
ipu_cpmem_interlaced_scan(priv->idmac_ch,
|
||||
image.pix.bytesperline);
|
||||
image.pix.bytesperline,
|
||||
image.pix.pixelformat);
|
||||
|
||||
ipu_idmac_set_double_buffer(priv->idmac_ch, true);
|
||||
|
||||
|
|
|
@ -258,7 +258,8 @@ void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride);
|
|||
void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch);
|
||||
void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf);
|
||||
void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off);
|
||||
void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride);
|
||||
void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride,
|
||||
u32 pixelformat);
|
||||
void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id);
|
||||
int ipu_cpmem_get_burstsize(struct ipuv3_channel *ch);
|
||||
void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize);
|
||||
|
|
Loading…
Reference in New Issue