Przeglądaj źródła

Video: Driver: acquire xo_reset mutex for gdsc access

[1] Acquire xo_reset mutex for gdsc access.
[2] Retry acquire_regulator for 1sec and BUG_ON if still fails.

Change-Id: Ie0ed4561a0c12b8526e2ede96a879f9d311aafab
Signed-off-by: Vedang Nagar <[email protected]>
Vedang Nagar 1 rok temu
rodzic
commit
726326d756

+ 16 - 51
driver/variant/iris33/src/msm_vidc_iris33.c

@@ -383,7 +383,6 @@ static int __power_off_iris33_controller(struct msm_vidc_core *core)
 {
 	int rc = 0;
 	int value = 0;
-	u32 count = 0;
 
 	/*
 	 * mask fal10_veto QLPAC error since fal10_veto can go 1
@@ -473,22 +472,9 @@ static int __power_off_iris33_controller(struct msm_vidc_core *core)
 	 * drivers (eva driver) operating on this shared reset clock
 	 * and AON_WRAPPER_SPARE register in parallel.
 	 */
-	count = 0;
-	do {
-		rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
-		if (!rc) {
-			break;
-		} else {
-			d_vpr_e(
-				"%s: failed to acquire video_xo_reset control, count %d\n",
-				__func__, count);
-			count++;
-			usleep_range(1000, 1000);
-		}
-	} while (count < 100);
-
-	if (count >= 100) {
-		d_vpr_e("%s: timeout acquiring video_xo_reset\n", __func__);
+	rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
+	if (rc) {
+		d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
 		goto skip_video_xo_reset;
 	}
 
@@ -501,7 +487,7 @@ static int __power_off_iris33_controller(struct msm_vidc_core *core)
 	/* enable bit(1) to avoid cvp noc xo reset */
 	rc = __write_register(core, AON_WRAPPER_SPARE, value | 0x2);
 	if (rc)
-		return rc;
+		goto exit;
 
 	/* assert video_cc XO reset */
 	rc = call_res_op(core, reset_control_assert, core, "video_xo_reset");
@@ -523,7 +509,7 @@ static int __power_off_iris33_controller(struct msm_vidc_core *core)
 	/* reset AON spare register */
 	rc = __write_register(core, AON_WRAPPER_SPARE, 0x0);
 	if (rc)
-		return rc;
+		goto exit;
 
 	/* release reset control for other consumers */
 	rc = call_res_op(core, reset_control_release, core, "video_xo_reset");
@@ -570,6 +556,10 @@ skip_video_xo_reset:
 	}
 
 	return rc;
+
+exit:
+	call_res_op(core, reset_control_release, core, "video_xo_reset");
+	return rc;
 }
 
 static int __power_off_iris33(struct msm_vidc_core *core)
@@ -677,7 +667,6 @@ static int __power_on_iris33(struct msm_vidc_core *core)
 	struct frequency_table *freq_tbl;
 	u32 freq = 0;
 	int rc = 0;
