diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 3ddbf614ea43..275d86a677a1 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -387,6 +387,8 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, return -EINVAL; } + inst->last_qbuf_time_ns = ktime_get_ns(); + for (i = 0; i < b->length; i++) { b->m.planes[i].m.fd = b->m.planes[i].reserved[MSM_VIDC_BUFFER_FD]; @@ -1510,6 +1512,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->full_range = COLOR_RANGE_UNSPECIFIED; inst->bse_vpp_delay = DEFAULT_BSE_VPP_DELAY; inst->first_reconfig = 0; + inst->active = true; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 8fbe805618fd..2aedffc911c8 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -17,6 +17,8 @@ #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) #define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) +#define MSM_VIDC_SESSION_INACTIVE_THRESHOLD_MS 1000 + static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq_ar50_lt(struct msm_vidc_inst *inst, u32 filled_len); @@ -155,6 +157,19 @@ int msm_vidc_get_fps(struct msm_vidc_inst *inst) return fps; } +static inline bool is_active_session(u64 prev, u64 curr) +{ + u64 ts_delta; + + if (!prev || !curr) + return true; + + ts_delta = (prev < curr) ? curr - prev : prev - curr; + + return ((ts_delta / NSEC_PER_MSEC) <= + MSM_VIDC_SESSION_INACTIVE_THRESHOLD_MS); +} + void update_recon_stats(struct msm_vidc_inst *inst, struct recon_stats_type *recon_stats) { @@ -263,12 +278,14 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) struct msm_vidc_inst *inst = NULL; struct hfi_device *hdev; unsigned long total_bw_ddr = 0, total_bw_llcc = 0; + u64 curr_time_ns; if (!core || !core->device) { s_vpr_e(sid, "%s: Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; + curr_time_ns = ktime_get_ns(); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { @@ -292,6 +309,12 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) continue; } + /* skip inactive session bus bandwidth */ + if (!is_active_session(inst->last_qbuf_time_ns, curr_time_ns)) { + inst->active = false; + continue; + } + if (inst->bus_data.power_mode == VIDC_POWER_TURBO) { total_bw_ddr = total_bw_llcc = INT_MAX; break; @@ -766,8 +789,10 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) int rc = 0, i = 0; struct allowed_clock_rates_table *allowed_clks_tbl = NULL; bool increment, decrement; + u64 curr_time_ns; hdev = core->device; + curr_time_ns = ktime_get_ns(); allowed_clks_tbl = core->resources.allowed_clks_tbl; if (!allowed_clks_tbl) { s_vpr_e(sid, "%s: Invalid parameters\n", __func__); @@ -796,6 +821,12 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) continue; } + /* skip inactive session clock rate */ + if (!is_active_session(inst->last_qbuf_time_ns, curr_time_ns)) { + inst->active = false; + continue; + } + if (inst->clk_data.core_id == VIDC_CORE_ID_1) freq_core_1 += inst->clk_data.min_freq; else if (inst->clk_data.core_id == VIDC_CORE_ID_2) @@ -919,6 +950,12 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) core = inst->core; hdev = core->device; + if (!inst->active) { + /* do not skip bw voting for inactive -> active session */ + do_bw_calc = true; + inst->active = true; + } + if (msm_comm_scale_clocks(inst)) { s_vpr_e(inst->sid, "Failed to scale clocks. May impact performance\n"); @@ -930,6 +967,7 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) "Failed to scale DDR bus. May impact perf\n"); } } + return 0; } diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 9b8c1cdb9d58..f14e8d3abe90 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -569,6 +569,8 @@ struct msm_vidc_inst { struct msm_vidc_ubwc_stats ubwc_stats; u32 bse_vpp_delay; u32 first_reconfig; + u64 last_qbuf_time_ns; + bool active; }; extern struct msm_vidc_drv *vidc_driver;