summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap/omap_vout.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-15 12:49:56 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-15 12:49:56 -0800
commit122804ecb59493fbb4d31b3ba9ac59faaf45276f (patch)
treecff4d8a158c412e4a8d3abc8d91bb0eb52b01c9a /drivers/media/video/omap/omap_vout.c
parent16008d641670571ff4cd750b416c7caf2d89f467 (diff)
parent126400033940afb658123517a2e80eb68259fbd7 (diff)
downloadop-kernel-dev-122804ecb59493fbb4d31b3ba9ac59faaf45276f.zip
op-kernel-dev-122804ecb59493fbb4d31b3ba9ac59faaf45276f.tar.gz
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (655 commits) [media] revert patch: HDIC HD29L2 DMB-TH USB2.0 reference design driver mb86a20s: Add a few more register settings at the init seq mb86a20s: Group registers into the same line [media] [PATCH] don't reset the delivery system on DTV_CLEAR [media] [BUG] it913x-fe fix typo error making SNR levels unstable [media] cx23885: Query the CX25840 during enum_input for status [media] cx25840: Add support for g_input_status [media] rc-videomate-m1f.c Rename to match remote controler name [media] drivers: media: au0828: Fix dependency for VIDEO_AU0828 [media] convert drivers/media/* to use module_platform_driver() [media] drivers: video: cx231xx: Fix dependency for VIDEO_CX231XX_DVB [media] Exynos4 JPEG codec v4l2 driver [media] doc: v4l: selection: choose pixels as units for selection rectangles [media] v4l: s5p-tv: mixer: fix setup of VP scaling [media] v4l: s5p-tv: mixer: add support for selection API [media] v4l: emulate old crop API using extended crop/compose API [media] doc: v4l: add documentation for selection API [media] doc: v4l: add binary images for selection API [media] v4l: add support for selection api [media] hd29l2: fix review findings ...
Diffstat (limited to 'drivers/media/video/omap/omap_vout.c')
-rw-r--r--drivers/media/video/omap/omap_vout.c187
1 files changed, 96 insertions, 91 deletions
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index a378c2c..a277f95 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -524,10 +524,50 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
return 0;
}
+static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
+ unsigned int irqstatus, struct timeval timevalue)
+{
+ u32 fid;
+
+ if (vout->first_int) {
+ vout->first_int = 0;
+ goto err;
+ }
+
+ if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
+ fid = 1;
+ else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
+ fid = 0;
+ else
+ goto err;
+
+ vout->field_id ^= 1;
+ if (fid != vout->field_id) {
+ if (fid == 0)
+ vout->field_id = fid;
+ } else if (0 == fid) {
+ if (vout->cur_frm == vout->next_frm)
+ goto err;
+
+ vout->cur_frm->ts = timevalue;
+ vout->cur_frm->state = VIDEOBUF_DONE;
+ wake_up_interruptible(&vout->cur_frm->done);
+ vout->cur_frm = vout->next_frm;
+ } else {
+ if (list_empty(&vout->dma_queue) ||
+ (vout->cur_frm != vout->next_frm))
+ goto err;
+ }
+
+ return vout->field_id;
+err:
+ return 0;
+}
+
static void omap_vout_isr(void *arg, unsigned int irqstatus)
{
- int ret;
- u32 addr, fid;
+ int ret, fid, mgr_id;
+ u32 addr, irq;
struct omap_overlay *ovl;
struct timeval timevalue;
struct omapvideo_info *ovid;
@@ -543,112 +583,73 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
if (!ovl->manager || !ovl->manager->device)
return;
+ mgr_id = ovl->manager->id;
cur_display = ovl->manager->device;
spin_lock(&vout->vbq_lock);
do_gettimeofday(&timevalue);
- if (cur_display->type != OMAP_DISPLAY_TYPE_VENC) {
- switch (cur_display->type) {
- case OMAP_DISPLAY_TYPE_DPI:
- if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2)))
- goto vout_isr_err;
- break;
- case OMAP_DISPLAY_TYPE_HDMI:
- if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
- goto vout_isr_err;
- break;
- default:
- goto vout_isr_err;
- }
- if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
- vout->cur_frm->ts = timevalue;
- vout->cur_frm->state = VIDEOBUF_DONE;
- wake_up_interruptible(&vout->cur_frm->done);
- vout->cur_frm = vout->next_frm;
- }
- vout->first_int = 0;
- if (list_empty(&vout->dma_queue))
+ switch (cur_display->type) {
+ case OMAP_DISPLAY_TYPE_DSI:
+ case OMAP_DISPLAY_TYPE_DPI:
+ if (mgr_id == OMAP_DSS_CHANNEL_LCD)
+ irq = DISPC_IRQ_VSYNC;
+ else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
+ irq = DISPC_IRQ_VSYNC2;
+ else
goto vout_isr_err;
- vout->next_frm = list_entry(vout->dma_queue.next,
- struct videobuf_buffer, queue);
- list_del(&vout->next_frm->queue);
-
- vout->next_frm->state = VIDEOBUF_ACTIVE;
+ if (!(irqstatus & irq))
+ goto vout_isr_err;
+ break;
+ case OMAP_DISPLAY_TYPE_VENC:
+ fid = omapvid_handle_interlace_display(vout, irqstatus,
+ timevalue);
+ if (!fid)
+ goto vout_isr_err;
+ break;
+ case OMAP_DISPLAY_TYPE_HDMI:
+ if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
+ goto vout_isr_err;
+ break;
+ default:
+ goto vout_isr_err;
+ }
- addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
- + vout->cropped_offset;
+ if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
+ vout->cur_frm->ts = timevalue;
+ vout->cur_frm->state = VIDEOBUF_DONE;
+ wake_up_interruptible(&vout->cur_frm->done);
+ vout->cur_frm = vout->next_frm;
+ }
- /* First save the configuration in ovelray structure */
- ret = omapvid_init(vout, addr);
- if (ret)
- printk(KERN_ERR VOUT_NAME
- "failed to set overlay info\n");
- /* Enable the pipeline and set the Go bit */
- ret = omapvid_apply_changes(vout);
- if (ret)
- printk(KERN_ERR VOUT_NAME "failed to change mode\n");
- } else {
+ vout->first_int = 0;
+ if (list_empty(&vout->dma_queue))
+ goto vout_isr_err;
- if (vout->first_int) {
- vout->first_int = 0;
- goto vout_isr_err;
- }
- if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
- fid = 1;
- else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
- fid = 0;
- else
- goto vout_isr_err;
+ vout->next_frm = list_entry(vout->dma_queue.next,
+ struct videobuf_buffer, queue);
+ list_del(&vout->next_frm->queue);
- vout->field_id ^= 1;
- if (fid != vout->field_id) {
- if (0 == fid)
- vout->field_id = fid;
+ vout->next_frm->state = VIDEOBUF_ACTIVE;
- goto vout_isr_err;
- }
- if (0 == fid) {
- if (vout->cur_frm == vout->next_frm)
- goto vout_isr_err;
-
- vout->cur_frm->ts = timevalue;
- vout->cur_frm->state = VIDEOBUF_DONE;
- wake_up_interruptible(&vout->cur_frm->done);
- vout->cur_frm = vout->next_frm;
- } else if (1 == fid) {
- if (list_empty(&vout->dma_queue) ||
- (vout->cur_frm != vout->next_frm))
- goto vout_isr_err;
-
- vout->next_frm = list_entry(vout->dma_queue.next,
- struct videobuf_buffer, queue);
- list_del(&vout->next_frm->queue);
-
- vout->next_frm->state = VIDEOBUF_ACTIVE;
- addr = (unsigned long)
- vout->queued_buf_addr[vout->next_frm->i] +
- vout->cropped_offset;
- /* First save the configuration in ovelray structure */
- ret = omapvid_init(vout, addr);
- if (ret)
- printk(KERN_ERR VOUT_NAME
- "failed to set overlay info\n");
- /* Enable the pipeline and set the Go bit */
- ret = omapvid_apply_changes(vout);
- if (ret)
- printk(KERN_ERR VOUT_NAME
- "failed to change mode\n");
- }
+ addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
+ + vout->cropped_offset;
- }
+ /* First save the configuration in ovelray structure */
+ ret = omapvid_init(vout, addr);
+ if (ret)
+ printk(KERN_ERR VOUT_NAME
+ "failed to set overlay info\n");
+ /* Enable the pipeline and set the Go bit */
+ ret = omapvid_apply_changes(vout);
+ if (ret)
+ printk(KERN_ERR VOUT_NAME "failed to change mode\n");
vout_isr_err:
spin_unlock(&vout->vbq_lock);
}
-
/* Video buffer call backs */
/*
@@ -664,10 +665,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
u32 phy_addr = 0, virt_addr = 0;
struct omap_vout_device *vout = q->priv_data;
struct omapvideo_info *ovid = &vout->vid_info;
+ int vid_max_buf_size;
if (!vout)
return -EINVAL;
+ vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
+ video2_bufsize;
+
if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
return -EINVAL;
@@ -690,7 +695,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
video1_numbuffers : video2_numbuffers;
/* Check the size of the buffer */
- if (*size > vout->buffer_size) {
+ if (*size > vid_max_buf_size) {
v4l2_err(&vout->vid_dev->v4l2_dev,
"buffer allocation mismatch [%u] [%u]\n",
*size, vout->buffer_size);
OpenPOWER on IntegriCloud