video: iris3: Fix the issue in power collapsing video hardware
During power collapse, video driver would power collapse video hardware followed by video controller. While power collapsing video hardware, it may happen that video firmware has already power collapsed the video hardware, since it is hardware controlled. For certain cases, like XS WD, it may happen that video hardware may not be power collapsed by video firmware. In such scenario, skipping power collapse sequence of video hardware would lead to unhandled transactions from video hardware. There is a power status register which can clearly suggest if the video hardware is power down or not. Added a check to confirm the power status of video hardware before skipping or executing the power collapse sequence for video hardware. Change-Id: Ibd9cd708a259897262fcc6cab27b26aaf37f1b13 Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Esse commit está contido em:
@@ -110,6 +110,7 @@
|
||||
#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS3 (WRAPPER_BASE_OFFS_IRIS3 + 0x58)
|
||||
#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS_IRIS3 + 0x5C)
|
||||
#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS_IRIS3 + 0x60)
|
||||
#define WRAPPER_CORE_POWER_STATUS (WRAPPER_BASE_OFFS_IRIS3 + 0x80)
|
||||
#define WRAPPER_CORE_CLOCK_CONFIG_IRIS3 (WRAPPER_BASE_OFFS_IRIS3 + 0x88)
|
||||
|
||||
/*
|
||||
@@ -448,14 +449,47 @@ static int __setup_ucregion_memory_map_iris3(struct msm_vidc_core *vidc_core)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_iris3_hw_power_collapsed(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 value = 0, pwr_status = 0;
|
||||
|
||||
rc = __read_register(core, WRAPPER_CORE_POWER_STATUS, &value);
|
||||
if (rc)
|
||||
return false;
|
||||
|
||||
/* if BIT(1) is 1 then video hw power is on else off */
|
||||
pwr_status = value & BIT(1);
|
||||
return pwr_status ? false : true;
|
||||
}
|
||||
|
||||
static int __power_off_iris3_hardware(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0, i;
|
||||
u32 value = 0;
|
||||
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
|
||||
* to power collapse video hw always.
|
||||
*/
|
||||
if (core->hw_power_control) {
|
||||
d_vpr_h("%s: hardware power control enabled\n", __func__);
|
||||
goto disable_power;
|
||||
pwr_collapsed = is_iris3_hw_power_collapsed(core);
|
||||
if (core->cpu_watchdog) {
|
||||
if (pwr_collapsed) {
|
||||
d_vpr_e("%s: CPU WD and video hw power collapsed\n", __func__);
|
||||
goto disable_power;
|
||||
} else {
|
||||
d_vpr_e("%s: CPU WD and video hw is power ON\n", __func__);
|
||||
}
|
||||
} else {
|
||||
if (!pwr_collapsed)
|
||||
d_vpr_e("%s: video hw is not power collapsed\n", __func__);
|
||||
|
||||
goto disable_power;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -119,6 +119,7 @@ struct msm_vidc_core {
|
||||
bool handoff_done;
|
||||
bool hw_power_control;
|
||||
bool pm_suspended;
|
||||
bool cpu_watchdog;
|
||||
};
|
||||
|
||||
#endif // _MSM_VIDC_CORE_H_
|
||||
|
@@ -2456,6 +2456,7 @@ int __load_fw(struct msm_vidc_core *core)
|
||||
d_vpr_h("%s\n", __func__);
|
||||
core->handoff_done = false;
|
||||
core->hw_power_control = false;
|
||||
core->cpu_watchdog = false;
|
||||
|
||||
trace_msm_v4l2_vidc_fw_load("START");
|
||||
rc = __init_resources(core);
|
||||
@@ -2533,6 +2534,8 @@ void __unload_fw(struct msm_vidc_core *core)
|
||||
__venus_power_off(core);
|
||||
__deinit_resources(core);
|
||||
|
||||
core->cpu_watchdog = false;
|
||||
|
||||
d_vpr_h("%s done\n", __func__);
|
||||
}
|
||||
|
||||
@@ -2542,6 +2545,8 @@ static int __response_handler(struct msm_vidc_core *core)
|
||||
|
||||
if (call_venus_op(core, watchdog, core, core->intr_status)) {
|
||||
struct hfi_packet pkt = {.type = HFI_SYS_ERROR_WD_TIMEOUT};
|
||||
core->cpu_watchdog = true;
|
||||
d_vpr_e("%s: CPU WD error received\n", __func__);
|
||||
|
||||
return handle_system_error(core, &pkt);
|
||||
}
|
||||
|
Referência em uma nova issue
Block a user