linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] Venus Codec API addition and few fixes
@ 2020-04-08 21:33 Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 1/7] venus: core: Add missing mutex destroy Stanimir Varbanov
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

Hello,

Here are few fixes found during testing and one new addition
related to decoder dynamic-resolution-change Codec API requirement.

Please comment.

Stanimir Varbanov (7):
  venus: core: Add missing mutex destroy
  venus: core: Fix mutex destroy in remove
  venus: core: Constify codec frequency data array
  venus: helpers: Done buffers per queue type
  venus: vdec: Mark flushed buffers with error state
  venus: vdec: Init registered list unconditionally
  venus: Mark last capture buffer

 drivers/media/platform/qcom/venus/core.c     |  6 +-
 drivers/media/platform/qcom/venus/core.h     |  5 +-
 drivers/media/platform/qcom/venus/helpers.c  | 18 ++++--
 drivers/media/platform/qcom/venus/helpers.h  |  2 +-
 drivers/media/platform/qcom/venus/hfi.c      | 10 ++--
 drivers/media/platform/qcom/venus/hfi.h      |  3 +-
 drivers/media/platform/qcom/venus/hfi_msgs.c |  2 +
 drivers/media/platform/qcom/venus/vdec.c     | 58 ++++++++++++++++----
 drivers/media/platform/qcom/venus/venc.c     |  2 +-
 9 files changed, 80 insertions(+), 26 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/7] venus: core: Add missing mutex destroy
  2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
@ 2020-04-08 21:33 ` Stanimir Varbanov
  2020-04-09 21:47   ` Matthias Kaehlcke
  2020-04-08 21:33 ` [PATCH 2/7] venus: core: Fix mutex destroy in remove Stanimir Varbanov
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

This adds missing mutex_destroy in remove method of venus core driver.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 4395cb96fb04..f8b9a732bc65 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -335,6 +335,7 @@ static int venus_remove(struct platform_device *pdev)
 
 	v4l2_device_unregister(&core->v4l2_dev);
 	mutex_destroy(&core->pm_lock);
+	mutex_destroy(&core->lock);
 
 	return ret;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/7] venus: core: Fix mutex destroy in remove
  2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 1/7] venus: core: Add missing mutex destroy Stanimir Varbanov
@ 2020-04-08 21:33 ` Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 3/7] venus: core: Constify codec frequency data array Stanimir Varbanov
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

The hfi_destroy function is called too early in remove method. It
destroys a mutex which is used later in the .remove from pmruntime.
Solve the issue by moving hfi_destroy after last usage of the mutex.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index f8b9a732bc65..afd76bcd9978 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -318,7 +318,6 @@ static int venus_remove(struct platform_device *pdev)
 	ret = hfi_core_deinit(core, true);
 	WARN_ON(ret);
 
-	hfi_destroy(core);
 	venus_shutdown(core);
 	of_platform_depopulate(dev);
 
@@ -330,6 +329,8 @@ static int venus_remove(struct platform_device *pdev)
 	if (pm_ops->core_put)
 		pm_ops->core_put(dev);
 
+	hfi_destroy(core);
+
 	icc_put(core->video_path);
 	icc_put(core->cpucfg_path);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/7] venus: core: Constify codec frequency data array
  2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 1/7] venus: core: Add missing mutex destroy Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 2/7] venus: core: Fix mutex destroy in remove Stanimir Varbanov
@ 2020-04-08 21:33 ` Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 4/7] venus: helpers: Done buffers per queue type Stanimir Varbanov
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

The array is not changed in the code, so make it const.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index afd76bcd9978..203c6538044f 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -456,7 +456,7 @@ static const struct freq_tbl sdm845_freq_table[] = {
 	{  244800, 100000000 },	/* 1920x1080@30 */
 };
 
-static struct codec_freq_data sdm845_codec_freq_data[] =  {
+static const struct codec_freq_data sdm845_codec_freq_data[] =  {
 	{ V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 },
 	{ V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 },
 	{ V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 },
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/7] venus: helpers: Done buffers per queue type
  2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
                   ` (2 preceding siblings ...)
  2020-04-08 21:33 ` [PATCH 3/7] venus: core: Constify codec frequency data array Stanimir Varbanov
@ 2020-04-08 21:33 ` Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 5/7] venus: vdec: Mark flushed buffers with error state Stanimir Varbanov
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

