video: driver: Add support to enable enc ring buffer
Add support to enable ring buffer for enc intermediate bin buffer to improve encoding performance. Change-Id: Ifbf50cb48278c62c09a20bc7626a3b6288813830 Signed-off-by: Akshata Sahukar <quic_asahukar@quicinc.com>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
fb2e2c5715
commit
9a5fea8ef3
@@ -12,6 +12,7 @@
|
||||
|
||||
#define ENABLE_LEGACY_POWER_CALCULATIONS 1
|
||||
|
||||
int msm_vidc_ring_buf_count_iris33(struct msm_vidc_inst *inst, u32 data_size);
|
||||
u64 msm_vidc_calc_freq_iris33(struct msm_vidc_inst* inst, u32 data_size);
|
||||
int msm_vidc_calc_bw_iris33(struct msm_vidc_inst* inst,
|
||||
struct vidc_bus_vote_data* vote_data);
|
||||
|
@@ -338,7 +338,7 @@ static u32 msm_vidc_encoder_bin_size_iris33(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_vidc_core *core;
|
||||
u32 size = 0;
|
||||
u32 width, height, num_vpp_pipes, stage, profile;
|
||||
u32 width, height, num_vpp_pipes, stage, profile, ring_buf_count;
|
||||
struct v4l2_format *f;
|
||||
|
||||
if (!inst || !inst->core || !inst->capabilities) {
|
||||
@@ -356,13 +356,14 @@ static u32 msm_vidc_encoder_bin_size_iris33(struct msm_vidc_inst *inst)
|
||||
width = f->fmt.pix_mp.width;
|
||||
height = f->fmt.pix_mp.height;
|
||||
profile = inst->capabilities->cap[PROFILE].value;
|
||||
ring_buf_count = inst->capabilities->cap[ENC_RING_BUFFER_COUNT].value;
|
||||
|
||||
if (inst->codec == MSM_VIDC_H264)
|
||||
HFI_BUFFER_BIN_H264E(size, inst->hfi_rc_type, width,
|
||||
height, stage, num_vpp_pipes, profile);
|
||||
height, stage, num_vpp_pipes, profile, ring_buf_count);
|
||||
else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC)
|
||||
HFI_BUFFER_BIN_H265E(size, inst->hfi_rc_type, width,
|
||||
height, stage, num_vpp_pipes, profile);
|
||||
height, stage, num_vpp_pipes, profile, ring_buf_count);
|
||||
|
||||
i_vpr_l(inst, "%s: size %d\n", __func__, size);
|
||||
return size;
|
||||
|
@@ -1231,6 +1231,7 @@ static struct msm_vidc_session_ops msm_session_ops = {
|
||||
.buffer_size = msm_buffer_size_iris33,
|
||||
.min_count = msm_buffer_min_count_iris33,
|
||||
.extra_count = msm_buffer_extra_count_iris33,
|
||||
.ring_buf_count = msm_vidc_ring_buf_count_iris33,
|
||||
.calc_freq = msm_vidc_calc_freq_iris33,
|
||||
.calc_bw = msm_vidc_calc_bw_iris33,
|
||||
.decide_work_route = msm_vidc_decide_work_route_iris33,
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include "perf_static_model.h"
|
||||
#include "msm_vidc_power.h"
|
||||
|
||||
#define VPP_MIN_FREQ_MARGIN_PERCENT 5 /* to be tuned */
|
||||
|
||||
static u64 __calculate_decoder(struct vidc_bus_vote_data *d);
|
||||
static u64 __calculate_encoder(struct vidc_bus_vote_data *d);
|
||||
static u64 __calculate(struct msm_vidc_inst* inst, struct vidc_bus_vote_data *d);
|
||||
@@ -284,6 +286,49 @@ static int msm_vidc_init_codec_input_bus(struct msm_vidc_inst *inst, struct vidc
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_vpp_cycles_close_to_freq_corner(struct msm_vidc_core *core,
|
||||
u64 vpp_min_freq)
|
||||
{
|
||||
u64 margin_freq = 0;
|
||||
u64 closest_freq_upper_corner = 0;
|
||||
u32 margin_percent = 0;
|
||||
int i = 0;
|
||||
|
||||
if (!core || !core->resource || !core->resource->freq_set.freq_tbl ||
|
||||
!core->resource->freq_set.count) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
vpp_min_freq = vpp_min_freq * 1000000; /* convert to hz */
|
||||
|
||||
closest_freq_upper_corner =
|
||||
core->resource->freq_set.freq_tbl[0].freq;
|
||||
|
||||
if (vpp_min_freq > closest_freq_upper_corner)
|
||||
return false;
|
||||
|
||||
/* get the closest freq corner for vpp_min_freq */
|
||||
for (i = 0; i < core->resource->freq_set.count; i++) {
|
||||
if (vpp_min_freq <=
|
||||
core->resource->freq_set.freq_tbl[i].freq) {
|
||||
closest_freq_upper_corner =
|
||||
core->resource->freq_set.freq_tbl[i].freq;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
margin_freq = closest_freq_upper_corner - vpp_min_freq;
|
||||
margin_percent = div_u64((margin_freq * 100), closest_freq_upper_corner);
|
||||
|
||||
/* check if margin is less than cutoff */
|
||||
if (margin_percent < VPP_MIN_FREQ_MARGIN_PERCENT)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static u64 msm_vidc_calc_freq_iris33_new(struct msm_vidc_inst *inst, u32 data_size)
|
||||
{
|
||||
u64 freq = 0;
|
||||
@@ -311,6 +356,25 @@ static u64 msm_vidc_calc_freq_iris33_new(struct msm_vidc_inst *inst, u32 data_si
|
||||
ret = msm_vidc_calculate_frequency(codec_input, &codec_output);
|
||||
if (ret)
|
||||
return freq;
|
||||
|
||||
if (inst->domain == MSM_VIDC_ENCODER) {
|
||||
if (!inst->capabilities->cap[ENC_RING_BUFFER_COUNT].value &&
|
||||
is_vpp_cycles_close_to_freq_corner(core,
|
||||
codec_output.vpp_min_freq)) {
|
||||
/*
|
||||
* if ring buffer not enabled and required vpp cycles
|
||||
* is too close to the frequency corner then increase
|
||||
* the vpp cycles by VPP_MIN_FREQ_MARGIN_PERCENT
|
||||
*/
|
||||
codec_output.vpp_min_freq += div_u64(
|
||||
codec_output.vpp_min_freq *
|
||||
VPP_MIN_FREQ_MARGIN_PERCENT, 100);
|
||||
codec_output.hw_min_freq = max(
|
||||
codec_output.hw_min_freq,
|
||||
codec_output.vpp_min_freq);
|
||||
}
|
||||
}
|
||||
|
||||
freq = codec_output.hw_min_freq * 1000000; /* Convert to Hz */
|
||||
|
||||
i_vpr_p(inst, "%s: filled len %d, required freq %llu, fps %u, mbpf %u\n",
|
||||
@@ -1173,4 +1237,47 @@ int msm_vidc_calc_bw_iris33(struct msm_vidc_inst *inst,
|
||||
value = msm_vidc_calc_bw_iris33_new(inst, vidc_data);
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
int msm_vidc_ring_buf_count_iris33(struct msm_vidc_inst *inst, u32 data_size)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct api_calculation_input codec_input;
|
||||
struct api_calculation_freq_output codec_output;
|
||||
|
||||
if (!inst || !inst->core || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
if (!core->resource || !core->resource->freq_set.freq_tbl ||
|
||||
!core->resource->freq_set.count) {
|
||||
i_vpr_e(inst, "%s: invalid frequency table\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ENABLE_LEGACY_POWER_CALCULATIONS)
|
||||
return 0;
|
||||
|
||||
memset(&codec_input, 0, sizeof(struct api_calculation_input));
|
||||
memset(&codec_output, 0, sizeof(struct api_calculation_freq_output));
|
||||
rc = msm_vidc_init_codec_input_freq(inst, data_size, &codec_input);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = msm_vidc_calculate_frequency(codec_input, &codec_output);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* check if vpp_min_freq is exceeding closest freq corner margin */
|
||||
if (is_vpp_cycles_close_to_freq_corner(core,
|
||||
codec_output.vpp_min_freq))
|
||||
/* enables ring buffer */
|
||||
inst->capabilities->cap[ENC_RING_BUFFER_COUNT].value =
|
||||
MAX_ENC_RING_BUF_COUNT;
|
||||
else
|
||||
inst->capabilities->cap[ENC_RING_BUFFER_COUNT].value = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user