Jelajahi Sumber

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 <[email protected]>
Signed-off-by: Ankush Mitra <[email protected]>
Ankush Mitra 2 tahun lalu
induk
melakukan
dc39a04e6e

+ 9 - 6
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)

+ 9 - 6
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)

+ 3 - 1
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_

+ 3 - 0
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);

+ 3 - 0
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;
 	}