Currently calling venus_helper_buffers_done() will return buffers to
user for both capture and output queues in the same call. This is
wrong because both queues are really separate and calling
stop_streaming on one queue shouldn't return buffers for the other.
Solve this by add a new queue type argument and fix the clients of
the helper function.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 18 ++++++++++++------
 drivers/media/platform/qcom/venus/helpers.h |  2 +-
 drivers/media/platform/qcom/venus/vdec.c    |  5 ++---
 drivers/media/platform/qcom/venus/venc.c    |  2 +-
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index bcc603804041..0143af7822b2 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -1129,15 +1129,18 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
 }
 EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_queue);
 
-void venus_helper_buffers_done(struct venus_inst *inst,
+void venus_helper_buffers_done(struct venus_inst *inst, unsigned int type,
 			       enum vb2_buffer_state state)
 {
 	struct vb2_v4l2_buffer *buf;
 
-	while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
-		v4l2_m2m_buf_done(buf, state);
-	while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
-		v4l2_m2m_buf_done(buf, state);
+	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	}
 }
 EXPORT_SYMBOL_GPL(venus_helper_buffers_done);
 
@@ -1168,7 +1171,10 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q)
 		INIT_LIST_HEAD(&inst->registeredbufs);
 	}
 
-	venus_helper_buffers_done(inst, VB2_BUF_STATE_ERROR);
+	venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+				  VB2_BUF_STATE_ERROR);
+	venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+				  VB2_BUF_STATE_ERROR);
 
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 		inst->streamon_out = 0;
diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h
index b64875564064..8fbbda12a4fe 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -14,7 +14,7 @@ struct venus_core;
 bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt);
 struct vb2_v4l2_buffer *venus_helper_find_buf(struct venus_inst *inst,
 					      unsigned int type, u32 idx);
-void venus_helper_buffers_done(struct venus_inst *inst,
+void venus_helper_buffers_done(struct venus_inst *inst, unsigned int type,
 			       enum vb2_buffer_state state);
 int venus_helper_vb2_buf_init(struct vb2_buffer *vb);
 int venus_helper_vb2_buf_prepare(struct vb2_buffer *vb);
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index e8e1ecf7cf4a..7d093accbd59 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1044,7 +1044,7 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 put_power:
 	vdec_pm_put(inst, false);
 error:
-	venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
+	venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED);
 	mutex_unlock(&inst->lock);
 	return ret;
 }
@@ -1071,7 +1071,6 @@ static int vdec_stop_capture(struct venus_inst *inst)
 		break;
 	case VENUS_DEC_STATE_DRC:
 		ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT);
-		vdec_cancel_dst_buffers(inst);
 		inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
 		INIT_LIST_HEAD(&inst->registeredbufs);
 		venus_helper_free_dpb_bufs(inst);
@@ -1117,7 +1116,7 @@ static void vdec_stop_streaming(struct vb2_queue *q)
 	else
 		ret = vdec_stop_output(inst);
 
-	venus_helper_buffers_done(inst, VB2_BUF_STATE_ERROR);
+	venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR);
 
 	if (ret)
 		goto unlock;
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index 9981a2a27c90..3d8431dc14c4 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -1018,7 +1018,7 @@ static int venc_start_streaming(struct vb2_queue *q, unsigned int count)
 deinit_sess:
 	hfi_session_deinit(inst);
 bufs_done:
-	venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
+	venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED);
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 		inst->streamon_out = 0;
 	else
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/7] venus: vdec: Mark flushed buffers with error state
  2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
                   ` (3 preceding siblings ...)
  2020-04-08 21:33 ` [PATCH 4/7] venus: helpers: Done buffers per queue type Stanimir Varbanov
