AnsweredAssumed Answered


Question asked by Erez Steinberg on Dec 10, 2014
Latest reply on Jul 22, 2015 by Erez Steinberg
Branched to a new discussion

Hello experts,


I am capturing video from a MIPI-CSI2 sensor directly to memory. I need to perform some processing on the input image, however there is a huge performance impact when accessing the V4L2 buffer. It is allocated using V4L2_MEMORY_MMAP, which allocates the buffers by calling dma_alloc_coherent(). This allocated non-cacheable memory which is slow...


Therefore, I am trying to use user-allocated buffers (V4L2_MEMORY_USERPTR), but am having problems.


First, it seems I have to call VIDIOC_QUERYBUF ioctl before VIDIOC_QBUF, otherwise I get an error when starting streaming.


However, looking in mxc_v4l2_capture.c, VIDIOC_QUERYBUF calls mxc_v4l2_prepare_bufs() -  but, it seems that paddress is copied from the v4l2_buffer provided by the user.


My question -- Are user-space buffers (V4L2_MEMORY_USERPTR) supported in iMX6 Linux?

If not -- is there a way to map a buffer allocated by dma_alloc_coherent without getting such a big performance hit?






-- for reference :


static int mxc_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)


  pr_debug("In MVC:mxc_v4l2_prepare_bufs\n");


  if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <

    cam->v2f.fmt.pix.sizeimage) {

      pr_err("ERROR: v4l2 capture: mxc_v4l2_prepare_bufs buffers "

          "not allocated,index=%d, length=%d\n", buf->index, buf->length);

      return -EINVAL;



  cam->frame[buf->index].buffer.index = buf->index;

  cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;

  cam->frame[buf->index].buffer.length = buf->length;

  cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress = buf->m.offset;

  cam->frame[buf->index].buffer.type = buf->type;

  cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;

  cam->frame[buf->index].index = buf->index;


  return 0;