Merge "video driver: calculate power based on max rate"

This commit is contained in:
qctecmdr
2022-03-31 07:49:37 -07:00
committed by Gerrit - the friendly Code Review server
11 changed files with 155 additions and 130 deletions

View File

@@ -240,6 +240,10 @@ static struct msm_platform_inst_capability instance_data_kalama[] = {
{MBPS, DEC, VP9, 36, 4423680, 1, 4423680}, {MBPS, DEC, VP9, 36, 4423680, 1, 4423680},
/* ((4096 * 2304) / 256) * 60 fps */ /* ((4096 * 2304) / 256) * 60 fps */
{POWER_SAVE_MBPS, ENC, CODECS_ALL, 0, 2211840, 1, 2211840}, {POWER_SAVE_MBPS, ENC, CODECS_ALL, 0, 2211840, 1, 2211840},
/* Enable check mbps for encoder */
{CHECK_MBPS, ENC, CODECS_ALL, 0, 1, 1, 1},
/* Disable check mbps for encoder */
{CHECK_MBPS, DEC, CODECS_ALL, 0, 1, 1, 0},
{FRAME_RATE, ENC, CODECS_ALL, {FRAME_RATE, ENC, CODECS_ALL,
(MINIMUM_FPS << 16), (MAXIMUM_FPS << 16), (MINIMUM_FPS << 16), (MAXIMUM_FPS << 16),
@@ -298,6 +302,10 @@ static struct msm_platform_inst_capability instance_data_kalama[] = {
(MINIMUM_FPS << 16), INT_MAX, (MINIMUM_FPS << 16), INT_MAX,
1, (DEFAULT_FPS << 16)}, 1, (DEFAULT_FPS << 16)},
{TIMESTAMP_RATE, ENC|DEC, CODECS_ALL,
(MINIMUM_FPS << 16), INT_MAX,
1, (DEFAULT_FPS << 16)},
{SCALE_FACTOR, ENC, H264|HEVC, 1, 8, 1, 8}, {SCALE_FACTOR, ENC, H264|HEVC, 1, 8, 1, 8},
{MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25}, {MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25},

View File

@@ -225,6 +225,10 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
{MBPS, DEC, VP9, 36, 4423680, 1, 4423680}, {MBPS, DEC, VP9, 36, 4423680, 1, 4423680},
/* ((4096 * 2304) / 256) * 60 fps */ /* ((4096 * 2304) / 256) * 60 fps */
{POWER_SAVE_MBPS, ENC, CODECS_ALL, 0, 2211840, 1, 2211840}, {POWER_SAVE_MBPS, ENC, CODECS_ALL, 0, 2211840, 1, 2211840},
/* Enable check mbps for encoder */
{CHECK_MBPS, ENC, CODECS_ALL, 0, 1, 1, 1},
/* Disable check mbps for encoder */
{CHECK_MBPS, DEC, CODECS_ALL, 0, 1, 1, 0},
{FRAME_RATE, ENC, CODECS_ALL, {FRAME_RATE, ENC, CODECS_ALL,
(MINIMUM_FPS << 16), (MAXIMUM_FPS << 16), (MINIMUM_FPS << 16), (MAXIMUM_FPS << 16),
@@ -283,6 +287,10 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
(MINIMUM_FPS << 16), INT_MAX, (MINIMUM_FPS << 16), INT_MAX,
1, (DEFAULT_FPS << 16)}, 1, (DEFAULT_FPS << 16)},
{TIMESTAMP_RATE, ENC|DEC, CODECS_ALL,
(MINIMUM_FPS << 16), INT_MAX,
1, (DEFAULT_FPS << 16)},
{SCALE_FACTOR, ENC, H264|HEVC, 1, 8, 1, 8}, {SCALE_FACTOR, ENC, H264|HEVC, 1, 8, 1, 8},
{MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25}, {MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25},

View File

@@ -20,8 +20,7 @@ u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 data_size)
u32 mbs_per_second; u32 mbs_per_second;
u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1; u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1;
u32 base_cycles = 0; u32 base_cycles = 0;
u32 fps; u32 fps, mbpf;
u32 buf_timetamps_fps, mbpf, input_rate;
if (!inst || !inst->core || !inst->capabilities) { if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
@@ -35,29 +34,7 @@ u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 data_size)
} }
mbpf = msm_vidc_get_mbs_per_frame(inst); mbpf = msm_vidc_get_mbs_per_frame(inst);
fps = msm_vidc_get_fps(inst); fps = inst->max_rate;
buf_timetamps_fps = msm_vidc_calc_window_avg_framerate(inst);
/*
* when buffer detected fps is more than client set value by 10%,
* utilize buffer detected fps to scale clock.
*/
if (div_u64(fps * 11, 10) < buf_timetamps_fps) {
fps = buf_timetamps_fps;
inst->priority_level = MSM_VIDC_PRIORITY_LOW;
}
if (!is_realtime_session(inst)) {
input_rate = msm_vidc_get_input_rate(inst);
if (input_rate > fps) {
fps = input_rate;
/*
* add 12.5% more fps to increase power to make firmware
* processing little faster than client queuing rate
*/
fps = fps + fps / 8;
}
}
mbs_per_second = mbpf * fps; mbs_per_second = mbpf * fps;
/* /*

View File

@@ -21,8 +21,7 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
u32 mbs_per_second; u32 mbs_per_second;
u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1; u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1;
u32 base_cycles = 0; u32 base_cycles = 0;
u32 fps; u32 fps, mbpf;
u32 buf_timetamps_fps, mbpf, input_rate;
if (!inst || !inst->core || !inst->capabilities) { if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
@@ -36,29 +35,7 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
} }
mbpf = msm_vidc_get_mbs_per_frame(inst); mbpf = msm_vidc_get_mbs_per_frame(inst);
fps = msm_vidc_get_fps(inst); fps = inst->max_rate;
buf_timetamps_fps = msm_vidc_calc_window_avg_framerate(inst);
/*
* when buffer detected fps is more than client set value by 10%,
* utilize buffer detected fps to scale clock.
*/
if (div_u64(fps * 11, 10) < buf_timetamps_fps) {
fps = buf_timetamps_fps;
inst->priority_level = MSM_VIDC_PRIORITY_LOW;
}
if (!is_realtime_session(inst)) {
input_rate = msm_vidc_get_input_rate(inst);
if (input_rate > fps) {
fps = input_rate;
/*
* add 12.5% more fps to increase power to make firmware
* processing little faster than client queuing rate
*/
fps = fps + fps / 8;
}
}
mbs_per_second = mbpf * fps; mbs_per_second = mbpf * fps;
/* /*

View File

@@ -480,9 +480,9 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst);
int msm_vidc_check_core_mbps(struct msm_vidc_inst *inst); int msm_vidc_check_core_mbps(struct msm_vidc_inst *inst);
int msm_vidc_check_core_mbpf(struct msm_vidc_inst *inst); int msm_vidc_check_core_mbpf(struct msm_vidc_inst *inst);
int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst); int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst);
int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp); int msm_vidc_update_timestamp_rate(struct msm_vidc_inst *inst, u64 timestamp);
int msm_vidc_set_auto_framerate(struct msm_vidc_inst *inst, u64 timestamp); int msm_vidc_set_auto_framerate(struct msm_vidc_inst *inst, u64 timestamp);
int msm_vidc_calc_window_avg_framerate(struct msm_vidc_inst *inst); int msm_vidc_get_timestamp_rate(struct msm_vidc_inst *inst);
int msm_vidc_flush_ts(struct msm_vidc_inst *inst); int msm_vidc_flush_ts(struct msm_vidc_inst *inst);
int msm_vidc_ts_reorder_insert_timestamp(struct msm_vidc_inst *inst, u64 timestamp); int msm_vidc_ts_reorder_insert_timestamp(struct msm_vidc_inst *inst, u64 timestamp);
int msm_vidc_ts_reorder_remove_timestamp(struct msm_vidc_inst *inst, u64 timestamp); int msm_vidc_ts_reorder_remove_timestamp(struct msm_vidc_inst *inst, u64 timestamp);
@@ -502,5 +502,7 @@ int msm_vidc_create_input_metadata_buffer(struct msm_vidc_inst *inst, int buf_fd
int msm_vidc_update_input_meta_buffer_index(struct msm_vidc_inst *inst, struct vb2_buffer *vb2); int msm_vidc_update_input_meta_buffer_index(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us); int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us);
int msm_vidc_get_input_rate(struct msm_vidc_inst *inst); int msm_vidc_get_input_rate(struct msm_vidc_inst *inst);
int msm_vidc_get_frame_rate(struct msm_vidc_inst *inst);
int msm_vidc_get_operating_rate(struct msm_vidc_inst *inst);
#endif // _MSM_VIDC_DRIVER_H_ #endif // _MSM_VIDC_DRIVER_H_

View File

@@ -170,6 +170,7 @@ struct msm_vidc_inst {
u32 dpb_list_payload[MAX_DPB_LIST_ARRAY_SIZE]; u32 dpb_list_payload[MAX_DPB_LIST_ARRAY_SIZE];
u32 max_map_output_count; u32 max_map_output_count;
u32 auto_framerate; u32 auto_framerate;
u32 max_rate;
bool has_bframe; bool has_bframe;
}; };
#endif // _MSM_VIDC_INST_H_ #endif // _MSM_VIDC_INST_H_

View File

@@ -398,9 +398,11 @@ enum msm_vidc_inst_capability_type {
SECURE_MBPF, SECURE_MBPF,
MBPS, MBPS,
POWER_SAVE_MBPS, POWER_SAVE_MBPS,
CHECK_MBPS,
FRAME_RATE, FRAME_RATE,
OPERATING_RATE, OPERATING_RATE,
INPUT_RATE, INPUT_RATE,
TIMESTAMP_RATE,
SCALE_FACTOR, SCALE_FACTOR,
MB_CYCLES_VSP, MB_CYCLES_VSP,
MB_CYCLES_VPP, MB_CYCLES_VPP,

View File

@@ -97,9 +97,11 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
{SECURE_MBPF, "SECURE_MBPF" }, {SECURE_MBPF, "SECURE_MBPF" },
{MBPS, "MBPS" }, {MBPS, "MBPS" },
{POWER_SAVE_MBPS, "POWER_SAVE_MBPS" }, {POWER_SAVE_MBPS, "POWER_SAVE_MBPS" },
{CHECK_MBPS, "CHECK_MPBS" },
{FRAME_RATE, "FRAME_RATE" }, {FRAME_RATE, "FRAME_RATE" },
{OPERATING_RATE, "OPERATING_RATE" }, {OPERATING_RATE, "OPERATING_RATE" },
{INPUT_RATE, "INPUT_RATE" }, {INPUT_RATE, "INPUT_RATE" },
{TIMESTAMP_RATE, "TIMESTAMP_RATE" },
{SCALE_FACTOR, "SCALE_FACTOR" }, {SCALE_FACTOR, "SCALE_FACTOR" },
{MB_CYCLES_VSP, "MB_CYCLES_VSP" }, {MB_CYCLES_VSP, "MB_CYCLES_VSP" },
{MB_CYCLES_VPP, "MB_CYCLES_VPP" }, {MB_CYCLES_VPP, "MB_CYCLES_VPP" },
@@ -2181,14 +2183,13 @@ int msm_vidc_get_fps(struct msm_vidc_inst *inst)
return -EINVAL; return -EINVAL;
} }
frame_rate = inst->capabilities->cap[FRAME_RATE].value; frame_rate = msm_vidc_get_frame_rate(inst);
operating_rate = inst->capabilities->cap[OPERATING_RATE].value; operating_rate = msm_vidc_get_operating_rate(inst);
if (operating_rate > frame_rate) if (operating_rate > frame_rate)
fps = (operating_rate >> 16) ? fps = operating_rate ? operating_rate : 1;
(operating_rate >> 16) : 1;
else else
fps = frame_rate >> 16; fps = frame_rate;
return fps; return fps;
} }
@@ -2331,7 +2332,7 @@ int msm_vidc_set_auto_framerate(struct msm_vidc_inst *inst, u64 timestamp)
!inst->capabilities->cap[TIME_DELTA_BASED_RC].value) !inst->capabilities->cap[TIME_DELTA_BASED_RC].value)
goto exit; goto exit;
rc = msm_vidc_update_timestamp(inst, timestamp); rc = msm_vidc_update_timestamp_rate(inst, timestamp);
if (rc) if (rc)
goto exit; goto exit;
@@ -2373,32 +2374,6 @@ exit:
return rc; return rc;
} }
int msm_vidc_calc_window_avg_framerate(struct msm_vidc_inst *inst)
{
struct msm_vidc_timestamp *ts;
struct msm_vidc_timestamp *prev = NULL;
u32 counter = 0;
u64 ts_ms = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
list_for_each_entry(ts, &inst->timestamps.list, sort.list) {
if (prev) {
if (ts->sort.val == prev->sort.val)
continue;
ts_ms += div_u64(ts->sort.val - prev->sort.val, 1000000);
counter++;
}
prev = ts;
}
return ts_ms ? (1000 * counter) / ts_ms : 0;
}
int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us) int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us)
{ {
struct msm_vidc_input_timer *input_timer; struct msm_vidc_input_timer *input_timer;
@@ -2452,6 +2427,36 @@ int msm_vidc_get_input_rate(struct msm_vidc_inst *inst)
return inst->capabilities->cap[INPUT_RATE].value >> 16; return inst->capabilities->cap[INPUT_RATE].value >> 16;
} }
int msm_vidc_get_timestamp_rate(struct msm_vidc_inst *inst)
{
if (!inst || !inst->capabilities) {
d_vpr_e("%s: Invalid params\n", __func__);
return 0;
}
return inst->capabilities->cap[TIMESTAMP_RATE].value >> 16;
}
int msm_vidc_get_frame_rate(struct msm_vidc_inst *inst)
{
if (!inst || !inst->capabilities) {
d_vpr_e("%s: Invalid params\n", __func__);
return 0;
}
return inst->capabilities->cap[FRAME_RATE].value >> 16;
}
int msm_vidc_get_operating_rate(struct msm_vidc_inst *inst)
{
if (!inst || !inst->capabilities) {
d_vpr_e("%s: Invalid params\n", __func__);
return 0;
}
return inst->capabilities->cap[OPERATING_RATE].value >> 16;
}
static int msm_vidc_insert_sort(struct list_head *head, static int msm_vidc_insert_sort(struct list_head *head,
struct msm_vidc_sort *entry) struct msm_vidc_sort *entry)
{ {
@@ -2532,11 +2537,14 @@ int msm_vidc_flush_ts(struct msm_vidc_inst *inst)
return 0; return 0;
} }
int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp) int msm_vidc_update_timestamp_rate(struct msm_vidc_inst *inst, u64 timestamp)
{ {
struct msm_vidc_timestamp *ts; struct msm_vidc_timestamp *ts, *prev;
int rc = 0; int rc = 0;
u32 window_size = 0; u32 window_size = 0;
u32 timestamp_rate = 0;
u64 ts_ms = 0;
u32 counter = 0;
if (!inst) { if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__); d_vpr_e("%s: Invalid params\n", __func__);
@@ -2574,6 +2582,21 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
msm_memory_pool_free(inst, ts); msm_memory_pool_free(inst, ts);
} }
/* Calculate timestamp rate */
list_for_each_entry(ts, &inst->timestamps.list, sort.list) {
if (prev) {
if (ts->sort.val == prev->sort.val)
continue;
ts_ms += div_u64(ts->sort.val - prev->sort.val, 1000000);
counter++;
}
prev = ts;
}
if (ts_ms)
timestamp_rate = (u32)div_u64((u64)counter * 1000, ts_ms);
msm_vidc_update_cap_value(inst, TIMESTAMP_RATE, timestamp_rate << 16, __func__);
return 0; return 0;
} }
@@ -5825,11 +5848,17 @@ int msm_vidc_check_core_mbps(struct msm_vidc_inst *inst)
u64 curr_time_ns; u64 curr_time_ns;
int rc = 0; int rc = 0;
if (!inst || !inst->core) { if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
core = inst->core; core = inst->core;
if (!inst->capabilities->cap[CHECK_MBPS].value) {
i_vpr_h(inst, "%s: skip mbps check\n", __func__);
return 0;
}
curr_time_ns = ktime_get_ns(); curr_time_ns = ktime_get_ns();
core_lock(core, __func__); core_lock(core, __func__);

View File

@@ -45,34 +45,44 @@ u64 msm_vidc_max_freq(struct msm_vidc_inst *inst)
int msm_vidc_get_mbps(struct msm_vidc_inst *inst) int msm_vidc_get_mbps(struct msm_vidc_inst *inst)
{ {
u32 mbpf, fps; u32 mbpf, fps, input_rate;
mbpf = msm_vidc_get_mbs_per_frame(inst); mbpf = msm_vidc_get_mbs_per_frame(inst);
fps = msm_vidc_get_fps(inst); fps = msm_vidc_get_fps(inst);
input_rate = msm_vidc_get_input_rate(inst);
return mbpf * fps; return mbpf * max(fps, input_rate);
} }
int msm_vidc_get_inst_load(struct msm_vidc_inst *inst) int msm_vidc_get_inst_load(struct msm_vidc_inst *inst)
{ {
int load = 0; int load = 0;
u32 mbpf, fps;
u32 frame_rate, operating_rate, input_rate, timestamp_rate;
if (!inst || !inst->capabilities) { if (!inst || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
/* /* return zero load for thumbnail and NRT session */
* NRT sessions - clock scaling is based on OPP table.
* - No load based rejection.
* RT sessions - clock scaling and session admission based on load.
*/
if (is_thumbnail_session(inst) || !is_realtime_session(inst)) if (is_thumbnail_session(inst) || !is_realtime_session(inst))
load = 0; return load;
else
load = msm_vidc_get_mbps(inst);
return load; /* calculate load for RT session */
mbpf = msm_vidc_get_mbs_per_frame(inst);
frame_rate = msm_vidc_get_frame_rate(inst);
operating_rate = msm_vidc_get_operating_rate(inst);
fps = max(frame_rate, operating_rate);
if (is_decode_session(inst)) {
input_rate = msm_vidc_get_input_rate(inst);
timestamp_rate = msm_vidc_get_timestamp_rate(inst);
fps = max(fps, input_rate);
fps = max(fps, timestamp_rate);
}
return load = mbpf * fps;
} }
static int fill_dynamic_stats(struct msm_vidc_inst *inst, static int fill_dynamic_stats(struct msm_vidc_inst *inst,
@@ -178,7 +188,8 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
struct vidc_bus_vote_data *vote_data; struct vidc_bus_vote_data *vote_data;
struct v4l2_format *out_f; struct v4l2_format *out_f;
struct v4l2_format *inp_f; struct v4l2_format *inp_f;
int codec = 0, frame_rate, buf_ts_fps, input_rate; int codec = 0;
u32 operating_rate, frame_rate;
if (!inst || !inst->core || !inst->capabilities) { if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params: %pK\n", __func__, inst); d_vpr_e("%s: invalid params: %pK\n", __func__, inst);
@@ -213,7 +224,6 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
break; break;
} }
frame_rate = inst->capabilities->cap[FRAME_RATE].value;
vote_data->codec = inst->codec; vote_data->codec = inst->codec;
vote_data->input_width = inp_f->fmt.pix_mp.width; vote_data->input_width = inp_f->fmt.pix_mp.width;
vote_data->input_height = inp_f->fmt.pix_mp.height; vote_data->input_height = inp_f->fmt.pix_mp.height;
@@ -221,38 +231,21 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
vote_data->output_height = out_f->fmt.pix_mp.height; vote_data->output_height = out_f->fmt.pix_mp.height;
vote_data->lcu_size = (codec == V4L2_PIX_FMT_HEVC || vote_data->lcu_size = (codec == V4L2_PIX_FMT_HEVC ||
codec == V4L2_PIX_FMT_VP9) ? 32 : 16; codec == V4L2_PIX_FMT_VP9) ? 32 : 16;
vote_data->fps = msm_vidc_get_fps(inst); vote_data->fps = inst->max_rate;
buf_ts_fps = msm_vidc_calc_window_avg_framerate(inst);
if (buf_ts_fps > vote_data->fps) {
i_vpr_l(inst, "%s: bitstream: fps %d, client rate %u\n", __func__,
buf_ts_fps, vote_data->fps);
vote_data->fps = buf_ts_fps;
}
if (!is_realtime_session(inst)) {
input_rate = msm_vidc_get_input_rate(inst);
if (input_rate > vote_data->fps) {
i_vpr_h(inst, "%s: use input rate %d for fps (%u)\n", __func__,
input_rate, vote_data->fps);
vote_data->fps = input_rate;
/*
* add 12.5% more fps to increase power to make firmware
* processing little faster than client queuing rate
*/
vote_data->fps = vote_data->fps + vote_data->fps / 8;
}
}
if (inst->domain == MSM_VIDC_ENCODER) { if (inst->domain == MSM_VIDC_ENCODER) {
vote_data->domain = MSM_VIDC_ENCODER; vote_data->domain = MSM_VIDC_ENCODER;
vote_data->bitrate = inst->capabilities->cap[BIT_RATE].value; vote_data->bitrate = inst->capabilities->cap[BIT_RATE].value;
vote_data->rotation = inst->capabilities->cap[ROTATION].value; vote_data->rotation = inst->capabilities->cap[ROTATION].value;
vote_data->b_frames_enabled = vote_data->b_frames_enabled =
inst->capabilities->cap[B_FRAME].value > 0; inst->capabilities->cap[B_FRAME].value > 0;
/* scale bitrate if operating rate is larger than fps */
if (vote_data->fps > (frame_rate >> 16) && /* scale bitrate if operating rate is larger than frame rate */
(frame_rate >> 16)) { frame_rate = msm_vidc_get_frame_rate(inst);
vote_data->bitrate = vote_data->bitrate / operating_rate = msm_vidc_get_frame_rate(inst);
(frame_rate >> 16) * vote_data->fps; if (frame_rate && operating_rate && operating_rate > frame_rate)
} vote_data->bitrate = (vote_data->bitrate / frame_rate) * operating_rate;
vote_data->num_formats = 1; vote_data->num_formats = 1;
vote_data->color_formats[0] = v4l2_colorformat_to_driver( vote_data->color_formats[0] = v4l2_colorformat_to_driver(
inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat, __func__); inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat, __func__);
@@ -488,6 +481,8 @@ int msm_vidc_scale_power(struct msm_vidc_inst *inst, bool scale_buses)
struct msm_vidc_core *core; struct msm_vidc_core *core;
struct msm_vidc_buffer *vbuf; struct msm_vidc_buffer *vbuf;
u32 data_size = 0; u32 data_size = 0;
u32 fps;
u32 frame_rate, operating_rate, timestamp_rate, input_rate;
if (!inst || !inst->core) { if (!inst || !inst->core) {
d_vpr_e("%s: invalid params %pK\n", __func__, inst); d_vpr_e("%s: invalid params %pK\n", __func__, inst);
@@ -505,6 +500,31 @@ int msm_vidc_scale_power(struct msm_vidc_inst *inst, bool scale_buses)
data_size = max(data_size, vbuf->data_size); data_size = max(data_size, vbuf->data_size);
inst->max_input_data_size = data_size; inst->max_input_data_size = data_size;
frame_rate = msm_vidc_get_frame_rate(inst);
operating_rate = msm_vidc_get_operating_rate(inst);
fps = max(frame_rate, operating_rate);
if (is_decode_session(inst)) {
/*
* when buffer detected fps is more than client set value by 12.5%,
* utilize buffer detected fps to scale clock.
*/
timestamp_rate = msm_vidc_get_timestamp_rate(inst);
input_rate = msm_vidc_get_input_rate(inst);
if (timestamp_rate > (fps + fps / 8)) {
fps = timestamp_rate;
inst->priority_level = MSM_VIDC_PRIORITY_LOW;
}
if (input_rate > fps) {
fps = input_rate;
/*
* add 6.25% more fps to increase power to make firmware
* processing little faster than client queuing rate
*/
fps = fps + fps / 16;
}
}
inst->max_rate = fps;
/* no pending inputs - skip scale power */ /* no pending inputs - skip scale power */
if (!inst->max_input_data_size) if (!inst->max_input_data_size)
return 0; return 0;
@@ -518,10 +538,11 @@ int msm_vidc_scale_power(struct msm_vidc_inst *inst, bool scale_buses)
} }
i_vpr_hp(inst, i_vpr_hp(inst,
"power: inst: clk %lld ddr %d llcc %d dcvs flags %#x, core: clk %lld ddr %lld llcc %lld\n", "power: inst: clk %lld ddr %d llcc %d dcvs flags %#x fps %u (%u %u %u %u) core: clk %lld ddr %lld llcc %lld\n",
inst->power.curr_freq, inst->power.ddr_bw, inst->power.curr_freq, inst->power.ddr_bw,
inst->power.sys_cache_bw, inst->power.dcvs_flags, inst->power.sys_cache_bw, inst->power.dcvs_flags,
core->power.clk_freq, core->power.bw_ddr, inst->max_rate, frame_rate, operating_rate, timestamp_rate,
input_rate, core->power.clk_freq, core->power.bw_ddr,
core->power.bw_llcc); core->power.bw_llcc);
trace_msm_vidc_perf_power_scale(inst, core->power.clk_freq, trace_msm_vidc_perf_power_scale(inst, core->power.clk_freq,

View File

@@ -464,7 +464,7 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
} }
inst->last_qbuf_time_ns = ktime_ns; inst->last_qbuf_time_ns = ktime_ns;
if (!is_realtime_session(inst) && vb2->type == INPUT_MPLANE) { if (is_decode_session(inst) && vb2->type == INPUT_MPLANE) {
rc = msm_vidc_update_input_rate(inst, div_u64(ktime_ns, 1000)); rc = msm_vidc_update_input_rate(inst, div_u64(ktime_ns, 1000));
if (rc) if (rc)
goto unlock; goto unlock;

View File

@@ -904,7 +904,7 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
} }
if (!is_image_session(inst) && is_decode_session(inst) && buf->data_size) if (!is_image_session(inst) && is_decode_session(inst) && buf->data_size)
msm_vidc_update_timestamp(inst, buf->timestamp); msm_vidc_update_timestamp_rate(inst, buf->timestamp);
/* update output buffer timestamp, if ts_reorder is enabled */ /* update output buffer timestamp, if ts_reorder is enabled */
if (is_ts_reorder_allowed(inst) && buf->data_size) if (is_ts_reorder_allowed(inst) && buf->data_size)