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 <quic_vnagar@quicinc.com>
This commit is contained in:
@@ -383,7 +383,6 @@ static int __power_off_iris33_controller(struct msm_vidc_core *core)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int value = 0;
|
int value = 0;
|
||||||
u32 count = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mask fal10_veto QLPAC error since fal10_veto can go 1
|
* 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
|
* drivers (eva driver) operating on this shared reset clock
|
||||||
* and AON_WRAPPER_SPARE register in parallel.
|
* and AON_WRAPPER_SPARE register in parallel.
|
||||||
*/
|
*/
|
||||||
count = 0;
|
rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
|
||||||
do {
|
if (rc) {
|
||||||
rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
|
d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
|
||||||
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__);
|
|
||||||
goto skip_video_xo_reset;
|
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 */
|
/* enable bit(1) to avoid cvp noc xo reset */
|
||||||
rc = __write_register(core, AON_WRAPPER_SPARE, value | 0x2);
|
rc = __write_register(core, AON_WRAPPER_SPARE, value | 0x2);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
goto exit;
|
||||||
|
|
||||||
/* assert video_cc XO reset */
|
/* assert video_cc XO reset */
|
||||||
rc = call_res_op(core, reset_control_assert, core, "video_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 */
|
/* reset AON spare register */
|
||||||
rc = __write_register(core, AON_WRAPPER_SPARE, 0x0);
|
rc = __write_register(core, AON_WRAPPER_SPARE, 0x0);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
goto exit;
|
||||||
|
|
||||||
/* release reset control for other consumers */
|
/* release reset control for other consumers */
|
||||||
rc = call_res_op(core, reset_control_release, core, "video_xo_reset");
|
rc = call_res_op(core, reset_control_release, core, "video_xo_reset");
|
||||||
@@ -570,6 +556,10 @@ skip_video_xo_reset:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
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)
|
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;
|
struct frequency_table *freq_tbl;
|
||||||
u32 freq = 0;
|
u32 freq = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
|
if (is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
|
||||||
return 0;
|
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
|
* access failure, so acquire video_xo_reset to ensure EVA module is
|
||||||
* not doing assert or de-assert on video_xo_reset.
|
* not doing assert or de-assert on video_xo_reset.
|
||||||
*/
|
*/
|
||||||
do {
|
rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
|
||||||
rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
|
if (rc) {
|
||||||
if (!rc) {
|
d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
|
||||||
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__);
|
|
||||||
goto fail_assert_xo_reset;
|
goto fail_assert_xo_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -822,6 +799,7 @@ static int __power_on_iris33(struct msm_vidc_core *core)
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
fail_program_noc_regs:
|
fail_program_noc_regs:
|
||||||
|
call_res_op(core, reset_control_release, core, "video_xo_reset");
|
||||||
fail_deassert_xo_reset:
|
fail_deassert_xo_reset:
|
||||||
fail_assert_xo_reset:
|
fail_assert_xo_reset:
|
||||||
fail_power_on_substate:
|
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)
|
static int __noc_error_info_iris33(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
u32 count = 0;
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1070,21 +1047,9 @@ static int __noc_error_info_iris33(struct msm_vidc_core *core)
|
|||||||
* while reading noc registers
|
* while reading noc registers
|
||||||
*/
|
*/
|
||||||
d_vpr_e("%s: read NOC ERR LOG registers\n", __func__);
|
d_vpr_e("%s: read NOC ERR LOG registers\n", __func__);
|
||||||
do {
|
rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
|
||||||
rc = call_res_op(core, reset_control_acquire, core, "video_xo_reset");
|
if (rc) {
|
||||||
if (!rc) {
|
d_vpr_e("%s: failed to acquire video_xo_reset control\n", __func__);
|
||||||
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__);
|
|
||||||
goto fail_assert_xo_reset;
|
goto fail_assert_xo_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1445,7 +1445,7 @@ static int __reset_control_acquire_name(struct msm_vidc_core *core,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
struct reset_info *rcinfo = NULL;
|
struct reset_info *rcinfo = NULL;
|
||||||
int rc = 0;
|
int rc = 0, count = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
venus_hfi_for_each_reset_clock(core, rcinfo) {
|
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;
|
found = true;
|
||||||
/* reset_control_acquire is exposed in kernel version 6 */
|
/* reset_control_acquire is exposed in kernel version 6 */
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
|
#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
|
#else
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -89,6 +89,12 @@ static int __acquire_regulator(struct msm_vidc_core *core,
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
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->hw_power_collapse) {
|
||||||
if (!rinfo->regulator) {
|
if (!rinfo->regulator) {
|
||||||
d_vpr_e("%s: invalid regulator\n", __func__);
|
d_vpr_e("%s: invalid regulator\n", __func__);
|
||||||
@@ -133,6 +139,10 @@ static int __acquire_regulator(struct msm_vidc_core *core,
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,10 +151,16 @@ static int __hand_off_regulator(struct msm_vidc_core *core,
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
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->hw_power_collapse) {
|
||||||
if (!rinfo->regulator) {
|
if (!rinfo->regulator) {
|
||||||
d_vpr_e("%s: invalid regulator\n", __func__);
|
d_vpr_e("%s: invalid regulator\n", __func__);
|
||||||
return -EINVAL;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = regulator_set_mode(rinfo->regulator,
|
rc = regulator_set_mode(rinfo->regulator,
|
||||||
@@ -152,7 +168,7 @@ static int __hand_off_regulator(struct msm_vidc_core *core,
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("Failed to hand off regulator control: %s\n",
|
d_vpr_e("Failed to hand off regulator control: %s\n",
|
||||||
rinfo->name);
|
rinfo->name);
|
||||||
return rc;
|
goto exit;
|
||||||
} else {
|
} else {
|
||||||
/* set handoff done in core sub_state */
|
/* set handoff done in core sub_state */
|
||||||
msm_vidc_change_core_sub_state(core,
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,18 +209,30 @@ static int __enable_regulator(struct msm_vidc_core *core, const char *reg_name)
|
|||||||
continue;
|
continue;
|
||||||
found = true;
|
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);
|
rc = regulator_enable(rinfo->regulator);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: failed to enable %s, rc = %d\n",
|
d_vpr_e("%s: failed to enable %s, rc = %d\n",
|
||||||
__func__, rinfo->name, rc);
|
__func__, rinfo->name, rc);
|
||||||
return rc;
|
goto fail_regulator_enable;
|
||||||
}
|
}
|
||||||
if (!regulator_is_enabled(rinfo->regulator)) {
|
if (!regulator_is_enabled(rinfo->regulator)) {
|
||||||
d_vpr_e("%s: regulator %s not enabled\n",
|
d_vpr_e("%s: regulator %s not enabled\n",
|
||||||
__func__, rinfo->name);
|
__func__, rinfo->name);
|
||||||
regulator_disable(rinfo->regulator);
|
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);
|
d_vpr_h("%s: enabled regulator %s\n", __func__, rinfo->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -209,6 +242,11 @@ static int __enable_regulator(struct msm_vidc_core *core, const char *reg_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
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)
|
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 */
|
/* reset handoff done from core sub_state */
|
||||||
msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_GDSC_HANDOFF, 0, __func__);
|
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);
|
rc = regulator_disable(rinfo->regulator);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: failed to disable %s, rc = %d\n",
|
d_vpr_e("%s: failed to disable %s, rc = %d\n",
|
||||||
__func__, rinfo->name, rc);
|
__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);
|
d_vpr_h("%s: disabled regulator %s\n", __func__, rinfo->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -254,6 +303,11 @@ static int __disable_regulator(struct msm_vidc_core *core, const char *reg_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
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)
|
static int __hand_off_regulators(struct msm_vidc_core *core)
|
||||||
|
Reference in New Issue
Block a user