@ 2020-04-08 21:33 ` Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 6/7] venus: vdec: Init registered list unconditionally Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 7/7] venus: Mark last capture buffer Stanimir Varbanov
  6 siblings, 0 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

Once the hfi_session_flush is issued by the vdec all queued
buffers to firmware should be returned to the v4l driver. Some
of those buffers are not processed at the time of flush command,
those buffers has filled len zero (no data). Catch that in
buffer_done callback and mark not filled capture buffers with
error state so that client can discard them.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 7d093accbd59..5823537b3131 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1241,6 +1241,9 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
 			if (inst->codec_state == VENUS_DEC_STATE_DRAIN)
 				inst->codec_state = VENUS_DEC_STATE_STOPPED;
 		}
+
+		if (!bytesused)
+			state = VB2_BUF_STATE_ERROR;
 	} else {
 		vbuf->sequence = inst->sequence_out++;
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/7] venus: vdec: Init registered list unconditionally
  2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
                   ` (4 preceding siblings ...)
  2020-04-08 21:33 ` [PATCH 5/7] venus: vdec: Mark flushed buffers with error state Stanimir Varbanov
@ 2020-04-08 21:33 ` Stanimir Varbanov
  2020-04-08 21:33 ` [PATCH 7/7] venus: Mark last capture buffer Stanimir Varbanov
  6 siblings, 0 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

Presently the list initialization is done only in
dynamic-resolution-change state, which leads to list corruptions
and use-after-free. Init list_head unconditionally in
vdec_stop_capture called by vb2 stop_streaming without takeing
into account current codec state.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 5823537b3131..f23cbd812ef4 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1072,13 +1072,14 @@ static int vdec_stop_capture(struct venus_inst *inst)
 	case VENUS_DEC_STATE_DRC:
 		ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT);
 		inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
-		INIT_LIST_HEAD(&inst->registeredbufs);
 		venus_helper_free_dpb_bufs(inst);
 		break;
 	default:
-		return 0;
+		break;
 	}
 
+	INIT_LIST_HEAD(&inst->registeredbufs);
+
 	return ret;
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/7] venus: Mark last capture buffer
  2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
                   ` (5 preceding siblings ...)
  2020-04-08 21:33 ` [PATCH 6/7] venus: vdec: Init registered list unconditionally Stanimir Varbanov
@ 2020-04-08 21:33 ` Stanimir Varbanov
  6 siblings, 0 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-08 21:33 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel
  Cc: Vikash Garodia, Stanimir Varbanov

According to stateful Codec API the decoder will process all
remaining buffers from before the source change event in
dynamic-resolution-change state and mark the last buffer with
V4L2_BUF_FLAG_LAST.

In Venus case the firmware doesn't mark that last buffer and
some mechanism have to be created in v4l decoder driver.
Fortunately the firmware interface (HFI) claims that the
decoder output buffers will be returned to v4l decoder
driver before it send the insufficient event.

