[PATCH v3 7/9] v4l: xilinx: dma: Add multi-planar support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The current v4l driver supports single plane formats. This patch
will add support to handle multi-planar formats. Updated driver
capabilities to multi-planar, where it can handle both single and
multi-planar formats

Signed-off-by: Satish Kumar Nagireddy <satishna@xxxxxxxxxx>
---
 drivers/media/platform/xilinx/xilinx-dma.c  | 341 +++++++++++++++++++++++-----
 drivers/media/platform/xilinx/xilinx-dma.h  |   2 +-
 drivers/media/platform/xilinx/xilinx-vipp.c |  22 +-
 3 files changed, 307 insertions(+), 58 deletions(-)

diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index cb20ada..664981b 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -63,6 +63,7 @@ static int xvip_dma_verify_format(struct xvip_dma *dma)
        struct v4l2_subdev_format fmt;
        struct v4l2_subdev *subdev;
        int ret;
+       int width, height;

        subdev = xvip_dma_remote_subdev(&dma->pad, &fmt.pad);
        if (subdev == NULL)
@@ -73,9 +74,18 @@ static int xvip_dma_verify_format(struct xvip_dma *dma)
        if (ret < 0)
                return ret == -ENOIOCTLCMD ? -EINVAL : ret;

-       if (dma->fmtinfo->code != fmt.format.code ||
-           dma->format.height != fmt.format.height ||
-           dma->format.width != fmt.format.width)
+       if (dma->fmtinfo->code != fmt.format.code)
+               return -EINVAL;
+
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type)) {
+               width = dma->format.fmt.pix_mp.width;
+               height = dma->format.fmt.pix_mp.height;
+       } else {
+               width = dma->format.fmt.pix.width;
+               height = dma->format.fmt.pix.height;
+       }
+
+       if (width != fmt.format.width || height != fmt.format.height)
                return -EINVAL;

        return 0;
@@ -302,6 +312,8 @@ static void xvip_dma_complete(void *param)
 {
        struct xvip_dma_buffer *buf = param;
        struct xvip_dma *dma = buf->dma;
+       u8 num_planes, i;
+       int sizeimage;

        spin_lock(&dma->queued_lock);
        list_del(&buf->queue);
@@ -310,7 +322,28 @@ static void xvip_dma_complete(void *param)
        buf->buf.field = V4L2_FIELD_NONE;
        buf->buf.sequence = dma->sequence++;
        buf->buf.vb2_buf.timestamp = ktime_get_ns();
-       vb2_set_plane_payload(&buf->buf.vb2_buf, 0, dma->format.sizeimage);
+
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type)) {
+               /* Handling contiguous data with mplanes */
+               if (dma->fmtinfo->buffers == 1) {
+                       sizeimage =
+                               dma->format.fmt.pix_mp.plane_fmt[0].sizeimage;
+                       vb2_set_plane_payload(&buf->buf.vb2_buf, 0, sizeimage);
+               } else {
+                       /* Handling non-contiguous data with mplanes */
+                       num_planes = dma->format.fmt.pix_mp.num_planes;
+                       for (i = 0; i < num_planes; i++) {
+                               sizeimage =
+                                dma->format.fmt.pix_mp.plane_fmt[i].sizeimage;
+                               vb2_set_plane_payload(&buf->buf.vb2_buf, i,
+                                                     sizeimage);
+                       }
+               }
+       } else {
+               sizeimage = dma->format.fmt.pix.sizeimage;
+               vb2_set_plane_payload(&buf->buf.vb2_buf, 0, sizeimage);
+       }
+
        vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
 }

