To test buffer sharing with devices that require contiguous memory
buffers the dma-contig allocator is required. Support it and make the
allocator selectable through a module parameter. Support for the two
memory allocators can also be individually selected at compile-time to
avoid bloating the kernel with an unneeded allocator.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/media/platform/vivid/Kconfig         | 21 ++++++++++++-
 drivers/media/platform/vivid/vivid-core.c    | 44 ++++++++++++++++++++++++----
 drivers/media/platform/vivid/vivid-core.h    |  1 +
 drivers/media/platform/vivid/vivid-sdr-cap.c |  3 ++
 drivers/media/platform/vivid/vivid-vbi-cap.c |  2 ++
 drivers/media/platform/vivid/vivid-vbi-out.c |  1 +
 drivers/media/platform/vivid/vivid-vid-cap.c |  9 ++----
 drivers/media/platform/vivid/vivid-vid-out.c |  9 ++----
 8 files changed, 72 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/vivid/Kconfig 
b/drivers/media/platform/vivid/Kconfig
index 0885e93ad436..ddfec721c08c 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -6,7 +6,7 @@ config VIDEO_VIVID
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select VIDEOBUF2_VMALLOC
+       select VIDEO_VIVID_MEM_VMALLOC if !VIDEO_VIVID_MEM_DMA_CONTIG
        default n
        ---help---
          Enables a virtual video driver. This driver emulates a webcam,
@@ -28,3 +28,22 @@ config VIDEO_VIVID_MAX_DEVS
        ---help---
          This allows you to specify the maximum number of devices supported
          by the vivid driver.
+
+config VIDEO_VIVID_MEM_DMA_CONTIG
+       bool "Enable DMA-CONTIG Memory Type"
+       depends on VIDEO_VIVID
+       select VIDEOBUF2_DMA_CONTIG
+       default n
+       ---help---
+         Enable support for the DMA-CONTIG videobuf2 memory allocator. Say Y
+         here if you want to test buffer sharing with devices that require
+         contiguous memory buffers. When in doubt, say N.
+
+config VIDEO_VIVID_MEM_VMALLOC
+       bool "Enable VMALLOC Memory Type"
+       depends on VIDEO_VIVID
+       select VIDEOBUF2_VMALLOC
+       default y
+       ---help---
+         Enable support for the VMALLOC videobuf2 memory allocator. This is the
+         default memory allocator for the vivid driver. When in doubt, say Y.
diff --git a/drivers/media/platform/vivid/vivid-core.c 
b/drivers/media/platform/vivid/vivid-core.c
index f57ff1101e74..d526144151fc 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -29,6 +29,7 @@
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
 #include <linux/v4l2-dv-timings.h>
+#include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-vmalloc.h>
 #include <media/v4l2-dv-timings.h>
 #include <media/v4l2-ioctl.h>
@@ -150,6 +151,16 @@ static bool no_error_inj;
 module_param(no_error_inj, bool, 0444);
 MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting controls");
 