In order to do that we save last queued in the driver capture
buffer in the event_notify and issue flush on output firmware
buffers queue. Once the saved buffer is returned (as a result of
flush command) we mark it as LAST. For all that possible we
extend HFI flush command with one more argument and one more
flush_done HFI driver callback.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h     |  5 ++-
 drivers/media/platform/qcom/venus/hfi.c      | 10 +++--
 drivers/media/platform/qcom/venus/hfi.h      |  3 +-
 drivers/media/platform/qcom/venus/hfi_msgs.c |  2 +
 drivers/media/platform/qcom/venus/vdec.c     | 45 +++++++++++++++++---
 5 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 3ab644a39786..7118612673c9 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -261,7 +261,8 @@ enum venus_dec_state {
 	VENUS_DEC_STATE_SEEK		= 4,
 	VENUS_DEC_STATE_DRAIN		= 5,
 	VENUS_DEC_STATE_DECODING	= 6,
-	VENUS_DEC_STATE_DRC		= 7
+	VENUS_DEC_STATE_DRC		= 7,
+	VENUS_DEC_STATE_DRC_FLUSH_DONE	= 8,
 };
 
 struct venus_ts_metadata {
@@ -326,6 +327,7 @@ struct venus_ts_metadata {
  * @priv:	a private for HFI operations callbacks
  * @session_type:	the type of the session (decoder or encoder)
  * @hprop:	a union used as a holder by get property
+ * @last_buf:	last capture buffer for dynamic-resoluton-change
  */
 struct venus_inst {
 	struct list_head list;
@@ -387,6 +389,7 @@ struct venus_inst {
 	union hfi_get_property hprop;
 	unsigned int core_acquired: 1;
 	unsigned int bit_depth;
+	struct vb2_buffer *last_buf;
 };
 
 #define IS_V1(core)	((core)->res->hfi_version == HFI_VERSION_1XX)
diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
index 3d8b1284d1f3..a211eb93e0f9 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -382,7 +382,7 @@ int hfi_session_unload_res(struct venus_inst *inst)
 }
 EXPORT_SYMBOL_GPL(hfi_session_unload_res);
 
-int hfi_session_flush(struct venus_inst *inst, u32 type)
+int hfi_session_flush(struct venus_inst *inst, u32 type, bool block)
 {
 	const struct hfi_ops *ops = inst->core->ops;
 	int ret;
@@ -393,9 +393,11 @@ int hfi_session_flush(struct venus_inst *inst, u32 type)
 	if (ret)
 		return ret;
 
-	ret = wait_session_msg(inst);
-	if (ret)
-		return ret;
+	if (block) {
+		ret = wait_session_msg(inst);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
diff --git a/drivers/media/platform/qcom/venus/hfi.h b/drivers/media/platform/qcom/venus/hfi.h
index 855822c9f39b..62c315291484 100644
--- a/drivers/media/platform/qcom/venus/hfi.h
+++ b/drivers/media/platform/qcom/venus/hfi.h
@@ -102,6 +102,7 @@ struct hfi_inst_ops {
 			 u32 hfi_flags, u64 timestamp_us);
 	void (*event_notify)(struct venus_inst *inst, u32 event,
 			     struct hfi_event_data *data);
+	void (*flush_done)(struct venus_inst *inst);
 };
 
 struct hfi_ops {
@@ -161,7 +162,7 @@ int hfi_session_continue(struct venus_inst *inst);
 int hfi_session_abort(struct venus_inst *inst);
 int hfi_session_load_res(struct venus_inst *inst);
 int hfi_session_unload_res(struct venus_inst *inst);
-int hfi_session_flush(struct venus_inst *inst, u32 type);
+int hfi_session_flush(struct venus_inst *inst, u32 type, bool block);
 int hfi_session_set_buffers(struct venus_inst *inst,
 			    struct hfi_buffer_desc *bd);
 int hfi_session_unset_buffers(struct venus_inst *inst,
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 04ef2286efc6..279a9d6fe737 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -439,6 +439,8 @@ static void hfi_session_flush_done(struct venus_core *core,
 
 	inst->error = pkt->error_type;
 	complete(&inst->done);
+	if (inst->ops->flush_done)
+		inst->ops->flush_done(inst);
 }
 
 static void hfi_session_etb_done(struct venus_core *core,
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index f23cbd812ef4..527944c822b5 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -906,7 +906,7 @@ static int vdec_start_capture(struct venus_inst *inst)
 		return 0;
 
 reconfigure:
-	ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT);
+	ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true);
 	if (ret)
 		return ret;
 
@@ -1063,14 +1063,16 @@ static int vdec_stop_capture(struct venus_inst *inst)
 
 	switch (inst->codec_state) {
 	case VENUS_DEC_STATE_DECODING:
-		ret = hfi_session_flush(inst, HFI_FLUSH_ALL);
+		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
 		/* fallthrough */
 	case VENUS_DEC_STATE_DRAIN:
 		vdec_cancel_dst_buffers(inst);
 		inst->codec_state = VENUS_DEC_STATE_STOPPED;
 		break;
 	case VENUS_DEC_STATE_DRC:
-		ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT);
+		WARN_ON(1);
+		fallthrough;
+	case VENUS_DEC_STATE_DRC_FLUSH_DONE:
 		inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
 		venus_helper_free_dpb_bufs(inst);
 		break;
@@ -1091,12 +1093,12 @@ static int vdec_stop_output(struct venus_inst *inst)
 	case VENUS_DEC_STATE_DECODING:
 	case VENUS_DEC_STATE_DRAIN:
 	case VENUS_DEC_STATE_STOPPED:
-		ret = hfi_session_flush(inst, HFI_FLUSH_ALL);
+		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
 		inst->codec_state = VENUS_DEC_STATE_SEEK;
 		break;
 	case VENUS_DEC_STATE_INIT:
 	case VENUS_DEC_STATE_CAPTURE_SETUP:
-		ret = hfi_session_flush(inst, HFI_FLUSH_INPUT);
+		ret = hfi_session_flush(inst, HFI_FLUSH_INPUT, true);
 		break;
 	default:
 		break;
@@ -1234,6 +1236,13 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
 		vb->timestamp = timestamp_us * NSEC_PER_USEC;
 		vbuf->sequence = inst->sequence_cap++;
 
+		if (inst->last_buf == vb) {
+			inst->last_buf = NULL;
+			vbuf->flags |= V4L2_BUF_FLAG_LAST;
+			vb2_set_plane_payload(vb, 0, 0);
+			vb->timestamp = 0;
+		}
+
 		if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
 			const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
 
@@ -1311,6 +1320,25 @@ static void vdec_event_change(struct venus_inst *inst,
 		}
 	}
 
+	/*
+	 * The assumption is that the firmware have to return the last buffer
+	 * before this event is received in the v4l2 driver. Also the firmware
+	 * itself doesn't mark the last decoder output buffer with HFI EOS flag.
+	 */
+
+	if (!sufficient && inst->codec_state == VENUS_DEC_STATE_DRC) {
+		struct vb2_v4l2_buffer *last;
+		int ret;
+
+		last = v4l2_m2m_last_dst_buf(inst->m2m_ctx);
+		if (last)
+			inst->last_buf = &last->vb2_buf;
+
+		ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, false);
+		if (ret)
+			dev_dbg(dev, "flush output error %d\n", ret);
+	}
+
 	inst->reconfig = true;
 	v4l2_event_queue_fh(&inst->fh, &ev);
 	wake_up(&inst->reconf_wait);
@@ -1351,9 +1379,16 @@ static void vdec_event_notify(struct venus_inst *inst, u32 event,
 	}
 }
 
+static void vdec_flush_done(struct venus_inst *inst)
+{
+	if (inst->codec_state == VENUS_DEC_STATE_DRC)
+		inst->codec_state = VENUS_DEC_STATE_DRC_FLUSH_DONE;
+}
+
 static const struct hfi_inst_ops vdec_hfi_ops = {
 	.buf_done = vdec_buf_done,
 	.event_notify = vdec_event_notify,
+	.flush_done = vdec_flush_done,
 };
 
 static void vdec_inst_init(struct venus_inst *inst)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/7] venus: core: Add missing mutex destroy
  2020-04-08 21:33 ` [PATCH 1/7] venus: core: Add missing mutex destroy Stanimir Varbanov
@ 2020-04-09 21:47   ` Matthias Kaehlcke
  2020-04-10  8:07     ` Stanimir Varbanov
  0 siblings, 1 reply; 10+ messages in thread
From: Matthias Kaehlcke @ 2020-04-09 21:47 UTC (permalink / raw)
  To: Stanimir Varbanov
  Cc: linux-media, linux-arm-msm, linux-kernel, Vikash Garodia

Hi Stanimir,

On Thu, Apr 09, 2020 at 12:33:24AM +0300, Stanimir Varbanov wrote:
> This adds missing mutex_destroy in remove method of venus core driver.
> 
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
>  drivers/media/platform/qcom/venus/core.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
> index 4395cb96fb04..f8b9a732bc65 100644
> --- a/drivers/media/platform/qcom/venus/core.c
> +++ b/drivers/media/platform/qcom/venus/core.c
> @@ -335,6 +335,7 @@ static int venus_remove(struct platform_device *pdev)
>  
>  	v4l2_device_unregister(&core->v4l2_dev);
>  	mutex_destroy(&core->pm_lock);
> +	mutex_destroy(&core->lock);
>  
>  	return ret;
>  }

On which tree is this series based? From the context it seems that the
tree includes the patch "venus: vdec: Use pmruntime autosuspend"
(https://lore.kernel.org/patchwork/patch/1187829/), however I can not
find this patch in any of the branches of your git tree
(https://git.linuxtv.org/svarbanov/media_tree.git/)

Am I looking in the wrong place?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/7] venus: core: Add missing mutex destroy
  2020-04-09 21:47   ` Matthias Kaehlcke
