linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Venus - recovery from firmware crash
@ 2020-07-30 11:46 Stanimir Varbanov
  2020-07-30 11:46 ` [PATCH 1/3] venus: parser: Prepare parser for multiple invocations Stanimir Varbanov
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Stanimir Varbanov @ 2020-07-30 11:46 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel; +Cc: Stanimir Varbanov

Hello,

The intention of this patchset is to correct the recovery sequence
for Venus v4 (sdm845). Recently has been observed various recovery
failures which leads to unreliable behavior in sys_error handler.
To fix that the sys_error_handler is reworked, proper delays has
been added over pmruntime handling to ensure that the hardware and
encoder/decoder drivers are idle. Also a wrong watchdog code in
threaded irq has been removed. 

regards,
Stan

Stanimir Varbanov (3):
  venus: parser: Prepare parser for multiple invocations
  venus: Rework recovery mechanism
  venus: Add new interface queues reinit

 drivers/media/platform/qcom/venus/core.c      | 25 ++++----
 drivers/media/platform/qcom/venus/hfi.c       |  5 ++
 drivers/media/platform/qcom/venus/hfi.h       |  1 +
 .../media/platform/qcom/venus/hfi_parser.c    |  3 +
 drivers/media/platform/qcom/venus/hfi_venus.c | 62 +++++++++++++++----
 drivers/media/platform/qcom/venus/hfi_venus.h |  1 +
 6 files changed, 74 insertions(+), 23 deletions(-)

-- 
2.17.1


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

* [PATCH 1/3] venus: parser: Prepare parser for multiple invocations
  2020-07-30 11:46 [PATCH 0/3] Venus - recovery from firmware crash Stanimir Varbanov
@ 2020-07-30 11:46 ` Stanimir Varbanov
  2020-08-07 21:28   ` Fritz Koenig
  2020-07-30 11:46 ` [PATCH 2/3] venus: Rework recovery mechanism Stanimir Varbanov
  2020-07-30 11:46 ` [PATCH 3/3] venus: Add new interface queues reinit Stanimir Varbanov
  2 siblings, 1 reply; 7+ messages in thread
From: Stanimir Varbanov @ 2020-07-30 11:46 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel; +Cc: Stanimir Varbanov

Presently the hfi_parser has been called only once during driver
probe. To prepare the parser function to be called multiple times
from recovery we need to initialize few variables which are used
during parsing time.

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

diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
index 7f515a4b9bd1..363ee2a65453 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -239,6 +239,9 @@ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
 
 	parser_init(inst, &codecs, &domain);
 
+	core->codecs_count = 0;
+	memset(core->caps, 0, sizeof(core->caps));
+
 	while (words_count) {
 		data = word + 1;
 
-- 
2.17.1


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

* [PATCH 2/3] venus: Rework recovery mechanism
  2020-07-30 11:46 [PATCH 0/3] Venus - recovery from firmware crash Stanimir Varbanov
  2020-07-30 11:46 ` [PATCH 1/3] venus: parser: Prepare parser for multiple invocations Stanimir Varbanov
