diff --git a/driver/vidc/inc/hfi_packet.h b/driver/vidc/inc/hfi_packet.h index e1c9cbee10..43eda70d80 100644 --- a/driver/vidc/inc/hfi_packet.h +++ b/driver/vidc/inc/hfi_packet.h @@ -42,4 +42,6 @@ int hfi_packet_sys_debug_config(struct msm_vidc_core *core, int hfi_packet_session_command(struct msm_vidc_inst *inst, u32 pkt_type, u32 flags, u32 port, u32 session_id, u32 payload_type, void *payload, u32 payload_size); +int hfi_packet_sys_intraframe_powercollapse(struct msm_vidc_core* core, + u8* pkt, u32 pkt_size, u32 enable); #endif // _HFI_PACKET_H_ diff --git a/driver/vidc/inc/msm_vidc_core.h b/driver/vidc/inc/msm_vidc_core.h index f8bd3a960a..f8a1f52da8 100644 --- a/driver/vidc/inc/msm_vidc_core.h +++ b/driver/vidc/inc/msm_vidc_core.h @@ -109,6 +109,7 @@ struct msm_vidc_core { u32 header_id; u32 packet_id; struct completion init_done; + u32 handoff_done; }; #endif // _MSM_VIDC_CORE_H_ diff --git a/driver/vidc/src/hfi_packet.c b/driver/vidc/src/hfi_packet.c index 3d774ccb3d..63d48febdb 100644 --- a/driver/vidc/src/hfi_packet.c +++ b/driver/vidc/src/hfi_packet.c @@ -354,20 +354,6 @@ int hfi_packet_sys_init(struct msm_vidc_core *core, if (rc) goto err_sys_init; - /* HFI_PROP_INTRA_FRAME_POWER_COLLAPSE */ - payload = 0; - d_vpr_h("%s: intra frame power collapse %d\n", __func__, payload); - rc = hfi_create_packet(pkt, pkt_size, - HFI_PROP_INTRA_FRAME_POWER_COLLAPSE, - HFI_HOST_FLAGS_NONE, - HFI_PAYLOAD_U32, - HFI_PORT_NONE, - core->packet_id++, - &payload, - sizeof(u32)); - if (rc) - goto err_sys_init; - /* HFI_PROP_UBWC_MAX_CHANNELS */ payload = core->platform->data.ubwc_config->max_channels; d_vpr_h("%s: ubwc max channels %d\n", __func__, payload); @@ -635,3 +621,42 @@ err_cmd: d_vpr_e("%s: create packet failed\n", __func__); return rc; } + +int hfi_packet_sys_intraframe_powercollapse(struct msm_vidc_core* core, + u8* pkt, u32 pkt_size, u32 enable) +{ + int rc = 0; + u32 payload = 0; + + if (!core || !pkt) { + d_vpr_e("%s: Invalid params\n", __func__); + return -EINVAL; + } + + rc = hfi_create_header(pkt, pkt_size, + 0 /*session_id*/, + core->header_id++); + if (rc) + goto err; + + /* HFI_PROP_INTRA_FRAME_POWER_COLLAPSE */ + payload = enable; + d_vpr_h("%s: intra frame power collapse %d\n", __func__, payload); + rc = hfi_create_packet(pkt, pkt_size, + HFI_PROP_INTRA_FRAME_POWER_COLLAPSE, + HFI_HOST_FLAGS_NONE, + HFI_PAYLOAD_U32, + HFI_PORT_NONE, + core->packet_id++, + &payload, + sizeof(u32)); + if (rc) + goto err; + + d_vpr_h("IFPC packet created\n"); + return rc; + +err: + d_vpr_e("%s: create packet failed\n", __func__); + return rc; +} diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 78e5da2546..a25b7a2baa 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -713,7 +713,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) kref_init(&inst->kref); mutex_init(&inst->lock); - i_vpr_e(inst, "Opening video instance: %d\n", session_type); + i_vpr_h(inst, "Opening video instance: %d\n", session_type); inst->response_workq = create_singlethread_workqueue("response_workq"); if (!inst->response_workq) { diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index f9a3b5e808..b1eb5fb14b 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -386,10 +386,12 @@ static int __hand_off_regulator(struct msm_vidc_core *core, rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_FAST); if (rc) { + core->handoff_done = 0; d_vpr_e("Failed to hand off regulator control: %s\n", rinfo->name); return rc; } else { + core->handoff_done = 1; d_vpr_h("Hand off regulator control to HW: %s\n", rinfo->name); } @@ -1049,28 +1051,24 @@ static int __sys_set_coverage(struct msm_vidc_core *core, return 0; } - +*/ static int __sys_set_power_control(struct msm_vidc_core *core, bool enable) { - struct regulator_info *rinfo; - bool supported = false; + int rc = 0; - venus_hfi_for_each_regulator(core, rinfo) { - if (rinfo->has_hw_power_collapse) { - supported = true; - break; - } - } + if (!core->handoff_done) + return rc; - if (!supported) - return 0; + rc = hfi_packet_sys_intraframe_powercollapse(core, core->packet, core->packet_size, enable); + if (rc) + return rc; - //call_hfi_pkt_op(core, sys_power_control, pkt, enable); - //if (__iface_cmdq_write(core, pkt, sid)) - // return -ENOTEMPTY; - return 0; + rc = __iface_cmdq_write(core, core->packet); + if (rc) + return rc; + + return rc; } -*/ int __prepare_pc(struct msm_vidc_core *core) { @@ -1698,14 +1696,11 @@ static int __enable_hw_power_collapse(struct msm_vidc_core *core) { int rc = 0; - // TODO: skip if hardwar power control feature is not present - d_vpr_e("%s: skip hand off regulators\n", __func__); - return 0; - rc = __hand_off_regulators(core); if (rc) d_vpr_e("%s: Failed to enable HW power collapse %d\n", - __func__, rc); + __func__, rc); + return rc; } @@ -2122,6 +2117,7 @@ static int __resume(struct msm_vidc_core *core) } __sys_set_debug(core, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT); + rc = __enable_subcaches(core); if (rc) { d_vpr_e("Failed to activate subcache\n"); @@ -2129,6 +2125,9 @@ static int __resume(struct msm_vidc_core *core) } __set_subcaches(core); + if (core->handoff_done) + __sys_set_power_control(core, true); + d_vpr_h("Resumed from power collapse\n"); exit: /* Don't reset skip_pc_count for SYS_PC_PREP cmd */ @@ -2679,6 +2678,9 @@ int venus_hfi_core_init(struct msm_vidc_core *core) if (rc) goto error; + if (core->handoff_done) + __sys_set_power_control(core, true); + d_vpr_h("%s(): successful\n", __func__); return 0;