video: driver: add core sub_state support

Introduce core->sub_state similar to inst->sub_state.

[1] pm_suspended - moved to this substate in case of PM suspend
[2] handoff - moved to this state after successful
    handoff_regulator call.
[3] fw_power_control - moved to this state in case of IFPC.
[4] power_enable - will track core power_on/power_off status.
[5] page_fault - used to rate_limit fault logs.
[6] cpu_wd - indicates hw fired wd interrupt.
[7] video_unresponsive - moved to this state if sync cmd fails.

Change-Id: Iceb65cf404fd93aff7846860b0276307e4eab570
Signed-off-by: Govindaraj Rajagopal <quic_grajagop@quicinc.com>
此提交包含在:
Govindaraj Rajagopal
2022-11-14 20:22:08 +05:30
父節點 1addb15e58
當前提交 9b0140cf03
共有 14 個檔案被更改,包括 293 行新增129 行删除

查看文件

@@ -8,6 +8,7 @@
#include <linux/iopoll.h>
#include "msm_vidc_core.h"
#include "msm_vidc_driver.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_variant.h"
#include "msm_vidc_platform.h"
@@ -44,7 +45,7 @@ int __write_register(struct msm_vidc_core *core, u32 reg, u32 value)
if (rc)
return rc;
if (!core->power_enabled) {
if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
d_vpr_e("HFI Write register failed : Power is OFF\n");
return -EINVAL;
}
@@ -83,7 +84,7 @@ int __write_register_masked(struct msm_vidc_core *core, u32 reg, u32 value,
if (rc)
return rc;
if (!core->power_enabled) {
if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
d_vpr_e("%s: register write failed, power is off\n",
__func__);
return -EINVAL;
@@ -121,7 +122,7 @@ int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value)
return -EINVAL;
}
if (!core->power_enabled) {
if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
d_vpr_e("HFI Read register failed : Power is OFF\n");
return -EINVAL;
}
@@ -152,7 +153,7 @@ int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg,
return -EINVAL;
}
if (!core->power_enabled) {
if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
d_vpr_e("%s failed: Power is OFF\n", __func__);
return -EINVAL;
}

查看文件

@@ -252,7 +252,7 @@ static int __power_off_iris2_hardware(struct msm_vidc_core *core)
int rc = 0, i;
u32 value = 0;
if (core->hw_power_control) {
if (is_core_sub_state(core, CORE_SUBSTATE_FW_PWR_CTRL)) {
d_vpr_h("%s: hardware power control enabled\n", __func__);
goto disable_power;
}
@@ -417,7 +417,7 @@ static int __power_off_iris2(struct msm_vidc_core *core)
return -EINVAL;
}
if (!core->power_enabled)
if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
return 0;
/**
@@ -442,7 +442,7 @@ static int __power_off_iris2(struct msm_vidc_core *core)
disable_irq_nosync(core->resource->irq);
core->intr_status = 0;
core->power_enabled = false;
msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE, 0, __func__);
return rc;
}
@@ -504,9 +504,15 @@ static int __power_on_iris2(struct msm_vidc_core *core)
u32 freq = 0;
int rc = 0;
if (core->power_enabled)
if (is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
return 0;
if (!core_in_valid_state(core)) {
d_vpr_e("%s: invalid core state %s\n",
__func__, core_state_name(core->state));
return -EINVAL;
}
/* Vote for all hardware resources */
rc = call_res_op(core, set_bw, core, INT_MAX, INT_MAX);
if (rc) {
@@ -526,7 +532,9 @@ static int __power_on_iris2(struct msm_vidc_core *core)
goto fail_power_on_hardware;
}
/* video controller and hardware powered on successfully */
core->power_enabled = true;
rc = msm_vidc_change_core_sub_state(core, 0, CORE_SUBSTATE_POWER_ENABLE, __func__);
if (rc)
goto fail_power_on_substate;
freq_tbl = core->resource->freq_set.freq_tbl;
freq = core->power.clk_freq ? core->power.clk_freq :
@@ -552,12 +560,14 @@ static int __power_on_iris2(struct msm_vidc_core *core)
return rc;
fail_power_on_substate:
__power_off_iris2_hardware(core);
fail_power_on_hardware:
__power_off_iris2_controller(core);
fail_power_on_controller:
call_res_op(core, set_bw, core, 0, 0);
fail_vote_buses:
core->power_enabled = false;
msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE, 0, __func__);
return rc;
}

查看文件

