diff options
author | Amber Jain <amber@ti.com> | 2011-07-07 05:03:25 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:56:06 -0400 |
commit | 72915e851da9aeea2bf619f8f52ab0ee4bc241ca (patch) | |
tree | 0e62a4cf88c4868bf69d736b5dd0b9cca5f1beba | |
parent | 5251dd6c07ad4a921c1cf40d9bf41f842364f936 (diff) |
[media] V4L2: OMAP: VOUT: dma map and unmap v4l2 buffers in qbuf and dqbuf
Add support to map the buffer using dma_map_single during qbuf which inturn
calls cache flush and unmap the same during dqbuf. This is done to prevent
the artifacts seen because of cache-coherency issues on OMAP4
Signed-off-by: Amber Jain <amber@ti.com>
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/omap/omap_vout.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index d6cdf6fda4d1..a2f9651b7be7 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/irq.h> | 38 | #include <linux/irq.h> |
39 | #include <linux/videodev2.h> | 39 | #include <linux/videodev2.h> |
40 | #include <linux/dma-mapping.h> | ||
40 | 41 | ||
41 | #include <media/videobuf-dma-contig.h> | 42 | #include <media/videobuf-dma-contig.h> |
42 | #include <media/v4l2-device.h> | 43 | #include <media/v4l2-device.h> |
@@ -778,6 +779,17 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q, | |||
778 | vout->queued_buf_addr[vb->i] = (u8 *) | 779 | vout->queued_buf_addr[vb->i] = (u8 *) |
779 | omap_vout_uservirt_to_phys(vb->baddr); | 780 | omap_vout_uservirt_to_phys(vb->baddr); |
780 | } else { | 781 | } else { |
782 | u32 addr, dma_addr; | ||
783 | unsigned long size; | ||
784 | |||
785 | addr = (unsigned long) vout->buf_virt_addr[vb->i]; | ||
786 | size = (unsigned long) vb->size; | ||
787 | |||
788 | dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr, | ||
789 | size, DMA_TO_DEVICE); | ||
790 | if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr)) | ||
791 | v4l2_err(&vout->vid_dev->v4l2_dev, "dma_map_single failed\n"); | ||
792 | |||
781 | vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i]; | 793 | vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i]; |
782 | } | 794 | } |
783 | 795 | ||
@@ -1567,15 +1579,28 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) | |||
1567 | struct omap_vout_device *vout = fh; | 1579 | struct omap_vout_device *vout = fh; |
1568 | struct videobuf_queue *q = &vout->vbq; | 1580 | struct videobuf_queue *q = &vout->vbq; |
1569 | 1581 | ||
1582 | int ret; | ||
1583 | u32 addr; | ||
1584 | unsigned long size; | ||
1585 | struct videobuf_buffer *vb; | ||
1586 | |||
1587 | vb = q->bufs[b->index]; | ||
1588 | |||
1570 | if (!vout->streaming) | 1589 | if (!vout->streaming) |
1571 | return -EINVAL; | 1590 | return -EINVAL; |
1572 | 1591 | ||
1573 | if (file->f_flags & O_NONBLOCK) | 1592 | if (file->f_flags & O_NONBLOCK) |
1574 | /* Call videobuf_dqbuf for non blocking mode */ | 1593 | /* Call videobuf_dqbuf for non blocking mode */ |
1575 | return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); | 1594 | ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); |
1576 | else | 1595 | else |
1577 | /* Call videobuf_dqbuf for blocking mode */ | 1596 | /* Call videobuf_dqbuf for blocking mode */ |
1578 | return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0); | 1597 | ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0); |
1598 | |||
1599 | addr = (unsigned long) vout->buf_phy_addr[vb->i]; | ||
1600 | size = (unsigned long) vb->size; | ||
1601 | dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr, | ||
1602 | size, DMA_TO_DEVICE); | ||
1603 | return ret; | ||
1579 | } | 1604 | } |
1580 | 1605 | ||
1581 | static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | 1606 | static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) |