@@ -320,13 +353,48 @@ xvip_dma_queue_setup(struct vb2_queue *vq,
                     unsigned int sizes[], struct device *alloc_devs[])
 {
        struct xvip_dma *dma = vb2_get_drv_priv(vq);
+       u8 i;
+       int sizeimage;
+
+       /* Multi planar case: Make sure the image size is large enough */
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type)) {
+               if (*nplanes) {
+                       if (*nplanes != dma->format.fmt.pix_mp.num_planes)
+                               return -EINVAL;
+
+                       for (i = 0; i < *nplanes; i++) {
+                            sizeimage =
+                             dma->format.fmt.pix_mp.plane_fmt[i].sizeimage;
+                       if (sizes[i] < sizeimage)
+                               return -EINVAL;
+                       }
+               } else {
+                       /* Handling contiguous data with mplanes */
+                       if (dma->fmtinfo->buffers == 1) {
+                           *nplanes = 1;
+                           sizes[0] =
+                             dma->format.fmt.pix_mp.plane_fmt[0].sizeimage;
+                           return 0;
+                       } else {
+                           /* Handling non-contiguous data with mplanes */
+                           *nplanes = dma->format.fmt.pix_mp.num_planes;
+                           for (i = 0; i < *nplanes; i++) {
+                                sizeimage =
+                                 dma->format.fmt.pix_mp.plane_fmt[i].sizeimage;
+                                sizes[i] = sizeimage;
+                           }
+                       }
+               }
+               return 0;
+       }

-       /* Make sure the image size is large enough. */
-       if (*nplanes)
-               return sizes[0] < dma->format.sizeimage ? -EINVAL : 0;
+       /* Single planar case: Make sure the image size is large enough */
+       sizeimage = dma->format.fmt.pix.sizeimage;
+       if (*nplanes == 1)
+               return sizes[0] < sizeimage ? -EINVAL : 0;

        *nplanes = 1;
-       sizes[0] = dma->format.sizeimage;
+       sizes[0] = sizeimage;

        return 0;
 }
@@ -348,10 +416,11 @@ static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
        struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
        struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vbuf);
        struct dma_async_tx_descriptor *desc;
+       u32 flags, luma_size;
        dma_addr_t addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-       u32 flags;

-       if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+       if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+           dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
                flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
                dma->xt.dir = DMA_DEV_TO_MEM;
                dma->xt.src_sgl = false;
@@ -365,10 +434,50 @@ static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
                dma->xt.src_start = addr;
        }

-       dma->xt.frame_size = 1;
-       dma->sgl[0].size = dma->format.width * dma->fmtinfo->bpp;
-       dma->sgl[0].icg = dma->format.bytesperline - dma->sgl[0].size;
-       dma->xt.numf = dma->format.height;
+       /*
+        * DMA IP supports only 2 planes, so one datachunk is sufficient
+        * to get start address of 2nd plane
+        */
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type)) {
+               struct v4l2_pix_format_mplane *pix_mp;
+
+               pix_mp = &dma->format.fmt.pix_mp;
+               dma->xt.frame_size = dma->fmtinfo->num_planes;
+               dma->sgl[0].size = pix_mp->width * dma->fmtinfo->bpl_factor;
+               dma->sgl[0].icg = pix_mp->plane_fmt[0].bytesperline -
+                                                       dma->sgl[0].size;
+               dma->xt.numf = pix_mp->height;
+
+               /*
+                * dst_icg is the number of bytes to jump after last luma addr
+                * and before first chroma addr
+                */
+
+               /* Handling contiguous data with mplanes */
+               if (dma->fmtinfo->buffers == 1) {
+                   dma->sgl[0].dst_icg = 0;
+               } else {
+                   /* Handling non-contiguous data with mplanes */
+                   if (vb->num_planes == 2) {
+                       dma_addr_t chroma_addr =
+                                       vb2_dma_contig_plane_dma_addr(vb, 1);
+                       luma_size = pix_mp->plane_fmt[0].bytesperline *
+                                                               dma->xt.numf;
+                       if (chroma_addr > addr)
+                           dma->sgl[0].dst_icg =
+                               chroma_addr - addr - luma_size;
+                   }
+               }
+       } else {
+               struct v4l2_pix_format *pix;
+
+               pix = &dma->format.fmt.pix;
+               dma->xt.frame_size = dma->fmtinfo->num_planes;
+               dma->sgl[0].size = pix->width * dma->fmtinfo->bpl_factor;
+               dma->sgl[0].icg = pix->bytesperline - dma->sgl[0].size;
+               dma->xt.numf = pix->height;
+               dma->sgl[0].dst_icg = dma->sgl[0].size;
+       }

        desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags);
        if (!desc) {
@@ -496,10 +605,21 @@ xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
        cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
                          | dma->xdev->v4l2_caps;

-       if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-       else
-               cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+       cap->device_caps = V4L2_CAP_STREAMING;
+       switch (dma->queue.type) {
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+               cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE_MPLANE;
+               break;
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+               cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
+               break;
+       case V4L2_CAP_VIDEO_OUTPUT_MPLANE:
+               cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+               break;
+       case V4L2_CAP_VIDEO_OUTPUT:
+               cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT;
+               break;
+       }

        strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver));
        strlcpy(cap->card, dma->video.name, sizeof(cap->card));
