[media] omap3isp: queue: Map PFNMAP buffers to device
Userspace PFNMAP buffers need to be mapped to the device like the userspace non-PFNMAP buffers in order for the DMA mapping implementation to create IOMMU mappings when we'll switch to the IOMMU-aware DMA mapping backend. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
b8d642826d
commit
49ac3695d0
|
@ -173,6 +173,7 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
|
||||||
struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
|
struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
|
||||||
struct isp_video *video = vfh->video;
|
struct isp_video *video = vfh->video;
|
||||||
enum dma_data_direction direction;
|
enum dma_data_direction direction;
|
||||||
|
DEFINE_DMA_ATTRS(attrs);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (buf->dma) {
|
if (buf->dma) {
|
||||||
|
@ -181,11 +182,14 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
|
||||||
buf->dma = 0;
|
buf->dma = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buf->vm_flags & VM_PFNMAP)) {
|
if (buf->vbuf.memory == V4L2_MEMORY_USERPTR) {
|
||||||
|
if (buf->skip_cache)
|
||||||
|
dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
|
||||||
|
|
||||||
direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|
direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|
||||||
? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||||
dma_unmap_sg(buf->queue->dev, buf->sgt.sgl, buf->sgt.orig_nents,
|
dma_unmap_sg_attrs(buf->queue->dev, buf->sgt.sgl,
|
||||||
direction);
|
buf->sgt.orig_nents, direction, &attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_free_table(&buf->sgt);
|
sg_free_table(&buf->sgt);
|
||||||
|
@ -345,10 +349,6 @@ unlock:
|
||||||
|
|
||||||
for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) {
|
for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) {
|
||||||
sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset);
|
sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset);
|
||||||
/* PFNMAP buffers will not get DMA-mapped, set the DMA address
|
|
||||||
* manually.
|
|
||||||
*/
|
|
||||||
sg_dma_address(sg) = (pfn << PAGE_SHIFT) + offset;
|
|
||||||
sg = sg_next(sg);
|
sg = sg_next(sg);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
@ -434,12 +434,15 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
|
||||||
struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
|
struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
|
||||||
struct isp_video *video = vfh->video;
|
struct isp_video *video = vfh->video;
|
||||||
enum dma_data_direction direction;
|
enum dma_data_direction direction;
|
||||||
|
DEFINE_DMA_ATTRS(attrs);
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (buf->vbuf.memory) {
|
switch (buf->vbuf.memory) {
|
||||||
case V4L2_MEMORY_MMAP:
|
case V4L2_MEMORY_MMAP:
|
||||||
ret = isp_video_buffer_prepare_kernel(buf);
|
ret = isp_video_buffer_prepare_kernel(buf);
|
||||||
|
if (ret < 0)
|
||||||
|
goto done;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case V4L2_MEMORY_USERPTR:
|
case V4L2_MEMORY_USERPTR:
|
||||||
|
@ -451,24 +454,26 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
|
||||||
ret = isp_video_buffer_prepare_pfnmap(buf);
|
ret = isp_video_buffer_prepare_pfnmap(buf);
|
||||||
else
|
else
|
||||||
ret = isp_video_buffer_prepare_user(buf);
|
ret = isp_video_buffer_prepare_user(buf);
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
if (ret < 0)
|
||||||
return -EINVAL;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (buf->skip_cache)
|
||||||
goto done;
|
dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
|
||||||
|
|
||||||
if (!(buf->vm_flags & VM_PFNMAP)) {
|
|
||||||
direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|
direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|
||||||
? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||||
ret = dma_map_sg(buf->queue->dev, buf->sgt.sgl,
|
ret = dma_map_sg_attrs(buf->queue->dev, buf->sgt.sgl,
|
||||||
buf->sgt.orig_nents, direction);
|
buf->sgt.orig_nents, direction, &attrs);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = omap_iommu_vmap(video->isp->domain, video->isp->dev, 0,
|
addr = omap_iommu_vmap(video->isp->domain, video->isp->dev, 0,
|
||||||
|
|
|
@ -72,7 +72,7 @@ enum isp_video_buffer_state {
|
||||||
* @vm_flags: Buffer VMA flags (for userspace buffers)
|
* @vm_flags: Buffer VMA flags (for userspace buffers)
|
||||||
* @npages: Number of pages (for userspace buffers)
|
* @npages: Number of pages (for userspace buffers)
|
||||||
* @pages: Pages table (for userspace non-VM_PFNMAP buffers)
|
* @pages: Pages table (for userspace non-VM_PFNMAP buffers)
|
||||||
* @sgt: Scatter gather table (for non-VM_PFNMAP buffers)
|
* @sgt: Scatter gather table
|
||||||
* @vbuf: V4L2 buffer
|
* @vbuf: V4L2 buffer
|
||||||
* @irqlist: List head for insertion into IRQ queue
|
* @irqlist: List head for insertion into IRQ queue
|
||||||
* @state: Current buffer state
|
* @state: Current buffer state
|
||||||
|
@ -94,7 +94,7 @@ struct isp_video_buffer {
|
||||||
unsigned int npages;
|
unsigned int npages;
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
|
|
||||||
/* For all buffers except VM_PFNMAP. */
|
/* For all buffers. */
|
||||||
struct sg_table sgt;
|
struct sg_table sgt;
|
||||||
|
|
||||||
/* Touched by the interrupt handler. */
|
/* Touched by the interrupt handler. */
|
||||||
|
|
Loading…
Reference in New Issue