diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 4fab5a81fdd2..5725062d96cf 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -854,12 +854,12 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, } /* - * Special handling for operating rate 0xFFFFFFFF, + * Special handling for operating rate INT_MAX, * client's intention is not to skip cvp preprocess * based on operating rate, skip logic can still be * executed based on framerate though. */ - if (cvp->operating_rate == 0xFFFFFFFF) + if (cvp->operating_rate == INT_MAX) operating_rate = fps_max << 16; else operating_rate = cvp->operating_rate; diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 4628185b3bb3..4e309de188bd 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -382,7 +382,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, .name = "Decoder Operating rate", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = (MINIMUM_FPS << 16), + .minimum = (DEFAULT_FPS << 16),/* Power Vote min fps */ .maximum = INT_MAX, .default_value = (DEFAULT_FPS << 16), .step = 1, @@ -906,6 +906,9 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: inst->clk_data.operating_rate = ctrl->val; + inst->flags &= ~VIDC_TURBO; + if (ctrl->val == INT_MAX) + inst->flags |= VIDC_TURBO; break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = !!ctrl->val; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 514997a45cee..dffecc0ca4c3 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -762,7 +762,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, .name = "Encoder Operating rate", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = (MINIMUM_FPS << 16), + .minimum = (DEFAULT_FPS << 16),/* Power Vote min fps */ .maximum = INT_MAX, .default_value = (DEFAULT_FPS << 16), .step = 1, @@ -1601,6 +1601,10 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: inst->clk_data.operating_rate = ctrl->val; + inst->flags &= ~VIDC_TURBO; + if (ctrl->val == INT_MAX) + inst->flags |= VIDC_TURBO; + if (inst->state < MSM_VIDC_LOAD_RESOURCES) msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 39cb2b83845a..00684eab68c4 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -358,7 +358,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW && inst->session_type != MSM_VIDC_CVP) vote_data->power_mode = VIDC_POWER_TURBO; - if (msm_vidc_clock_voting || is_turbo) + if (msm_vidc_clock_voting || is_turbo || is_turbo_session(inst)) vote_data->power_mode = VIDC_POWER_TURBO; if (inst->session_type == MSM_VIDC_CVP) { @@ -640,7 +640,7 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); fps = msm_vidc_get_fps(inst); @@ -726,7 +726,7 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); fps = msm_vidc_get_fps(inst); @@ -822,7 +822,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); fps = msm_vidc_get_fps(inst); @@ -1105,6 +1105,7 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) inst->flags & VIDC_THUMBNAIL || inst->clk_data.low_latency_mode || inst->batch.enable || + is_turbo_session(inst) || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ); dprintk(VIDC_HIGH|VIDC_PERF, "DCVS %s: %pK\n", @@ -1171,7 +1172,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) core = inst->core; dcvs = &inst->clk_data; - load = msm_comm_get_inst_load_per_core(inst, LOAD_CALC_NO_QUIRKS); + load = msm_comm_get_inst_load_per_core(inst, LOAD_POWER); cycles = inst->clk_data.entry->vpp_cycles; allowed_clks_tbl = core->resources.allowed_clks_tbl; if (inst->session_type == MSM_VIDC_ENCODER) { @@ -1678,7 +1679,7 @@ static u32 get_core_load(struct msm_vidc_core *core, continue; } current_inst_mbs_per_sec = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); load += current_inst_mbs_per_sec * cycles / inst->clk_data.work_route; } @@ -1715,11 +1716,11 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) inst->clk_data.entry->low_power_cycles : inst->clk_data.entry->vpp_cycles; - cur_inst_load = (msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) * + cur_inst_load = (msm_comm_get_inst_load(inst, LOAD_POWER) * inst->clk_data.entry->vpp_cycles)/inst->clk_data.work_route; cur_inst_lp_load = (msm_comm_get_inst_load(inst, - LOAD_CALC_NO_QUIRKS) * lp_cycles)/inst->clk_data.work_route; + LOAD_POWER) * lp_cycles)/inst->clk_data.work_route; mbpf = msm_vidc_get_mbs_per_frame(inst); mbps = mbpf * msm_vidc_get_fps(inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index bb52869c5fbc..1e03c00711a4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -775,7 +775,8 @@ exit: return count; } -static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) +static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst, + enum load_calc_quirks quirks) { int input_port_mbs, output_port_mbs; int fps; @@ -789,11 +790,15 @@ static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) output_port_mbs = NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, f->fmt.pix_mp.height); - if (inst->clk_data.operating_rate > inst->clk_data.frame_rate) - fps = (inst->clk_data.operating_rate >> 16) ? - inst->clk_data.operating_rate >> 16 : 1; - else - fps = inst->clk_data.frame_rate >> 16; + fps = inst->clk_data.frame_rate; + + /* For admission control operating rate is ignored */ + if (quirks == LOAD_POWER) + fps = max(inst->clk_data.operating_rate, + inst->clk_data.frame_rate); + + /* In case of fps < 1 we assume 1 */ + fps = max(fps >> 16, 1); return max(input_port_mbs, output_port_mbs) * fps; } @@ -809,40 +814,28 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, inst->state < MSM_VIDC_STOP_DONE)) goto exit; - load = msm_comm_get_mbs_per_sec(inst); - - if (is_thumbnail_session(inst)) { - if (quirks & LOAD_CALC_IGNORE_THUMBNAIL_LOAD) - load = 0; - } - - if (is_turbo_session(inst)) { - if (!(quirks & LOAD_CALC_IGNORE_TURBO_LOAD)) - load = inst->core->resources.max_load; - } - /* Clock and Load calculations for REALTIME/NON-REALTIME - * OPERATING RATE SET/NO OPERATING RATE SET - * - * | OPERATING RATE SET | OPERATING RATE NOT SET | - * ----------------|--------------------- |------------------------| - * REALTIME | load = res * op_rate | load = res * fps | - * | clk = res * op_rate | clk = res * fps | - * ----------------|----------------------|------------------------| - * NON-REALTIME | load = res * 1 fps | load = res * 1 fps | - * | clk = res * op_rate | clk = res * fps | - * ----------------|----------------------|------------------------| + * Operating rate will either Default or Client value. + * Session admission control will be based on Load. + * Power requests based of calculated Clock/Freq. + * ----------------|----------------------------| + * REALTIME | Admission Control Load = | + * | res * fps | + * | Power Request Load = | + * | res * max(op, fps)| + * ----------------|----------------------------| + * NON-REALTIME/ | Admission Control Load = 0 | + * THUMBNAIL | Power Request Load = | + * | res * max(op, fps)| + * ----------------|----------------------------| */ - if (!is_realtime_session(inst) && - (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { - if (!(inst->clk_data.frame_rate >> 16)) { - dprintk(VIDC_LOW, "instance:%pK fps = 0\n", inst); - load = 0; - } else { - load = msm_comm_get_mbs_per_sec(inst) / - (inst->clk_data.frame_rate >> 16); - } + if ((is_thumbnail_session(inst) || + !is_realtime_session(inst)) && + quirks == LOAD_ADMISSION_CONTROL) { + load = 0; + } else { + load = msm_comm_get_mbs_per_sec(inst, quirks); } exit: @@ -861,7 +854,7 @@ int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, return load; } -int msm_comm_get_load(struct msm_vidc_core *core, +int msm_comm_get_device_load(struct msm_vidc_core *core, enum session_type type, enum load_calc_quirks quirks) { struct msm_vidc_inst *inst = NULL; @@ -3277,9 +3270,7 @@ static int msm_vidc_load_resources(int flipped_state, struct hfi_device *hdev; int num_mbs_per_sec = 0, max_load_adj = 0; struct msm_vidc_core *core; - enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | - LOAD_CALC_IGNORE_THUMBNAIL_LOAD | - LOAD_CALC_IGNORE_NON_REALTIME_LOAD; + enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); @@ -3298,8 +3289,8 @@ static int msm_vidc_load_resources(int flipped_state, core = inst->core; num_mbs_per_sec = - msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) + - msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks); + msm_comm_get_device_load(core, MSM_VIDC_DECODER, quirks) + + msm_comm_get_device_load(core, MSM_VIDC_ENCODER, quirks); max_load_adj = core->resources.max_load + inst->capability.cap[CAP_MBS_PER_FRAME].max; @@ -5629,15 +5620,13 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) { int num_mbs_per_sec = 0, max_load_adj = 0; - enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | - LOAD_CALC_IGNORE_THUMBNAIL_LOAD | - LOAD_CALC_IGNORE_NON_REALTIME_LOAD; + enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (inst->state == MSM_VIDC_OPEN_DONE) { max_load_adj = inst->core->resources.max_load; - num_mbs_per_sec = msm_comm_get_load(inst->core, + num_mbs_per_sec = msm_comm_get_device_load(inst->core, MSM_VIDC_DECODER, quirks); - num_mbs_per_sec += msm_comm_get_load(inst->core, + num_mbs_per_sec += msm_comm_get_device_load(inst->core, MSM_VIDC_ENCODER, quirks); if (num_mbs_per_sec > max_load_adj) { dprintk(VIDC_ERR, diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 8a9e516411bc..e854cd3abf3d 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -33,10 +33,8 @@ struct getprop_buf { }; enum load_calc_quirks { - LOAD_CALC_NO_QUIRKS = 0, - LOAD_CALC_IGNORE_TURBO_LOAD = 1 << 0, - LOAD_CALC_IGNORE_THUMBNAIL_LOAD = 1 << 1, - LOAD_CALC_IGNORE_NON_REALTIME_LOAD = 1 << 2, + LOAD_POWER = 0, + LOAD_ADMISSION_CONTROL = 1, }; enum client_set_controls { @@ -241,7 +239,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, enum load_calc_quirks quirks); int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, enum load_calc_quirks quirks); -int msm_comm_get_load(struct msm_vidc_core *core, +int msm_comm_get_device_load(struct msm_vidc_core *core, enum session_type type, enum load_calc_quirks quirks); int msm_comm_set_color_format(struct msm_vidc_inst *inst, enum hal_buffer buffer_type, int fourcc);