mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
msm: vidc: Update DCVS thresholds
DCVS Min Threshold should be FW Min count. Switch to Load_Norm only when buffers are equally distributed between FW and Client. This reduces clock transitions and increases residency in Load_Low and Load_High. CRs-Fixed: 2502809 Change-Id: I4896fd8fdffb44b546c6df3321e0155ee4a18dcb Signed-off-by: Chinmay Sawarkar <chinmays@codeaurora.org>
This commit is contained in:
parent
0f6ff6216f
commit
9c6de09cc9
8 changed files with 74 additions and 81 deletions
|
|
@ -380,7 +380,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
|
|||
},
|
||||
{
|
||||
.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE,
|
||||
.name = "Set Decoder Operating rate",
|
||||
.name = "Decoder Operating rate",
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.minimum = (MINIMUM_FPS << 16),
|
||||
.maximum = INT_MAX,
|
||||
|
|
@ -670,6 +670,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
|
|||
*/
|
||||
if (inst->batch.enable)
|
||||
inst->batch.enable = is_batching_allowed(inst);
|
||||
msm_dcvs_try_enable(inst);
|
||||
|
||||
err_invalid_fmt:
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -760,7 +760,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
|
|||
},
|
||||
{
|
||||
.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE,
|
||||
.name = "Set Encoder Operating rate",
|
||||
.name = "Encoder Operating rate",
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.minimum = (MINIMUM_FPS << 16),
|
||||
.maximum = INT_MAX,
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@
|
|||
/* extra output buffers in case of decoder batch */
|
||||
#define BATCH_DEC_EXTRA_OUTPUT_BUFFERS 6
|
||||
|
||||
/* extra o/p buffers in case of decoder dcvs */
|
||||
#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4
|
||||
|
||||
/* Encoder buffer count macros */
|
||||
/* total input buffers for encoder HFR usecase */
|
||||
#define HFR_ENC_TOTAL_INPUT_BUFFERS 8
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
#ifndef __H_MSM_VIDC_BUFFER_MEM_DEFS_H__
|
||||
#define __H_MSM_VIDC_BUFFER_MEM_DEFS_H__
|
||||
|
||||
/* extra o/p buffers in case of decoder dcvs */
|
||||
#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4
|
||||
|
||||
struct msm_vidc_dec_buff_size_calculators {
|
||||
u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width,
|
||||
u32 height, bool is_interlaced);
|
||||
|
|
|
|||
|
|
@ -48,14 +48,10 @@ struct msm_vidc_core_ops core_ops_iris2 = {
|
|||
static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs)
|
||||
{
|
||||
dprintk(VIDC_PERF,
|
||||
"DCVS: Load_Low %lld, Load Norm %lld, Load High %lld\n",
|
||||
dcvs->load_low,
|
||||
dcvs->load_norm,
|
||||
dcvs->load_high);
|
||||
|
||||
dprintk(VIDC_PERF,
|
||||
"DCVS: min_threshold %d, max_threshold %d\n",
|
||||
dcvs->min_threshold, dcvs->max_threshold);
|
||||
"DCVS: Loads %lld %lld %lld, Thresholds %d %d %d\n",
|
||||
dcvs->load_low, dcvs->load_norm, dcvs->load_high,
|
||||
dcvs->min_threshold, dcvs->nom_threshold,
|
||||
dcvs->max_threshold);
|
||||
}
|
||||
|
||||
static inline unsigned long get_ubwc_compression_ratio(
|
||||
|
|
@ -423,7 +419,6 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst,
|
|||
{
|
||||
int rc = 0;
|
||||
int bufs_with_fw = 0;
|
||||
int bufs_with_client = 0;
|
||||
struct msm_vidc_format *fmt;
|
||||
struct clock_data *dcvs;
|
||||
|
||||
|
|
@ -432,13 +427,9 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* assume no increment or decrement is required initially */
|
||||
inst->clk_data.dcvs_flags = 0;
|
||||
|
||||
if (!inst->clk_data.dcvs_mode || inst->batch.enable) {
|
||||
dprintk(VIDC_LOW, "Skip DCVS (dcvs %d, batching %d)\n",
|
||||
inst->clk_data.dcvs_mode, inst->batch.enable);
|
||||
/* update load (freq) with normal value */
|
||||
inst->clk_data.load = inst->clk_data.load_norm;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -452,44 +443,46 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst,
|
|||
bufs_with_fw = msm_comm_num_queued_bufs(inst, INPUT_MPLANE);
|
||||
fmt = &inst->fmts[INPUT_PORT];
|
||||
}
|
||||
|
||||
/* +1 as one buffer is going to be queued after the function */
|
||||
bufs_with_fw += 1;
|
||||
bufs_with_client = fmt->count_actual - bufs_with_fw;
|
||||
|
||||
/*
|
||||
* PMS decides clock level based on below algo
|
||||
* DCVS decides clock level based on below algo
|
||||
|
||||
* Limits :
|
||||
* max_threshold : Client extra allocated buffers. Client
|
||||
* reserves these buffers for it's smooth flow.
|
||||
* min_output_buf : HW requested buffers for it's smooth
|
||||
* flow of buffers.
|
||||
* min_threshold : Driver requested extra buffers for PMS.
|
||||
* min_threshold : Buffers required for reference by FW.
|
||||
* nom_threshold : Midpoint of Min and Max thresholds
|
||||
* max_threshold : Total - Client extra buffers, allocated
|
||||
* for it's smooth flow.
|
||||
|
||||
* 1) When buffers outside FW are reaching client's extra buffers,
|
||||
* FW is slow and will impact pipeline, Increase clock.
|
||||
* 2) When pending buffers with FW are same as FW requested,
|
||||
* pipeline has cushion to absorb FW slowness, Decrease clocks.
|
||||
* 3) When none of 1) or 2) FW is just fast enough to maintain
|
||||
* pipeline, request Right Clocks.
|
||||
* 3) When buffers are equally distributed between FW and Client
|
||||
* switch to NOM as this is the ideal steady state.
|
||||
* 4) Otherwise maintain previous Load config.
|
||||
*/
|
||||
|
||||
if (bufs_with_client <= dcvs->max_threshold) {
|
||||
dcvs->load = dcvs->load_high;
|
||||
dcvs->dcvs_flags |= MSM_VIDC_DCVS_INCR;
|
||||
} else if (bufs_with_fw < (int) fmt->count_min) {
|
||||
dcvs->load = dcvs->load_low;
|
||||
dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR;
|
||||
} else {
|
||||
if (dcvs->dcvs_window < DCVS_DEC_EXTRA_OUTPUT_BUFFERS ||
|
||||
bufs_with_fw == dcvs->nom_threshold) {
|
||||
dcvs->load = dcvs->load_norm;
|
||||
dcvs->dcvs_flags = 0;
|
||||
} else if (bufs_with_fw >= dcvs->max_threshold) {
|
||||
dcvs->load = dcvs->load_high;
|
||||
dcvs->dcvs_flags |= MSM_VIDC_DCVS_INCR;
|
||||
} else if (bufs_with_fw < dcvs->min_threshold) {
|
||||
dcvs->load = dcvs->load_low;
|
||||
dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR;
|
||||
}
|
||||
|
||||
dprintk(VIDC_PERF,
|
||||
"DCVS: %x : total bufs %d outside fw %d max threshold %d with fw %d min bufs %d flags %#x\n",
|
||||
hash32_ptr(inst->session), fmt->count_actual,
|
||||
bufs_with_client, dcvs->max_threshold, bufs_with_fw,
|
||||
fmt->count_min, dcvs->dcvs_flags);
|
||||
"DCVS: %x: bufs_with_fw %d Th[%d %d %d] Flag %#x Load %llu\n",
|
||||
hash32_ptr(inst->session), bufs_with_fw,
|
||||
dcvs->min_threshold, dcvs->nom_threshold, dcvs->max_threshold,
|
||||
dcvs->dcvs_flags, dcvs->load);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -672,6 +665,9 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst,
|
|||
break;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
dcvs->load_norm = rate;
|
||||
dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ?
|
||||
allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm;
|
||||
|
|
@ -765,6 +761,9 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst,
|
|||
break;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
dcvs->load_norm = rate;
|
||||
dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ?
|
||||
allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm;
|
||||
|
|
@ -865,6 +864,9 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst,
|
|||
break;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
dcvs->load_norm = rate;
|
||||
dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ?
|
||||
allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm;
|
||||
|
|
@ -959,6 +961,10 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core)
|
|||
if (rate >= freq_core_max)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
if (increment) {
|
||||
if (i > 0)
|
||||
rate = allowed_clks_tbl[i-1].clock_rate;
|
||||
|
|
@ -1016,15 +1022,15 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst)
|
|||
return 0;
|
||||
}
|
||||
|
||||
freq = call_core_op(inst->core, calc_freq, inst, filled_len);
|
||||
inst->clk_data.min_freq = freq;
|
||||
/* update dcvs flags */
|
||||
msm_dcvs_scale_clocks(inst, freq);
|
||||
|
||||
if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo ||
|
||||
msm_vidc_clock_voting) {
|
||||
inst->clk_data.min_freq = msm_vidc_max_freq(inst->core);
|
||||
inst->clk_data.dcvs_flags = 0;
|
||||
} else {
|
||||
freq = call_core_op(inst->core, calc_freq, inst, filled_len);
|
||||
inst->clk_data.min_freq = freq;
|
||||
/* update dcvs flags */
|
||||
msm_dcvs_scale_clocks(inst, freq);
|
||||
}
|
||||
|
||||
msm_vidc_update_freq_entry(inst, freq, device_addr, is_turbo);
|
||||
|
|
@ -1067,20 +1073,18 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (msm_vidc_clock_voting ||
|
||||
inst->clk_data.dcvs_mode =
|
||||
!(msm_vidc_clock_voting ||
|
||||
!inst->core->resources.dcvs ||
|
||||
inst->flags & VIDC_THUMBNAIL ||
|
||||
inst->clk_data.low_latency_mode ||
|
||||
inst->batch.enable ||
|
||||
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) {
|
||||
dprintk(VIDC_HIGH, "DCVS disabled: %pK\n", inst);
|
||||
inst->clk_data.dcvs_mode = false;
|
||||
return false;
|
||||
}
|
||||
inst->clk_data.dcvs_mode = true;
|
||||
dprintk(VIDC_HIGH, "DCVS enabled: %pK\n", inst);
|
||||
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ);
|
||||
|
||||
return true;
|
||||
dprintk(VIDC_HIGH|VIDC_PERF, "DCVS %s: %pK\n",
|
||||
inst->clk_data.dcvs_mode ? "enabled" : "disabled", inst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst)
|
||||
|
|
@ -1149,26 +1153,26 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst)
|
|||
inst->clk_data.entry->low_power_cycles :
|
||||
cycles;
|
||||
|
||||
dcvs->buffer_type = HAL_BUFFER_INPUT;
|
||||
dcvs->min_threshold =
|
||||
msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT);
|
||||
fmt = &inst->fmts[INPUT_PORT];
|
||||
dcvs->max_threshold =
|
||||
fmt->count_actual - fmt->count_min_host + 2;
|
||||
} else if (inst->session_type == MSM_VIDC_DECODER) {
|
||||
dcvs->buffer_type = HAL_BUFFER_OUTPUT;
|
||||
fmt = &inst->fmts[OUTPUT_PORT];
|
||||
dcvs->max_threshold =
|
||||
fmt->count_actual - fmt->count_min_host + 2;
|
||||
|
||||
dcvs->min_threshold =
|
||||
msm_vidc_get_extra_buff_count(inst, dcvs->buffer_type);
|
||||
} else {
|
||||
dprintk(VIDC_ERR, "%s: invalid session type %#x\n",
|
||||
__func__, inst->session_type);
|
||||
return;
|
||||
}
|
||||
|
||||
dcvs->min_threshold = fmt->count_min;
|
||||
dcvs->max_threshold =
|
||||
max(fmt->count_min,
|
||||
(fmt->count_actual - DCVS_DEC_EXTRA_OUTPUT_BUFFERS));
|
||||
|
||||
dcvs->dcvs_window =
|
||||
dcvs->max_threshold - dcvs->min_threshold;
|
||||
dcvs->nom_threshold = dcvs->min_threshold +
|
||||
(dcvs->dcvs_window ?
|
||||
(dcvs->dcvs_window / 2) : 0);
|
||||
|
||||
total_freq = cycles * load;
|
||||
|
||||
for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) {
|
||||
|
|
@ -1177,12 +1181,14 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst)
|
|||
break;
|
||||
}
|
||||
|
||||
dcvs->load = dcvs->load_norm = rate;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
dcvs->load = dcvs->load_norm = rate;
|
||||
dcvs->load_low = i < (core->resources.allowed_clks_tbl_size - 1) ?
|
||||
allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm;
|
||||
dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate :
|
||||
dcvs->load_norm;
|
||||
dcvs->load_high = i > 0 ?
|
||||
allowed_clks_tbl[i-1].clock_rate : dcvs->load_norm;
|
||||
|
||||
inst->clk_data.buffer_counter = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1820,7 +1820,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
|
|||
dprintk(VIDC_HIGH|VIDC_PERF, "%s: %x : batching %s\n",
|
||||
__func__, hash32_ptr(inst->session),
|
||||
inst->batch.enable ? "enabled" : "disabled");
|
||||
|
||||
msm_dcvs_try_enable(inst);
|
||||
extra_buff_count = msm_vidc_get_extra_buff_count(inst,
|
||||
HAL_BUFFER_OUTPUT);
|
||||
fmt->count_min = event_notify->capture_buf_count;
|
||||
|
|
|
|||
|
|
@ -393,9 +393,10 @@ struct clock_data {
|
|||
u64 load_norm;
|
||||
u64 load_high;
|
||||
int min_threshold;
|
||||
int nom_threshold;
|
||||
int max_threshold;
|
||||
enum hal_buffer buffer_type;
|
||||
bool dcvs_mode;
|
||||
u32 dcvs_window;
|
||||
unsigned long bitrate;
|
||||
unsigned long min_freq;
|
||||
unsigned long curr_freq;
|
||||
|
|
|
|||
|
|
@ -13,18 +13,6 @@
|
|||
|
||||
#define MAX_BUFFER_TYPES 32
|
||||
|
||||
struct dcvs_table {
|
||||
u32 load;
|
||||
u32 load_low;
|
||||
u32 load_high;
|
||||
u32 supported_codecs;
|
||||
};
|
||||
|
||||
struct dcvs_limit {
|
||||
u32 min_mbpf;
|
||||
u32 fps;
|
||||
};
|
||||
|
||||
struct reg_value_pair {
|
||||
u32 reg;
|
||||
u32 value;
|
||||
|
|
@ -156,9 +144,6 @@ struct msm_vidc_platform_resources {
|
|||
struct allowed_clock_rates_table *allowed_clks_tbl;
|
||||
u32 allowed_clks_tbl_size;
|
||||
struct clock_freq_table clock_freq_tbl;
|
||||
struct dcvs_table *dcvs_tbl;
|
||||
uint32_t dcvs_tbl_size;
|
||||
struct dcvs_limit *dcvs_limit;
|
||||
bool sys_cache_present;
|
||||
bool sys_cache_res_set;
|
||||
struct subcache_set subcache_set;
|
||||
|
|
|
|||
Loading…
Reference in a new issue