@@ -523,7 +643,11 @@ xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
        if (f->index > 0)
                return -EINVAL;

-       f->pixelformat = dma->format.pixelformat;
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type))
+               f->pixelformat = dma->format.fmt.pix_mp.pixelformat;
+       else
+               f->pixelformat = dma->format.fmt.pix.pixelformat;
+
        strlcpy(f->description, dma->fmtinfo->description,
                sizeof(f->description));

@@ -536,13 +660,17 @@ xvip_dma_get_format(struct file *file, void *fh, struct v4l2_format *format)
        struct v4l2_fh *vfh = file->private_data;
        struct xvip_dma *dma = to_xvip_dma(vfh->vdev);

-       format->fmt.pix = dma->format;
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type))
+               format->fmt.pix_mp = dma->format.fmt.pix_mp;
+       else
+               format->fmt.pix = dma->format.fmt.pix;

        return 0;
 }

 static void
-__xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix,
+__xvip_dma_try_format(struct xvip_dma *dma,
+                     struct v4l2_format *format,
                      const struct xvip_video_format **fmtinfo)
 {
        const struct xvip_video_format *info;
@@ -553,40 +681,91 @@ __xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix,
        unsigned int width;
        unsigned int align;
        unsigned int bpl;
+       unsigned int i, hsub, vsub, plane_width, plane_height;

        /* Retrieve format information and select the default format if the
         * requested format isn't supported.
         */
-       info = xvip_get_format_by_fourcc(pix->pixelformat);
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type))
+           info = xvip_get_format_by_fourcc(format->fmt.pix_mp.pixelformat);
+       else
+           info = xvip_get_format_by_fourcc(format->fmt.pix.pixelformat);
+
        if (IS_ERR(info))
                info = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);

-       pix->pixelformat = info->fourcc;
-       pix->field = V4L2_FIELD_NONE;
-
        /* The transfer alignment requirements are expressed in bytes. Compute
         * the minimum and maximum values, clamp the requested width and convert
         * it back to pixels.
         */
-       align = lcm(dma->align, info->bpp);
+       align = lcm(dma->align, info->bpl_factor);
        min_width = roundup(XVIP_DMA_MIN_WIDTH, align);
        max_width = rounddown(XVIP_DMA_MAX_WIDTH, align);
-       width = rounddown(pix->width * info->bpp, align);

