media: vimc: Add support for contiguous DMA buffers
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Fri, 30 Jul 2021 13:18:29 +0000 (15:18 +0200)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Wed, 16 Feb 2022 11:47:02 +0000 (12:47 +0100)
The vimc driver is used for testing purpose, and some test use cases
involve sharing buffers with a consumer device. Consumers often require
DMA contiguous memory, which vimc doesn't currently support. This leads
in the best case to usage of bounce buffers, which is very slow, and in
the worst case in a complete failure.

Add support for the dma-contig allocator in vimc to support those use
cases properly. The allocator is selected through a new "allocator"
module parameter, which defaults to vmalloc.

[hverkuil: add missing 'select VIDEOBUF2_DMA_CONFIG' to Kconfig]

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Documentation/admin-guide/media/vimc.rst
drivers/media/test-drivers/vimc/Kconfig
drivers/media/test-drivers/vimc/vimc-capture.c
drivers/media/test-drivers/vimc/vimc-common.h
drivers/media/test-drivers/vimc/vimc-core.c

index 180507d455f2ee4beca5f529be705bef09614407..0b07f05dde250084eda88a1dec4e6ac4c0017a3a 100644 (file)
@@ -76,3 +76,16 @@ vimc-capture:
 
        * 1 Pad sink
        * 1 Pad source
+
+Module options
+--------------
+
+Vimc has a module parameter to configure the driver.
+
+* ``allocator=<unsigned int>``
+
+       memory allocator selection, default is 0. It specifies the way buffers
+       will be allocated.
+
+               - 0: vmalloc
+               - 1: dma-contig
index da4b2ad6e40c985672236a1b500d52fe1a936f70..ea37a102dec8bd8413cd97768f513c307e109012 100644 (file)
@@ -7,6 +7,7 @@ config VIDEO_VIMC
        select MEDIA_CONTROLLER
        select VIDEO_V4L2_SUBDEV_API
        select VIDEOBUF2_VMALLOC
+       select VIDEOBUF2_DMA_CONTIG
        select VIDEO_V4L2_TPG
        help
          Skeleton driver for Virtual Media Controller
index 5e9fd902cd37ac2dfca7f6ad3c647a5c2a6bba81..d1e2d0739c00c48e3569329f998d69f6cae21a66 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-vmalloc.h>
 
 #include "vimc-common.h"
@@ -423,14 +424,18 @@ static struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
        /* Initialize the vb2 queue */
        q = &vcap->queue;
        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
+       q->io_modes = VB2_MMAP | VB2_DMABUF;
+       if (vimc_allocator == VIMC_ALLOCATOR_VMALLOC)
+               q->io_modes |= VB2_USERPTR;
        q->drv_priv = vcap;
        q->buf_struct_size = sizeof(struct vimc_cap_buffer);
        q->ops = &vimc_cap_qops;
-       q->mem_ops = &vb2_vmalloc_memops;
+       q->mem_ops = vimc_allocator == VIMC_ALLOCATOR_DMA_CONTIG
+                  ? &vb2_dma_contig_memops : &vb2_vmalloc_memops;
        q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        q->min_buffers_needed = 2;
        q->lock = &vcap->lock;
+       q->dev = v4l2_dev->dev;
 
        ret = vb2_queue_init(q);
        if (ret) {
index a289434e75ba08e34fc59d83829d04db48dc1cc5..ba19307725894f4de8b5b67c790879ef1f13c6de 100644 (file)
 
 #define VIMC_PIX_FMT_MAX_CODES 8
 
+extern unsigned int vimc_allocator;
+
+enum vimc_allocator_type {
+       VIMC_ALLOCATOR_VMALLOC = 0,
+       VIMC_ALLOCATOR_DMA_CONTIG = 1,
+};
+
 /**
  * vimc_colorimetry_clamp - Adjust colorimetry parameters
  *
index 4b0ae6f51d765b3ed21e4465f8146619268cc2d5..06edf9d4d92c45205070b5c52c5e58052575a7c5 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
  */
 
+#include <linux/dma-mapping.h>
 #include <linux/font.h>
 #include <linux/init.h>
 #include <linux/module.h>
 
 #include "vimc-common.h"
 
+unsigned int vimc_allocator;
+module_param_named(allocator, vimc_allocator, uint, 0444);
+MODULE_PARM_DESC(allocator, " memory allocator selection, default is 0.\n"
+                            "\t\t    0 == vmalloc\n"
+                            "\t\t    1 == dma-contig");
+
 #define VIMC_MDEV_MODEL_NAME "VIMC MDEV"
 
 #define VIMC_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) {        \
@@ -278,6 +285,9 @@ static int vimc_probe(struct platform_device *pdev)
 
        tpg_set_font(font->data);
 
+       if (vimc_allocator == VIMC_ALLOCATOR_DMA_CONTIG)
+               dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+
        vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);
        if (!vimc)
                return -ENOMEM;