diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index fde836d1dd..ecb58aada1 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -61,10 +61,10 @@ static struct msm_platform_core_capability core_data_waipio[] = { {MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */ {MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */ {NUM_VPP_PIPE, 4}, - {SW_PC, 0}, - {SW_PC_DELAY, 1500}, /* 1500 ms */ + {SW_PC, 1}, + {SW_PC_DELAY, 20000}, /* 20000 ms (>HW_RESPONSE_TIMEOUT)*/ {FW_UNLOAD, 0}, - {FW_UNLOAD_DELAY, 1000}, /* 1000 ms */ + {FW_UNLOAD_DELAY, 25000}, /* 25000 ms (>PC_DELAY)*/ {HW_RESPONSE_TIMEOUT, 15000}, /* 1000 ms */ {DEBUG_TIMEOUT, 0}, // TODO: review below entries, and if required rename as PREFETCH diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index fef4fb7454..f8100a3314 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -226,7 +226,7 @@ int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst); int msm_vidc_change_core_state(struct msm_vidc_core *core, enum msm_vidc_core_state request_state, const char *func); int msm_vidc_core_init(struct msm_vidc_core *core); -int msm_vidc_core_deinit(struct msm_vidc_core *core); +int msm_vidc_core_deinit(struct msm_vidc_core *core, bool force); int msm_vidc_core_timeout(struct msm_vidc_core *core); int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags, void *data); @@ -298,5 +298,6 @@ void inst_lock(struct msm_vidc_inst *inst, const char *function); void inst_unlock(struct msm_vidc_inst *inst, const char *function); bool inst_lock_check(struct msm_vidc_inst *inst, const char *function); int msm_vidc_update_meta_port_settings(struct msm_vidc_inst *inst); +void msm_vidc_schedule_core_deinit(struct msm_vidc_core *core); #endif // _MSM_VIDC_DRIVER_H_ diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 31cbe069e2..47739399dc 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -817,11 +817,15 @@ int msm_vidc_close(void *instance) { int rc = 0; struct msm_vidc_inst *inst = instance; + struct msm_vidc_core *core; if (!inst) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } + + core = inst->core; + s_vpr_h(inst->sid, "%s()\n", __func__); mutex_lock(&inst->lock); msm_vidc_session_close(inst); @@ -829,6 +833,8 @@ int msm_vidc_close(void *instance) msm_vidc_destroy_buffers(inst); mutex_unlock(&inst->lock); put_inst(inst); + msm_vidc_schedule_core_deinit(core); + return rc; } EXPORT_SYMBOL(msm_vidc_close); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 9dad8957bc..a6517e1c27 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -442,11 +442,6 @@ int msm_vidc_change_core_state(struct msm_vidc_core *core, return -EINVAL; } - if (!request_state) { - d_vpr_e("%s: invalid core request state\n", func); - return -EINVAL; - } - d_vpr_h("%s: core state changed from %s to %s\n", func, core_state_name(core->state), core_state_name(request_state)); @@ -2457,7 +2452,7 @@ error: return rc; } -int msm_vidc_core_deinit(struct msm_vidc_core *core) +int msm_vidc_core_deinit(struct msm_vidc_core *core, bool force) { int rc = 0; struct msm_vidc_inst *inst, *dummy; @@ -2466,10 +2461,14 @@ int msm_vidc_core_deinit(struct msm_vidc_core *core) d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } + mutex_lock(&core->lock); d_vpr_h("%s()\n", __func__); if (core->state == MSM_VIDC_CORE_DEINIT) goto unlock; + if (!force) + if (!list_empty(&core->instances)) + goto unlock; venus_hfi_core_deinit(core); msm_vidc_deinit_instance_caps(core); @@ -2542,7 +2541,7 @@ unlock: int msm_vidc_core_timeout(struct msm_vidc_core *core) { - return msm_vidc_core_deinit(core); + return msm_vidc_core_deinit(core, true); } int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, @@ -2567,6 +2566,20 @@ void msm_vidc_pm_work_handler(struct work_struct *work) void msm_vidc_fw_unload_handler(struct work_struct *work) { + struct msm_vidc_core *core = NULL; + int rc = 0; + + core = container_of(work, struct msm_vidc_core, fw_unload_work.work); + if (!core) { + d_vpr_e("%s: invalid work or core handle\n", __func__); + return; + } + + d_vpr_h("%s: deinitializing video core\n",__func__); + rc = msm_vidc_core_deinit(core, false); + if (rc) + d_vpr_e("%s: Failed to deinit core\n", __func__); + } void msm_vidc_batch_handler(struct work_struct *work) @@ -2811,3 +2824,23 @@ int msm_vidc_update_meta_port_settings(struct msm_vidc_inst *inst) } return 0; } + +void msm_vidc_schedule_core_deinit(struct msm_vidc_core *core) +{ + if (!core) + return; + + if (!core->capabilities[FW_UNLOAD].value) + return; + + cancel_delayed_work(&core->fw_unload_work); + + schedule_delayed_work(&core->fw_unload_work, + msecs_to_jiffies(core->capabilities[FW_UNLOAD_DELAY].value)); + + d_vpr_h("firmware unload delayed by %u ms\n", + core->capabilities[FW_UNLOAD_DELAY].value); + + return; +} + diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index 92095e64c9..84a3757736 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -230,7 +230,7 @@ static int handle_system_error(struct msm_vidc_core *core, struct hfi_packet *pkt) { d_vpr_e("%s: system error received\n", __func__); - msm_vidc_core_deinit(core); + msm_vidc_core_deinit(core, true); return 0; }