@@ -277,24 +277,26 @@ static int __power_off_iris3_hardware(struct msm_vidc_core *core)
* 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
* is no CPU WD and hw power control is enabled, fw is expected
* to power collapse video hw always.
*/
if (core->hw_power_control) {
if (is_core_sub_state(core, CORE_SUBSTATE_FW_PWR_CTRL)) {
pwr_collapsed = is_iris3_hw_power_collapsed(core);
if (core->cpu_watchdog || core->video_unresponsive) {
if (is_core_sub_state(core, CORE_SUBSTATE_CPU_WATCHDOG) ||
is_core_sub_state(core, CORE_SUBSTATE_VIDEO_UNRESPONSIVE)) {
if (pwr_collapsed) {
d_vpr_e("%s: video hw power collapsed %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
d_vpr_e("%s: video hw power collapsed %s\n",
__func__, core->sub_state_name);
goto disable_power;
} else {
d_vpr_e("%s: video hw is power ON %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
d_vpr_e("%s: video hw is power ON %s\n",
__func__, core->sub_state_name);
}
} else {
if (!pwr_collapsed)
d_vpr_e("%s: video hw is not power collapsed\n", __func__);
d_vpr_h("%s: disabling hw power\n", __func__);
goto disable_power;
}
}
@@ -465,7 +467,7 @@ static int __power_off_iris3(struct msm_vidc_core *core)
return -EINVAL;
}
if (!core->power_enabled)
if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
return 0;
/**
@@ -490,7 +492,7 @@ static int __power_off_iris3(struct msm_vidc_core *core)
disable_irq_nosync(core->resource->irq);
core->intr_status = 0;
core->power_enabled = false;
msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE, 0, __func__);
return rc;
}
@@ -552,9 +554,15 @@ static int __power_on_iris3(struct msm_vidc_core *core)
u32 freq = 0;
int rc = 0;
if (core->power_enabled)
if (is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
return 0;
if (!core_in_valid_state(core)) {
d_vpr_e("%s: invalid core state %s\n",
__func__, core_state_name(core->state));
return -EINVAL;
}
/* Vote for all hardware resources */
rc = call_res_op(core, set_bw, core, INT_MAX, INT_MAX);
if (rc) {
@@ -574,7 +582,9 @@ static int __power_on_iris3(struct msm_vidc_core *core)
goto fail_power_on_hardware;
}
/* video controller and hardware powered on successfully */
core->power_enabled = true;
rc = msm_vidc_change_core_sub_state(core, 0, CORE_SUBSTATE_POWER_ENABLE, __func__);
if (rc)
goto fail_power_on_substate;
freq_tbl = core->resource->freq_set.freq_tbl;
freq = core->power.clk_freq ? core->power.clk_freq :
@@ -597,12 +607,14 @@ static int __power_on_iris3(struct msm_vidc_core *core)
return rc;
fail_power_on_substate:
__power_off_iris3_hardware(core);
fail_power_on_hardware:
__power_off_iris3_controller(core);
fail_power_on_controller:
call_res_op(core, set_bw, core, 0, 0);
fail_vote_buses:
core->power_enabled = false;
msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE, 0, __func__);
return rc;
}

查看文件

@@ -280,24 +280,26 @@ static int __power_off_iris33_hardware(struct msm_vidc_core *core)
* 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
* is no CPU WD and hw power control is enabled, fw is expected
* to power collapse video hw always.
*/
if (core->hw_power_control) {
if (is_core_sub_state(core, CORE_SUBSTATE_FW_PWR_CTRL)) {
pwr_collapsed = is_iris33_hw_power_collapsed(core);
if (core->cpu_watchdog || core->video_unresponsive) {
if (is_core_sub_state(core, CORE_SUBSTATE_CPU_WATCHDOG) ||
is_core_sub_state(core, CORE_SUBSTATE_VIDEO_UNRESPONSIVE)) {
if (pwr_collapsed) {
d_vpr_e("%s: video hw power collapsed %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
d_vpr_e("%s: video hw power collapsed %s\n",
__func__, core->sub_state_name);
goto disable_power;
} else {
d_vpr_e("%s: video hw is power ON %d, %d\n",
__func__, core->cpu_watchdog, core->video_unresponsive);
d_vpr_e("%s: video hw is power ON %s\n",
__func__, core->sub_state_name);
}
} else {
if (!pwr_collapsed)
d_vpr_e("%s: video hw is not power collapsed\n", __func__);
d_vpr_h("%s: disabling hw power\n", __func__);
goto disable_power;
}
}
@@ -530,7 +532,7 @@ static int __power_off_iris33(struct msm_vidc_core *core)
return -EINVAL;
}
if (!core->power_enabled)
if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
return 0;
/**
@@ -555,7 +557,7 @@ static int __power_off_iris33(struct msm_vidc_core *core)
disable_irq_nosync(core->resource->irq);
core->intr_status = 0;
core->power_enabled = false;
msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE, 0, __func__);
return rc;
}
@@ -633,9 +635,15 @@ static int __power_on_iris33(struct msm_vidc_core *core)
u32 freq = 0;
int rc = 0;
if (core->power_enabled)
if (is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE))
return 0;
if (!core_in_valid_state(core)) {
d_vpr_e("%s: invalid core state %s\n",
__func__, core_state_name(core->state));
return -EINVAL;
}
/* Vote for all hardware resources */
rc = call_res_op(core, set_bw, core, INT_MAX, INT_MAX);
if (rc) {
@@ -655,7 +663,9 @@ static int __power_on_iris33(struct msm_vidc_core *core)
goto fail_power_on_hardware;
}
/* video controller and hardware powered on successfully */
core->power_enabled = true;
rc = msm_vidc_change_core_sub_state(core, 0, CORE_SUBSTATE_POWER_ENABLE, __func__);
if (rc)
goto fail_power_on_substate;
freq_tbl = core->resource->freq_set.freq_tbl;
freq = core->power.clk_freq ? core->power.clk_freq :
@@ -678,12 +688,14 @@ static int __power_on_iris33(struct msm_vidc_core *core)
return rc;
fail_power_on_substate:
__power_off_iris33_hardware(core);
fail_power_on_hardware:
__power_off_iris33_controller(core);
fail_power_on_controller:
call_res_op(core, set_bw, core, 0, 0);
fail_vote_buses:
core->power_enabled = false;
msm_vidc_change_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE, 0, __func__);
return rc;
}