@ 2020-07-30 11:46 ` Stanimir Varbanov
  2020-08-07 21:29   ` Fritz Koenig
  2020-07-30 11:46 ` [PATCH 3/3] venus: Add new interface queues reinit Stanimir Varbanov
  2 siblings, 1 reply; 7+ messages in thread
From: Stanimir Varbanov @ 2020-07-30 11:46 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel; +Cc: Stanimir Varbanov

After power domains and clock restructuring the recovery for
sdm845 and v4 did not work properly. Fix that by reworking the
recovery function and the sequence.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/core.c      | 24 ++++++++++---------
 drivers/media/platform/qcom/venus/hfi_venus.c | 11 ---------
 2 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 203c6538044f..46f6e34d435a 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -6,6 +6,7 @@
 #include <linux/init.h>
 #include <linux/interconnect.h>
 #include <linux/ioctl.h>
+#include <linux/delay.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
@@ -40,13 +41,7 @@ static void venus_event_notify(struct venus_core *core, u32 event)
 	mutex_unlock(&core->lock);
 
 	disable_irq_nosync(core->irq);
-
-	/*
-	 * Delay recovery to ensure venus has completed any pending cache
-	 * operations. Without this sleep, we see device reset when firmware is
-	 * unloaded after a system error.
-	 */
-	schedule_delayed_work(&core->work, msecs_to_jiffies(100));
+	schedule_delayed_work(&core->work, msecs_to_jiffies(10));
 }
 
 static const struct hfi_core_ops venus_core_ops = {
@@ -59,23 +54,30 @@ static void venus_sys_error_handler(struct work_struct *work)
 			container_of(work, struct venus_core, work.work);
 	int ret = 0;
 
-	dev_warn(core->dev, "system error has occurred, starting recovery!\n");
-
 	pm_runtime_get_sync(core->dev);
 
 	hfi_core_deinit(core, true);
-	hfi_destroy(core);
+
+	dev_warn(core->dev, "system error has occurred, starting recovery!\n");
+
 	mutex_lock(&core->lock);
+
+	while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc))
+		msleep(10);
+
 	venus_shutdown(core);
 
 	pm_runtime_put_sync(core->dev);
 
+	while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
+		usleep_range(1000, 1500);
+
+	hfi_destroy(core);
 	ret |= hfi_create(core, &venus_core_ops);
 
 	pm_runtime_get_sync(core->dev);
 
 	ret |= venus_boot(core);
-
 	ret |= hfi_core_resume(core, true);
 
 	enable_irq(core->irq);
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index 0d8855014ab3..3392fd177d22 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -986,13 +986,6 @@ static void venus_process_msg_sys_error(struct venus_hfi_device *hdev,
 
 	venus_set_state(hdev, VENUS_STATE_DEINIT);
 
-	/*
-	 * Once SYS_ERROR received from HW, it is safe to halt the AXI.
-	 * With SYS_ERROR, Venus FW may have crashed and HW might be
-	 * active and causing unnecessary transactions. Hence it is
-	 * safe to stop all AXI transactions from venus subsystem.
-	 */
-	venus_halt_axi(hdev);
 	venus_sfr_print(hdev);
 }
 
@@ -1009,10 +1002,6 @@ static irqreturn_t venus_isr_thread(struct venus_core *core)
 	res = hdev->core->res;
 	pkt = hdev->pkt_buf;
 
-	if (hdev->irq_status & WRAPPER_INTR_STATUS_A2HWD_MASK) {
-		venus_sfr_print(hdev);
-		hfi_process_watchdog_timeout(core);
-	}
 
 	while (!venus_iface_msgq_read(hdev, pkt)) {
 		msg_ret = hfi_process_msg_packet(core, pkt);
-- 
2.17.1


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

* [PATCH 3/3] venus: Add new interface queues reinit
  2020-07-30 11:46 [PATCH 0/3] Venus - recovery from firmware crash Stanimir Varbanov
  2020-07-30 11:46 ` [PATCH 1/3] venus: parser: Prepare parser for multiple invocations Stanimir Varbanov
  2020-07-30 11:46 ` [PATCH 2/3] venus: Rework recovery mechanism Stanimir Varbanov
@ 2020-07-30 11:46 ` Stanimir Varbanov
  2020-08-07 21:29   ` Fritz Koenig
  2 siblings, 1 reply; 7+ messages in thread
From: Stanimir Varbanov @ 2020-07-30 11:46 UTC (permalink / raw)
  To: linux-media, linux-arm-msm, linux-kernel; +Cc: Stanimir Varbanov

Presently the recovery mechanism is using two hfi functions
to destroy and create interface queues. For the purpose of
recovery we don't need to free and allocate the memory used
for interface message queues, that's why we introduce new
function which just reinit the queues.  Also this will give
to the recovery procedure one less reason to fail (if for
some reason we couldn't allocate memory).

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/media/platform/qcom/venus/core.c      |  3 +-
 drivers/media/platform/qcom/venus/hfi.c       |  5 ++
 drivers/media/platform/qcom/venus/hfi.h       |  1 +
 drivers/media/platform/qcom/venus/hfi_venus.c | 51 +++++++++++++++++++
 drivers/media/platform/qcom/venus/hfi_venus.h |  1 +
 5 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 46f6e34d435a..eda8f35425df 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -72,8 +72,7 @@ static void venus_sys_error_handler(struct work_struct *work)
 	while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
 		usleep_range(1000, 1500);
 
-	hfi_destroy(core);
-	ret |= hfi_create(core, &venus_core_ops);
+	hfi_reinit(core);
 
 	pm_runtime_get_sync(core->dev);
 
diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
index a211eb93e0f9..a59022adb14c 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -517,3 +517,8 @@ void hfi_destroy(struct venus_core *core)
 {
 	venus_hfi_destroy(core);
 }
+
+void hfi_reinit(struct venus_core *core)
+{
+	venus_hfi_queues_reinit(core);
+}
diff --git a/drivers/media/platform/qcom/venus/hfi.h b/drivers/media/platform/qcom/venus/hfi.h
index 62c315291484..f25d412d6553 100644
--- a/drivers/media/platform/qcom/venus/hfi.h
+++ b/drivers/media/platform/qcom/venus/hfi.h
@@ -145,6 +145,7 @@ struct hfi_ops {
 
 int hfi_create(struct venus_core *core, const struct hfi_core_ops *ops);
 void hfi_destroy(struct venus_core *core);
+void hfi_reinit(struct venus_core *core);
 
 int hfi_core_init(struct venus_core *core);
 int hfi_core_deinit(struct venus_core *core, bool blocking);
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index 3392fd177d22..90067cd8c892 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -1603,3 +1603,54 @@ int venus_hfi_create(struct venus_core *core)
 	core->ops = NULL;
 	return ret;
 }
+
+void venus_hfi_queues_reinit(struct venus_core *core)
+{
+	struct venus_hfi_device *hdev = to_hfi_priv(core);
+	struct hfi_queue_table_header *tbl_hdr;
+	struct iface_queue *queue;
+	struct hfi_sfr *sfr;
+	unsigned int i;
+
+	mutex_lock(&hdev->lock);
+
+	for (i = 0; i < IFACEQ_NUM; i++) {
+		queue = &hdev->queues[i];
+		queue->qhdr =
+			IFACEQ_GET_QHDR_START_ADDR(hdev->ifaceq_table.kva, i);
+
+		venus_set_qhdr_defaults(queue->qhdr);
+
+		queue->qhdr->start_addr = queue->qmem.da;
+
+		if (i == IFACEQ_CMD_IDX)
+			queue->qhdr->type |= HFI_HOST_TO_CTRL_CMD_Q;
+		else if (i == IFACEQ_MSG_IDX)
+			queue->qhdr->type |= HFI_CTRL_TO_HOST_MSG_Q;
+		else if (i == IFACEQ_DBG_IDX)
+			queue->qhdr->type |= HFI_CTRL_TO_HOST_DBG_Q;
+	}
+
+	tbl_hdr = hdev->ifaceq_table.kva;
+	tbl_hdr->version = 0;
+	tbl_hdr->size = IFACEQ_TABLE_SIZE;
+	tbl_hdr->qhdr0_offset = sizeof(struct hfi_queue_table_header);
+	tbl_hdr->qhdr_size = sizeof(struct hfi_queue_header);
+	tbl_hdr->num_q = IFACEQ_NUM;
+	tbl_hdr->num_active_q = IFACEQ_NUM;
+
+	/*
+	 * Set receive request to zero on debug queue as there is no
+	 * need of interrupt from video hardware for debug messages
+	 */
+	queue = &hdev->queues[IFACEQ_DBG_IDX];
+	queue->qhdr->rx_req = 0;
+
+	sfr = hdev->sfr.kva;
+	sfr->buf_size = ALIGNED_SFR_SIZE;
+
+	/* ensure table and queue header structs are settled in memory */
+	wmb();
+
+	mutex_unlock(&hdev->lock);
+}
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.h b/drivers/media/platform/qcom/venus/hfi_venus.h
index 57154832090e..1b656ef2bf07 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.h
+++ b/drivers/media/platform/qcom/venus/hfi_venus.h
@@ -10,5 +10,6 @@ struct venus_core;
 
 void venus_hfi_destroy(struct venus_core *core);
 int venus_hfi_create(struct venus_core *core);
+void venus_hfi_queues_reinit(struct venus_core *core);
 
 #endif
-- 
2.17.1


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

* Re: [PATCH 1/3] venus: parser: Prepare parser for multiple invocations
  2020-07-30 11:46 ` [PATCH 1/3] venus: parser: Prepare parser for multiple invocations Stanimir Varbanov
