waipio: driver: Add support for fw unload and power collapse
If required, Firmware can be unloaded after every session. Power collapse is enabled by default. Change-Id: Ie014a26ae600816d8713cd34826f1f9a77088e4a Signed-off-by: Chinmay Sawarkar <chinmays@codeaurora.org>
This commit is contained in:
@@ -61,10 +61,10 @@ static struct msm_platform_core_capability core_data_waipio[] = {
|
|||||||
{MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */
|
{MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */
|
||||||
{MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */
|
{MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */
|
||||||
{NUM_VPP_PIPE, 4},
|
{NUM_VPP_PIPE, 4},
|
||||||
{SW_PC, 0},
|
{SW_PC, 1},
|
||||||
{SW_PC_DELAY, 1500}, /* 1500 ms */
|
{SW_PC_DELAY, 20000}, /* 20000 ms (>HW_RESPONSE_TIMEOUT)*/
|
||||||
{FW_UNLOAD, 0},
|
{FW_UNLOAD, 0},
|
||||||
{FW_UNLOAD_DELAY, 1000}, /* 1000 ms */
|
{FW_UNLOAD_DELAY, 25000}, /* 25000 ms (>PC_DELAY)*/
|
||||||
{HW_RESPONSE_TIMEOUT, 15000}, /* 1000 ms */
|
{HW_RESPONSE_TIMEOUT, 15000}, /* 1000 ms */
|
||||||
{DEBUG_TIMEOUT, 0},
|
{DEBUG_TIMEOUT, 0},
|
||||||
// TODO: review below entries, and if required rename as PREFETCH
|
// TODO: review below entries, and if required rename as PREFETCH
|
||||||
|
@@ -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,
|
int msm_vidc_change_core_state(struct msm_vidc_core *core,
|
||||||
enum msm_vidc_core_state request_state, const char *func);
|
enum msm_vidc_core_state request_state, const char *func);
|
||||||
int msm_vidc_core_init(struct msm_vidc_core *core);
|
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_core_timeout(struct msm_vidc_core *core);
|
||||||
int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
|
int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
|
||||||
struct device *dev, unsigned long iova, int flags, void *data);
|
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);
|
void inst_unlock(struct msm_vidc_inst *inst, const char *function);
|
||||||
bool inst_lock_check(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);
|
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_
|
#endif // _MSM_VIDC_DRIVER_H_
|
||||||
|
|
||||||
|
@@ -817,11 +817,15 @@ int msm_vidc_close(void *instance)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct msm_vidc_inst *inst = instance;
|
struct msm_vidc_inst *inst = instance;
|
||||||
|
struct msm_vidc_core *core;
|
||||||
|
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core = inst->core;
|
||||||
|
|
||||||
s_vpr_h(inst->sid, "%s()\n", __func__);
|
s_vpr_h(inst->sid, "%s()\n", __func__);
|
||||||
mutex_lock(&inst->lock);
|
mutex_lock(&inst->lock);
|
||||||
msm_vidc_session_close(inst);
|
msm_vidc_session_close(inst);
|
||||||
@@ -829,6 +833,8 @@ int msm_vidc_close(void *instance)
|
|||||||
msm_vidc_destroy_buffers(inst);
|
msm_vidc_destroy_buffers(inst);
|
||||||
mutex_unlock(&inst->lock);
|
mutex_unlock(&inst->lock);
|
||||||
put_inst(inst);
|
put_inst(inst);
|
||||||
|
msm_vidc_schedule_core_deinit(core);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msm_vidc_close);
|
EXPORT_SYMBOL(msm_vidc_close);
|
||||||
|
@@ -442,11 +442,6 @@ int msm_vidc_change_core_state(struct msm_vidc_core *core,
|
|||||||
return -EINVAL;
|
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",
|
d_vpr_h("%s: core state changed from %s to %s\n",
|
||||||
func, core_state_name(core->state),
|
func, core_state_name(core->state),
|
||||||
core_state_name(request_state));
|
core_state_name(request_state));
|
||||||
@@ -2457,7 +2452,7 @@ error:
|
|||||||
return rc;
|
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;
|
int rc = 0;
|
||||||
struct msm_vidc_inst *inst, *dummy;
|
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__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&core->lock);
|
mutex_lock(&core->lock);
|
||||||
d_vpr_h("%s()\n", __func__);
|
d_vpr_h("%s()\n", __func__);
|
||||||
if (core->state == MSM_VIDC_CORE_DEINIT)
|
if (core->state == MSM_VIDC_CORE_DEINIT)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
if (!force)
|
||||||
|
if (!list_empty(&core->instances))
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
venus_hfi_core_deinit(core);
|
venus_hfi_core_deinit(core);
|
||||||
msm_vidc_deinit_instance_caps(core);
|
msm_vidc_deinit_instance_caps(core);
|
||||||
@@ -2542,7 +2541,7 @@ unlock:
|
|||||||
|
|
||||||
int msm_vidc_core_timeout(struct msm_vidc_core *core)
|
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,
|
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)
|
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)
|
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;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -230,7 +230,7 @@ static int handle_system_error(struct msm_vidc_core *core,
|
|||||||
struct hfi_packet *pkt)
|
struct hfi_packet *pkt)
|
||||||
{
|
{
|
||||||
d_vpr_e("%s: system error received\n", __func__);
|
d_vpr_e("%s: system error received\n", __func__);
|
||||||
msm_vidc_core_deinit(core);
|
msm_vidc_core_deinit(core, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user