video: driver: follow vcodec power collapse seq for PC failure case

if PC fails for 10 times then video driver is treating that situation
as fatal and doing force core_deinit(), in this case firmware will not
follow vcodec power_collapse sequence and if there any pending
transaction from any session it will cause smmu_fault during next
firmware_boot sequence. Added change to perform vcodec power_collapse
from power_off_iris3_hardware() incase of core_deinit due to PC failure.

Change-Id: I45e32985d87b5cc882c4f96f77d1cabc796e6ba0
Signed-off-by: Govindaraj Rajagopal <quic_grajagop@quicinc.com>
Signed-off-by: Ankush Mitra <quic_ankumitr@quicinc.com>
This commit is contained in:
Ankush Mitra
2022-09-07 18:50:21 +05:30
committed by Gerrit - the friendly Code Review server
parent 78246c24fb
commit dc39a04e6e
5 changed files with 27 additions and 13 deletions

View File

@@ -274,19 +274,22 @@ static int __power_off_iris3_hardware(struct msm_vidc_core *core)
bool pwr_collapsed = false; bool pwr_collapsed = false;
/* /*
* Incase hw power control is enabled, when CPU WD occurred, check for power * Incase hw power control is enabled, for both CPU WD, video
* status to decide on executing NOC reset sequence before disabling power. * hw unresponsive cases, check for power status to decide on
* If there is no CPU WD and hw_power_control is enabled, fw is expected * executing NOC reset sequence before disabling power. If there
* is no CPU WD and hw_power_control is enabled, fw is expected
* to power collapse video hw always. * to power collapse video hw always.
*/ */
if (core->hw_power_control) { if (core->hw_power_control) {
pwr_collapsed = is_iris3_hw_power_collapsed(core); pwr_collapsed = is_iris3_hw_power_collapsed(core);
if (core->cpu_watchdog) { if (core->cpu_watchdog || core->video_unresponsive) {
if (pwr_collapsed) { if (pwr_collapsed) {
d_vpr_e("%s: CPU WD and video hw power collapsed\n", __func__); d_vpr_e("%s: video hw power collapsed %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
goto disable_power; goto disable_power;
} else { } else {
d_vpr_e("%s: CPU WD and video hw is power ON\n", __func__); d_vpr_e("%s: video hw is power ON %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
} }
} else { } else {
if (!pwr_collapsed) if (!pwr_collapsed)

View File

@@ -285,19 +285,22 @@ static int __power_off_iris33_hardware(struct msm_vidc_core *core)
bool pwr_collapsed = false; bool pwr_collapsed = false;
/* /*
* Incase hw power control is enabled, when CPU WD occurred, check for power * Incase hw power control is enabled, for both CPU WD, video
* status to decide on executing NOC reset sequence before disabling power. * hw unresponsive cases, check for power status to decide on
* If there is no CPU WD and hw_power_control is enabled, fw is expected * executing NOC reset sequence before disabling power. If there
* is no CPU WD and hw_power_control is enabled, fw is expected
* to power collapse video hw always. * to power collapse video hw always.
*/ */
if (core->hw_power_control) { if (core->hw_power_control) {
pwr_collapsed = is_iris33_hw_power_collapsed(core); pwr_collapsed = is_iris33_hw_power_collapsed(core);
if (core->cpu_watchdog) { if (core->cpu_watchdog || core->video_unresponsive) {
if (pwr_collapsed) { if (pwr_collapsed) {
d_vpr_e("%s: CPU WD and video hw power collapsed\n", __func__); d_vpr_e("%s: video hw power collapsed %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
goto disable_power; goto disable_power;
} else { } else {
d_vpr_e("%s: CPU WD and video hw is power ON\n", __func__); d_vpr_e("%s: video hw is power ON %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
} }
} else { } else {
if (!pwr_collapsed) if (!pwr_collapsed)

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2020-2021,, The Linux Foundation. All rights reserved. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _MSM_VIDC_CORE_H_ #ifndef _MSM_VIDC_CORE_H_
@@ -118,6 +119,7 @@ struct msm_vidc_core {
bool hw_power_control; bool hw_power_control;
bool pm_suspended; bool pm_suspended;
bool cpu_watchdog; bool cpu_watchdog;
bool video_unresponsive;
}; };
#endif // _MSM_VIDC_CORE_H_ #endif // _MSM_VIDC_CORE_H_

View File

@@ -4905,6 +4905,7 @@ int msm_vidc_core_init_wait(struct msm_vidc_core *core)
} else { } else {
d_vpr_h("%s: sys init wait timedout. state %s\n", d_vpr_h("%s: sys init wait timedout. state %s\n",
__func__, core_state_name(core->state)); __func__, core_state_name(core->state));
core->video_unresponsive = true;
rc = -EINVAL; rc = -EINVAL;
goto unlock; goto unlock;
} }
@@ -4979,6 +4980,8 @@ int msm_vidc_inst_timeout(struct msm_vidc_inst *inst)
rc = -EINVAL; rc = -EINVAL;
goto unlock; goto unlock;
} }
/* mark video hw unresponsive */
core->video_unresponsive = true;
/* call core deinit for a valid instance timeout case */ /* call core deinit for a valid instance timeout case */
msm_vidc_core_deinit_locked(core, true); msm_vidc_core_deinit_locked(core, true);

View File

@@ -687,6 +687,7 @@ int __load_fw(struct msm_vidc_core *core)
core->handoff_done = false; core->handoff_done = false;
core->hw_power_control = false; core->hw_power_control = false;
core->cpu_watchdog = false; core->cpu_watchdog = false;
core->video_unresponsive = false;
trace_msm_v4l2_vidc_fw_load("START"); trace_msm_v4l2_vidc_fw_load("START");
rc = __venus_power_on(core); rc = __venus_power_on(core);
@@ -726,6 +727,7 @@ void __unload_fw(struct msm_vidc_core *core)
__venus_power_off(core); __venus_power_off(core);
core->cpu_watchdog = false; core->cpu_watchdog = false;
core->video_unresponsive = false;
d_vpr_h("%s done\n", __func__); d_vpr_h("%s done\n", __func__);
} }
@@ -815,6 +817,7 @@ void venus_hfi_pm_work_handler(struct work_struct *work)
d_vpr_e("Failed to PC for %d times\n", d_vpr_e("Failed to PC for %d times\n",
core->skip_pc_count); core->skip_pc_count);
core->skip_pc_count = 0; core->skip_pc_count = 0;
core->video_unresponsive = true;
msm_vidc_core_deinit(core, true); msm_vidc_core_deinit(core, true);
return; return;
} }