From 9c6de09cc90e63b6e665dbd9bebdc04566695c5c Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 6 Aug 2019 11:43:14 -0700 Subject: [PATCH] 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 --- msm/vidc/msm_vdec.c | 3 +- msm/vidc/msm_venc.c | 2 +- msm/vidc/msm_vidc_buffer_calculations.c | 3 - msm/vidc/msm_vidc_buffer_calculations.h | 3 + msm/vidc/msm_vidc_clocks.c | 128 +++++++++++++----------- msm/vidc/msm_vidc_common.c | 2 +- msm/vidc/msm_vidc_internal.h | 3 +- msm/vidc/msm_vidc_resources.h | 15 --- 8 files changed, 76 insertions(+), 83 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 33c4e07f7a5e..4628185b3bb3 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -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; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 185b6cc9472d..bc5571f2e77e 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -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, diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 13200fc29a58..3250e90bda5b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -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 diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 7e4575ad6e56..7a6db350d5fa 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -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); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 12cb998a2d27..861addc889b8 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -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; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b9cc0dabc1bf..a270b6c8cbf3 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -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; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index af433a2a17eb..891a15a80fa7 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -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; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 7c5619de22dc..443e07be14b1 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -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;