diff options
author | Archit Taneja <archit@ti.com> | 2010-08-02 11:31:54 +0530 |
---|---|---|
committer | Ricardo Perez Olivares <x0081762@ti.com> | 2010-09-14 19:26:41 -0500 |
commit | 978e5839df5b3b52e64e2688ca2217d2c006be31 (patch) | |
tree | 8e869c98e05c52ca6deeb89090228a2160090ee9 /drivers/media | |
parent | 9a316e59515f511d8571bede317785e1652d2c40 (diff) |
V4L2 Multi Display Support in ISR
Restructs the omap_vout_isr to handle multiple displays
Signed-off-by: Lajos Molnar <molnar@ti.com>
Signed-off-by: Sumit Semwal <sumit.semwal@ti.com>
Signed-off-by: Guruswamy Senthilvadivu <svadivu@ti.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/omap/omap_vout.c | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index b692ffe16a82..30f2c13e115d 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -1048,6 +1048,7 @@ void omap_vout_isr(void *arg, unsigned int irqstatus) struct omap_dss_device *cur_display; struct omap_vout_device *vout = (struct omap_vout_device *)arg; u32 flags; + int irq = 0; if (!vout->streaming) return; @@ -1060,42 +1061,24 @@ void omap_vout_isr(void *arg, unsigned int irqstatus) cur_display = ovl->manager->device; + if (cur_display->channel == OMAP_DSS_CHANNEL_LCD) + irq = DISPC_IRQ_FRAMEDONE; + else if (cur_display->channel == OMAP_DSS_CHANNEL_LCD2) + irq = DISPC_IRQ_FRAMEDONE2; + spin_lock_irqsave(&vout->vbq_lock, flags); do_gettimeofday(&timevalue); - if (cur_display->type == OMAP_DISPLAY_TYPE_DPI) { - if (!(irqstatus & DISPC_IRQ_VSYNC)) + switch (cur_display->type) { + case OMAP_DISPLAY_TYPE_DSI: + if (!(irqstatus & irq)) 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)) + break; + case OMAP_DISPLAY_TYPE_DPI: + if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) goto vout_isr_err; + break; - 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, uv_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 { - + case OMAP_DISPLAY_TYPE_VENC: if (vout->first_int) { vout->first_int = 0; goto vout_isr_err; @@ -1106,7 +1089,7 @@ void omap_vout_isr(void *arg, unsigned int irqstatus) fid = 0; else goto vout_isr_err; - + fid = 1; vout->field_id ^= 1; if (fid != vout->field_id) { if (0 == fid) @@ -1117,16 +1100,34 @@ void omap_vout_isr(void *arg, unsigned int irqstatus) 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; + goto vout_isr_err; } else if (1 == fid) { if (list_empty(&vout->dma_queue) || - (vout->cur_frm != vout->next_frm)) + (vout->cur_frm != vout->next_frm)) { goto vout_isr_err; + } + goto venc; + } + 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)) + goto vout_isr_err; + +venc: vout->next_frm = list_entry(vout->dma_queue.next, struct videobuf_buffer, queue); list_del(&vout->next_frm->queue); @@ -1135,6 +1136,10 @@ void omap_vout_isr(void *arg, unsigned int irqstatus) addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i] + vout->cropped_offset; + uv_addr = (unsigned long)vout->queued_buf_uv_addr[ + vout->next_frm->i] + + vout->cropped_uv_offset; + /* First save the configuration in ovelray structure */ ret = omapvid_init(vout, addr, uv_addr); if (ret) @@ -1145,9 +1150,6 @@ void omap_vout_isr(void *arg, unsigned int irqstatus) if (ret) printk(KERN_ERR VOUT_NAME "failed to change mode\n"); - } - - } vout_isr_err: spin_unlock_irqrestore(&vout->vbq_lock, flags); @@ -2307,8 +2309,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) uv_addr = (unsigned long) vout->queued_buf_uv_addr[vout->cur_frm->i] + vout->cropped_uv_offset; - mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD; - + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | + DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_FRAMEDONE | + DISPC_IRQ_FRAMEDONE2 | DISPC_IRQ_VSYNC2; omap_dispc_register_isr(omap_vout_isr, vout, mask); for (j = 0; j < ovid->num_overlays; j++) { @@ -2358,7 +2361,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) return -EINVAL; vout->streaming = 0; - mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD; + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | + DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_FRAMEDONE | + DISPC_IRQ_FRAMEDONE2 | DISPC_IRQ_VSYNC2; omap_dispc_unregister_isr(omap_vout_isr, vout, mask); |