-       pix->width = clamp(width, min_width, max_width) / info->bpp;
-       pix->height = clamp(pix->height, XVIP_DMA_MIN_HEIGHT,
-                           XVIP_DMA_MAX_HEIGHT);
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type)) {
+               struct v4l2_pix_format_mplane *pix_mp;
+
+               pix_mp = &format->fmt.pix_mp;
+               pix_mp->field = V4L2_FIELD_NONE;
+               width = rounddown(pix_mp->width * info->bpl_factor, align);
+               pix_mp->width = clamp(width, min_width, max_width) /
+                                                       info->bpl_factor;
+               pix_mp->height = clamp(pix_mp->height, XVIP_DMA_MIN_HEIGHT,
+                                      XVIP_DMA_MAX_HEIGHT);
+
+               /*
+                * Clamp the requested bytes per line value. If the maximum
+                * bytes per line value is zero, the module doesn't support
+                * user configurable line sizes. Override the requested value
+                * with the minimum in that case.
+                */
+
+               /* Handling contiguous data with mplanes */
+               if (info->buffers == 1) {
+                       min_bpl = pix_mp->width * info->bpl_factor;
+                       max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align);
+                       bpl = rounddown(pix_mp->plane_fmt[0].bytesperline,
+                                       dma->align);
+                       pix_mp->plane_fmt[0].bytesperline = clamp(bpl, min_bpl,
+                                                                 max_bpl);
+                       pix_mp->plane_fmt[0].sizeimage =
+                             (pix_mp->width * pix_mp->height * info->bpp) >> 3;
+               } else {
+                       /* Handling non-contiguous data with mplanes */
+                       hsub = info->hsub;
+                       vsub = info->vsub;
+                       for (i = 0; i < info->num_planes; i++) {
+                               plane_width = pix_mp->width / (i ? hsub : 1);
+                               plane_height = pix_mp->height / (i ? vsub : 1);
+                               min_bpl = plane_width * info->bpl_factor;
+                               max_bpl = rounddown(XVIP_DMA_MAX_WIDTH,
+                                                   dma->align);
+                               bpl = pix_mp->plane_fmt[i].bytesperline;
+                               bpl = rounddown(bpl, dma->align);
+                               pix_mp->plane_fmt[i].bytesperline =
+                                               clamp(bpl, min_bpl, max_bpl);
+                               pix_mp->plane_fmt[i].sizeimage =
+                                       pix_mp->plane_fmt[i].bytesperline *
+                                                               plane_height;
+                       }
+               }
+       } else {
+               struct v4l2_pix_format *pix;

-       /* Clamp the requested bytes per line value. If the maximum bytes per
-        * line value is zero, the module doesn't support user configurable line
-        * sizes. Override the requested value with the minimum in that case.
-        */
-       min_bpl = pix->width * info->bpp;
-       max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align);
-       bpl = rounddown(pix->bytesperline, dma->align);
+               pix = &format->fmt.pix;
+               pix->field = V4L2_FIELD_NONE;
+
+               width = rounddown(pix->width * info->bpp, align);
+               pix->width = clamp(width, min_width, max_width) / info->bpp;
+               pix->height = clamp(pix->height, XVIP_DMA_MIN_HEIGHT,
+                                   XVIP_DMA_MAX_HEIGHT);

-       pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
-       pix->sizeimage = pix->bytesperline * pix->height;
+               min_bpl = pix->width * info->bpl_factor;
+               max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align);
+               bpl = rounddown(pix->bytesperline, dma->align);
+               pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
+               pix->sizeimage = (pix->width * pix->height * info->bpp) >> 3;
+       }

        if (fmtinfo)
                *fmtinfo = info;
@@ -598,7 +777,7 @@ xvip_dma_try_format(struct file *file, void *fh, struct v4l2_format *format)
        struct v4l2_fh *vfh = file->private_data;
        struct xvip_dma *dma = to_xvip_dma(vfh->vdev);

-       __xvip_dma_try_format(dma, &format->fmt.pix, NULL);
+       __xvip_dma_try_format(dma, format, NULL);
        return 0;
 }

@@ -609,12 +788,16 @@ xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format)
        struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
        const struct xvip_video_format *info;

-       __xvip_dma_try_format(dma, &format->fmt.pix, &info);
+       __xvip_dma_try_format(dma, format, &info);

        if (vb2_is_busy(&dma->queue))
                return -EBUSY;