@ 2020-08-07 21:28   ` Fritz Koenig
  0 siblings, 0 replies; 7+ messages in thread
From: Fritz Koenig @ 2020-08-07 21:28 UTC (permalink / raw)
  To: Stanimir Varbanov; +Cc: linux-media, linux-arm-msm, linux-kernel

On Thu, Jul 30, 2020 at 4:47 AM Stanimir Varbanov
<stanimir.varbanov@linaro.org> wrote:
>
> Presently the hfi_parser has been called only once during driver
> probe. To prepare the parser function to be called multiple times
> from recovery we need to initialize few variables which are used
> during parsing time.
>
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
>  drivers/media/platform/qcom/venus/hfi_parser.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
> index 7f515a4b9bd1..363ee2a65453 100644
> --- a/drivers/media/platform/qcom/venus/hfi_parser.c
> +++ b/drivers/media/platform/qcom/venus/hfi_parser.c
> @@ -239,6 +239,9 @@ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
>
>         parser_init(inst, &codecs, &domain);
>
> +       core->codecs_count = 0;
> +       memset(core->caps, 0, sizeof(core->caps));
> +
>         while (words_count) {
>                 data = word + 1;
>
> --
> 2.17.1
>

Reviewed-by: Fritz Koenig <frkoenig@chromium.org>

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

* Re: [PATCH 2/3] venus: Rework recovery mechanism
  2020-07-30 11:46 ` [PATCH 2/3] venus: Rework recovery mechanism Stanimir Varbanov