-	int count = 0;
 
 	if (is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
 		return 0;
@@ -728,21 +717,9 @@ static int __power_on_iris33(struct msm_vidc_core *core)
 	 * access failure, so acquire video_xo_reset to ensure EVA module is
 	 * not doing assert or de-assert on video_xo_reset.
 	 */
-	do {
-		rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
-		if (!rc) {
-			break;
-		} else {
-			d_vpr_e(
-				"%s: failed to acquire video_xo_reset control, count %d\n",
-				__func__, count);
-			count++;
-			usleep_range(1000, 1000);
-		}
-	} while (count < 100);
-
-	if (count >= 100) {
-		d_vpr_e("%s: timeout acquiring video_xo_reset\n", __func__);
+	rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
+	if (rc) {
+		d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
 		goto fail_assert_xo_reset;
 	}
 
@@ -822,6 +799,7 @@ static int __power_on_iris33(struct msm_vidc_core *core)
 	return rc;
 
 fail_program_noc_regs:
+	call_res_op(core, reset_control_release, core, "video_xo_reset");
 fail_deassert_xo_reset:
 fail_assert_xo_reset:
 fail_power_on_substate:
@@ -1020,7 +998,6 @@ static int __read_noc_err_register_iris33_2p(struct msm_vidc_core *core)
 
 static int __noc_error_info_iris33(struct msm_vidc_core *core)
 {
-	u32 count = 0;
 	int rc = 0;
 
 	/*
@@ -1070,21 +1047,9 @@ static int __noc_error_info_iris33(struct msm_vidc_core *core)
 	 * while reading noc registers
 	 */
 	d_vpr_e("%s: read NOC ERR LOG registers\n", __func__);
-	do {
-		rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
-		if (!rc) {
-			break;
-		} else {
-			d_vpr_e(
-				"%s: failed to acquire video_xo_reset control, count %d\n",
-				__func__, count);
-			count++;
-			usleep_range(1000, 1000);
-		}
-	} while (count < 100);
-
-	if (count >= 100) {
-		d_vpr_e("%s: timeout acquiring video_xo_reset\n", __func__);
+	rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
+	if (rc) {
+		d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
 		goto fail_assert_xo_reset;
 	}
 

+ 17 - 2
driver/vidc/src/resources.c

@@ -1445,7 +1445,7 @@ static int __reset_control_acquire_name(struct msm_vidc_core *core,
 		const char *name)
 {
 	struct reset_info *rcinfo = NULL;
-	int rc = 0;
+	int rc = 0, count = 0;
 	bool found = false;
 
 	venus_hfi_for_each_reset_clock(core, rcinfo) {
@@ -1462,7 +1462,22 @@ static int __reset_control_acquire_name(struct msm_vidc_core *core,
 		found = true;
 		/* reset_control_acquire is exposed in kernel version 6 */
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
-		rc = reset_control_acquire(rcinfo->rst);
+		do {
+			rc = reset_control_acquire(rcinfo->rst);
+			if (!rc)
+				break;
+
+			d_vpr_e("%s: failed to acquire video_xo_reset control, count %d\n",
+				__func__, count);
+			count++;
+			usleep_range(1000, 1500);
+		} while (count < 1000);
+
+		if (count >= 1000) {
+			d_vpr_e("%s: timeout acquiring video_xo_reset\n", __func__);
+			rc = -EINVAL;
+			MSM_VIDC_FATAL(true);
+		}
 #else
 		rc = -EINVAL;
 #endif

+ 59 - 5
driver/vidc/src/resources_ext.c

@@ -89,6 +89,12 @@ static int __acquire_regulator(struct msm_vidc_core *core,
 {
 	int rc = 0;
 
+	rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
+	if (rc) {
+		d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
+		goto fail_assert_xo_reset;
+	}
+
 	if (rinfo->hw_power_collapse) {
 		if (!rinfo->regulator) {
 			d_vpr_e("%s: invalid regulator\n", __func__);
@@ -133,6 +139,10 @@ static int __acquire_regulator(struct msm_vidc_core *core,
 	}
 
 exit:
+	rc = call_res_op(core, reset_control_release, core, "video_xo_reset");
+	if (rc)
+		d_vpr_e("%s: failed to release video_xo_reset reset\n", __func__);
+fail_assert_xo_reset:
 	return rc;
 }
 
@@ -141,10 +151,16 @@ static int __hand_off_regulator(struct msm_vidc_core *core,
 {
 	int rc = 0;
 
+	rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
+	if (rc) {
+		d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
+		goto fail_assert_xo_reset;
+	}
+
 	if (rinfo->hw_power_collapse) {
 		if (!rinfo->regulator) {
 			d_vpr_e("%s: invalid regulator\n", __func__);
-			return -EINVAL;
+			goto exit;
 		}
 
 		rc = regulator_set_mode(rinfo->regulator,
@@ -152,7 +168,7 @@ static int __hand_off_regulator(struct msm_vidc_core *core,
 		if (rc) {
 			d_vpr_e("Failed to hand off regulator control: %s\n",
 				rinfo->name);
-			return rc;
+			goto exit;
 		} else {
 			/* set handoff done in core sub_state */
 			msm_vidc_change_core_sub_state(core,
@@ -168,6 +184,11 @@ static int __hand_off_regulator(struct msm_vidc_core *core,
 		}
 	}
 
+exit:
+	rc = call_res_op(core, reset_control_release, core, "video_xo_reset");
+	if (rc)
+		d_vpr_e("%s: failed to release video_xo_reset reset\n", __func__);
+fail_assert_xo_reset:
 	return rc;
 }
 
@@ -188,18 +209,30 @@ static int __enable_regulator(struct msm_vidc_core *core, const char *reg_name)
 			continue;
 		found = true;
 
+		rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
+		if (rc) {
+			d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
+			goto fail_assert_xo_reset;
+		}
+
 		rc = regulator_enable(rinfo->regulator);
 		if (rc) {
 			d_vpr_e("%s: failed to enable %s, rc = %d\n",
 				__func__, rinfo->name, rc);
-			return rc;
+			goto fail_regulator_enable;
 		}
 		if (!regulator_is_enabled(rinfo->regulator)) {
 			d_vpr_e("%s: regulator %s not enabled\n",
 				__func__, rinfo->name);
 			regulator_disable(rinfo->regulator);
-			return -EINVAL;
+			rc = -EINVAL;
+			goto fail_regulator_enable;
 		}
+
+		rc = call_res_op(core, reset_control_release, core, "video_xo_reset");
+		if (rc)
+			d_vpr_e("%s: failed to release video_xo_reset reset\n", __func__);
+
 		d_vpr_h("%s: enabled regulator %s\n", __func__, rinfo->name);
 		break;
 	}
@@ -209,6 +242,11 @@ static int __enable_regulator(struct msm_vidc_core *core, const char *reg_name)
 	}
 
 	return rc;
+
+fail_regulator_enable:
+	call_res_op(core, reset_control_release, core, "video_xo_reset");
+fail_assert_xo_reset:
+	return rc;
 }
 
 static int __disable_regulator(struct msm_vidc_core *core, const char *reg_name)
@@ -239,12 +277,23 @@ static int __disable_regulator(struct msm_vidc_core *core, const char *reg_name)
 		/* reset handoff done from core sub_state */
 		msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_GDSC_HANDOFF, 0, __func__);
 
+		rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
+		if (rc) {
+			d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
+			goto fail_assert_xo_reset;
+		}
+
 		rc = regulator_disable(rinfo->regulator);
 		if (rc) {
 			d_vpr_e("%s: failed to disable %s, rc = %d\n",
 				__func__, rinfo->name, rc);
-			return rc;
+			goto fail_regulator_disable;
 		}
+
+		rc = call_res_op(core, reset_control_release, core, "video_xo_reset");
+		if (rc)
+			d_vpr_e("%s: failed to release video_xo_reset reset\n", __func__);
+
 		d_vpr_h("%s: disabled regulator %s\n", __func__, rinfo->name);
 		break;
 	}
@@ -254,6 +303,11 @@ static int __disable_regulator(struct msm_vidc_core *core, const char *reg_name)
 	}
 
 	return rc;
+
+fail_regulator_disable:
+	call_res_op(core, reset_control_release, core, "video_xo_reset");
+fail_assert_xo_reset:
+	return rc;
 }
 
 static int __hand_off_regulators(struct msm_vidc_core *core)