-       dma->format = format->fmt.pix;
+       if (V4L2_TYPE_IS_MULTIPLANAR(dma->format.type))
+               dma->format.fmt.pix_mp = format->fmt.pix_mp;
+       else
+               dma->format.fmt.pix = format->fmt.pix;
+
        dma->fmtinfo = info;

        return 0;
@@ -623,11 +806,15 @@ xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format)
 static const struct v4l2_ioctl_ops xvip_dma_ioctl_ops = {
        .vidioc_querycap                = xvip_dma_querycap,
        .vidioc_enum_fmt_vid_cap        = xvip_dma_enum_format,
+       .vidioc_enum_fmt_vid_cap_mplane = xvip_dma_enum_format,
        .vidioc_g_fmt_vid_cap           = xvip_dma_get_format,
+       .vidioc_g_fmt_vid_cap_mplane    = xvip_dma_get_format,
        .vidioc_g_fmt_vid_out           = xvip_dma_get_format,
        .vidioc_s_fmt_vid_cap           = xvip_dma_set_format,
+       .vidioc_s_fmt_vid_cap_mplane    = xvip_dma_set_format,
        .vidioc_s_fmt_vid_out           = xvip_dma_set_format,
        .vidioc_try_fmt_vid_cap         = xvip_dma_try_format,
+       .vidioc_try_fmt_vid_cap_mplane  = xvip_dma_try_format,
        .vidioc_try_fmt_vid_out         = xvip_dma_try_format,
        .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
        .vidioc_querybuf                = vb2_ioctl_querybuf,
@@ -661,6 +848,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
 {
        char name[16];
        int ret;
+       u32 i, hsub, vsub, width, height;

        dma->xdev = xdev;
        dma->port = port;
@@ -670,17 +858,55 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
        spin_lock_init(&dma->queued_lock);

        dma->fmtinfo = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);
-       dma->format.pixelformat = dma->fmtinfo->fourcc;
-       dma->format.colorspace = V4L2_COLORSPACE_SRGB;
-       dma->format.field = V4L2_FIELD_NONE;
-       dma->format.width = XVIP_DMA_DEF_WIDTH;
-       dma->format.height = XVIP_DMA_DEF_HEIGHT;
-       dma->format.bytesperline = dma->format.width * dma->fmtinfo->bpp;
-       dma->format.sizeimage = dma->format.bytesperline * dma->format.height;
+       dma->format.type = type;
+
+       if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+               struct v4l2_pix_format_mplane *pix_mp;
+
+               pix_mp = &dma->format.fmt.pix_mp;
+               pix_mp->pixelformat = dma->fmtinfo->fourcc;
+               pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
+               pix_mp->field = V4L2_FIELD_NONE;
+               pix_mp->width = XVIP_DMA_DEF_WIDTH;
+
+               /* Handling contiguous data with mplanes */
+               if (dma->fmtinfo->buffers == 1) {
+                   pix_mp->plane_fmt[0].bytesperline =
+                     pix_mp->width * dma->fmtinfo->bpl_factor;
+                   pix_mp->plane_fmt[0].sizeimage =
+                     (pix_mp->width * pix_mp->height * dma->fmtinfo->bpp) >> 3;
+               } else {
+                   /* Handling non-contiguous data with mplanes */
+                   hsub = dma->fmtinfo->hsub;
+                   vsub = dma->fmtinfo->vsub;
+                   for (i = 0; i < dma->fmtinfo->num_planes; i++) {
+                               width  = pix_mp->width / (i ? hsub : 1);
+                               height = pix_mp->height / (i ? vsub : 1);
+                               pix_mp->plane_fmt[i].bytesperline = width *
+                                               dma->fmtinfo->bpl_factor;
+                               pix_mp->plane_fmt[i].sizeimage = width * height;
+                   }
+               }
+       } else {
+               struct v4l2_pix_format *pix;
+
+               pix = &dma->format.fmt.pix;
+               pix->pixelformat = dma->fmtinfo->fourcc;
+               pix->colorspace = V4L2_COLORSPACE_SRGB;
+               pix->field = V4L2_FIELD_NONE;
+               pix->width = XVIP_DMA_DEF_WIDTH;
+               pix->height = XVIP_DMA_DEF_HEIGHT;
+               pix->bytesperline = pix->width * dma->fmtinfo->bpl_factor;
+               pix->sizeimage =
+                       (pix->width * pix->height * dma->fmtinfo->bpp) >> 3;
+       }

        /* Initialize the media entity... */