+enum memory_type {
+       VIVID_MEM_VMALLOC,
+       VIVID_MEM_DMA_CONTIG,
+};
+
+static unsigned memory_type;
+module_param(memory_type, uint, 0444);
+MODULE_PARM_DESC(memory_type, " memory type, default is vmalloc,\n"
+                             "\t\t    0 == vmalloc, 1 == dma-contig");
+
 static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
 
 const struct v4l2_rect vivid_min_rect = {
@@ -634,6 +645,10 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev)
 {
        struct vivid_dev *dev = container_of(v4l2_dev, struct vivid_dev, 
v4l2_dev);
 
+       if (memory_type == VIVID_MEM_DMA_CONTIG &&
+           IS_ENABLED(CONFIG_VIDEO_VIVID_DMA_CONTIG))
+               vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
+
        vivid_free_controls(dev);
        v4l2_device_unregister(&dev->v4l2_dev);
        vfree(dev->scaled_line);
@@ -659,6 +674,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
        struct vivid_dev *dev;
        struct video_device *vfd;
        struct vb2_queue *q;
+       const struct vb2_mem_ops *vb2_memops;
        unsigned node_type = node_types[inst];
        v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
        int ret;
@@ -1026,6 +1042,24 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
        INIT_LIST_HEAD(&dev->sdr_cap_active);
 
        /* start creating the vb2 queues */
+       if (memory_type == VIVID_MEM_DMA_CONTIG &&
+           IS_ENABLED(CONFIG_VIDEO_VIVID_DMA_CONTIG)) {
+               ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+               if (ret)
+                       goto unreg_dev;
+
+               vb2_memops = &vb2_dma_contig_memops;
+               dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+       } else if (memory_type == VIVID_MEM_VMALLOC &&
+                  IS_ENABLED(CONFIG_VIDEO_VIVID_VMALLOC)) {
+               vb2_memops = &vb2_vmalloc_memops;
+       } else {
+               dev_err(&pdev->dev, "unsupported memory type %u\n",
+                       memory_type);
+               ret = -EINVAL;
+               goto unreg_dev;
+       }
+
        if (dev->has_vid_cap) {
                /* initialize vid_cap queue */
                q = &dev->vb_vid_cap_q;
@@ -1035,7 +1069,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
                q->drv_priv = dev;
                q->buf_struct_size = sizeof(struct vivid_buffer);
                q->ops = &vivid_vid_cap_qops;
-               q->mem_ops = &vb2_vmalloc_memops;
+               q->mem_ops = vb2_memops;
                q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
@@ -1054,7 +1088,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
                q->drv_priv = dev;
                q->buf_struct_size = sizeof(struct vivid_buffer);
                q->ops = &vivid_vid_out_qops;
-               q->mem_ops = &vb2_vmalloc_memops;
+               q->mem_ops = vb2_memops;
                q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
@@ -1073,7 +1107,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
                q->drv_priv = dev;
                q->buf_struct_size = sizeof(struct vivid_buffer);
                q->ops = &vivid_vbi_cap_qops;
-               q->mem_ops = &vb2_vmalloc_memops;
+               q->mem_ops = vb2_memops;
                q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
@@ -1092,7 +1126,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
                q->drv_priv = dev;
                q->buf_struct_size = sizeof(struct vivid_buffer);
                q->ops = &vivid_vbi_out_qops;
-               q->mem_ops = &vb2_vmalloc_memops;
+               q->mem_ops = vb2_memops;
                q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
@@ -1110,7 +1144,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
                q->drv_priv = dev;
                q->buf_struct_size = sizeof(struct vivid_buffer);
                q->ops = &vivid_sdr_cap_qops;
-               q->mem_ops = &vb2_vmalloc_memops;
+               q->mem_ops = vb2_memops;
                q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
                q->min_buffers_needed = 8;
                q->lock = &dev->mutex;
diff --git a/drivers/media/platform/vivid/vivid-core.h 
b/drivers/media/platform/vivid/vivid-core.h
index 55b304a705d5..22be49c5d5eb 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -157,6 +157,7 @@ struct vivid_dev {
        struct v4l2_ctrl_handler        ctrl_hdl_sdr_cap;
        spinlock_t                      slock;
        struct mutex                    mutex;
+       void                            *alloc_ctx;
 
        /* capabilities */
        u32                             vid_cap_caps;
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c 
b/drivers/media/platform/vivid/vivid-sdr-cap.c
index 082c401764ce..595501d96550 100644
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
@@ -217,9 +217,12 @@ static int sdr_cap_queue_setup(struct vb2_queue *vq, const 
void *parg,
                       unsigned *nbuffers, unsigned *nplanes,
                       unsigned sizes[], void *alloc_ctxs[])
 {
+       struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
        /* 2 = max 16-bit sample returned */
        sizes[0] = SDR_CAP_SAMPLES_PER_BUF * 2;
        *nplanes = 1;
+       alloc_ctxs[0] = dev->alloc_ctx;
        return 0;
 }
 
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c 
b/drivers/media/platform/vivid/vivid-vbi-cap.c
index e903d023e9df..afb880fb7d5f 100644
--- a/drivers/media/platform/vivid/vivid-vbi-cap.c
+++ b/drivers/media/platform/vivid/vivid-vbi-cap.c
@@ -156,6 +156,8 @@ static int vbi_cap_queue_setup(struct vb2_queue *vq, const 
void *parg,
                *nbuffers = 2 - vq->num_buffers;
 
        *nplanes = 1;
+       alloc_ctxs[0] = dev->alloc_ctx;
+
        return 0;
 }
 
diff --git a/drivers/media/platform/vivid/vivid-vbi-out.c 
b/drivers/media/platform/vivid/vivid-vbi-out.c
index 75c5709f938e..8ff5a41b9a0f 100644
--- a/drivers/media/platform/vivid/vivid-vbi-out.c
+++ b/drivers/media/platform/vivid/vivid-vbi-out.c
@@ -46,6 +46,7 @@ static int vbi_out_queue_setup(struct vb2_queue *vq, const 
void *parg,
                *nbuffers = 2 - vq->num_buffers;
 
        *nplanes = 1;
+       alloc_ctxs[0] = dev->alloc_ctx;
        return 0;
 }
 
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c 
b/drivers/media/platform/vivid/vivid-vid-cap.c
index d9cb609b7381..305cf1b8b141 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -156,14 +156,11 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, 
const void *parg,
 
        *nplanes = buffers;
 
-       /*
-        * videobuf2-vmalloc allocator is context-less so no need to set
-        * alloc_ctxs array.
-        */
-
        dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
-       for (p = 0; p < buffers; p++)
+       for (p = 0; p < buffers; p++) {
+               alloc_ctxs[p] = dev->alloc_ctx;
                dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
+       }
 
        return 0;
 }
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c 
b/drivers/media/platform/vivid/vivid-vid-out.c
index b77acb6a7013..36eb2a3c8c55 100644
--- a/drivers/media/platform/vivid/vivid-vid-out.c
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
@@ -97,14 +97,11 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const 
void *parg,
 
        *nplanes = planes;
 
-       /*
-        * videobuf2-vmalloc allocator is context-less so no need to set
-        * alloc_ctxs array.
-        */
-
        dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
-       for (p = 0; p < planes; p++)
+       for (p = 0; p < planes; p++) {
+               alloc_ctxs[p] = dev->alloc_ctx;
                dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
+       }
        return 0;
 }
 
-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to