Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72915e85 authored by Amber Jain's avatar Amber Jain Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarAmber Jain <amber@ti.com>
Signed-off-by: default avatarVaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5251dd6c
Loading
Loading
Loading
Loading
+27 −2
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/videodev2.h>
#include <linux/videodev2.h>
#include <linux/dma-mapping.h>


#include <media/videobuf-dma-contig.h>
#include <media/videobuf-dma-contig.h>
#include <media/v4l2-device.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 *)
		vout->queued_buf_addr[vb->i] = (u8 *)
			omap_vout_uservirt_to_phys(vb->baddr);
			omap_vout_uservirt_to_phys(vb->baddr);
	} else {
	} 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];
		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 omap_vout_device *vout = fh;
	struct videobuf_queue *q = &vout->vbq;
	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)
	if (!vout->streaming)
		return -EINVAL;
		return -EINVAL;


	if (file->f_flags & O_NONBLOCK)
	if (file->f_flags & O_NONBLOCK)
		/* Call videobuf_dqbuf for non blocking mode */
		/* 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
	else
		/* Call videobuf_dqbuf for  blocking mode */
		/* 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)
static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)