Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1663877 > unrolled thread
| Started by | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| First post | 2017-06-12 18:30 +0200 |
| Last post | 2017-06-14 14:30 +0200 |
| Articles | 16 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v10 00/18] Qualcomm video decoder/encoder driver Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:30 +0200
[PATCH v10 01/18] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:30 +0200
[PATCH v10 12/18] media: venus: helpers: fix variable dereferenced before check Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 16/18] media: venus: venc: fix compile error in venc_close Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 03/18] MAINTAINERS: Add Qualcomm Venus video accelerator driver Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 13/18] media: venus: hfi_venus: fix variable dereferenced before check Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 11/18] media: venus: hfi_cmds: fix variable dereferenced before check Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 17/18] media: venus: vdec: add support for min buffers for capture Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 05/18] media: venus: vdec: add video decoder files Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 10/18] media: venus: hfi: fix mutex unlock Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 18/18] media: venus: enable building with COMPILE_TEST Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 09/18] media: venus: enable building of Venus video driver Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 02/18] doc: DT: venus: binding document for Qualcomm video driver Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 15/18] media: venus: vdec: fix compile error in vdec_close Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
[PATCH v10 14/18] media: venus: hfi_msgs: fix set but not used variables Stanimir Varbanov <stanimir.varbanov@linaro.org> - 2017-06-12 18:40 +0200
Re: [PATCH v10 00/18] Qualcomm video decoder/encoder driver Stanimir Varbanov <svarbanov@mm-sol.com> - 2017-06-14 14:30 +0200
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:30 +0200 |
| Subject | [PATCH v10 00/18] Qualcomm video decoder/encoder driver |
| Message-ID | <tRAo1-4qP-1@gated-at.bofh.it> |
Hello,
The changes since patchset v9 are the following:
* patches from 1/18 to 9/18 are the same.
* patches from 10/18 to 16/18 are fixes for warns/errors found by
Mauro when building with its gcc7.
* patch 17/18 adding support for minimum buffers for capture
get control. This fixes an issue with gstreamer and it will
be good to have it in the inital version of the venus driver.
* patch 18/18 enable COMPILE_TEST Kconfig option for the driver,
and this patch depends on the other one for qcom_scm driver.
The submited patch for qcom_scm driver can be found at [1].
Mauro, I failed to build gcc7 on my own machine and fallback to
a pre-built version of the gcc-7 for may Ubuntu distro. The version
which I tried was: gcc version 7.1.0 (Ubuntu 7.1.0-5ubuntu2~16.04).
Unfortunately I cannot reproduce the warns/errors (except two
warnings) from your compiler (even that the version looks
the same 7.1.0). So I fixed the warns/errors as per your response
to v9, and hope that the errors will disappear.
[1] https://patchwork.kernel.org/patch/9775803/
Stanimir Varbanov (18):
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
media: venus: hfi: fix mutex unlock
media: venus: hfi_cmds: fix variable dereferenced before check
media: venus: helpers: fix variable dereferenced before check
media: venus: hfi_venus: fix variable dereferenced before check
media: venus: hfi_msgs: fix set but not used variables
media: venus: vdec: fix compile error in vdec_close
media: venus: venc: fix compile error in venc_close
media: venus: vdec: add support for min buffers for capture
media: venus: enable building with COMPILE_TEST
.../devicetree/bindings/media/qcom,venus.txt | 107 ++
MAINTAINERS | 8 +
drivers/media/platform/Kconfig | 13 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/qcom/venus/Makefile | 11 +
drivers/media/platform/qcom/venus/core.c | 388 +++++
drivers/media/platform/qcom/venus/core.h | 323 ++++
drivers/media/platform/qcom/venus/firmware.c | 109 ++
drivers/media/platform/qcom/venus/firmware.h | 22 +
drivers/media/platform/qcom/venus/helpers.c | 725 +++++++++
drivers/media/platform/qcom/venus/helpers.h | 45 +
drivers/media/platform/qcom/venus/hfi.c | 522 +++++++
drivers/media/platform/qcom/venus/hfi.h | 175 +++
drivers/media/platform/qcom/venus/hfi_cmds.c | 1259 ++++++++++++++++
drivers/media/platform/qcom/venus/hfi_cmds.h | 304 ++++
drivers/media/platform/qcom/venus/hfi_helper.h | 1050 +++++++++++++
drivers/media/platform/qcom/venus/hfi_msgs.c | 1052 +++++++++++++
drivers/media/platform/qcom/venus/hfi_msgs.h | 283 ++++
drivers/media/platform/qcom/venus/hfi_venus.c | 1572 ++++++++++++++++++++
drivers/media/platform/qcom/venus/hfi_venus.h | 23 +
drivers/media/platform/qcom/venus/hfi_venus_io.h | 113 ++
drivers/media/platform/qcom/venus/vdec.c | 1162 +++++++++++++++
drivers/media/platform/qcom/venus/vdec.h | 23 +
drivers/media/platform/qcom/venus/vdec_ctrls.c | 158 ++
drivers/media/platform/qcom/venus/venc.c | 1283 ++++++++++++++++
drivers/media/platform/qcom/venus/venc.h | 23 +
drivers/media/platform/qcom/venus/venc_ctrls.c | 270 ++++
drivers/media/v4l2-core/v4l2-mem2mem.c | 37 +
include/media/v4l2-mem2mem.h | 92 ++
29 files changed, 11154 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/firmware.c
create mode 100644 drivers/media/platform/qcom/venus/firmware.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
Here is the output of v4l2-compliance for decoder (as in this version
of the patchset only decoder has functional changes):
dragonboard-410c:~$ ./v4l2-compliance -d /dev/video0
v4l2-compliance SHA : 8fc88615b49843acb82cd8316d0bc4ab8474cba2
Driver Info:
Driver name : qcom-venus
Card type : Qualcomm Venus video decoder
Bus info : platform:qcom-venus
Driver version: 4.9.27
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Compliance test for device /dev/video0 (not using libv4l2):
Required ioctls:
test VIDIOC_QUERYCAP: OK
Allow for multiple opens:
test second video open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 9 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test VIDIOC_EXPBUF: OK
Test input 0:
Total: 43, Succeeded: 43, Failed: 0, Warnings: 0
--
2.7.4
[toc] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:30 +0200 |
| Subject | [PATCH v10 01/18] media: v4l2-mem2mem: extend m2m APIs for more accurate buffer management |
| Message-ID | <tRAo2-4qP-23@gated-at.bofh.it> |
| In reply to | #1663877 |
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 | 92 ++++++++++++++++++++++++++++++++++
2 files changed, 129 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 6bc27e7b2a33..f62e68aa04c4 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_by_buf(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_by_buf);
+
+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..e157d5c9b224 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -437,6 +437,47 @@ 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
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#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
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#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
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#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
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#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 +529,57 @@ 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_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+ struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - 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
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+ v4l2_m2m_buf_remove_by_buf(&m2m_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - 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
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_dst_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
+{
+ v4l2_m2m_buf_remove_by_buf(&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 | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 12/18] media: venus: helpers: fix variable dereferenced before check |
| Message-ID | <tRAxI-4uO-15@gated-at.bofh.it> |
| In reply to | #1663877 |
This fixes a warning found when building the driver with gcc7:
drivers/media/platform/qcom/venus/helpers.c:157
load_per_instance() warn: variable dereferenced before check
'inst' (see line 153)
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/helpers.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index f777ef80b941..5f4434c0a8f1 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -150,14 +150,12 @@ static int intbufs_free(struct venus_inst *inst)
static u32 load_per_instance(struct venus_inst *inst)
{
- u32 w = inst->width;
- u32 h = inst->height;
u32 mbs;
if (!inst || !(inst->state >= INST_INIT && inst->state < INST_STOP))
return 0;
- mbs = (ALIGN(w, 16) / 16) * (ALIGN(h, 16) / 16);
+ mbs = (ALIGN(inst->width, 16) / 16) * (ALIGN(inst->height, 16) / 16);
return mbs * inst->fps;
}
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 16/18] media: venus: venc: fix compile error in venc_close |
| Message-ID | <tRAxI-4uO-17@gated-at.bofh.it> |
| In reply to | #1663877 |
This fixes the following compile error ocured when building with gcc7: drivers/media/platform/qcom/venus/venc.c:1150 venc_close() error: dereferencing freed memory 'inst' by moving kfree as a last call. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> --- drivers/media/platform/qcom/venus/venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index d5b4b5bf10a2..39748e7a08e4 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1145,10 +1145,10 @@ static int venc_close(struct file *file) mutex_destroy(&inst->lock); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); - kfree(inst); pm_runtime_put_sync(inst->core->dev_enc); + kfree(inst); return 0; } -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 03/18] MAINTAINERS: Add Qualcomm Venus video accelerator driver |
| Message-ID | <tRAxI-4uO-23@gated-at.bofh.it> |
| In reply to | #1663877 |
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 053c3bdd1fe5..2cf03bb969b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10584,6 +10584,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 | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 13/18] media: venus: hfi_venus: fix variable dereferenced before check |
| Message-ID | <tRAxJ-4uO-37@gated-at.bofh.it> |
| In reply to | #1663877 |
This fixes a warning found when building with gcc7:
drivers/media/platform/qcom/venus/hfi_venus.c:998
venus_isr_thread() warn: variable dereferenced before check
'hdev' (see line 994)
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/hfi_venus.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index ab209f3d9498..1caae8feaa36 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -991,13 +991,14 @@ static void venus_process_msg_sys_error(struct venus_hfi_device *hdev,
static irqreturn_t venus_isr_thread(struct venus_core *core)
{
struct venus_hfi_device *hdev = to_hfi_priv(core);
- const struct venus_resources *res = hdev->core->res;
+ const struct venus_resources *res;
void *pkt;
u32 msg_ret;
if (!hdev)
return IRQ_NONE;
+ res = hdev->core->res;
pkt = hdev->pkt_buf;
if (hdev->irq_status & WRAPPER_INTR_STATUS_A2HWD_MASK) {
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 11/18] media: venus: hfi_cmds: fix variable dereferenced before check |
| Message-ID | <tRAxJ-4uO-49@gated-at.bofh.it> |
| In reply to | #1663877 |
This fixes a warning found when building the driver with gcc7:
drivers/media/platform/qcom/venus/hfi_cmds.c:415
pkt_session_set_property_1x() warn: variable dereferenced before
check 'pkt' (see line 412)
drivers/media/platform/qcom/venus/hfi_cmds.c:1177
pkt_session_set_property_3xx() warn: variable dereferenced before
check 'pkt' (see line 1174)
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/hfi_cmds.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c
index dad41a6af42e..b83c5b8ddccb 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -409,12 +409,14 @@ static int pkt_session_get_property_1x(struct hfi_session_get_property_pkt *pkt,
static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
void *cookie, u32 ptype, void *pdata)
{
- void *prop_data = &pkt->data[1];
+ void *prop_data;
int ret = 0;
if (!pkt || !cookie || !pdata)
return -EINVAL;
+ prop_data = &pkt->data[1];
+
pkt->shdr.hdr.size = sizeof(*pkt);
pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
pkt->shdr.session_id = hash32_ptr(cookie);
@@ -1171,12 +1173,14 @@ static int
pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
void *cookie, u32 ptype, void *pdata)
{
- void *prop_data = &pkt->data[1];
+ void *prop_data;
int ret = 0;
if (!pkt || !cookie || !pdata)
return -EINVAL;
+ prop_data = &pkt->data[1];
+
pkt->shdr.hdr.size = sizeof(*pkt);
pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
pkt->shdr.session_id = hash32_ptr(cookie);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 17/18] media: venus: vdec: add support for min buffers for capture |
| Message-ID | <tRAxJ-4uO-43@gated-at.bofh.it> |
| In reply to | #1663877 |
This adds support for V4L2_CID_MIN_BUFFERS_FOR_CAPTURE get control
in venus decoder, it is usable in case when the userspace wants
to know minimum capture buffers before calling request_buf for
capture queue in mem2mem drivers. Also this will fix an issue
found gstreamer v4l2videodec element, i.e. the video decoder
element cannot continue because the buffers are insufficient.
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/vdec.c | 7 +++++++
drivers/media/platform/qcom/venus/vdec_ctrls.c | 10 +++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 594315b55b1f..eb0c1c51cfef 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -627,6 +627,12 @@ static int vdec_queue_setup(struct vb2_queue *q,
inst->out_height);
inst->input_buf_size = sizes[0];
inst->num_input_bufs = *num_buffers;
+
+ ret = vdec_cap_num_buffers(inst, &num);
+ if (ret)
+ break;
+
+ inst->num_output_bufs = num;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
*num_planes = inst->fmt_cap->num_planes;
@@ -951,6 +957,7 @@ static int vdec_open(struct file *file)
inst->core = core;
inst->session_type = VIDC_SESSION_TYPE_DEC;
+ inst->num_output_bufs = 1;
venus_helper_init_instance(inst);
diff --git a/drivers/media/platform/qcom/venus/vdec_ctrls.c b/drivers/media/platform/qcom/venus/vdec_ctrls.c
index 1045fc5b4925..032839bbc967 100644
--- a/drivers/media/platform/qcom/venus/vdec_ctrls.c
+++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c
@@ -70,6 +70,9 @@ static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
ctrl->val = ctr->post_loop_deb_mode;
break;
+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+ ctrl->val = inst->num_output_bufs;
+ break;
default:
return -EINVAL;
};
@@ -87,7 +90,7 @@ int vdec_ctrl_init(struct venus_inst *inst)
struct v4l2_ctrl *ctrl;
int ret;
- ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 6);
+ ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 7);
if (ret)
return ret;
@@ -135,6 +138,11 @@ int vdec_ctrl_init(struct venus_inst *inst)
v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 0, 1, 1, 0);
+ ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 1);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
ret = inst->ctrl_handler.error;
if (ret) {
v4l2_ctrl_handler_free(&inst->ctrl_handler);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 05/18] media: venus: vdec: add video decoder files |
| Message-ID | <tRAxJ-4uO-27@gated-at.bofh.it> |
| In reply to | #1663877 |
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 | 1154 ++++++++++++++++++++++++
drivers/media/platform/qcom/venus/vdec.h | 23 +
drivers/media/platform/qcom/venus/vdec_ctrls.c | 150 +++
3 files changed, 1327 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..96e7e7e71e5f
--- /dev/null
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017 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/clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.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 "hfi_venus_io.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;
+}
+
+/*
+ * Three resons to keep MPLANE formats (despite that the number of planes
+ * currently is one):
+ * - the MPLANE formats allow only one plane to be used
+ * - the downstream driver use MPLANE formats too
+ * - future firmware versions could add support for >1 planes
+ */
+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_VP9,
+ .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(unsigned int index, u32 type)
+{
+ const struct venus_format *fmt = vdec_formats;
+ unsigned int size = ARRAY_SIZE(vdec_formats);
+ unsigned int i, k = 0;
+
+ if (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_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 int
+vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
+{
+ if (cmd->cmd != V4L2_DEC_CMD_STOP)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int
+vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
+{
+ struct venus_inst *inst = to_inst(file);
+ int ret;
+
+ ret = vdec_try_decoder_cmd(file, fh, cmd);
+ if (ret)
+ return ret;
+
+ mutex_lock(&inst->lock);
+ inst->cmd_stop = true;
+ mutex_unlock(&inst->lock);
+
+ hfi_session_flush(inst);
+
+ return 0;
+}
+
+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_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,
+ .vidioc_try_decoder_cmd = vdec_try_decoder_cmd,
+ .vidioc_decoder_cmd = vdec_decoder_cmd,
+};
+
+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;
+
+ if (core->res->hfi_version == HFI_VERSION_1XX) {
+ 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 ||
+ inst->cap_bufs_mode_dynamic) {
+ 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 = venus_helper_set_input_resolution(inst, inst->out_width,
+ inst->out_height);
+ if (ret)
+ goto deinit;
+
+ ret = venus_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 hfi_buffer_requirements bufreq;
+ int ret;
+
+ ret = vdec_init_session(inst);
+ if (ret)
+ return ret;
+
+ ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
+
+ *num = bufreq.count_actual;
+
+ hfi_session_deinit(inst);
+
+ return ret;
+}
+
+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 = venus_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 = venus_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;
+ 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;
+ }
+
+ venus_helper_init_instance(inst);
+
+ inst->reconfig = false;
+ inst->sequence_cap = 0;
+ inst->sequence_out = 0;
+ inst->cmd_stop = false;
+
+ ret = vdec_init_session(inst);
+ if (ret)
+ goto bufs_done;
+
+ 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 = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
+ VB2_MAX_FRAME);
+ if (ret)
+ goto deinit_sess;
+
+ ret = venus_helper_vb2_start_streaming(inst);
+ if (ret)
+ goto deinit_sess;
+
+ mutex_unlock(&inst->lock);
+
+ return 0;
+
+deinit_sess:
+ hfi_session_deinit(inst);
+bufs_done:
+ venus_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 = venus_helper_vb2_buf_init,
+ .buf_prepare = venus_helper_vb2_buf_prepare,
+ .start_streaming = vdec_start_streaming,
+ .stop_streaming = venus_helper_vb2_stop_streaming,
+ .buf_queue = venus_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,
+ u32 hfi_flags, u64 timestamp_us)
+{
+ enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
+ 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 = venus_helper_find_buf(inst, type, tag);
+ if (!vbuf)
+ return;
+
+ vbuf->flags = flags;
+ vbuf->field = V4L2_FIELD_NONE;
+
+ 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_cap++;
+
+ if (inst->cmd_stop) {
+ vbuf->flags |= V4L2_BUF_FLAG_LAST;
+ inst->cmd_stop = false;
+ }
+
+ if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
+ const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
+
+ v4l2_event_queue_fh(&inst->fh, &ev);
+ }
+ } else {
+ vbuf->sequence = inst->sequence_out++;
+ }
+
+ if (hfi_flags & HFI_BUFFERFLAG_READONLY)
+ venus_helper_acquire_buf_ref(vbuf);
+
+ if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT)
+ state = VB2_BUF_STATE_ERROR;
+
+ v4l2_m2m_buf_done(vbuf, state);
+}
+
+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_dec;
+ 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;
+ case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
+ venus_helper_release_buf_ref(inst, data->tag);
+ 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;
+ if (inst->core->res->hfi_version == HFI_VERSION_3XX)
+ inst->cap_width.max = 3840;
+ inst->cap_width.step_size = 1;
+ inst->cap_height.min = 64;
+ inst->cap_height.max = ALIGN(1080, 32);
+ if (inst->core->res->hfi_version == HFI_VERSION_3XX)
+ inst->cap_height.max = ALIGN(2160, 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 = venus_helper_m2m_device_run,
+ .job_abort = venus_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;
+}
+
+static int vdec_open(struct file *file)
+{
+ struct venus_core *core = video_drvdata(file);
+ struct venus_inst *inst;
+ int ret;
+
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&inst->registeredbufs);
+ INIT_LIST_HEAD(&inst->internalbufs);
+ INIT_LIST_HEAD(&inst->list);
+ mutex_init(&inst->lock);
+
+ inst->core = core;
+ inst->session_type = VIDC_SESSION_TYPE_DEC;
+
+ venus_helper_init_instance(inst);
+
+ ret = pm_runtime_get_sync(core->dev_dec);
+ if (ret < 0)
+ goto err_free_inst;
+
+ ret = vdec_ctrl_init(inst);
+ if (ret)
+ goto err_put_sync;
+
+ 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;
+ }
+
+ v4l2_fh_init(&inst->fh, core->vdev_dec);
+
+ inst->fh.ctrl_handler = &inst->ctrl_handler;
+ v4l2_fh_add(&inst->fh);
+ inst->fh.m2m_ctx = inst->m2m_ctx;
+ file->private_data = &inst->fh;
+
+ 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);
+err_put_sync:
+ pm_runtime_put_sync(core->dev_dec);
+err_free_inst:
+ kfree(inst);
+ return ret;
+}
+
+static int vdec_close(struct file *file)
+{
+ struct venus_inst *inst = to_inst(file);
+
+ v4l2_m2m_ctx_release(inst->m2m_ctx);
+ v4l2_m2m_release(inst->m2m_dev);
+ vdec_ctrl_deinit(inst);
+ hfi_session_destroy(inst);
+ mutex_destroy(&inst->lock);
+ v4l2_fh_del(&inst->fh);
+ v4l2_fh_exit(&inst->fh);
+ kfree(inst);
+
+ pm_runtime_put_sync(inst->core->dev_dec);
+ return 0;
+}
+
+static const struct v4l2_file_operations vdec_fops = {
+ .owner = THIS_MODULE,
+ .open = vdec_open,
+ .release = vdec_close,
+ .unlocked_ioctl = video_ioctl2,
+ .poll = v4l2_m2m_fop_poll,
+ .mmap = v4l2_m2m_fop_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl32 = v4l2_compat_ioctl32,
+#endif
+};
+
+static int vdec_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct video_device *vdev;
+ struct venus_core *core;
+ int ret;
+
+ if (!dev->parent)
+ return -EPROBE_DEFER;
+
+ core = dev_get_drvdata(dev->parent);
+ if (!core)
+ return -EPROBE_DEFER;
+
+ if (core->res->hfi_version == HFI_VERSION_3XX) {
+ core->core0_clk = devm_clk_get(dev, "core");
+ if (IS_ERR(core->core0_clk))
+ return PTR_ERR(core->core0_clk);
+ }
+
+ platform_set_drvdata(pdev, core);
+
+ vdev = video_device_alloc();
+ if (!vdev)
+ return -ENOMEM;
+
+ vdev->release = video_device_release;
+ vdev->fops = &vdec_fops;
+ vdev->ioctl_ops = &vdec_ioctl_ops;
+ vdev->vfl_dir = VFL_DIR_M2M;
+ vdev->v4l2_dev = &core->v4l2_dev;
+ vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+ ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+ if (ret)
+ goto err_vdev_release;
+
+ core->vdev_dec = vdev;
+ core->dev_dec = dev;
+
+ video_set_drvdata(vdev, core);
+ pm_runtime_enable(dev);
+
+ return 0;
+
+err_vdev_release:
+ video_device_release(vdev);
+ return ret;
+}
+
+static int vdec_remove(struct platform_device *pdev)
+{
+ struct venus_core *core = dev_get_drvdata(pdev->dev.parent);
+
+ video_unregister_device(core->vdev_dec);
+ pm_runtime_disable(core->dev_dec);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int vdec_runtime_suspend(struct device *dev)
+{
+ struct venus_core *core = dev_get_drvdata(dev);
+
+ if (core->res->hfi_version == HFI_VERSION_1XX)
+ return 0;
+
+ writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+ clk_disable_unprepare(core->core0_clk);
+ writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+
+ return 0;
+}
+
+static int vdec_runtime_resume(struct device *dev)
+{
+ struct venus_core *core = dev_get_drvdata(dev);
+ int ret;
+
+ if (core->res->hfi_version == HFI_VERSION_1XX)
+ return 0;
+
+ writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+ ret = clk_prepare_enable(core->core0_clk);
+ writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+
+ return ret;
+}
+#endif
+
+static const struct dev_pm_ops vdec_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(vdec_runtime_suspend, vdec_runtime_resume, NULL)
+};
+
+static const struct of_device_id vdec_dt_match[] = {
+ { .compatible = "venus-decoder" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, vdec_dt_match);
+
+static struct platform_driver qcom_venus_dec_driver = {
+ .probe = vdec_probe,
+ .remove = vdec_remove,
+ .driver = {
+ .name = "qcom-venus-decoder",
+ .of_match_table = vdec_dt_match,
+ .pm = &vdec_pm_ops,
+ },
+};
+module_platform_driver(qcom_venus_dec_driver);
+
+MODULE_ALIAS("platform:qcom-venus-decoder");
+MODULE_DESCRIPTION("Qualcomm Venus video decoder driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/qcom/venus/vdec.h b/drivers/media/platform/qcom/venus/vdec.h
new file mode 100644
index 000000000000..84b672c54d02
--- /dev/null
+++ b/drivers/media/platform/qcom/venus/vdec.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017 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_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..1045fc5b4925
--- /dev/null
+++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017 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"
+#include "vdec.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 | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 10/18] media: venus: hfi: fix mutex unlock |
| Message-ID | <tRAxK-4uO-55@gated-at.bofh.it> |
| In reply to | #1663877 |
This fixed a warning when build driver with gcc7:
drivers/media/platform/qcom/venus/hfi.c:171
hfi_core_ping() warn: inconsistent returns 'mutex:&core->lock'.
Locked on: line 159
Unlocked on: line 171
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/hfi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
index 20c9205fdbb4..c09490876516 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -156,7 +156,7 @@ int hfi_core_ping(struct venus_core *core)
ret = core->ops->core_ping(core, 0xbeef);
if (ret)
- return ret;
+ goto unlock;
ret = wait_for_completion_timeout(&core->done, TIMEOUT);
if (!ret) {
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 18/18] media: venus: enable building with COMPILE_TEST |
| Message-ID | <tRAxK-4uO-61@gated-at.bofh.it> |
| In reply to | #1663877 |
We want all media drivers to build with COMPILE_TEST, as the Coverity instance we use on Kernel works only for x86. Also, our test workflow relies on it, in order to identify git bisect breakages. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> --- drivers/media/platform/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 017e42ce0ff9..0898f63fa451 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -467,7 +467,7 @@ config VIDEO_TI_VPE_DEBUG config VIDEO_QCOM_VENUS tristate "Qualcomm Venus V4L2 encoder/decoder driver" depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA - depends on ARCH_QCOM && IOMMU_DMA + depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST select QCOM_MDT_LOADER select VIDEOBUF2_DMA_SG select V4L2_MEM2MEM_DEV -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 09/18] media: venus: enable building of Venus video driver |
| Message-ID | <tRAxK-4uO-57@gated-at.bofh.it> |
| In reply to | #1663877 |
This adds Venus driver Makefile and changes v4l2 platform Makefile/Kconfig in order to enable building of the driver. Note that in this initial version the COMPILE_TEST-ing is not supported because the drivers specific to ARM builds are still in process of enabling the aforementioned compile testing. Once that disadvantage is fixed the Venus driver compile testing will be possible with follow-up changes. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> --- drivers/media/platform/Kconfig | 13 +++++++++++++ drivers/media/platform/Makefile | 2 ++ drivers/media/platform/qcom/venus/Makefile | 11 +++++++++++ 3 files changed, 26 insertions(+) create mode 100644 drivers/media/platform/qcom/venus/Makefile diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 288d3b0dc812..017e42ce0ff9 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -464,6 +464,19 @@ config VIDEO_TI_VPE_DEBUG ---help--- Enable debug messages on VPE driver. +config VIDEO_QCOM_VENUS + tristate "Qualcomm Venus V4L2 encoder/decoder driver" + depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA + depends on ARCH_QCOM && IOMMU_DMA + select QCOM_MDT_LOADER + select VIDEOBUF2_DMA_SG + select V4L2_MEM2MEM_DEV + ---help--- + This is a V4L2 driver for Qualcomm Venus video accelerator + hardware. It accelerates encoding and decoding operations + on various Qualcomm SoCs. + To compile this driver as a module choose m here. + endif # V4L_MEM2MEM_DRIVERS # TI VIDEO PORT Helper Modules diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index c3588d570f5d..37053723fb03 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -79,3 +79,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/ obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/ obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk-jpeg/ + +obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ diff --git a/drivers/media/platform/qcom/venus/Makefile b/drivers/media/platform/qcom/venus/Makefile new file mode 100644 index 000000000000..0fe9afb83697 --- /dev/null +++ b/drivers/media/platform/qcom/venus/Makefile @@ -0,0 +1,11 @@ +# Makefile for Qualcomm Venus driver + +venus-core-objs += core.o helpers.o firmware.o \ + hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o + +venus-dec-objs += vdec.o vdec_ctrls.o +venus-enc-objs += venc.o venc_ctrls.o + +obj-$(CONFIG_VIDEO_QCOM_VENUS) += venus-core.o +obj-$(CONFIG_VIDEO_QCOM_VENUS) += venus-dec.o +obj-$(CONFIG_VIDEO_QCOM_VENUS) += venus-enc.o -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 02/18] doc: DT: venus: binding document for Qualcomm video driver |
| Message-ID | <tRAxK-4uO-63@gated-at.bofh.it> |
| In reply to | #1663877 |
Add binding document for Venus video encoder/decoder driver
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
.../devicetree/bindings/media/qcom,venus.txt | 107 +++++++++++++++++++++
1 file changed, 107 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..2693449daf73
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,venus.txt
@@ -0,0 +1,107 @@
+* Qualcomm Venus video encoder/decoder accelerators
+
+- 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 base address and length of the register map.
+- interrupts:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Should contain interrupt line number.
+- 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 for msm8916
+ 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:
+ - "core" Core video accelerator clock
+ - "iface" Video accelerator AHB clock
+ - "bus" Video accelerator AXI clock
+ - "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.
+- iommus:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A list of phandle and IOMMU specifier pairs.
+- memory-region:
+ Usage: required
+ Value type: <phandle>
+ Definition: reference to the reserved-memory for the firmware
+ memory region.
+
+* Subnodes
+The Venus video-codec node must contain two subnodes representing
+video-decoder and video-encoder.
+
+Every of video-encoder or video-decoder subnode should have:
+
+- compatible:
+ Usage: required
+ Value type: <stringlist>
+ Definition: Value should contain "venus-decoder" or "venus-encoder"
+- clocks:
+ Usage: required for msm8996
+ Value type: <prop-encoded-array>
+ Definition: A List of phandle and clock specifier pairs as listed
+ in clock-names property.
+- clock-names:
+ Usage: required for msm8996
+ Value type: <stringlist>
+ Definition: Should contain the following entries:
+ - "core" Subcore video accelerator clock
+
+- power-domains:
+ Usage: required for msm8996
+ 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 subcore.
+
+* An Example
+ video-codec@1d00000 {
+ compatible = "qcom,msm8916-venus";
+ reg = <0x01d00000 0xff000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ 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>;
+ iommus = <&apps_iommu 5>;
+ memory-region = <&venus_mem>;
+
+ video-decoder {
+ compatible = "venus-decoder";
+ clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
+ clock-names = "core";
+ power-domains = <&mmcc VENUS_CORE0_GDSC>;
+ };
+
+ video-encoder {
+ compatible = "venus-encoder";
+ clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
+ clock-names = "core";
+ power-domains = <&mmcc VENUS_CORE1_GDSC>;
+ };
+ };
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 15/18] media: venus: vdec: fix compile error in vdec_close |
| Message-ID | <tRAxK-4uO-65@gated-at.bofh.it> |
| In reply to | #1663877 |
This fixes the following compile error ocured when building with gcc7: drivers/media/platform/qcom/venus/vdec.c:1022 vdec_close() error: dereferencing freed memory 'inst' by moving kfree as a last call. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> --- drivers/media/platform/qcom/venus/vdec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 96e7e7e71e5f..594315b55b1f 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1017,9 +1017,10 @@ static int vdec_close(struct file *file) mutex_destroy(&inst->lock); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); - kfree(inst); pm_runtime_put_sync(inst->core->dev_dec); + + kfree(inst); return 0; } -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <stanimir.varbanov@linaro.org> |
|---|---|
| Date | 2017-06-12 18:40 +0200 |
| Subject | [PATCH v10 14/18] media: venus: hfi_msgs: fix set but not used variables |
| Message-ID | <tRAxK-4uO-71@gated-at.bofh.it> |
| In reply to | #1663877 |
This fixes a warning found when building with gcc7:
drivers/media/platform/qcom/venus/hfi_msgs.c:465:40:
warning: variable 'domain' set but not used [-Wunused-but-set-variable]
u32 rem_bytes, num_props, codecs = 0, domain = 0;
^~~~~~
drivers/media/platform/qcom/venus/hfi_msgs.c:465:28:
warning: variable 'codecs' set but not used [-Wunused-but-set-variable]
u32 rem_bytes, num_props, codecs = 0, domain = 0;
The warning is avoided by deleting the variables declaration.
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/hfi_msgs.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 88898118f6af..f8841713e417 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -462,7 +462,7 @@ static u32 init_done_read_prop(struct venus_core *core, struct venus_inst *inst,
struct hfi_msg_session_init_done_pkt *pkt)
{
struct device *dev = core->dev;
- u32 rem_bytes, num_props, codecs = 0, domain = 0;
+ u32 rem_bytes, num_props;
u32 ptype, next_offset = 0;
u32 err;
u8 *data;
@@ -490,8 +490,6 @@ static u32 init_done_read_prop(struct venus_core *core, struct venus_inst *inst,
(struct hfi_codec_mask_supported *)
(data + next_offset);
- codecs = masks->codecs;
- domain = masks->video_domains;
next_offset += sizeof(*masks);
num_props--;
break;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stanimir Varbanov <svarbanov@mm-sol.com> |
|---|---|
| Date | 2017-06-14 14:30 +0200 |
| Message-ID | <tSfAT-57e-31@gated-at.bofh.it> |
| In reply to | #1663877 |
Hi Mauro, One note, I have sent pull request for the firmware but forgot to update the firmware path in the driver for the new location. It is not a big deal, but I have to send one more patch which changes the firmware path. About COMPILE_TEST, the patch for qcom_scm driver probably will be taken in 4.13 merge window through arm-soc. So I'm wondering could you postpone 18/18 until this patch is merged to avoid build breakage. regards, Stan On 06/12/2017 07:27 PM, Stanimir Varbanov wrote: > Hello, > > The changes since patchset v9 are the following: > * patches from 1/18 to 9/18 are the same. > * patches from 10/18 to 16/18 are fixes for warns/errors found by > Mauro when building with its gcc7. > * patch 17/18 adding support for minimum buffers for capture > get control. This fixes an issue with gstreamer and it will > be good to have it in the inital version of the venus driver. > * patch 18/18 enable COMPILE_TEST Kconfig option for the driver, > and this patch depends on the other one for qcom_scm driver. > The submited patch for qcom_scm driver can be found at [1]. > > Mauro, I failed to build gcc7 on my own machine and fallback to > a pre-built version of the gcc-7 for may Ubuntu distro. The version > which I tried was: gcc version 7.1.0 (Ubuntu 7.1.0-5ubuntu2~16.04). > Unfortunately I cannot reproduce the warns/errors (except two > warnings) from your compiler (even that the version looks > the same 7.1.0). So I fixed the warns/errors as per your response > to v9, and hope that the errors will disappear. > > [1] https://patchwork.kernel.org/patch/9775803/ > > Stanimir Varbanov (18): > 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 > media: venus: hfi: fix mutex unlock > media: venus: hfi_cmds: fix variable dereferenced before check > media: venus: helpers: fix variable dereferenced before check > media: venus: hfi_venus: fix variable dereferenced before check > media: venus: hfi_msgs: fix set but not used variables > media: venus: vdec: fix compile error in vdec_close > media: venus: venc: fix compile error in venc_close > media: venus: vdec: add support for min buffers for capture > media: venus: enable building with COMPILE_TEST > > .../devicetree/bindings/media/qcom,venus.txt | 107 ++ > MAINTAINERS | 8 + > drivers/media/platform/Kconfig | 13 + > drivers/media/platform/Makefile | 2 + > drivers/media/platform/qcom/venus/Makefile | 11 + > drivers/media/platform/qcom/venus/core.c | 388 +++++ > drivers/media/platform/qcom/venus/core.h | 323 ++++ > drivers/media/platform/qcom/venus/firmware.c | 109 ++ > drivers/media/platform/qcom/venus/firmware.h | 22 + > drivers/media/platform/qcom/venus/helpers.c | 725 +++++++++ > drivers/media/platform/qcom/venus/helpers.h | 45 + > drivers/media/platform/qcom/venus/hfi.c | 522 +++++++ > drivers/media/platform/qcom/venus/hfi.h | 175 +++ > drivers/media/platform/qcom/venus/hfi_cmds.c | 1259 ++++++++++++++++ > drivers/media/platform/qcom/venus/hfi_cmds.h | 304 ++++ > drivers/media/platform/qcom/venus/hfi_helper.h | 1050 +++++++++++++ > drivers/media/platform/qcom/venus/hfi_msgs.c | 1052 +++++++++++++ > drivers/media/platform/qcom/venus/hfi_msgs.h | 283 ++++ > drivers/media/platform/qcom/venus/hfi_venus.c | 1572 ++++++++++++++++++++ > drivers/media/platform/qcom/venus/hfi_venus.h | 23 + > drivers/media/platform/qcom/venus/hfi_venus_io.h | 113 ++ > drivers/media/platform/qcom/venus/vdec.c | 1162 +++++++++++++++ > drivers/media/platform/qcom/venus/vdec.h | 23 + > drivers/media/platform/qcom/venus/vdec_ctrls.c | 158 ++ > drivers/media/platform/qcom/venus/venc.c | 1283 ++++++++++++++++ > drivers/media/platform/qcom/venus/venc.h | 23 + > drivers/media/platform/qcom/venus/venc_ctrls.c | 270 ++++ > drivers/media/v4l2-core/v4l2-mem2mem.c | 37 + > include/media/v4l2-mem2mem.h | 92 ++ > 29 files changed, 11154 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/firmware.c > create mode 100644 drivers/media/platform/qcom/venus/firmware.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 > > Here is the output of v4l2-compliance for decoder (as in this version > of the patchset only decoder has functional changes): > > dragonboard-410c:~$ ./v4l2-compliance -d /dev/video0 > v4l2-compliance SHA : 8fc88615b49843acb82cd8316d0bc4ab8474cba2 > > Driver Info: > Driver name : qcom-venus > Card type : Qualcomm Venus video decoder > Bus info : platform:qcom-venus > Driver version: 4.9.27 > Capabilities : 0x84204000 > Video Memory-to-Memory Multiplanar > Streaming > Extended Pix Format > Device Capabilities > Device Caps : 0x04204000 > Video Memory-to-Memory Multiplanar > Streaming > Extended Pix Format > > Compliance test for device /dev/video0 (not using libv4l2): > > Required ioctls: > test VIDIOC_QUERYCAP: OK > > Allow for multiple opens: > test second video open: OK > test VIDIOC_QUERYCAP: OK > test VIDIOC_G/S_PRIORITY: OK > test for unlimited opens: OK > > Debug ioctls: > test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported) > test VIDIOC_LOG_STATUS: OK (Not Supported) > > Input ioctls: > test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported) > test VIDIOC_G/S_FREQUENCY: OK (Not Supported) > test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported) > test VIDIOC_ENUMAUDIO: OK (Not Supported) > test VIDIOC_G/S/ENUMINPUT: OK (Not Supported) > test VIDIOC_G/S_AUDIO: OK (Not Supported) > Inputs: 0 Audio Inputs: 0 Tuners: 0 > > Output ioctls: > test VIDIOC_G/S_MODULATOR: OK (Not Supported) > test VIDIOC_G/S_FREQUENCY: OK (Not Supported) > test VIDIOC_ENUMAUDOUT: OK (Not Supported) > test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported) > test VIDIOC_G/S_AUDOUT: OK (Not Supported) > Outputs: 0 Audio Outputs: 0 Modulators: 0 > > Input/Output configuration ioctls: > test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported) > test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported) > test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported) > test VIDIOC_G/S_EDID: OK (Not Supported) > > Control ioctls: > test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK > test VIDIOC_QUERYCTRL: OK > test VIDIOC_G/S_CTRL: OK > test VIDIOC_G/S/TRY_EXT_CTRLS: OK > test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK > test VIDIOC_G/S_JPEGCOMP: OK (Not Supported) > Standard Controls: 9 Private Controls: 0 > > Format ioctls: > test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK > test VIDIOC_G/S_PARM: OK (Not Supported) > test VIDIOC_G_FBUF: OK (Not Supported) > test VIDIOC_G_FMT: OK > test VIDIOC_TRY_FMT: OK > test VIDIOC_S_FMT: OK > test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported) > test Cropping: OK (Not Supported) > test Composing: OK (Not Supported) > test Scaling: OK > > Codec ioctls: > test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported) > test VIDIOC_G_ENC_INDEX: OK (Not Supported) > test VIDIOC_(TRY_)DECODER_CMD: OK > > Buffer ioctls: > test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK > test VIDIOC_EXPBUF: OK > > Test input 0: > > > Total: 43, Succeeded: 43, Failed: 0, Warnings: 0 >
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web