-       dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
-                      ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+       if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+           type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               dma->pad.flags = MEDIA_PAD_FL_SINK;
+       else
+               dma->pad.flags = MEDIA_PAD_FL_SOURCE;

        ret = media_entity_pads_init(&dma->video.entity, 1, &dma->pad);
        if (ret < 0)
@@ -692,11 +918,18 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
        dma->video.queue = &dma->queue;
        snprintf(dma->video.name, sizeof(dma->video.name), "%s %s %u",
                 xdev->dev->of_node->name,
-                type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input",
+                (type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+                type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+                                       ? "output" : "input",
                 port);
+
        dma->video.vfl_type = VFL_TYPE_GRABBER;
-       dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
-                          ? VFL_DIR_RX : VFL_DIR_TX;
+       if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+           type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               dma->video.vfl_dir = VFL_DIR_RX;
+       else
+               dma->video.vfl_dir = VFL_DIR_TX;
+
        dma->video.release = video_device_release_empty;
        dma->video.ioctl_ops = &xvip_dma_ioctl_ops;
        dma->video.lock = &dma->lock;
diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h
index e95d136..b352bef 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.h
+++ b/drivers/media/platform/xilinx/xilinx-dma.h
@@ -83,7 +83,7 @@ struct xvip_dma {
        unsigned int port;

        struct mutex lock;
-       struct v4l2_pix_format format;
+       struct v4l2_format format;
        const struct xvip_video_format *fmtinfo;

        struct vb2_queue queue;
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index 6bb28cd..508cfac 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -30,6 +30,15 @@
 #define XVIPP_DMA_S2MM                         0
 #define XVIPP_DMA_MM2S                         1

+/*
+ * This is for backward compatibility for existing applications,
+ * and planned to be deprecated
+ */
+static bool xvip_is_mplane = true;
+MODULE_PARM_DESC(is_mplane,
+                "v4l2 device capability to handle multi planar formats");
+module_param_named(is_mplane, xvip_is_mplane, bool, 0444);
+
 /**
  * struct xvip_graph_entity - Entity in the video graph
  * @list: list entry in a graph entities list
@@ -434,7 +443,8 @@ static int xvip_graph_dma_init_one(struct xvip_composite_device *xdev,
                return ret;

        if (strcmp(direction, "input") == 0)
-               type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               type = xvip_is_mplane ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+                                               V4L2_BUF_TYPE_VIDEO_CAPTURE;
        else if (strcmp(direction, "output") == 0)
                type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
        else
@@ -454,8 +464,14 @@ static int xvip_graph_dma_init_one(struct xvip_composite_device *xdev,

        list_add_tail(&dma->list, &xdev->dmas);

-       xdev->v4l2_caps |= type == V4L2_BUF_TYPE_VIDEO_CAPTURE
-                        ? V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_VIDEO_OUTPUT;
+       if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               xdev->v4l2_caps |= V4L2_CAP_VIDEO_CAPTURE_MPLANE;
+       else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               xdev->v4l2_caps |= V4L2_CAP_VIDEO_CAPTURE;
+       else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               xdev->v4l2_caps |= V4L2_CAP_VIDEO_OUTPUT;
+       else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+               xdev->v4l2_caps |= V4L2_CAP_VIDEO_OUTPUT_MPLANE;

        return 0;
 }
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux