summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2010-08-02 11:31:54 +0530
committerRicardo Perez Olivares <x0081762@ti.com>2010-09-14 19:26:41 -0500
commit978e5839df5b3b52e64e2688ca2217d2c006be31 (patch)
tree8e869c98e05c52ca6deeb89090228a2160090ee9 /drivers/media
parent9a316e59515f511d8571bede317785e1652d2c40 (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.c85
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);