@ 2020-08-07 21:29   ` Fritz Koenig
  0 siblings, 0 replies; 7+ messages in thread
From: Fritz Koenig @ 2020-08-07 21:29 UTC (permalink / raw)
  To: Stanimir Varbanov; +Cc: linux-media, linux-arm-msm, linux-kernel

On Thu, Jul 30, 2020 at 4:47 AM Stanimir Varbanov
<stanimir.varbanov@linaro.org> wrote:
>
> After power domains and clock restructuring the recovery for
> sdm845 and v4 did not work properly. Fix that by reworking the
> recovery function and the sequence.
>
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
>  drivers/media/platform/qcom/venus/core.c      | 24 ++++++++++---------
>  drivers/media/platform/qcom/venus/hfi_venus.c | 11 ---------
>  2 files changed, 13 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
> index 203c6538044f..46f6e34d435a 100644
> --- a/drivers/media/platform/qcom/venus/core.c
> +++ b/drivers/media/platform/qcom/venus/core.c
> @@ -6,6 +6,7 @@
>  #include <linux/init.h>
>  #include <linux/interconnect.h>
>  #include <linux/ioctl.h>
> +#include <linux/delay.h>
>  #include <linux/list.h>
>  #include <linux/module.h>
>  #include <linux/of_device.h>
> @@ -40,13 +41,7 @@ static void venus_event_notify(struct venus_core *core, u32 event)
>         mutex_unlock(&core->lock);
>
>         disable_irq_nosync(core->irq);
> -
> -       /*
> -        * Delay recovery to ensure venus has completed any pending cache
> -        * operations. Without this sleep, we see device reset when firmware is
> -        * unloaded after a system error.
> -        */
> -       schedule_delayed_work(&core->work, msecs_to_jiffies(100));
> +       schedule_delayed_work(&core->work, msecs_to_jiffies(10));
>  }
>
>  static const struct hfi_core_ops venus_core_ops = {
> @@ -59,23 +54,30 @@ static void venus_sys_error_handler(struct work_struct *work)
>                         container_of(work, struct venus_core, work.work);
>         int ret = 0;
>
> -       dev_warn(core->dev, "system error has occurred, starting recovery!\n");
> -
>         pm_runtime_get_sync(core->dev);
>
>         hfi_core_deinit(core, true);
> -       hfi_destroy(core);
> +
> +       dev_warn(core->dev, "system error has occurred, starting recovery!\n");
> +
>         mutex_lock(&core->lock);
> +
> +       while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc))
> +               msleep(10);
> +
>         venus_shutdown(core);
>
>         pm_runtime_put_sync(core->dev);
>
> +       while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
> +               usleep_range(1000, 1500);
> +
> +       hfi_destroy(core);
>         ret |= hfi_create(core, &venus_core_ops);
>
>         pm_runtime_get_sync(core->dev);
>
>         ret |= venus_boot(core);
> -
>         ret |= hfi_core_resume(core, true);
>
>         enable_irq(core->irq);
> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
> index 0d8855014ab3..3392fd177d22 100644
> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
> @@ -986,13 +986,6 @@ static void venus_process_msg_sys_error(struct venus_hfi_device *hdev,
>
>         venus_set_state(hdev, VENUS_STATE_DEINIT);
>
> -       /*
> -        * Once SYS_ERROR received from HW, it is safe to halt the AXI.
> -        * With SYS_ERROR, Venus FW may have crashed and HW might be
> -        * active and causing unnecessary transactions. Hence it is
> -        * safe to stop all AXI transactions from venus subsystem.
> -        */
> -       venus_halt_axi(hdev);
>         venus_sfr_print(hdev);
>  }
>
> @@ -1009,10 +1002,6 @@ static irqreturn_t venus_isr_thread(struct venus_core *core)
>         res = hdev->core->res;
>         pkt = hdev->pkt_buf;
>
> -       if (hdev->irq_status & WRAPPER_INTR_STATUS_A2HWD_MASK) {
> -               venus_sfr_print(hdev);
> -               hfi_process_watchdog_timeout(core);
> -       }
>
>         while (!venus_iface_msgq_read(hdev, pkt)) {
>                 msg_ret = hfi_process_msg_packet(core, pkt);
> --
> 2.17.1
>
Reviewed-by: Fritz Koenig <frkoenig@chromium.org>

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

* Re: [PATCH 3/3] venus: Add new interface queues reinit
  2020-07-30 11:46 ` [PATCH 3/3] venus: Add new interface queues reinit Stanimir Varbanov
