diff --git a/driver/variant/iris3/src/msm_vidc_iris3.c b/driver/variant/iris3/src/msm_vidc_iris3.c index 01a09c43fa..6dd48d6fab 100644 --- a/driver/variant/iris3/src/msm_vidc_iris3.c +++ b/driver/variant/iris3/src/msm_vidc_iris3.c @@ -274,19 +274,22 @@ static int __power_off_iris3_hardware(struct msm_vidc_core *core) bool pwr_collapsed = false; /* - * Incase hw power control is enabled, when CPU WD occurred, check for power - * status to decide on executing NOC reset sequence before disabling power. - * If there is no CPU WD and hw_power_control is enabled, fw is expected + * Incase hw power control is enabled, for both CPU WD, video + * hw unresponsive cases, check for power status to decide on + * 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. */ if (core->hw_power_control) { pwr_collapsed = is_iris3_hw_power_collapsed(core); - if (core->cpu_watchdog) { + if (core->cpu_watchdog || core->video_unresponsive) { 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; } 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 { if (!pwr_collapsed) diff --git a/driver/variant/iris33/src/msm_vidc_iris33.c b/driver/variant/iris33/src/msm_vidc_iris33.c index afd92ca702..175bcb0e09 100644 --- a/driver/variant/iris33/src/msm_vidc_iris33.c +++ b/driver/variant/iris33/src/msm_vidc_iris33.c @@ -285,19 +285,22 @@ static int __power_off_iris33_hardware(struct msm_vidc_core *core) bool pwr_collapsed = false; /* - * Incase hw power control is enabled, when CPU WD occurred, check for power - * status to decide on executing NOC reset sequence before disabling power. - * If there is no CPU WD and hw_power_control is enabled, fw is expected + * Incase hw power control is enabled, for both CPU WD, video + * hw unresponsive cases, check for power status to decide on + * 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. */ if (core->hw_power_control) { pwr_collapsed = is_iris33_hw_power_collapsed(core); - if (core->cpu_watchdog) { + if (core->cpu_watchdog || core->video_unresponsive) { 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; } 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 { if (!pwr_collapsed) diff --git a/driver/vidc/inc/msm_vidc_core.h b/driver/vidc/inc/msm_vidc_core.h index 0623bdfbe9..79d44c872e 100644 --- a/driver/vidc/inc/msm_vidc_core.h +++ b/driver/vidc/inc/msm_vidc_core.h @@ -1,6 +1,7 @@ /* 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_ @@ -118,6 +119,7 @@ struct msm_vidc_core { bool hw_power_control; bool pm_suspended; bool cpu_watchdog; + bool video_unresponsive; }; #endif // _MSM_VIDC_CORE_H_ diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 0e2246e618..cf5bb73af4 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -4905,6 +4905,7 @@ int msm_vidc_core_init_wait(struct msm_vidc_core *core) } else { d_vpr_h("%s: sys init wait timedout. state %s\n", __func__, core_state_name(core->state)); + core->video_unresponsive = true; rc = -EINVAL; goto unlock; } @@ -4979,6 +4980,8 @@ int msm_vidc_inst_timeout(struct msm_vidc_inst *inst) rc = -EINVAL; goto unlock; } + /* mark video hw unresponsive */ + core->video_unresponsive = true; /* call core deinit for a valid instance timeout case */ msm_vidc_core_deinit_locked(core, true); diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index 4417c7707f..99833a62a9 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -687,6 +687,7 @@ int __load_fw(struct msm_vidc_core *core) core->handoff_done = false; core->hw_power_control = false; core->cpu_watchdog = false; + core->video_unresponsive = false; trace_msm_v4l2_vidc_fw_load("START"); rc = __venus_power_on(core); @@ -726,6 +727,7 @@ void __unload_fw(struct msm_vidc_core *core) __venus_power_off(core); core->cpu_watchdog = false; + core->video_unresponsive = false; 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", core->skip_pc_count); core->skip_pc_count = 0; + core->video_unresponsive = true; msm_vidc_core_deinit(core, true); return; }