Commit 9a36d8ed authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] omap3isp: ccdc: Add basic support for interlaced video

When the CCDC input is interlaced enable the alternate field order on
the CCDC output video node. The field signal polarity is specified
through platform data.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: default avatarEnrico Butera <ebutera@users.sourceforge.net>
Acked-by: default avatarSakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 0a7b1a01
...@@ -1001,6 +1001,9 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc, ...@@ -1001,6 +1001,9 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
if (pdata && pdata->vs_pol) if (pdata && pdata->vs_pol)
syn_mode |= ISPCCDC_SYN_MODE_VDPOL; syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
if (pdata && pdata->fld_pol)
syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
/* The CCDC_CFG.Y8POS bit is used in YCbCr8 input mode only. The /* The CCDC_CFG.Y8POS bit is used in YCbCr8 input mode only. The
...@@ -1140,6 +1143,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) ...@@ -1140,6 +1143,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge); omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge);
/* Configure the sync interface. */
ccdc_config_sync_if(ccdc, pdata, depth_out); ccdc_config_sync_if(ccdc, pdata, depth_out);
syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
...@@ -1499,6 +1503,17 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc) ...@@ -1499,6 +1503,17 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
return 1; return 1;
} }
/* When capturing fields in alternate order read the current field
* identifier and store it in the pipeline.
*/
if (ccdc->formats[CCDC_PAD_SOURCE_OF].field == V4L2_FIELD_ALTERNATE) {
u32 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC,
ISPCCDC_SYN_MODE);
pipe->field = syn_mode & ISPCCDC_SYN_MODE_FLDSTAT
? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
}
if (ccdc_sbl_wait_idle(ccdc, 1000)) { if (ccdc_sbl_wait_idle(ccdc, 1000)) {
dev_info(isp->dev, "CCDC won't become idle!\n"); dev_info(isp->dev, "CCDC won't become idle!\n");
isp->crashed |= 1U << ccdc->subdev.entity.id; isp->crashed |= 1U << ccdc->subdev.entity.id;
...@@ -1830,6 +1845,11 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, ...@@ -1830,6 +1845,11 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
/* Clamp the input size. */ /* Clamp the input size. */
fmt->width = clamp_t(u32, width, 32, 4096); fmt->width = clamp_t(u32, width, 32, 4096);
fmt->height = clamp_t(u32, height, 32, 4096); fmt->height = clamp_t(u32, height, 32, 4096);
/* Default to progressive field order. */
if (fmt->field == V4L2_FIELD_ANY)
fmt->field = V4L2_FIELD_NONE;
break; break;
case CCDC_PAD_SOURCE_OF: case CCDC_PAD_SOURCE_OF:
...@@ -1885,7 +1905,6 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, ...@@ -1885,7 +1905,6 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
* stored on 2 bytes. * stored on 2 bytes.
*/ */
fmt->colorspace = V4L2_COLORSPACE_SRGB; fmt->colorspace = V4L2_COLORSPACE_SRGB;
fmt->field = V4L2_FIELD_NONE;
} }
/* /*
......
...@@ -482,6 +482,11 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video) ...@@ -482,6 +482,11 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
else else
buf->vb.v4l2_buf.sequence = atomic_read(&pipe->frame_number); buf->vb.v4l2_buf.sequence = atomic_read(&pipe->frame_number);
if (pipe->field != V4L2_FIELD_NONE)
buf->vb.v4l2_buf.sequence /= 2;
buf->vb.v4l2_buf.field = pipe->field;
/* Report pipeline errors to userspace on the capture device side. */ /* Report pipeline errors to userspace on the capture device side. */
if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) { if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
state = VB2_BUF_STATE_ERROR; state = VB2_BUF_STATE_ERROR;
...@@ -1038,6 +1043,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) ...@@ -1038,6 +1043,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
video->queue = &vfh->queue; video->queue = &vfh->queue;
INIT_LIST_HEAD(&video->dmaqueue); INIT_LIST_HEAD(&video->dmaqueue);
atomic_set(&pipe->frame_number, -1); atomic_set(&pipe->frame_number, -1);
pipe->field = vfh->format.fmt.pix.field;
mutex_lock(&video->queue_lock); mutex_lock(&video->queue_lock);
ret = vb2_streamon(&vfh->queue, type); ret = vb2_streamon(&vfh->queue, type);
......
...@@ -78,6 +78,7 @@ enum isp_pipeline_state { ...@@ -78,6 +78,7 @@ enum isp_pipeline_state {
/* /*
* struct isp_pipeline - An ISP hardware pipeline * struct isp_pipeline - An ISP hardware pipeline
* @field: The field being processed by the pipeline
* @error: A hardware error occurred during capture * @error: A hardware error occurred during capture
* @entities: Bitmask of entities in the pipeline (indexed by entity ID) * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
*/ */
...@@ -91,6 +92,7 @@ struct isp_pipeline { ...@@ -91,6 +92,7 @@ struct isp_pipeline {
u32 entities; u32 entities;
unsigned long l3_ick; unsigned long l3_ick;
unsigned int max_rate; unsigned int max_rate;
enum v4l2_field field;
atomic_t frame_number; atomic_t frame_number;
bool do_propagation; /* of frame number */ bool do_propagation; /* of frame number */
bool error; bool error;
......
...@@ -57,6 +57,8 @@ enum { ...@@ -57,6 +57,8 @@ enum {
* 0 - Active high, 1 - Active low * 0 - Active high, 1 - Active low
* @vs_pol: Vertical synchronization polarity * @vs_pol: Vertical synchronization polarity
* 0 - Active high, 1 - Active low * 0 - Active high, 1 - Active low
* @fld_pol: Field signal polarity
* 0 - Positive, 1 - Negative
* @data_pol: Data polarity * @data_pol: Data polarity
* 0 - Normal, 1 - One's complement * 0 - Normal, 1 - One's complement
*/ */
...@@ -65,6 +67,7 @@ struct isp_parallel_platform_data { ...@@ -65,6 +67,7 @@ struct isp_parallel_platform_data {
unsigned int clk_pol:1; unsigned int clk_pol:1;
unsigned int hs_pol:1; unsigned int hs_pol:1;
unsigned int vs_pol:1; unsigned int vs_pol:1;
unsigned int fld_pol:1;
unsigned int data_pol:1; unsigned int data_pol:1;
}; };
......
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