[PATCH 6/7] s5p-fimc: Add support for vb2-s5p-iommu allocator
Marek Szyprowski
m.szyprowski at samsung.com
Fri Mar 4 04:01:13 EST 2011
This patch adds support for videobuf2-s5p-iommu allocator to s5p-fimc
driver. This allocator is selected only on systems that contains support
for S5P SYSMMU module. Otherwise the standard videobuf2-dma-contig is
used.
Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
---
drivers/media/video/Kconfig | 3 +-
drivers/media/video/s5p-fimc/fimc-capture.c | 4 +-
drivers/media/video/s5p-fimc/fimc-core.c | 22 ++++---
drivers/media/video/s5p-fimc/fimc-mem.h | 87 +++++++++++++++++++++++++++
4 files changed, 104 insertions(+), 12 deletions(-)
create mode 100644 drivers/media/video/s5p-fimc/fimc-mem.h
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 9806505..12fb325 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1018,7 +1018,8 @@ config VIDEO_MEM2MEM_TESTDEV
config VIDEO_SAMSUNG_S5P_FIMC
tristate "Samsung S5P FIMC (video postprocessor) driver"
depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
- select VIDEOBUF2_DMA_CONTIG
+ select VIDEOBUF2_S5P_IOMMU if S5P_SYSTEM_MMU
+ select VIDEOBUF2_DMA_CONTIG if !S5P_SYSTEM_MMU
select V4L2_MEM2MEM_DEV
help
This is a v4l2 driver for the S5P camera interface
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index f8d7de5..6819908 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -29,8 +29,8 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
+#include "fimc-mem.h"
#include "fimc-core.h"
static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
@@ -881,7 +881,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
q->io_modes = VB2_MMAP | VB2_USERPTR;
q->drv_priv = fimc->vid_cap.ctx;
q->ops = &fimc_capture_qops;
- q->mem_ops = &vb2_dma_contig_memops;
+ q->mem_ops = &fimc_vb2_allocator_memops;
q->buf_struct_size = sizeof(struct fimc_vid_buffer);
vb2_queue_init(q);
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index c92dbdb..f06aaea 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -27,8 +27,8 @@
#include <linux/clk.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
+#include "fimc-mem.h"
#include "fimc-core.h"
static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
@@ -458,7 +458,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
dbg("memplanes= %d, colplanes= %d, pix_size= %d",
frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
- paddr->y = vb2_dma_contig_plane_paddr(vb, 0);
+ paddr->y = fimc_vb2_plane_addr(vb, 0);
if (frame->fmt->memplanes == 1) {
switch (frame->fmt->colplanes) {
@@ -486,10 +486,10 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
}
} else {
if (frame->fmt->memplanes >= 2)
- paddr->cb = vb2_dma_contig_plane_paddr(vb, 1);
+ paddr->cb = fimc_vb2_plane_addr(vb, 1);
if (frame->fmt->memplanes == 3)
- paddr->cr = vb2_dma_contig_plane_paddr(vb, 2);
+ paddr->cr = fimc_vb2_plane_addr(vb, 2);
}
dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
@@ -1375,7 +1375,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
src_vq->drv_priv = ctx;
src_vq->ops = &fimc_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->mem_ops = &fimc_vb2_allocator_memops;
src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
ret = vb2_queue_init(src_vq);
@@ -1387,7 +1387,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
dst_vq->ops = &fimc_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->mem_ops = &fimc_vb2_allocator_memops;
dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
return vb2_queue_init(dst_vq);
@@ -1685,12 +1685,15 @@ static int fimc_probe(struct platform_device *pdev)
goto err_clk;
}
- /* Initialize contiguous memory allocator */
- fimc->alloc_ctx = vb2_dma_contig_init_ctx(&fimc->pdev->dev);
+ /* Initialize memory allocator */
+ fimc->alloc_ctx = fimc_vb2_allocator_init(pdev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
goto err_irq;
}
+ ret = fimc_vb2_allocator_enable(fimc->alloc_ctx);
+ if (ret)
+ goto err_irq;
ret = fimc_register_m2m_device(fimc);
if (ret)
@@ -1747,7 +1750,8 @@ static int __devexit fimc_remove(struct platform_device *pdev)
fimc_clk_release(fimc);
- vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
+ fimc_vb2_allocator_disable(fimc->alloc_ctx);
+ fimc_vb2_allocator_cleanup(fimc->alloc_ctx);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/media/video/s5p-fimc/fimc-mem.h b/drivers/media/video/s5p-fimc/fimc-mem.h
new file mode 100644
index 0000000..9ac9bc6
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/fimc-mem.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef FIMC_MEM_H_
+#define FIMC_MEM_H_
+
+/*
+ * fimc-mem.h is the interface for videbuf2 allocator. It is a proxy
+ * to real allocator depending on system capabilities.
+ * 1. on S5PC100 & S5PV210/S5PC110 systems vb2-dma-contig is used
+ * 2. on S5PV310/S5PC210 systems vb2-s5p-iommu allocator is selected.
+ *
+ */
+
+#ifdef CONFIG_S5P_SYSTEM_MMU
+
+#include <media/videobuf2-s5p-iommu.h>
+
+#define fimc_vb2_allocator_memops vb2_s5p_iommu_memops
+
+static inline void *fimc_vb2_allocator_init(struct platform_device *pdev)
+{
+ struct vb2_s5p_iommu_request iommu_req;
+ memset(&iommu_req, 0, sizeof(iommu_req));
+ iommu_req.ip = S5P_SYSMMU_FIMC0 + pdev->id;
+ return vb2_s5p_iommu_init(&pdev->dev, &iommu_req);
+}
+
+static inline void fimc_vb2_allocator_cleanup(void *alloc_ctx)
+{
+ return vb2_s5p_iommu_cleanup(alloc_ctx);
+}
+
+static inline unsigned long fimc_vb2_plane_addr(struct vb2_buffer *b, int n)
+{
+ return vb2_s5p_iommu_plane_addr(b, n);
+}
+
+static inline int fimc_vb2_allocator_enable(void *alloc_ctx)
+{
+ return vb2_s5p_iommu_enable(alloc_ctx);
+}
+
+static inline int fimc_vb2_allocator_disable(void *alloc_ctx)
+{
+ return vb2_s5p_iommu_disable(alloc_ctx);
+}
+
+#else /* use vb2-dma-contig allocator */
+
+#include <media/videobuf2-dma-contig.h>
+
+#define fimc_vb2_allocator_memops vb2_dma_contig_memops
+
+static inline void *fimc_vb2_allocator_init(struct platform_device *pdev)
+{
+ return vb2_dma_contig_init_ctx(&pdev->dev);
+}
+
+static inline void fimc_vb2_allocator_cleanup(void *alloc_ctx)
+{
+ vb2_dma_contig_cleanup_ctx(alloc_ctx);
+}
+
+static inline unsigned long fimc_vb2_plane_addr(struct vb2_buffer *b, int n)
+{
+ return vb2_dma_contig_plane_paddr(b, n);
+}
+
+static inline int fimc_vb2_allocator_enable(void *alloc_ctx)
+{
+ return 0;
+}
+
+static inline int fimc_vb2_allocator_disable(void *alloc_ctx)
+{
+ return 0;
+}
+
+#endif
+
+#endif /* FIMC_CORE_H_ */
--
1.7.1.569.g6f426
More information about the linux-arm-kernel
mailing list