Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1533909 > unrolled thread
| Started by | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| First post | 2016-12-01 10:10 +0100 |
| Last post | 2016-12-05 13:30 +0100 |
| Articles | 13 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v4 0/9] Qualcomm video decoder/encoder driver Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-01 10:10 +0100
[PATCH v4 5/9] media: venus: vdec: add video decoder files Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-01 10:10 +0100
Re: [PATCH v4 5/9] media: venus: vdec: add video decoder files Hans Verkuil <hverkuil@xs4all.nl> - 2016-12-05 12:40 +0100
Re: [PATCH v4 5/9] media: venus: vdec: add video decoder files Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-05 13:40 +0100
[PATCH v4 2/9] doc: DT: venus: binding document for Qualcomm video driver Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-01 10:20 +0100
Re: [PATCH v4 2/9] doc: DT: venus: binding document for Qualcomm video driver Rob Herring <robh@kernel.org> - 2016-12-06 01:30 +0100
[PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-01 10:20 +0100
Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management kbuild test robot <lkp@intel.com> - 2016-12-03 02:00 +0100
Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management Hans Verkuil <hverkuil@xs4all.nl> - 2016-12-05 12:30 +0100
Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-05 13:30 +0100
[PATCH v4 3/9] MAINTAINERS: Add Qualcomm Venus video accelerator driver Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-01 10:20 +0100
Re: [PATCH v4 8/9] media: venus: hfi: add Venus HFI files Hans Verkuil <hverkuil@xs4all.nl> - 2016-12-05 13:10 +0100
Re: [PATCH v4 8/9] media: venus: hfi: add Venus HFI files Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2016-12-05 13:30 +0100
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-01 10:10 +0100 |
| Subject | [PATCH v4 0/9] Qualcomm video decoder/encoder driver |
| Message-ID | <sJvxn-1QI-7@gated-at.bofh.it> |
Hi,
Here is version 4 of the Venus video driver.
The changes since v3 are:
* the driver now use m2m APIs. In order to make possible to
use m2m I had to extend m2m APIs with few more helper functions
for buffer list manipulations.
* addressed comments from Hans about buffer done on error path.
* simplify s_selection in decoder.
* avoid simple IRQ related wrappers in core.c and use HFI ones directly.
* added kernel doc description of venus_core|inst structures.
* replaced list_for_each_entry_safe with list_for_each_entry where
safer variants are not applicable.
* revisit the locking per instance and come down to one lock per
instance.
* added help text in the driver Kconfig option.
* deleted custom venus_ctrl structure which duplicates v4l2_ctrl_config.
* various cleanups on random places to avoid code duplications and
to reduce the code lines.
* removed video memory (vmem) DT properties from binding document, this
will need more work.
The previous version can be found at https://lkml.org/lkml/2016/11/7/554
regards,
Stan
Stanimir Varbanov (9):
media: v4l2-mem2mem: extend m2m APIs for more accurate buffer
management
doc: DT: venus: binding document for Qualcomm video driver
MAINTAINERS: Add Qualcomm Venus video accelerator driver
media: venus: adding core part and helper functions
media: venus: vdec: add video decoder files
media: venus: venc: add video encoder files
media: venus: hfi: add Host Firmware Interface (HFI)
media: venus: hfi: add Venus HFI files
media: venus: enable building of Venus video driver
.../devicetree/bindings/media/qcom,venus.txt | 82 ++
MAINTAINERS | 8 +
drivers/media/platform/Kconfig | 13 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/qcom/venus/Makefile | 14 +
drivers/media/platform/qcom/venus/core.c | 474 ++++++
drivers/media/platform/qcom/venus/core.h | 296 ++++
drivers/media/platform/qcom/venus/helpers.c | 621 ++++++++
drivers/media/platform/qcom/venus/helpers.h | 41 +
drivers/media/platform/qcom/venus/hfi.c | 492 +++++++
drivers/media/platform/qcom/venus/hfi.h | 174 +++
drivers/media/platform/qcom/venus/hfi_cmds.c | 1256 ++++++++++++++++
drivers/media/platform/qcom/venus/hfi_cmds.h | 304 ++++
drivers/media/platform/qcom/venus/hfi_helper.h | 1045 ++++++++++++++
drivers/media/platform/qcom/venus/hfi_msgs.c | 1054 ++++++++++++++
drivers/media/platform/qcom/venus/hfi_msgs.h | 283 ++++
drivers/media/platform/qcom/venus/hfi_venus.c | 1508 ++++++++++++++++++++
drivers/media/platform/qcom/venus/hfi_venus.h | 23 +
drivers/media/platform/qcom/venus/hfi_venus_io.h | 98 ++
drivers/media/platform/qcom/venus/vdec.c | 976 +++++++++++++
drivers/media/platform/qcom/venus/vdec.h | 32 +
drivers/media/platform/qcom/venus/vdec_ctrls.c | 149 ++
drivers/media/platform/qcom/venus/venc.c | 1099 ++++++++++++++
drivers/media/platform/qcom/venus/venc.h | 32 +
drivers/media/platform/qcom/venus/venc_ctrls.c | 258 ++++
drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +
include/media/v4l2-mem2mem.h | 83 ++
27 files changed, 10454 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/qcom,venus.txt
create mode 100644 drivers/media/platform/qcom/venus/Makefile
create mode 100644 drivers/media/platform/qcom/venus/core.c
create mode 100644 drivers/media/platform/qcom/venus/core.h
create mode 100644 drivers/media/platform/qcom/venus/helpers.c
create mode 100644 drivers/media/platform/qcom/venus/helpers.h
create mode 100644 drivers/media/platform/qcom/venus/hfi.c
create mode 100644 drivers/media/platform/qcom/venus/hfi.h
create mode 100644 drivers/media/platform/qcom/venus/hfi_cmds.c
create mode 100644 drivers/media/platform/qcom/venus/hfi_cmds.h
create mode 100644 drivers/media/platform/qcom/venus/hfi_helper.h
create mode 100644 drivers/media/platform/qcom/venus/hfi_msgs.c
create mode 100644 drivers/media/platform/qcom/venus/hfi_msgs.h
create mode 100644 drivers/media/platform/qcom/venus/hfi_venus.c
create mode 100644 drivers/media/platform/qcom/venus/hfi_venus.h
create mode 100644 drivers/media/platform/qcom/venus/hfi_venus_io.h
create mode 100644 drivers/media/platform/qcom/venus/vdec.c
create mode 100644 drivers/media/platform/qcom/venus/vdec.h
create mode 100644 drivers/media/platform/qcom/venus/vdec_ctrls.c
create mode 100644 drivers/media/platform/qcom/venus/venc.c
create mode 100644 drivers/media/platform/qcom/venus/venc.h
create mode 100644 drivers/media/platform/qcom/venus/venc_ctrls.c
--
2.7.4
[toc] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-01 10:10 +0100 |
| Subject | [PATCH v4 5/9] media: venus: vdec: add video decoder files |
| Message-ID | <sJvxo-1QI-49@gated-at.bofh.it> |
| In reply to | #1533909 |
This consists of video decoder implementation plus decoder
controls.
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/vdec.c | 976 +++++++++++++++++++++++++
drivers/media/platform/qcom/venus/vdec.h | 32 +
drivers/media/platform/qcom/venus/vdec_ctrls.c | 149 ++++
3 files changed, 1157 insertions(+)
create mode 100644 drivers/media/platform/qcom/venus/vdec.c
create mode 100644 drivers/media/platform/qcom/venus/vdec.h
create mode 100644 drivers/media/platform/qcom/venus/vdec_ctrls.c
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
new file mode 100644
index 000000000000..9f585a1e0ff1
--- /dev/null
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -0,0 +1,976 @@
+/*
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "core.h"
+#include "helpers.h"
+#include "vdec.h"
+
+static u32 get_framesize_uncompressed(unsigned int plane, u32 width, u32 height)
+{
+ u32 y_stride, uv_stride, y_plane;
+ u32 y_sclines, uv_sclines, uv_plane;
+ u32 size;
+
+ y_stride = ALIGN(width, 128);
+ uv_stride = ALIGN(width, 128);
+ y_sclines = ALIGN(height, 32);
+ uv_sclines = ALIGN(((height + 1) >> 1), 16);
+
+ y_plane = y_stride * y_sclines;
+ uv_plane = uv_stride * uv_sclines + SZ_4K;
+ size = y_plane + uv_plane + SZ_8K;
+
+ return ALIGN(size, SZ_4K);
+}
+
+static u32 get_framesize_compressed(unsigned int width, unsigned int height)
+{
+ return ((width * height * 3 / 2) / 2) + 128;
+}
+
+static const struct venus_format vdec_formats[] = {
+ {
+ .pixfmt = V4L2_PIX_FMT_NV12,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_MPEG2,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H263,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_VP8,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ }, {
+ .pixfmt = V4L2_PIX_FMT_XVID,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ },
+};
+
+static const struct venus_format *find_format(u32 pixfmt, u32 type)
+{
+ const struct venus_format *fmt = vdec_formats;
+ unsigned int size = ARRAY_SIZE(vdec_formats);
+ unsigned int i;
+
+ for (i = 0; i < size; i++) {
+ if (fmt[i].pixfmt == pixfmt)
+ break;
+ }
+
+ if (i == size || fmt[i].type != type)
+ return NULL;
+
+ return &fmt[i];
+}
+
+static const struct venus_format *find_format_by_index(int index, u32 type)
+{
+ const struct venus_format *fmt = vdec_formats;
+ unsigned int size = ARRAY_SIZE(vdec_formats);
+ int i, k = 0;
+
+ if (index < 0 || index > size)
+ return NULL;
+
+ for (i = 0; i < size; i++) {
+ if (fmt[i].type != type)
+ continue;
+ if (k == index)
+ break;
+ k++;
+ }
+
+ if (i == size)
+ return NULL;
+
+ return &fmt[i];
+}
+
+static const struct venus_format *
+vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
+{
+ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+ struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
+ const struct venus_format *fmt;
+ unsigned int p;
+
+ memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
+ memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
+
+ fmt = find_format(pixmp->pixelformat, f->type);
+ if (!fmt) {
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ pixmp->pixelformat = V4L2_PIX_FMT_NV12;
+ else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ pixmp->pixelformat = V4L2_PIX_FMT_H264;
+ else
+ return NULL;
+ fmt = find_format(pixmp->pixelformat, f->type);
+ pixmp->width = 1280;
+ pixmp->height = 720;
+ }
+
+ pixmp->width = clamp(pixmp->width, inst->cap_width.min,
+ inst->cap_width.max);
+ pixmp->height = clamp(pixmp->height, inst->cap_height.min,
+ inst->cap_height.max);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ pixmp->height = ALIGN(pixmp->height, 32);
+
+ if (pixmp->field == V4L2_FIELD_ANY)
+ pixmp->field = V4L2_FIELD_NONE;
+ pixmp->num_planes = fmt->num_planes;
+ pixmp->flags = 0;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ for (p = 0; p < pixmp->num_planes; p++) {
+ pfmt[p].sizeimage =
+ get_framesize_uncompressed(p, pixmp->width,
+ pixmp->height);
+ pfmt[p].bytesperline = ALIGN(pixmp->width, 128);
+ }
+ } else {
+ pfmt[0].sizeimage = get_framesize_compressed(pixmp->width,
+ pixmp->height);
+ pfmt[0].bytesperline = 0;
+ }
+
+ return fmt;
+}
+
+static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct venus_inst *inst = to_inst(file);
+
+ vdec_try_fmt_common(inst, f);
+
+ return 0;
+}
+
+static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct venus_inst *inst = to_inst(file);
+ const struct venus_format *fmt = NULL;
+ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ fmt = inst->fmt_cap;
+ else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ fmt = inst->fmt_out;
+
+ if (inst->reconfig) {
+ struct v4l2_format format = {};
+
+ inst->out_width = inst->reconfig_width;
+ inst->out_height = inst->reconfig_height;
+ inst->reconfig = false;
+
+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt;
+ format.fmt.pix_mp.width = inst->out_width;
+ format.fmt.pix_mp.height = inst->out_height;
+
+ vdec_try_fmt_common(inst, &format);
+
+ inst->width = format.fmt.pix_mp.width;
+ inst->height = format.fmt.pix_mp.height;
+ }
+
+ pixmp->pixelformat = fmt->pixfmt;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ pixmp->width = inst->width;
+ pixmp->height = inst->height;
+ pixmp->colorspace = inst->colorspace;
+ pixmp->ycbcr_enc = inst->ycbcr_enc;
+ pixmp->quantization = inst->quantization;
+ pixmp->xfer_func = inst->xfer_func;
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ pixmp->width = inst->out_width;
+ pixmp->height = inst->out_height;
+ }
+
+ vdec_try_fmt_common(inst, f);
+
+ return 0;
+}
+
+static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct venus_inst *inst = to_inst(file);
+ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+ struct v4l2_pix_format_mplane orig_pixmp;
+ const struct venus_format *fmt;
+ struct v4l2_format format;
+ u32 pixfmt_out = 0, pixfmt_cap = 0;
+
+ orig_pixmp = *pixmp;
+
+ fmt = vdec_try_fmt_common(inst, f);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ pixfmt_out = pixmp->pixelformat;
+ pixfmt_cap = inst->fmt_cap->pixfmt;
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ pixfmt_cap = pixmp->pixelformat;
+ pixfmt_out = inst->fmt_out->pixfmt;
+ }
+
+ memset(&format, 0, sizeof(format));
+
+ format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ format.fmt.pix_mp.pixelformat = pixfmt_out;
+ format.fmt.pix_mp.width = orig_pixmp.width;
+ format.fmt.pix_mp.height = orig_pixmp.height;
+ vdec_try_fmt_common(inst, &format);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ inst->out_width = format.fmt.pix_mp.width;
+ inst->out_height = format.fmt.pix_mp.height;
+ inst->colorspace = pixmp->colorspace;
+ inst->ycbcr_enc = pixmp->ycbcr_enc;
+ inst->quantization = pixmp->quantization;
+ inst->xfer_func = pixmp->xfer_func;
+ }
+
+ memset(&format, 0, sizeof(format));
+
+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ format.fmt.pix_mp.pixelformat = pixfmt_cap;
+ format.fmt.pix_mp.width = orig_pixmp.width;
+ format.fmt.pix_mp.height = orig_pixmp.height;
+ vdec_try_fmt_common(inst, &format);
+
+ inst->width = format.fmt.pix_mp.width;
+ inst->height = format.fmt.pix_mp.height;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ inst->fmt_out = fmt;
+ else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ inst->fmt_cap = fmt;
+
+ return 0;
+}
+
+static int
+vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+ struct venus_inst *inst = to_inst(file);
+
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ s->r.width = inst->out_width;
+ s->r.height = inst->out_height;
+ break;
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ case V4L2_SEL_TGT_COMPOSE_PADDED:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ s->r.width = inst->width;
+ s->r.height = inst->height;
+ break;
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ case V4L2_SEL_TGT_COMPOSE:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ s->r.width = inst->out_width;
+ s->r.height = inst->out_height;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ s->r.top = 0;
+ s->r.left = 0;
+
+ return 0;
+}
+
+static int
+vdec_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+ struct venus_inst *inst = to_inst(file);
+
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ s->target != V4L2_SEL_TGT_COMPOSE)
+ return -EINVAL;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE:
+ s->r.width = inst->out_width;
+ s->r.height = inst->out_height;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ s->r.top = 0;
+ s->r.left = 0;
+
+ return 0;
+}
+
+static int
+vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+ strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver));
+ strlcpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card));
+ strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
+
+ return 0;
+}
+
+static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+ const struct venus_format *fmt;
+
+ memset(f->reserved, 0, sizeof(f->reserved));
+
+ fmt = find_format_by_index(f->index, f->type);
+ if (!fmt)
+ return -EINVAL;
+
+ f->pixelformat = fmt->pixfmt;
+
+ return 0;
+}
+
+static int vdec_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+{
+ struct venus_inst *inst = to_inst(file);
+ struct v4l2_captureparm *cap = &a->parm.capture;
+ struct v4l2_fract *timeperframe = &cap->timeperframe;
+ u64 us_per_frame, fps;
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+ a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return -EINVAL;
+
+ memset(cap->reserved, 0, sizeof(cap->reserved));
+ if (!timeperframe->denominator)
+ timeperframe->denominator = inst->timeperframe.denominator;
+ if (!timeperframe->numerator)
+ timeperframe->numerator = inst->timeperframe.numerator;
+ cap->readbuffers = 0;
+ cap->extendedmode = 0;
+ cap->capability = V4L2_CAP_TIMEPERFRAME;
+ us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
+ do_div(us_per_frame, timeperframe->denominator);
+
+ if (!us_per_frame)
+ return -EINVAL;
+
+ fps = (u64)USEC_PER_SEC;
+ do_div(fps, us_per_frame);
+
+ inst->fps = fps;
+ inst->timeperframe = *timeperframe;
+
+ return 0;
+}
+
+static int vdec_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct venus_inst *inst = to_inst(file);
+ const struct venus_format *fmt;
+
+ fmt = find_format(fsize->pixel_format,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (!fmt) {
+ fmt = find_format(fsize->pixel_format,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (!fmt)
+ return -EINVAL;
+ }
+
+ if (fsize->index)
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+
+ fsize->stepwise.min_width = inst->cap_width.min;
+ fsize->stepwise.max_width = inst->cap_width.max;
+ fsize->stepwise.step_width = inst->cap_width.step_size;
+ fsize->stepwise.min_height = inst->cap_height.min;
+ fsize->stepwise.max_height = inst->cap_height.max;
+ fsize->stepwise.step_height = inst->cap_height.step_size;
+
+ return 0;
+}
+
+static int vdec_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(fh, sub, 2, NULL);
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
+ .vidioc_querycap = vdec_querycap,
+ .vidioc_enum_fmt_vid_cap_mplane = vdec_enum_fmt,
+ .vidioc_enum_fmt_vid_out_mplane = vdec_enum_fmt,
+ .vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt,
+ .vidioc_s_fmt_vid_out_mplane = vdec_s_fmt,
+ .vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt,
+ .vidioc_g_fmt_vid_out_mplane = vdec_g_fmt,
+ .vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
+ .vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
+ .vidioc_g_selection = vdec_g_selection,
+ .vidioc_s_selection = vdec_s_selection,
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+ .vidioc_s_parm = vdec_s_parm,
+ .vidioc_enum_framesizes = vdec_enum_framesizes,
+ .vidioc_subscribe_event = vdec_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int vdec_set_properties(struct venus_inst *inst)
+{
+ struct vdec_controls *ctr = &inst->controls.dec;
+ struct venus_core *core = inst->core;
+ struct hfi_enable en = { .enable = 1 };
+ u32 ptype;
+ int ret;
+
+ ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
+ ret = hfi_session_set_property(inst, ptype, &en);
+ if (ret)
+ return ret;
+
+ if (core->res->hfi_version == HFI_VERSION_3XX) {
+ struct hfi_buffer_alloc_mode mode;
+
+ ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
+ mode.type = HFI_BUFFER_OUTPUT;
+ mode.mode = HFI_BUFFER_MODE_DYNAMIC;
+
+ ret = hfi_session_set_property(inst, ptype, &mode);
+ if (ret)
+ return ret;
+ }
+
+ if (ctr->post_loop_deb_mode) {
+ ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
+ en.enable = 1;
+ ret = hfi_session_set_property(inst, ptype, &en);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int vdec_init_session(struct venus_inst *inst)
+{
+ int ret;
+
+ ret = hfi_session_init(inst, inst->fmt_out->pixfmt);
+ if (ret)
+ return ret;
+
+ ret = helper_set_input_resolution(inst, inst->out_width,
+ inst->out_height);
+ if (ret)
+ goto deinit;
+
+ ret = helper_set_color_format(inst, inst->fmt_cap->pixfmt);
+ if (ret)
+ goto deinit;
+
+ return 0;
+deinit:
+ hfi_session_deinit(inst);
+ return ret;
+}
+
+static int vdec_cap_num_buffers(struct venus_inst *inst, unsigned int *num)
+{
+ struct venus_core *core = inst->core;
+ struct hfi_buffer_requirements bufreq;
+ struct device *dev = core->dev;
+ int ret, ret2;
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ return ret;
+
+ ret = vdec_init_session(inst);
+ if (ret)
+ goto put_sync;
+
+ ret = helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
+
+ *num = bufreq.count_actual;
+
+ hfi_session_deinit(inst);
+
+put_sync:
+ ret2 = pm_runtime_put_sync(dev);
+
+ return ret ? ret : ret2;
+}
+
+static int vdec_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct venus_inst *inst = vb2_get_drv_priv(q);
+ unsigned int p, num;
+ int ret = 0;
+
+ if (*num_planes) {
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
+ *num_planes != inst->fmt_out->num_planes)
+ return -EINVAL;
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+ *num_planes != inst->fmt_cap->num_planes)
+ return -EINVAL;
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
+ sizes[0] < inst->input_buf_size)
+ return -EINVAL;
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+ sizes[0] < inst->output_buf_size)
+ return -EINVAL;
+
+ return 0;
+ }
+
+ switch (q->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ *num_planes = inst->fmt_out->num_planes;
+ sizes[0] = get_framesize_compressed(inst->out_width,
+ inst->out_height);
+ inst->input_buf_size = sizes[0];
+ inst->num_input_bufs = *num_buffers;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ *num_planes = inst->fmt_cap->num_planes;
+
+ ret = vdec_cap_num_buffers(inst, &num);
+ if (ret)
+ break;
+
+ *num_buffers = max(*num_buffers, num);
+
+ for (p = 0; p < *num_planes; p++)
+ sizes[p] = get_framesize_uncompressed(p, inst->width,
+ inst->height);
+
+ inst->num_output_bufs = *num_buffers;
+ inst->output_buf_size = sizes[0];
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int vdec_verify_conf(struct venus_inst *inst)
+{
+ struct hfi_buffer_requirements bufreq;
+ int ret;
+
+ if (!inst->num_input_bufs || !inst->num_output_bufs)
+ return -EINVAL;
+
+ ret = helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
+ if (ret)
+ return ret;
+
+ if (inst->num_output_bufs < bufreq.count_actual ||
+ inst->num_output_bufs < bufreq.count_min)
+ return -EINVAL;
+
+ ret = helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq);
+ if (ret)
+ return ret;
+
+ if (inst->num_input_bufs < bufreq.count_min)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct venus_inst *inst = vb2_get_drv_priv(q);
+ struct venus_core *core = inst->core;
+ struct device *dev = core->dev;
+ u32 ptype;
+ int ret;
+
+ mutex_lock(&inst->lock);
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ inst->streamon_out = 1;
+ else
+ inst->streamon_cap = 1;
+
+ if (!(inst->streamon_out & inst->streamon_cap)) {
+ mutex_unlock(&inst->lock);
+ return 0;
+ }
+
+ inst->reconfig = false;
+ inst->sequence = 0;
+ inst->codec_cfg = false;
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ return ret;
+
+ ret = vdec_init_session(inst);
+ if (ret)
+ goto put_sync;
+
+ ret = vdec_set_properties(inst);
+ if (ret)
+ goto deinit_sess;
+
+ if (core->res->hfi_version == HFI_VERSION_3XX) {
+ struct hfi_buffer_size_actual buf_sz;
+
+ ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
+ buf_sz.type = HFI_BUFFER_OUTPUT;
+ buf_sz.size = inst->output_buf_size;
+
+ ret = hfi_session_set_property(inst, ptype, &buf_sz);
+ if (ret)
+ goto deinit_sess;
+ }
+
+ ret = vdec_verify_conf(inst);
+ if (ret)
+ goto deinit_sess;
+
+ ret = helper_set_num_bufs(inst, inst->num_input_bufs,
+ inst->num_output_bufs);
+ if (ret)
+ goto deinit_sess;
+
+ ret = helper_vb2_start_streaming(inst);
+ if (ret)
+ goto deinit_sess;
+
+ mutex_unlock(&inst->lock);
+
+ return 0;
+
+deinit_sess:
+ hfi_session_deinit(inst);
+put_sync:
+ pm_runtime_put_sync(dev);
+ helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ inst->streamon_out = 0;
+ else
+ inst->streamon_cap = 0;
+ mutex_unlock(&inst->lock);
+ return ret;
+}
+
+static const struct vb2_ops vdec_vb2_ops = {
+ .queue_setup = vdec_queue_setup,
+ .buf_init = helper_vb2_buf_init,
+ .buf_prepare = helper_vb2_buf_prepare,
+ .start_streaming = vdec_start_streaming,
+ .stop_streaming = helper_vb2_stop_streaming,
+ .buf_queue = helper_vb2_buf_queue,
+};
+
+static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
+ u32 tag, u32 bytesused, u32 data_offset, u32 flags,
+ u64 timestamp_us)
+{
+ struct vb2_v4l2_buffer *vbuf;
+ struct vb2_buffer *vb;
+ unsigned int type;
+
+ if (buf_type == HFI_BUFFER_INPUT)
+ type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ else
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ vbuf = helper_find_buf(inst, type, tag);
+ if (!vbuf)
+ return;
+
+ vbuf->flags = flags;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ vb = &vbuf->vb2_buf;
+ vb->planes[0].bytesused =
+ max_t(unsigned int, inst->output_buf_size, bytesused);
+ vb->planes[0].data_offset = data_offset;
+ vb->timestamp = timestamp_us * NSEC_PER_USEC;
+ vbuf->sequence = inst->sequence++;
+
+ if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
+ const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
+
+ v4l2_event_queue_fh(&inst->fh, &ev);
+ }
+ }
+
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+}
+
+static void vdec_event_notify(struct venus_inst *inst, u32 event,
+ struct hfi_event_data *data)
+{
+ struct venus_core *core = inst->core;
+ struct device *dev = core->dev;
+ static const struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION };
+
+ switch (event) {
+ case EVT_SESSION_ERROR:
+ inst->session_error = true;
+ dev_err(dev, "dec: event session error %x\n", inst->error);
+ break;
+ case EVT_SYS_EVENT_CHANGE:
+ switch (data->event_type) {
+ case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
+ hfi_session_continue(inst);
+ dev_dbg(dev, "event sufficient resources\n");
+ break;
+ case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
+ inst->reconfig_height = data->height;
+ inst->reconfig_width = data->width;
+ inst->reconfig = true;
+
+ v4l2_event_queue_fh(&inst->fh, &ev);
+
+ dev_dbg(dev, "event not sufficient resources (%ux%u)\n",
+ data->width, data->height);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static const struct hfi_inst_ops vdec_hfi_ops = {
+ .buf_done = vdec_buf_done,
+ .event_notify = vdec_event_notify,
+};
+
+static void vdec_inst_init(struct venus_inst *inst)
+{
+ inst->fmt_out = &vdec_formats[6];
+ inst->fmt_cap = &vdec_formats[0];
+ inst->width = 1280;
+ inst->height = ALIGN(720, 32);
+ inst->out_width = 1280;
+ inst->out_height = 720;
+ inst->fps = 30;
+ inst->timeperframe.numerator = 1;
+ inst->timeperframe.denominator = 30;
+
+ inst->cap_width.min = 64;
+ inst->cap_width.max = 1920;
+ inst->cap_width.step_size = 1;
+ inst->cap_height.min = 64;
+ inst->cap_height.max = ALIGN(1080, 32);
+ inst->cap_height.step_size = 1;
+ inst->cap_framerate.min = 1;
+ inst->cap_framerate.max = 30;
+ inst->cap_framerate.step_size = 1;
+ inst->cap_mbs_per_frame.min = 16;
+ inst->cap_mbs_per_frame.max = 8160;
+}
+
+static const struct v4l2_m2m_ops vdec_m2m_ops = {
+ .device_run = helper_m2m_device_run,
+ .job_abort = helper_m2m_job_abort,
+};
+
+static int m2m_queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct venus_inst *inst = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->ops = &vdec_vb2_ops;
+ src_vq->mem_ops = &vb2_dma_sg_memops;
+ src_vq->drv_priv = inst;
+ src_vq->buf_struct_size = sizeof(struct venus_buffer);
+ src_vq->allow_zero_bytesused = 1;
+ src_vq->min_buffers_needed = 1;
+ src_vq->dev = inst->core->dev;
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->ops = &vdec_vb2_ops;
+ dst_vq->mem_ops = &vb2_dma_sg_memops;
+ dst_vq->drv_priv = inst;
+ dst_vq->buf_struct_size = sizeof(struct venus_buffer);
+ dst_vq->allow_zero_bytesused = 1;
+ dst_vq->min_buffers_needed = 1;
+ dst_vq->dev = inst->core->dev;
+ ret = vb2_queue_init(dst_vq);
+ if (ret) {
+ vb2_queue_release(src_vq);
+ return ret;
+ }
+
+ return 0;
+}
+
+int vdec_init(struct venus_core *core, struct video_device *dec,
+ const struct v4l2_file_operations *fops)
+{
+ int ret;
+
+ dec->release = video_device_release;
+ dec->fops = fops;
+ dec->ioctl_ops = &vdec_ioctl_ops;
+ dec->vfl_dir = VFL_DIR_M2M;
+ dec->v4l2_dev = &core->v4l2_dev;
+ dec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+ ret = video_register_device(dec, VFL_TYPE_GRABBER, -1);
+ if (ret)
+ return ret;
+
+ video_set_drvdata(dec, core);
+
+ return 0;
+}
+
+void vdec_deinit(struct venus_core *core, struct video_device *dec)
+{
+ video_unregister_device(dec);
+}
+
+int vdec_open(struct venus_inst *inst)
+{
+ int ret;
+
+ ret = vdec_ctrl_init(inst);
+ if (ret)
+ return ret;
+
+ ret = hfi_session_create(inst, &vdec_hfi_ops);
+ if (ret)
+ goto err_ctrl_deinit;
+
+ vdec_inst_init(inst);
+
+ /*
+ * create m2m device for every instance, the m2m context scheduling
+ * is made by firmware side so we do not need to care about.
+ */
+ inst->m2m_dev = v4l2_m2m_init(&vdec_m2m_ops);
+ if (IS_ERR(inst->m2m_dev)) {
+ ret = PTR_ERR(inst->m2m_dev);
+ goto err_session_destroy;
+ }
+
+ inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init);
+ if (IS_ERR(inst->m2m_ctx)) {
+ ret = PTR_ERR(inst->m2m_ctx);
+ goto err_m2m_release;
+ }
+
+ return 0;
+
+err_m2m_release:
+ v4l2_m2m_release(inst->m2m_dev);
+err_session_destroy:
+ hfi_session_destroy(inst);
+err_ctrl_deinit:
+ vdec_ctrl_deinit(inst);
+ return ret;
+}
+
+void vdec_close(struct venus_inst *inst)
+{
+ v4l2_m2m_ctx_release(inst->m2m_ctx);
+ v4l2_m2m_release(inst->m2m_dev);
+ vdec_ctrl_deinit(inst);
+ hfi_session_destroy(inst);
+}
diff --git a/drivers/media/platform/qcom/venus/vdec.h b/drivers/media/platform/qcom/venus/vdec.h
new file mode 100644
index 000000000000..297617998b26
--- /dev/null
+++ b/drivers/media/platform/qcom/venus/vdec.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __VENUS_VDEC_H__
+#define __VENUS_VDEC_H__
+
+struct venus_core;
+struct video_device;
+struct venus_inst;
+struct v4l2_file_operations;
+
+int vdec_init(struct venus_core *core, struct video_device *dec,
+ const struct v4l2_file_operations *fops);
+void vdec_deinit(struct venus_core *core, struct video_device *dec);
+int vdec_open(struct venus_inst *inst);
+void vdec_close(struct venus_inst *inst);
+
+int vdec_ctrl_init(struct venus_inst *inst);
+void vdec_ctrl_deinit(struct venus_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/qcom/venus/vdec_ctrls.c b/drivers/media/platform/qcom/venus/vdec_ctrls.c
new file mode 100644
index 000000000000..94b7eb32c457
--- /dev/null
+++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/types.h>
+#include <media/v4l2-ctrls.h>
+
+#include "core.h"
+
+static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct venus_inst *inst = ctrl_to_inst(ctrl);
+ struct vdec_controls *ctr = &inst->controls.dec;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
+ ctr->post_loop_deb_mode = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+ case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:
+ ctr->profile = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+ ctr->level = ctrl->val;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct venus_inst *inst = ctrl_to_inst(ctrl);
+ struct vdec_controls *ctr = &inst->controls.dec;
+ union hfi_get_property hprop;
+ u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
+ int ret;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+ case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:
+ ret = hfi_session_get_property(inst, ptype, &hprop);
+ if (!ret)
+ ctr->profile = hprop.profile_level.profile;
+ ctrl->val = ctr->profile;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+ ret = hfi_session_get_property(inst, ptype, &hprop);
+ if (!ret)
+ ctr->level = hprop.profile_level.level;
+ ctrl->val = ctr->level;
+ break;
+ case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
+ ctrl->val = ctr->post_loop_deb_mode;
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
+ .s_ctrl = vdec_op_s_ctrl,
+ .g_volatile_ctrl = vdec_op_g_volatile_ctrl,
+};
+
+int vdec_ctrl_init(struct venus_inst *inst)
+{
+ struct v4l2_ctrl *ctrl;
+ int ret;
+
+ ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 6);
+ if (ret)
+ return ret;
+
+ ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
+ V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY,
+ ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) |
+ (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)),
+ V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
+ 0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+ V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
+ ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) |
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)),
+ V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+ V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+ 0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_VPX_PROFILE, 0, 3, 1, 0);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 0, 1, 1, 0);
+
+ ret = inst->ctrl_handler.error;
+ if (ret) {
+ v4l2_ctrl_handler_free(&inst->ctrl_handler);
+ return ret;
+ }
+
+ return 0;
+}
+
+void vdec_ctrl_deinit(struct venus_inst *inst)
+{
+ v4l2_ctrl_handler_free(&inst->ctrl_handler);
+}
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Hans Verkuil <hverkuil@xs4all.nl> |
|---|---|
| Date | 2016-12-05 12:40 +0100 |
| Subject | Re: [PATCH v4 5/9] media: venus: vdec: add video decoder files |
| Message-ID | <sKZMK-3Vo-27@gated-at.bofh.it> |
| In reply to | #1533914 |
I have two comments (and the same two comments apply to the video encoder patch
as well):
On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
> This consists of video decoder implementation plus decoder
> controls.
>
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
> drivers/media/platform/qcom/venus/vdec.c | 976 +++++++++++++++++++++++++
> drivers/media/platform/qcom/venus/vdec.h | 32 +
> drivers/media/platform/qcom/venus/vdec_ctrls.c | 149 ++++
> 3 files changed, 1157 insertions(+)
> create mode 100644 drivers/media/platform/qcom/venus/vdec.c
> create mode 100644 drivers/media/platform/qcom/venus/vdec.h
> create mode 100644 drivers/media/platform/qcom/venus/vdec_ctrls.c
>
> diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
> new file mode 100644
> index 000000000000..9f585a1e0ff1
> --- /dev/null
> +++ b/drivers/media/platform/qcom/venus/vdec.c
> @@ -0,0 +1,976 @@
<snip>
> +static int
> +vdec_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
> +{
> + struct venus_inst *inst = to_inst(file);
> +
> + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
> + s->target != V4L2_SEL_TGT_COMPOSE)
> + return -EINVAL;
> +
> + switch (s->target) {
> + case V4L2_SEL_TGT_COMPOSE:
> + s->r.width = inst->out_width;
> + s->r.height = inst->out_height;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + s->r.top = 0;
> + s->r.left = 0;
> +
> + return 0;
> +}
This doesn't actually set anything, so what's the point of this function?
I've fixed the corresponding test in v4l2-compliance so you can now drop this
op and v4l2-compliance won't complain anymore.
> +static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> + struct venus_inst *inst = vb2_get_drv_priv(q);
> + struct venus_core *core = inst->core;
> + struct device *dev = core->dev;
> + u32 ptype;
> + int ret;
> +
> + mutex_lock(&inst->lock);
> +
> + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
> + inst->streamon_out = 1;
> + else
> + inst->streamon_cap = 1;
> +
> + if (!(inst->streamon_out & inst->streamon_cap)) {
> + mutex_unlock(&inst->lock);
> + return 0;
> + }
> +
> + inst->reconfig = false;
> + inst->sequence = 0;
> + inst->codec_cfg = false;
> +
> + ret = pm_runtime_get_sync(dev);
> + if (ret < 0)
> + return ret;
This should be a goto so that 'helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);'
is called on error.
It's wrong anyway since you don't unlock the mutex in this return path either.
> +
> + ret = vdec_init_session(inst);
> + if (ret)
> + goto put_sync;
> +
> + ret = vdec_set_properties(inst);
> + if (ret)
> + goto deinit_sess;
> +
> + if (core->res->hfi_version == HFI_VERSION_3XX) {
> + struct hfi_buffer_size_actual buf_sz;
> +
> + ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
> + buf_sz.type = HFI_BUFFER_OUTPUT;
> + buf_sz.size = inst->output_buf_size;
> +
> + ret = hfi_session_set_property(inst, ptype, &buf_sz);
> + if (ret)
> + goto deinit_sess;
> + }
> +
> + ret = vdec_verify_conf(inst);
> + if (ret)
> + goto deinit_sess;
> +
> + ret = helper_set_num_bufs(inst, inst->num_input_bufs,
> + inst->num_output_bufs);
> + if (ret)
> + goto deinit_sess;
> +
> + ret = helper_vb2_start_streaming(inst);
> + if (ret)
> + goto deinit_sess;
> +
> + mutex_unlock(&inst->lock);
> +
> + return 0;
> +
> +deinit_sess:
> + hfi_session_deinit(inst);
> +put_sync:
> + pm_runtime_put_sync(dev);
> + helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
> + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
> + inst->streamon_out = 0;
> + else
> + inst->streamon_cap = 0;
> + mutex_unlock(&inst->lock);
> + return ret;
> +}
Regards,
Hans
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-05 13:40 +0100 |
| Subject | Re: [PATCH v4 5/9] media: venus: vdec: add video decoder files |
| Message-ID | <sL0IO-4Aj-25@gated-at.bofh.it> |
| In reply to | #1536016 |
Hi Hans,
Thanks for the comments!
On 12/05/2016 01:32 PM, Hans Verkuil wrote:
> I have two comments (and the same two comments apply to the video encoder patch
> as well):
>
> On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
>> This consists of video decoder implementation plus decoder
>> controls.
>>
>> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
>> ---
>> drivers/media/platform/qcom/venus/vdec.c | 976 +++++++++++++++++++++++++
>> drivers/media/platform/qcom/venus/vdec.h | 32 +
>> drivers/media/platform/qcom/venus/vdec_ctrls.c | 149 ++++
>> 3 files changed, 1157 insertions(+)
>> create mode 100644 drivers/media/platform/qcom/venus/vdec.c
>> create mode 100644 drivers/media/platform/qcom/venus/vdec.h
>> create mode 100644 drivers/media/platform/qcom/venus/vdec_ctrls.c
>>
>> diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
>> new file mode 100644
>> index 000000000000..9f585a1e0ff1
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/venus/vdec.c
>> @@ -0,0 +1,976 @@
>
> <snip>
>
>> +static int
>> +vdec_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
>> +{
>> + struct venus_inst *inst = to_inst(file);
>> +
>> + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
>> + s->target != V4L2_SEL_TGT_COMPOSE)
>> + return -EINVAL;
>> +
>> + switch (s->target) {
>> + case V4L2_SEL_TGT_COMPOSE:
>> + s->r.width = inst->out_width;
>> + s->r.height = inst->out_height;
>> + break;
>> + default:
>> + return -EINVAL;
>> + }
>> +
>> + s->r.top = 0;
>> + s->r.left = 0;
>> +
>> + return 0;
>> +}
>
> This doesn't actually set anything, so what's the point of this function?
>
> I've fixed the corresponding test in v4l2-compliance so you can now drop this
> op and v4l2-compliance won't complain anymore.
OK I will give a try.
>
>> +static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
>> +{
>> + struct venus_inst *inst = vb2_get_drv_priv(q);
>> + struct venus_core *core = inst->core;
>> + struct device *dev = core->dev;
>> + u32 ptype;
>> + int ret;
>> +
>> + mutex_lock(&inst->lock);
>> +
>> + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
>> + inst->streamon_out = 1;
>> + else
>> + inst->streamon_cap = 1;
>> +
>> + if (!(inst->streamon_out & inst->streamon_cap)) {
>> + mutex_unlock(&inst->lock);
>> + return 0;
>> + }
>> +
>> + inst->reconfig = false;
>> + inst->sequence = 0;
>> + inst->codec_cfg = false;
>> +
>> + ret = pm_runtime_get_sync(dev);
>> + if (ret < 0)
>> + return ret;
>
> This should be a goto so that 'helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);'
> is called on error.
>
> It's wrong anyway since you don't unlock the mutex in this return path either.
yes, this return is wrong, will correct it in next version.
--
regards,
Stan
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-01 10:20 +0100 |
| Subject | [PATCH v4 2/9] doc: DT: venus: binding document for Qualcomm video driver |
| Message-ID | <sJvH4-1Xf-9@gated-at.bofh.it> |
| In reply to | #1533909 |
Add binding document for Venus video encoder/decoder driver
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
Rob, I have removed vmem clocks, interrupts and reg properties
for vmem thing. Probably I will come with a separate platform
driver fro that and pass the video memory DT node as phandle.
.../devicetree/bindings/media/qcom,venus.txt | 82 ++++++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/qcom,venus.txt
diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt
new file mode 100644
index 000000000000..a64b4ea1ebba
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,venus.txt
@@ -0,0 +1,82 @@
+* Qualcomm Venus video encode/decode accelerator
+
+- compatible:
+ Usage: required
+ Value type: <stringlist>
+ Definition: Value should contain one of:
+ - "qcom,msm8916-venus"
+ - "qcom,msm8996-venus"
+- reg:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Register ranges as listed in the reg-names property.
+- reg-names:
+ Usage: required
+ Value type: <stringlist>
+ Definition: Should contain following entries:
+ - "base" Venus register base
+- interrupts:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Should contain interrupts as listed in the interrupt-names
+ property.
+- interrupt-names:
+ Usage: required
+ Value type: <stringlist>
+ Definition: Should contain following entries:
+ - "venus" Venus interrupt line
+- clocks:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A List of phandle and clock specifier pairs as listed
+ in clock-names property.
+- clock-names:
+ Usage: required
+ Value type: <stringlist>
+ Definition: Should contain the following entries:
+ - "core" Core video accelerator clock
+ - "iface" Video accelerator AHB clock
+ - "bus" Video accelerator AXI clock
+- clock-names:
+ Usage: required for msm8996
+ Value type: <stringlist>
+ Definition: Should contain the following entries:
+ - "subcore0" Subcore0 video accelerator clock
+ - "subcore1" Subcore1 video accelerator clock
+ - "mmssnoc_axi" Multimedia subsystem NOC AXI clock
+ - "mmss_mmagic_iface" Multimedia subsystem MMAGIC AHB clock
+ - "mmss_mmagic_mbus" Multimedia subsystem MMAGIC MAXI clock
+ - "mmagic_video_bus" MMAGIC video AXI clock
+ - "video_mbus" Video MAXI clock
+- power-domains:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A phandle and power domain specifier pairs to the
+ power domain which is responsible for collapsing
+ and restoring power to the peripheral.
+- rproc:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A phandle to remote processor responsible for
+ firmware loading and processor booting.
+
+- iommus:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A list of phandle and IOMMU specifier pairs.
+
+* An Example
+ video-codec@1d00000 {
+ compatible = "qcom,msm8916-venus";
+ reg = <0x01d00000 0xff000>;
+ reg-names = "base";
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "venus";
+ clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>,
+ <&gcc GCC_VENUS0_AHB_CLK>,
+ <&gcc GCC_VENUS0_AXI_CLK>;
+ clock-names = "core", "iface", "bus";
+ power-domains = <&gcc VENUS_GDSC>;
+ rproc = <&venus_rproc>;
+ iommus = <&apps_iommu 5>;
+ };
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2016-12-06 01:30 +0100 |
| Subject | Re: [PATCH v4 2/9] doc: DT: venus: binding document for Qualcomm video driver |
| Message-ID | <sLbNU-3bh-27@gated-at.bofh.it> |
| In reply to | #1533919 |
On Thu, Dec 01, 2016 at 11:03:14AM +0200, Stanimir Varbanov wrote:
> Add binding document for Venus video encoder/decoder driver
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
> Rob, I have removed vmem clocks, interrupts and reg properties
> for vmem thing. Probably I will come with a separate platform
> driver fro that and pass the video memory DT node as phandle.
Looks good, a couple of minor things below.
>
> .../devicetree/bindings/media/qcom,venus.txt | 82 ++++++++++++++++++++++
> 1 file changed, 82 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/qcom,venus.txt
>
> diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt
> new file mode 100644
> index 000000000000..a64b4ea1ebba
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt
> @@ -0,0 +1,82 @@
> +* Qualcomm Venus video encode/decode accelerator
> +
> +- compatible:
> + Usage: required
> + Value type: <stringlist>
> + Definition: Value should contain one of:
> + - "qcom,msm8916-venus"
> + - "qcom,msm8996-venus"
> +- reg:
> + Usage: required
> + Value type: <prop-encoded-array>
> + Definition: Register ranges as listed in the reg-names property.
> +- reg-names:
> + Usage: required
> + Value type: <stringlist>
> + Definition: Should contain following entries:
> + - "base" Venus register base
-names is kind of pointless with only one.
> +- interrupts:
> + Usage: required
> + Value type: <prop-encoded-array>
> + Definition: Should contain interrupts as listed in the interrupt-names
> + property.
> +- interrupt-names:
> + Usage: required
> + Value type: <stringlist>
> + Definition: Should contain following entries:
> + - "venus" Venus interrupt line
ditto
> +- clocks:
> + Usage: required
> + Value type: <prop-encoded-array>
> + Definition: A List of phandle and clock specifier pairs as listed
> + in clock-names property.
> +- clock-names:
> + Usage: required
> + Value type: <stringlist>
> + Definition: Should contain the following entries:
> + - "core" Core video accelerator clock
> + - "iface" Video accelerator AHB clock
> + - "bus" Video accelerator AXI clock
> +- clock-names:
> + Usage: required for msm8996
It's not clear if this is in addition to the above list. I'd guess not
and you should make it clear the above applies to the 8916 only.
> + Value type: <stringlist>
> + Definition: Should contain the following entries:
> + - "subcore0" Subcore0 video accelerator clock
> + - "subcore1" Subcore1 video accelerator clock
> + - "mmssnoc_axi" Multimedia subsystem NOC AXI clock
> + - "mmss_mmagic_iface" Multimedia subsystem MMAGIC AHB clock
> + - "mmss_mmagic_mbus" Multimedia subsystem MMAGIC MAXI clock
> + - "mmagic_video_bus" MMAGIC video AXI clock
> + - "video_mbus" Video MAXI clock
> +- power-domains:
> + Usage: required
> + Value type: <prop-encoded-array>
> + Definition: A phandle and power domain specifier pairs to the
> + power domain which is responsible for collapsing
> + and restoring power to the peripheral.
> +- rproc:
> + Usage: required
> + Value type: <prop-encoded-array>
> + Definition: A phandle to remote processor responsible for
> + firmware loading and processor booting.
> +
> +- iommus:
> + Usage: required
> + Value type: <prop-encoded-array>
> + Definition: A list of phandle and IOMMU specifier pairs.
> +
> +* An Example
> + video-codec@1d00000 {
> + compatible = "qcom,msm8916-venus";
> + reg = <0x01d00000 0xff000>;
> + reg-names = "base";
> + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "venus";
> + clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>,
> + <&gcc GCC_VENUS0_AHB_CLK>,
> + <&gcc GCC_VENUS0_AXI_CLK>;
> + clock-names = "core", "iface", "bus";
> + power-domains = <&gcc VENUS_GDSC>;
> + rproc = <&venus_rproc>;
> + iommus = <&apps_iommu 5>;
> + };
> --
> 2.7.4
>
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-01 10:20 +0100 |
| Subject | [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management |
| Message-ID | <sJvH4-1Xf-27@gated-at.bofh.it> |
| In reply to | #1533909 |
this add functions for:
- remove buffers from src/dst queue by index
- remove exact buffer from src/dst queue
also extends m2m API to iterate over a list of src/dst buffers
in safely and non-safely manner.
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++++++++++++++
include/media/v4l2-mem2mem.h | 83 ++++++++++++++++++++++++++++++++++
2 files changed, 120 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..d689e7bb964f 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
}
EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
+void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+ struct v4l2_m2m_buffer *b;
+ unsigned long flags;
+
+ spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
+ b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+ list_del(&b->list);
+ q_ctx->num_rdy--;
+ spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_exact);
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
+
+{
+ struct v4l2_m2m_buffer *b, *tmp;
+ struct vb2_v4l2_buffer *ret = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
+ list_for_each_entry_safe(b, tmp, &q_ctx->rdy_queue, list) {
+ if (b->vb.vb2_buf.index == idx) {
+ list_del(&b->list);
+ q_ctx->num_rdy--;
+ ret = &b->vb;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
+
/*
* Scheduling handlers
*/
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 3ccd01bd245e..c8632c52d5e2 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,41 @@ static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
}
/**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b) \
+ list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b) \
+ list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n) \
+ list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n) \
+ list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
+
+/**
* v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
*
* @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
@@ -488,6 +523,54 @@ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
}
+/**
+ * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ */
+void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
+ struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void v4l2_m2m_src_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+ v4l2_m2m_buf_remove_exact(&m2m_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_src_buf_remove_exact() - take off exact destination buffer from the
+ * list of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void v4l2_m2m_dst_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+ v4l2_m2m_buf_remove_exact(&m2m_ctx->cap_q_ctx, vbuf);
+}
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx);
+
+static inline struct vb2_v4l2_buffer *
+v4l2_m2m_src_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
+{
+ return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->out_q_ctx, idx);
+}
+
+static inline struct vb2_v4l2_buffer *
+v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
+{
+ return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx);
+}
+
/* v4l2 ioctl helpers */
int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | kbuild test robot <lkp@intel.com> |
|---|---|
| Date | 2016-12-03 02:00 +0100 |
| Subject | Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management |
| Message-ID | <sK6Qi-2BA-17@gated-at.bofh.it> |
| In reply to | #1533920 |
[Multipart message — attachments visible in raw view] — view raw
Hi Stanimir,
[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.9-rc7 next-20161202]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Stanimir-Varbanov/Qualcomm-video-decoder-encoder-driver/20161203-054705
base: git://linuxtv.org/media_tree.git master
reproduce: make htmldocs
All warnings (new ones prefixed by >>):
make[3]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
include/linux/init.h:1: warning: no structured comments found
include/linux/workqueue.h:392: warning: No description found for parameter '...'
include/linux/workqueue.h:392: warning: Excess function parameter 'args' description in 'alloc_workqueue'
include/linux/workqueue.h:413: warning: No description found for parameter '...'
include/linux/workqueue.h:413: warning: Excess function parameter 'args' description in 'alloc_ordered_workqueue'
include/linux/kthread.h:26: warning: No description found for parameter '...'
kernel/sys.c:1: warning: no structured comments found
drivers/dma-buf/seqno-fence.c:1: warning: no structured comments found
include/linux/fence-array.h:61: warning: No description found for parameter 'fence'
include/sound/core.h:324: warning: No description found for parameter '...'
include/sound/core.h:335: warning: No description found for parameter '...'
include/sound/core.h:388: warning: No description found for parameter '...'
drivers/media/dvb-core/dvb_frontend.h:677: warning: No description found for parameter 'refcount'
include/media/media-entity.h:1054: warning: No description found for parameter '...'
>> include/media/v4l2-mem2mem.h:446: warning: No description found for parameter 'b'
include/media/v4l2-mem2mem.h:454: warning: No description found for parameter 'b'
include/media/v4l2-mem2mem.h:463: warning: No description found for parameter 'b'
>> include/media/v4l2-mem2mem.h:463: warning: No description found for parameter 'n'
include/media/v4l2-mem2mem.h:472: warning: No description found for parameter 'b'
include/media/v4l2-mem2mem.h:472: warning: No description found for parameter 'n'
>> include/media/v4l2-mem2mem.h:533: warning: No description found for parameter 'vbuf'
include/media/v4l2-mem2mem.h:543: warning: No description found for parameter 'vbuf'
include/media/v4l2-mem2mem.h:555: warning: No description found for parameter 'vbuf'
include/net/mac80211.h:3207: ERROR: Unexpected indentation.
include/net/mac80211.h:3210: WARNING: Block quote ends without a blank line; unexpected unindent.
include/net/mac80211.h:3212: ERROR: Unexpected indentation.
include/net/mac80211.h:3213: WARNING: Block quote ends without a blank line; unexpected unindent.
include/net/mac80211.h:1772: ERROR: Unexpected indentation.
include/net/mac80211.h:1776: WARNING: Block quote ends without a blank line; unexpected unindent.
kernel/sched/fair.c:7259: WARNING: Inline emphasis start-string without end-string.
kernel/time/timer.c:1240: ERROR: Unexpected indentation.
kernel/time/timer.c:1242: ERROR: Unexpected indentation.
kernel/time/timer.c:1243: WARNING: Block quote ends without a blank line; unexpected unindent.
include/linux/wait.h:121: WARNING: Block quote ends without a blank line; unexpected unindent.
include/linux/wait.h:124: ERROR: Unexpected indentation.
include/linux/wait.h:126: WARNING: Block quote ends without a blank line; unexpected unindent.
kernel/time/hrtimer.c:1021: WARNING: Block quote ends without a blank line; unexpected unindent.
kernel/signal.c:317: WARNING: Inline literal start-string without end-string.
drivers/base/firmware_class.c:1348: WARNING: Bullet list ends without a blank line; unexpected unindent.
drivers/message/fusion/mptbase.c:5054: WARNING: Definition list ends without a blank line; unexpected unindent.
drivers/tty/serial/serial_core.c:1893: WARNING: Definition list ends without a blank line; unexpected unindent.
include/linux/spi/spi.h:369: ERROR: Unexpected indentation.
WARNING: dvipng command 'dvipng' cannot be run (needed for math display), check the imgmath_dvipng setting
vim +/b +446 include/media/v4l2-mem2mem.h
440 * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
441 * buffers
442 *
443 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
444 */
445 #define v4l2_m2m_for_each_dst_buf(m2m_ctx, b) \
> 446 list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
447
448 /**
449 * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
450 *
451 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
452 */
453 #define v4l2_m2m_for_each_src_buf(m2m_ctx, b) \
454 list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
455
456 /**
457 * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
458 * buffers safely
459 *
460 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
461 */
462 #define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n) \
> 463 list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
464
465 /**
466 * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
467 * buffers safely
468 *
469 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
470 */
471 #define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n) \
472 list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
473
474 /**
475 * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
476 *
477 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
478 */
479 static inline
480 struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
481 {
482 return &m2m_ctx->out_q_ctx.q;
483 }
484
485 /**
486 * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers
487 *
488 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
489 */
490 static inline
491 struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
492 {
493 return &m2m_ctx->cap_q_ctx.q;
494 }
495
496 /**
497 * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
498 * return it
499 *
500 * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
501 */
502 void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx);
503
504 /**
505 * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
506 * buffers and return it
507 *
508 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
509 */
510 static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
511 {
512 return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx);
513 }
514
515 /**
516 * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of
517 * ready buffers and return it
518 *
519 * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
520 */
521 static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
522 {
523 return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
524 }
525
526 /**
527 * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
528 * buffers
529 *
530 * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
531 */
532 void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
> 533 struct vb2_v4l2_buffer *vbuf);
534
535 /**
536 * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the list
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[toc] | [prev] | [next] | [standalone]
| From | Hans Verkuil <hverkuil@xs4all.nl> |
|---|---|
| Date | 2016-12-05 12:30 +0100 |
| Subject | Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management |
| Message-ID | <sKZD3-3S7-3@gated-at.bofh.it> |
| In reply to | #1533920 |
On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
> this add functions for:
> - remove buffers from src/dst queue by index
> - remove exact buffer from src/dst queue
>
> also extends m2m API to iterate over a list of src/dst buffers
> in safely and non-safely manner.
>
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
> drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++++++++++++++
> include/media/v4l2-mem2mem.h | 83 ++++++++++++++++++++++++++++++++++
> 2 files changed, 120 insertions(+)
>
> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> index 6bc27e7b2a33..d689e7bb964f 100644
> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> @@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
> }
> EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
>
> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
> + struct vb2_v4l2_buffer *vbuf)
I'd call this v4l2_m2m_buf_remove_by_buf to be consistent with _by_idx.
Other than that, this looks OK.
Regards,
Hans
> +{
> + struct v4l2_m2m_buffer *b;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
> + b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
> + list_del(&b->list);
> + q_ctx->num_rdy--;
> + spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_exact);
> +
> +struct vb2_v4l2_buffer *
> +v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx)
> +
> +{
> + struct v4l2_m2m_buffer *b, *tmp;
> + struct vb2_v4l2_buffer *ret = NULL;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
> + list_for_each_entry_safe(b, tmp, &q_ctx->rdy_queue, list) {
> + if (b->vb.vb2_buf.index == idx) {
> + list_del(&b->list);
> + q_ctx->num_rdy--;
> + ret = &b->vb;
> + break;
> + }
> + }
> + spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove_by_idx);
> +
> /*
> * Scheduling handlers
> */
> diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> index 3ccd01bd245e..c8632c52d5e2 100644
> --- a/include/media/v4l2-mem2mem.h
> +++ b/include/media/v4l2-mem2mem.h
> @@ -437,6 +437,41 @@ static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
> }
>
> /**
> + * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
> + * buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b) \
> + list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_src_buf(m2m_ctx, b) \
> + list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n) \
> + list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
> +
> +/**
> + * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
> + * buffers safely
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n) \
> + list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
> +
> +/**
> * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
> *
> * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> @@ -488,6 +523,54 @@ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
> return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
> }
>
> +/**
> + * v4l2_m2m_buf_remove_exact() - take off exact buffer from the list of ready
> + * buffers
> + *
> + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
> + */
> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx,
> + struct vb2_v4l2_buffer *vbuf);
> +
> +/**
> + * v4l2_m2m_src_buf_remove_exact() - take off exact source buffer from the list
> + * of ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +static inline void v4l2_m2m_src_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
> + struct vb2_v4l2_buffer *vbuf)
> +{
> + v4l2_m2m_buf_remove_exact(&m2m_ctx->out_q_ctx, vbuf);
> +}
> +
> +/**
> + * v4l2_m2m_src_buf_remove_exact() - take off exact destination buffer from the
> + * list of ready buffers
> + *
> + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
> + */
> +static inline void v4l2_m2m_dst_buf_remove_exact(struct v4l2_m2m_ctx *m2m_ctx,
> + struct vb2_v4l2_buffer *vbuf)
> +{
> + v4l2_m2m_buf_remove_exact(&m2m_ctx->cap_q_ctx, vbuf);
> +}
> +
> +struct vb2_v4l2_buffer *
> +v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx);
> +
> +static inline struct vb2_v4l2_buffer *
> +v4l2_m2m_src_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
> +{
> + return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->out_q_ctx, idx);
> +}
> +
> +static inline struct vb2_v4l2_buffer *
> +v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
> +{
> + return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx);
> +}
> +
> /* v4l2 ioctl helpers */
>
> int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
>
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-05 13:30 +0100 |
| Subject | Re: [PATCH v4 1/9] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management |
| Message-ID | <sL0z8-4xj-27@gated-at.bofh.it> |
| In reply to | #1536009 |
Hi Hans, On 12/05/2016 01:25 PM, Hans Verkuil wrote: > On 12/01/2016 10:03 AM, Stanimir Varbanov wrote: >> this add functions for: >> - remove buffers from src/dst queue by index >> - remove exact buffer from src/dst queue >> >> also extends m2m API to iterate over a list of src/dst buffers >> in safely and non-safely manner. >> >> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> >> --- >> drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +++++++++++++++ >> include/media/v4l2-mem2mem.h | 83 ++++++++++++++++++++++++++++++++++ >> 2 files changed, 120 insertions(+) >> >> diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c >> index 6bc27e7b2a33..d689e7bb964f 100644 >> --- a/drivers/media/v4l2-core/v4l2-mem2mem.c >> +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c >> @@ -126,6 +126,43 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx) >> } >> EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove); >> >> +void v4l2_m2m_buf_remove_exact(struct v4l2_m2m_queue_ctx *q_ctx, >> + struct vb2_v4l2_buffer *vbuf) > > I'd call this v4l2_m2m_buf_remove_by_buf to be consistent with _by_idx. Thanks, I will rename it. -- regards, Stan
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-01 10:20 +0100 |
| Subject | [PATCH v4 3/9] MAINTAINERS: Add Qualcomm Venus video accelerator driver |
| Message-ID | <sJvH4-1Xf-19@gated-at.bofh.it> |
| In reply to | #1533909 |
Add an entry for Venus video encoder/decoder accelerator driver. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 52cc0775a799..9528488f538e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10013,6 +10013,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel.g S: Supported F: arch/hexagon/ +QUALCOMM VENUS VIDEO ACCELERATOR DRIVER +M: Stanimir Varbanov <stanimir.varbanov@linaro.org> +L: linux-media@vger.kernel.org +L: linux-arm-msm@vger.kernel.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/platform/qcom/venus/ + QUALCOMM WCN36XX WIRELESS DRIVER M: Eugene Krasnikov <k.eugene.e@gmail.com> L: wcn36xx@lists.infradead.org -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Hans Verkuil <hverkuil@xs4all.nl> |
|---|---|
| Date | 2016-12-05 13:10 +0100 |
| Subject | Re: [PATCH v4 8/9] media: venus: hfi: add Venus HFI files |
| Message-ID | <sL0fN-4nY-99@gated-at.bofh.it> |
| In reply to | #1533909 |
On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
> Here is the implementation of Venus video accelerator low-level
> functionality. It contanins code which setup the registers and
> startup uthe processor, allocate and manipulates with the shared
> memory used for sending commands and receiving messages.
>
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
> drivers/media/platform/qcom/venus/hfi_venus.c | 1508 ++++++++++++++++++++++
> drivers/media/platform/qcom/venus/hfi_venus.h | 23 +
> drivers/media/platform/qcom/venus/hfi_venus_io.h | 98 ++
> 3 files changed, 1629 insertions(+)
> create mode 100644 drivers/media/platform/qcom/venus/hfi_venus.c
> create mode 100644 drivers/media/platform/qcom/venus/hfi_venus.h
> create mode 100644 drivers/media/platform/qcom/venus/hfi_venus_io.h
>
> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
> new file mode 100644
> index 000000000000..f004a9a80d85
> --- /dev/null
> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
> @@ -0,0 +1,1508 @@
> +static int venus_tzbsp_set_video_state(enum tzbsp_video_state state)
> +{
> + return qcom_scm_video_set_state(state, 0);
This functions doesn't seem to exist. Is there a prerequisite patch series that
introduces this function?
> +}
Regards,
Hans
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2016-12-05 13:30 +0100 |
| Subject | Re: [PATCH v4 8/9] media: venus: hfi: add Venus HFI files |
| Message-ID | <sL0z8-4xj-21@gated-at.bofh.it> |
| In reply to | #1536033 |
Hi Hans,
On 12/05/2016 02:05 PM, Hans Verkuil wrote:
> On 12/01/2016 10:03 AM, Stanimir Varbanov wrote:
>> Here is the implementation of Venus video accelerator low-level
>> functionality. It contanins code which setup the registers and
>> startup uthe processor, allocate and manipulates with the shared
>> memory used for sending commands and receiving messages.
>>
>> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
>> ---
>> drivers/media/platform/qcom/venus/hfi_venus.c | 1508 ++++++++++++++++++++++
>> drivers/media/platform/qcom/venus/hfi_venus.h | 23 +
>> drivers/media/platform/qcom/venus/hfi_venus_io.h | 98 ++
>> 3 files changed, 1629 insertions(+)
>> create mode 100644 drivers/media/platform/qcom/venus/hfi_venus.c
>> create mode 100644 drivers/media/platform/qcom/venus/hfi_venus.h
>> create mode 100644 drivers/media/platform/qcom/venus/hfi_venus_io.h
>>
>> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
>> new file mode 100644
>> index 000000000000..f004a9a80d85
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
>> @@ -0,0 +1,1508 @@
>> +static int venus_tzbsp_set_video_state(enum tzbsp_video_state state)
>> +{
>> + return qcom_scm_video_set_state(state, 0);
>
> This functions doesn't seem to exist. Is there a prerequisite patch series that
> introduces this function?
yes, the patchset [1] is under review.
--
regards,
Stan
[1] https://lkml.org/lkml/2016/11/7/533
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web