diff options
author | Amber Jain <amber@ti.com> | 2011-07-07 06:03:25 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 17:56:06 -0300 |
commit | 72915e851da9aeea2bf619f8f52ab0ee4bc241ca (patch) | |
tree | 0e62a4cf88c4868bf69d736b5dd0b9cca5f1beba /drivers/media/video/omap | |
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>
Diffstat (limited to 'drivers/media/video/omap')
-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 d6cdf6fda4d..a2f9651b7be 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -37,6 +37,7 @@ #include <linux/platform_device.h> #include <linux/irq.h> #include <linux/videodev2.h> +#include <linux/dma-mapping.h> #include <media/videobuf-dma-contig.h> #include <media/v4l2-device.h> @@ -778,6 +779,17 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q, vout->queued_buf_addr[vb->i] = (u8 *) omap_vout_uservirt_to_phys(vb->baddr); } else { + u32 addr, dma_addr; + unsigned long size; + + addr = (unsigned long) vout->buf_virt_addr[vb->i]; + size = (unsigned long) vb->size; + + dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr, + size, DMA_TO_DEVICE); + if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr)) + v4l2_err(&vout->vid_dev->v4l2_dev, "dma_map_single failed\n"); + vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i]; } @@ -1567,15 +1579,28 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) struct omap_vout_device *vout = fh; struct videobuf_queue *q = &vout->vbq; + int ret; + u32 addr; + unsigned long size; + struct videobuf_buffer *vb; + + vb = q->bufs[b->index]; + if (!vout->streaming) return -EINVAL; if (file->f_flags & O_NONBLOCK) /* Call videobuf_dqbuf for non blocking mode */ - return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); + ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); else /* Call videobuf_dqbuf for blocking mode */ - return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0); + ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0); + + addr = (unsigned long) vout->buf_phy_addr[vb->i]; + size = (unsigned long) vb->size; + dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr, + size, DMA_TO_DEVICE); + return ret; } static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) |