aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/ti-vpe
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-12-12 03:36:03 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 03:57:32 -0500
commit30496799b07137654d2892270d063a4559acff3d (patch)
tree44474b8d0e3f5f66112d52bb06d2dee6abe9ea65 /drivers/media/platform/ti-vpe
parent6c4f4cbb585bbb124cadc2ed6ef7b8aeae5ce82e (diff)
[media] v4l: ti-vpe: enable CSC support for VPE
Use the csc library functions to configure the CSC block in VPE. Some changes are required in try_fmt to handle the pix->colorspace parameter more correctly. Previously, we copied the source queue colorspace to the destination queue colorspace as we didn't support RGB formats. Now, we configure pix->colorspace based on the color format set(and the height of the image if it's a YUV format). Add basic RGB color formats to the list of supported vpe formats. If the destination format is RGB colorspace, we also need to use the RGB output port instead of the Luma and Chroma output ports. This requires configuring the output data descriptors differently. Also, make the default colorspace V4L2_COLORSPACE_SMPTE170M as that resembles the Standard Definition colorspace more closely. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform/ti-vpe')
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c95
1 files changed, 72 insertions, 23 deletions
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 6c4db57fc0c9..1296c5386231 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -267,6 +267,38 @@ static struct vpe_fmt vpe_formats[] = {
267 .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422], 267 .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422],
268 }, 268 },
269 }, 269 },
270 {
271 .name = "RGB888 packed",
272 .fourcc = V4L2_PIX_FMT_RGB24,
273 .types = VPE_FMT_TYPE_CAPTURE,
274 .coplanar = 0,
275 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB24],
276 },
277 },
278 {
279 .name = "ARGB32",
280 .fourcc = V4L2_PIX_FMT_RGB32,
281 .types = VPE_FMT_TYPE_CAPTURE,
282 .coplanar = 0,
283 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ARGB32],
284 },
285 },
286 {
287 .name = "BGR888 packed",
288 .fourcc = V4L2_PIX_FMT_BGR24,
289 .types = VPE_FMT_TYPE_CAPTURE,
290 .coplanar = 0,
291 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_BGR24],
292 },
293 },
294 {
295 .name = "ABGR32",
296 .fourcc = V4L2_PIX_FMT_BGR32,
297 .types = VPE_FMT_TYPE_CAPTURE,
298 .coplanar = 0,
299 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ABGR32],
300 },
301 },
270}; 302};
271 303
272/* 304/*
@@ -689,17 +721,20 @@ static void set_src_registers(struct vpe_ctx *ctx)
689static void set_dst_registers(struct vpe_ctx *ctx) 721static void set_dst_registers(struct vpe_ctx *ctx)
690{ 722{
691 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; 723 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
724 enum v4l2_colorspace clrspc = ctx->q_data[Q_DATA_DST].colorspace;
692 struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt; 725 struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt;
693 u32 val = 0; 726 u32 val = 0;
694 727
695 /* select RGB path when color space conversion is supported in future */ 728 if (clrspc == V4L2_COLORSPACE_SRGB)
696 if (fmt->fourcc == V4L2_PIX_FMT_RGB24) 729 val |= VPE_RGB_OUT_SELECT;
697 val |= VPE_RGB_OUT_SELECT | VPE_CSC_SRC_DEI_SCALER;
698 else if (fmt->fourcc == V4L2_PIX_FMT_NV16) 730 else if (fmt->fourcc == V4L2_PIX_FMT_NV16)
699 val |= VPE_COLOR_SEPARATE_422; 731 val |= VPE_COLOR_SEPARATE_422;
700 732
701 /* The source of CHR_DS is always the scaler, whether it's used or not */ 733 /*
702 val |= VPE_DS_SRC_DEI_SCALER; 734 * the source of CHR_DS and CSC is always the scaler, irrespective of
735 * whether it's used or not
736 */
737 val |= VPE_DS_SRC_DEI_SCALER | VPE_CSC_SRC_DEI_SCALER;
703 738
704 if (fmt->fourcc != V4L2_PIX_FMT_NV12) 739 if (fmt->fourcc != V4L2_PIX_FMT_NV12)
705 val |= VPE_DS_BYPASS; 740 val |= VPE_DS_BYPASS;
@@ -813,7 +848,8 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
813 set_cfg_and_line_modes(ctx); 848 set_cfg_and_line_modes(ctx);
814 set_dei_regs(ctx); 849 set_dei_regs(ctx);
815 850
816 csc_set_coeff_bypass(ctx->dev->csc, &mmr_adb->csc_regs[5]); 851 csc_set_coeff(ctx->dev->csc, &mmr_adb->csc_regs[0],
852 s_q_data->colorspace, d_q_data->colorspace);
817 853
818 sc_set_hs_coeffs(ctx->dev->sc, ctx->sc_coeff_h.addr, src_w, dst_w); 854 sc_set_hs_coeffs(ctx->dev->sc, ctx->sc_coeff_h.addr, src_w, dst_w);
819 sc_set_vs_coeffs(ctx->dev->sc, ctx->sc_coeff_v.addr, src_h, dst_h); 855 sc_set_vs_coeffs(ctx->dev->sc, ctx->sc_coeff_v.addr, src_h, dst_h);
@@ -1095,9 +1131,13 @@ static void device_run(void *priv)
1095 if (ctx->deinterlacing) 1131 if (ctx->deinterlacing)
1096 add_out_dtd(ctx, VPE_PORT_MV_OUT); 1132 add_out_dtd(ctx, VPE_PORT_MV_OUT);
1097 1133
1098 add_out_dtd(ctx, VPE_PORT_LUMA_OUT); 1134 if (d_q_data->colorspace == V4L2_COLORSPACE_SRGB) {
1099 if (d_q_data->fmt->coplanar) 1135 add_out_dtd(ctx, VPE_PORT_RGB_OUT);
1100 add_out_dtd(ctx, VPE_PORT_CHROMA_OUT); 1136 } else {
1137 add_out_dtd(ctx, VPE_PORT_LUMA_OUT);
1138 if (d_q_data->fmt->coplanar)
1139 add_out_dtd(ctx, VPE_PORT_CHROMA_OUT);
1140 }
1101 1141
1102 /* input data descriptors */ 1142 /* input data descriptors */
1103 if (ctx->deinterlacing) { 1143 if (ctx->deinterlacing) {
@@ -1133,9 +1173,16 @@ static void device_run(void *priv)
1133 } 1173 }
1134 1174
1135 /* sync on channel control descriptors for output ports */ 1175 /* sync on channel control descriptors for output ports */
1136 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA_OUT); 1176 if (d_q_data->colorspace == V4L2_COLORSPACE_SRGB) {
1137 if (d_q_data->fmt->coplanar) 1177 vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1138 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA_OUT); 1178 VPE_CHAN_RGB_OUT);
1179 } else {
1180 vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1181 VPE_CHAN_LUMA_OUT);
1182 if (d_q_data->fmt->coplanar)
1183 vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1184 VPE_CHAN_CHROMA_OUT);
1185 }
1139 1186
1140 if (ctx->deinterlacing) 1187 if (ctx->deinterlacing)
1141 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT); 1188 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT);
@@ -1413,16 +1460,18 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1413 pix->num_planes = fmt->coplanar ? 2 : 1; 1460 pix->num_planes = fmt->coplanar ? 2 : 1;
1414 pix->pixelformat = fmt->fourcc; 1461 pix->pixelformat = fmt->fourcc;
1415 1462
1416 if (type == VPE_FMT_TYPE_CAPTURE) { 1463 if (!pix->colorspace) {
1417 struct vpe_q_data *s_q_data; 1464 if (fmt->fourcc == V4L2_PIX_FMT_RGB24 ||
1418 1465 fmt->fourcc == V4L2_PIX_FMT_BGR24 ||
1419 /* get colorspace from the source queue */ 1466 fmt->fourcc == V4L2_PIX_FMT_RGB32 ||
1420 s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 1467 fmt->fourcc == V4L2_PIX_FMT_BGR32) {
1421 1468 pix->colorspace = V4L2_COLORSPACE_SRGB;
1422 pix->colorspace = s_q_data->colorspace; 1469 } else {
1423 } else { 1470 if (pix->height > 1280) /* HD */
1424 if (!pix->colorspace) 1471 pix->colorspace = V4L2_COLORSPACE_REC709;
1425 pix->colorspace = V4L2_COLORSPACE_SMPTE240M; 1472 else /* SD */
1473 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1474 }
1426 } 1475 }
1427 1476
1428 for (i = 0; i < pix->num_planes; i++) { 1477 for (i = 0; i < pix->num_planes; i++) {
@@ -1817,7 +1866,7 @@ static int vpe_open(struct file *file)
1817 s_q_data->height = 1080; 1866 s_q_data->height = 1080;
1818 s_q_data->sizeimage[VPE_LUMA] = (s_q_data->width * s_q_data->height * 1867 s_q_data->sizeimage[VPE_LUMA] = (s_q_data->width * s_q_data->height *
1819 s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3; 1868 s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
1820 s_q_data->colorspace = V4L2_COLORSPACE_SMPTE240M; 1869 s_q_data->colorspace = V4L2_COLORSPACE_SMPTE170M;
1821 s_q_data->field = V4L2_FIELD_NONE; 1870 s_q_data->field = V4L2_FIELD_NONE;
1822 s_q_data->c_rect.left = 0; 1871 s_q_data->c_rect.left = 0;
1823 s_q_data->c_rect.top = 0; 1872 s_q_data->c_rect.top = 0;