@ 2020-04-10  8:07     ` Stanimir Varbanov
  0 siblings, 0 replies; 10+ messages in thread
From: Stanimir Varbanov @ 2020-04-10  8:07 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: linux-media, linux-arm-msm, linux-kernel, Vikash Garodia

Hi Matthias,

On 4/10/20 12:47 AM, Matthias Kaehlcke wrote:
> Hi Stanimir,
> 
> On Thu, Apr 09, 2020 at 12:33:24AM +0300, Stanimir Varbanov wrote:
>> This adds missing mutex_destroy in remove method of venus core driver.
>>
>> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
>> ---
>>  drivers/media/platform/qcom/venus/core.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
>> index 4395cb96fb04..f8b9a732bc65 100644
>> --- a/drivers/media/platform/qcom/venus/core.c
>> +++ b/drivers/media/platform/qcom/venus/core.c
>> @@ -335,6 +335,7 @@ static int venus_remove(struct platform_device *pdev)
>>  
>>  	v4l2_device_unregister(&core->v4l2_dev);
>>  	mutex_destroy(&core->pm_lock);
>> +	mutex_destroy(&core->lock);
>>  
>>  	return ret;
>>  }
> 
> On which tree is this series based? From the context it seems that the
> tree includes the patch "venus: vdec: Use pmruntime autosuspend"
> (https://lore.kernel.org/patchwork/patch/1187829/), however I can not
> find this patch in any of the branches of your git tree
> (https://git.linuxtv.org/svarbanov/media_tree.git/)

Yes, sorry about that. It is based on runtime suspend patch and few
others. I prepared a pull request but did not send it nor publish the
branch yet cause I wait for rc1 tag.

> 
> Am I looking in the wrong place?
> 

No, you are on right place. I will update my linuxtv tree with material
for v5.8.

-- 
regards,
Stan

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-04-10  8:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-08 21:33 [PATCH 0/7] Venus Codec API addition and few fixes Stanimir Varbanov
2020-04-08 21:33 ` [PATCH 1/7] venus: core: Add missing mutex destroy Stanimir Varbanov
2020-04-09 21:47   ` Matthias Kaehlcke
2020-04-10  8:07     ` Stanimir Varbanov
2020-04-08 21:33 ` [PATCH 2/7] venus: core: Fix mutex destroy in remove Stanimir Varbanov
2020-04-08 21:33 ` [PATCH 3/7] venus: core: Constify codec frequency data array Stanimir Varbanov
2020-04-08 21:33 ` [PATCH 4/7] venus: helpers: Done buffers per queue type Stanimir Varbanov
2020-04-08 21:33 ` [PATCH 5/7] venus: vdec: Mark flushed buffers with error state Stanimir Varbanov
2020-04-08 21:33 ` [PATCH 6/7] venus: vdec: Init registered list unconditionally Stanimir Varbanov
2020-04-08 21:33 ` [PATCH 7/7] venus: Mark last capture buffer Stanimir Varbanov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).