diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2014-03-08 07:29:15 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-25 10:17:14 -0400 |
commit | 49ac3695d08698c19d2b23af6bd0dd1dfd1a10af (patch) | |
tree | 3197927571e2f3ed3de6aeb88114de73377d9fa3 /drivers/media/platform | |
parent | b8d642826d031c8700ff1ad601fedf1ebe351033 (diff) |
[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>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r-- | drivers/media/platform/omap3isp/ispqueue.c | 37 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispqueue.h | 4 |
2 files changed, 23 insertions, 18 deletions
diff --git a/drivers/media/platform/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c index 479d348bb510..4a271c7a2cf5 100644 --- a/drivers/media/platform/omap3isp/ispqueue.c +++ b/drivers/media/platform/omap3isp/ispqueue.c | |||
@@ -173,6 +173,7 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf) | |||
173 | struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue); | 173 | struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue); |
174 | struct isp_video *video = vfh->video; | 174 | struct isp_video *video = vfh->video; |
175 | enum dma_data_direction direction; | 175 | enum dma_data_direction direction; |
176 | DEFINE_DMA_ATTRS(attrs); | ||
176 | unsigned int i; | 177 | unsigned int i; |
177 | 178 | ||
178 | if (buf->dma) { | 179 | if (buf->dma) { |
@@ -181,11 +182,14 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf) | |||
181 | buf->dma = 0; | 182 | buf->dma = 0; |
182 | } | 183 | } |
183 | 184 | ||
184 | if (!(buf->vm_flags & VM_PFNMAP)) { | 185 | if (buf->vbuf.memory == V4L2_MEMORY_USERPTR) { |
186 | if (buf->skip_cache) | ||
187 | dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); | ||
188 | |||
185 | direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE | 189 | direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE |
186 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 190 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
187 | dma_unmap_sg(buf->queue->dev, buf->sgt.sgl, buf->sgt.orig_nents, | 191 | dma_unmap_sg_attrs(buf->queue->dev, buf->sgt.sgl, |
188 | direction); | 192 | buf->sgt.orig_nents, direction, &attrs); |
189 | } | 193 | } |
190 | 194 | ||
191 | sg_free_table(&buf->sgt); | 195 | sg_free_table(&buf->sgt); |
@@ -345,10 +349,6 @@ unlock: | |||
345 | 349 | ||
346 | for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) { | 350 | for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) { |
347 | sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset); | 351 | sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset); |
348 | /* PFNMAP buffers will not get DMA-mapped, set the DMA address | ||
349 | * manually. | ||
350 | */ | ||
351 | sg_dma_address(sg) = (pfn << PAGE_SHIFT) + offset; | ||
352 | sg = sg_next(sg); | 352 | sg = sg_next(sg); |
353 | offset = 0; | 353 | offset = 0; |
354 | } | 354 | } |
@@ -434,12 +434,15 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf) | |||
434 | struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue); | 434 | struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue); |
435 | struct isp_video *video = vfh->video; | 435 | struct isp_video *video = vfh->video; |
436 | enum dma_data_direction direction; | 436 | enum dma_data_direction direction; |
437 | DEFINE_DMA_ATTRS(attrs); | ||
437 | unsigned long addr; | 438 | unsigned long addr; |
438 | int ret; | 439 | int ret; |
439 | 440 | ||
440 | switch (buf->vbuf.memory) { | 441 | switch (buf->vbuf.memory) { |
441 | case V4L2_MEMORY_MMAP: | 442 | case V4L2_MEMORY_MMAP: |
442 | ret = isp_video_buffer_prepare_kernel(buf); | 443 | ret = isp_video_buffer_prepare_kernel(buf); |
444 | if (ret < 0) | ||
445 | goto done; | ||
443 | break; | 446 | break; |
444 | 447 | ||
445 | case V4L2_MEMORY_USERPTR: | 448 | case V4L2_MEMORY_USERPTR: |
@@ -451,24 +454,26 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf) | |||
451 | ret = isp_video_buffer_prepare_pfnmap(buf); | 454 | ret = isp_video_buffer_prepare_pfnmap(buf); |
452 | else | 455 | else |
453 | ret = isp_video_buffer_prepare_user(buf); | 456 | ret = isp_video_buffer_prepare_user(buf); |
454 | break; | ||
455 | 457 | ||
456 | default: | 458 | if (ret < 0) |
457 | return -EINVAL; | 459 | goto done; |
458 | } | ||
459 | 460 | ||
460 | if (ret < 0) | 461 | if (buf->skip_cache) |
461 | goto done; | 462 | dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); |
462 | 463 | ||
463 | if (!(buf->vm_flags & VM_PFNMAP)) { | ||
464 | direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE | 464 | direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE |
465 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 465 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
466 | ret = dma_map_sg(buf->queue->dev, buf->sgt.sgl, | 466 | ret = dma_map_sg_attrs(buf->queue->dev, buf->sgt.sgl, |
467 | buf->sgt.orig_nents, direction); | 467 | buf->sgt.orig_nents, direction, &attrs); |
468 | if (ret <= 0) { | 468 | if (ret <= 0) { |
469 | ret = -EFAULT; | 469 | ret = -EFAULT; |
470 | goto done; | 470 | goto done; |
471 | } | 471 | } |
472 | |||
473 | break; | ||
474 | |||
475 | default: | ||
476 | return -EINVAL; | ||
472 | } | 477 | } |
473 | 478 | ||
474 | addr = omap_iommu_vmap(video->isp->domain, video->isp->dev, 0, | 479 | addr = omap_iommu_vmap(video->isp->domain, video->isp->dev, 0, |
diff --git a/drivers/media/platform/omap3isp/ispqueue.h b/drivers/media/platform/omap3isp/ispqueue.h index e03af74ded28..d580f581c209 100644 --- a/drivers/media/platform/omap3isp/ispqueue.h +++ b/drivers/media/platform/omap3isp/ispqueue.h | |||
@@ -72,7 +72,7 @@ enum isp_video_buffer_state { | |||
72 | * @vm_flags: Buffer VMA flags (for userspace buffers) | 72 | * @vm_flags: Buffer VMA flags (for userspace buffers) |
73 | * @npages: Number of pages (for userspace buffers) | 73 | * @npages: Number of pages (for userspace buffers) |
74 | * @pages: Pages table (for userspace non-VM_PFNMAP buffers) | 74 | * @pages: Pages table (for userspace non-VM_PFNMAP buffers) |
75 | * @sgt: Scatter gather table (for non-VM_PFNMAP buffers) | 75 | * @sgt: Scatter gather table |
76 | * @vbuf: V4L2 buffer | 76 | * @vbuf: V4L2 buffer |
77 | * @irqlist: List head for insertion into IRQ queue | 77 | * @irqlist: List head for insertion into IRQ queue |
78 | * @state: Current buffer state | 78 | * @state: Current buffer state |
@@ -94,7 +94,7 @@ struct isp_video_buffer { | |||
94 | unsigned int npages; | 94 | unsigned int npages; |
95 | struct page **pages; | 95 | struct page **pages; |
96 | 96 | ||
97 | /* For all buffers except VM_PFNMAP. */ | 97 | /* For all buffers. */ |
98 | struct sg_table sgt; | 98 | struct sg_table sgt; |
99 | 99 | ||
100 | /* Touched by the interrupt handler. */ | 100 | /* Touched by the interrupt handler. */ |