Commit 4a2e0a80 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

media: vimc: Add support for contiguous DMA buffers



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: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 79e8c421
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+7 −2
Original line number Diff line number Diff line
@@ -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) {
+7 −0
Original line number Diff line number Diff line
@@ -35,6 +35,13 @@

#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
 *
+10 −0
Original line number Diff line number Diff line
@@ -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>
@@ -15,6 +16,12 @@

#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;