@ 2020-08-07 21:29   ` Fritz Koenig
  0 siblings, 0 replies; 7+ messages in thread
From: Fritz Koenig @ 2020-08-07 21:29 UTC (permalink / raw)
  To: Stanimir Varbanov; +Cc: linux-media, linux-arm-msm, linux-kernel

On Thu, Jul 30, 2020 at 4:47 AM Stanimir Varbanov
<stanimir.varbanov@linaro.org> wrote:
>
> Presently the recovery mechanism is using two hfi functions
> to destroy and create interface queues. For the purpose of
> recovery we don't need to free and allocate the memory used
> for interface message queues, that's why we introduce new
> function which just reinit the queues.  Also this will give
> to the recovery procedure one less reason to fail (if for
> some reason we couldn't allocate memory).
>
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
>  drivers/media/platform/qcom/venus/core.c      |  3 +-
>  drivers/media/platform/qcom/venus/hfi.c       |  5 ++
>  drivers/media/platform/qcom/venus/hfi.h       |  1 +
>  drivers/media/platform/qcom/venus/hfi_venus.c | 51 +++++++++++++++++++
>  drivers/media/platform/qcom/venus/hfi_venus.h |  1 +
>  5 files changed, 59 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
> index 46f6e34d435a..eda8f35425df 100644
> --- a/drivers/media/platform/qcom/venus/core.c
> +++ b/drivers/media/platform/qcom/venus/core.c
> @@ -72,8 +72,7 @@ static void venus_sys_error_handler(struct work_struct *work)
>         while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
>                 usleep_range(1000, 1500);
>
> -       hfi_destroy(core);
> -       ret |= hfi_create(core, &venus_core_ops);
> +       hfi_reinit(core);
>
>         pm_runtime_get_sync(core->dev);
>
> diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
> index a211eb93e0f9..a59022adb14c 100644
> --- a/drivers/media/platform/qcom/venus/hfi.c
> +++ b/drivers/media/platform/qcom/venus/hfi.c
> @@ -517,3 +517,8 @@ void hfi_destroy(struct venus_core *core)
>  {
>         venus_hfi_destroy(core);
>  }
> +
> +void hfi_reinit(struct venus_core *core)
> +{
> +       venus_hfi_queues_reinit(core);
> +}
> diff --git a/drivers/media/platform/qcom/venus/hfi.h b/drivers/media/platform/qcom/venus/hfi.h
> index 62c315291484..f25d412d6553 100644
> --- a/drivers/media/platform/qcom/venus/hfi.h
> +++ b/drivers/media/platform/qcom/venus/hfi.h
> @@ -145,6 +145,7 @@ struct hfi_ops {
>
>  int hfi_create(struct venus_core *core, const struct hfi_core_ops *ops);
>  void hfi_destroy(struct venus_core *core);
> +void hfi_reinit(struct venus_core *core);
>
>  int hfi_core_init(struct venus_core *core);
>  int hfi_core_deinit(struct venus_core *core, bool blocking);
> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
> index 3392fd177d22..90067cd8c892 100644
> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
> @@ -1603,3 +1603,54 @@ int venus_hfi_create(struct venus_core *core)
>         core->ops = NULL;
>         return ret;
>  }
> +
> +void venus_hfi_queues_reinit(struct venus_core *core)
> +{
> +       struct venus_hfi_device *hdev = to_hfi_priv(core);
> +       struct hfi_queue_table_header *tbl_hdr;
> +       struct iface_queue *queue;
> +       struct hfi_sfr *sfr;
> +       unsigned int i;
> +
> +       mutex_lock(&hdev->lock);
> +
> +       for (i = 0; i < IFACEQ_NUM; i++) {
> +               queue = &hdev->queues[i];
> +               queue->qhdr =
> +                       IFACEQ_GET_QHDR_START_ADDR(hdev->ifaceq_table.kva, i);
> +
> +               venus_set_qhdr_defaults(queue->qhdr);
> +
> +               queue->qhdr->start_addr = queue->qmem.da;
> +
> +               if (i == IFACEQ_CMD_IDX)
> +                       queue->qhdr->type |= HFI_HOST_TO_CTRL_CMD_Q;
> +               else if (i == IFACEQ_MSG_IDX)
> +                       queue->qhdr->type |= HFI_CTRL_TO_HOST_MSG_Q;
> +               else if (i == IFACEQ_DBG_IDX)
> +                       queue->qhdr->type |= HFI_CTRL_TO_HOST_DBG_Q;
> +       }
> +
> +       tbl_hdr = hdev->ifaceq_table.kva;
> +       tbl_hdr->version = 0;
> +       tbl_hdr->size = IFACEQ_TABLE_SIZE;
> +       tbl_hdr->qhdr0_offset = sizeof(struct hfi_queue_table_header);
> +       tbl_hdr->qhdr_size = sizeof(struct hfi_queue_header);
> +       tbl_hdr->num_q = IFACEQ_NUM;
> +       tbl_hdr->num_active_q = IFACEQ_NUM;
> +
> +       /*
> +        * Set receive request to zero on debug queue as there is no
> +        * need of interrupt from video hardware for debug messages
> +        */
> +       queue = &hdev->queues[IFACEQ_DBG_IDX];
> +       queue->qhdr->rx_req = 0;
> +
> +       sfr = hdev->sfr.kva;
> +       sfr->buf_size = ALIGNED_SFR_SIZE;
> +
> +       /* ensure table and queue header structs are settled in memory */
> +       wmb();
> +
> +       mutex_unlock(&hdev->lock);
> +}
> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.h b/drivers/media/platform/qcom/venus/hfi_venus.h
> index 57154832090e..1b656ef2bf07 100644
> --- a/drivers/media/platform/qcom/venus/hfi_venus.h
> +++ b/drivers/media/platform/qcom/venus/hfi_venus.h
> @@ -10,5 +10,6 @@ struct venus_core;
>
>  void venus_hfi_destroy(struct venus_core *core);
>  int venus_hfi_create(struct venus_core *core);
> +void venus_hfi_queues_reinit(struct venus_core *core);
>
>  #endif
> --
> 2.17.1
>
Reviewed-by: Fritz Koenig <frkoenig@chromium.org>

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

end of thread, other threads:[~2020-08-07 21:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-30 11:46 [PATCH 0/3] Venus - recovery from firmware crash Stanimir Varbanov
2020-07-30 11:46 ` [PATCH 1/3] venus: parser: Prepare parser for multiple invocations Stanimir Varbanov
2020-08-07 21:28   ` Fritz Koenig
2020-07-30 11:46 ` [PATCH 2/3] venus: Rework recovery mechanism Stanimir Varbanov
2020-08-07 21:29   ` Fritz Koenig
2020-07-30 11:46 ` [PATCH 3/3] venus: Add new interface queues reinit Stanimir Varbanov
2020-08-07 21:29   ` Fritz Koenig

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).