Ver Fonte

video driver: calculate power based on input queuing rate

Use client input buffer queuing rate for power
calculations for non-realtime sessions

Change-Id: I498422ba1ae9ae96b782a2096dc0cd0aa7b05798
Signed-off-by: Deepa Guthyappa Madivalara <[email protected]>
Deepa Guthyappa Madivalara há 3 anos atrás
pai
commit
dc38176276

+ 4 - 0
driver/platform/kalama/src/msm_vidc_kalama.c

@@ -255,6 +255,10 @@ static struct msm_platform_inst_capability instance_data_kalama[] = {
 		(MINIMUM_FPS << 16), (MAXIMUM_OVERRIDE_VP9_FPS << 16),
 		1, (DEFAULT_FPS << 16)},
 
+	{INPUT_RATE, ENC|DEC, CODECS_ALL,
+		(MINIMUM_FPS << 16), INT_MAX,
+		1, (DEFAULT_FPS << 16)},
+
 	{SCALE_FACTOR, ENC, H264|HEVC, 1, 8, 1, 8},
 
 	{MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25},

+ 4 - 0
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -241,6 +241,10 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		(MINIMUM_FPS << 16), (MAXIMUM_OVERRIDE_VP9_FPS << 16),
 		1, (DEFAULT_FPS << 16)},
 
+	{INPUT_RATE, ENC|DEC, CODECS_ALL,
+		(MINIMUM_FPS << 16), INT_MAX,
+		1, (DEFAULT_FPS << 16)},
+
 	{SCALE_FACTOR, ENC, H264|HEVC, 1, 8, 1, 8},
 
 	{MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25},

+ 12 - 11
driver/variant/iris2/src/msm_vidc_power_iris2.c

@@ -21,8 +21,7 @@ u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 data_size)
 	u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1;
 	u32 base_cycles = 0;
 	u32 fps;
-	u32 prio_val;
-	u32 buf_timetamps_fps, mbpf;
+	u32 buf_timetamps_fps, mbpf, input_rate;
 
 	if (!inst || !inst->core || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -35,14 +34,6 @@ u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 data_size)
 		return freq;
 	}
 
-	if (!is_realtime_session(inst)) {
-		prio_val = inst->capabilities->cap[PRIORITY].value;
-		if (!prio_val || prio_val > core->dt->allowed_clks_tbl_size)
-			prio_val = core->dt->allowed_clks_tbl_size;
-
-		return core->dt->allowed_clks_tbl[prio_val-1].clock_rate;
-	}
-
 	mbpf = msm_vidc_get_mbs_per_frame(inst);
 	fps = msm_vidc_get_fps(inst);
 
@@ -56,7 +47,17 @@ u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 data_size)
 		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;
 
 	/*

+ 12 - 11
driver/variant/iris3/src/msm_vidc_power_iris3.c

@@ -22,8 +22,7 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
 	u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1;
 	u32 base_cycles = 0;
 	u32 fps;
-	u32 prio_val;
-	u32 buf_timetamps_fps, mbpf;
+	u32 buf_timetamps_fps, mbpf, input_rate;
 
 	if (!inst || !inst->core || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -36,14 +35,6 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
 		return freq;
 	}
 
-	if (!is_realtime_session(inst)) {
-		prio_val = inst->capabilities->cap[PRIORITY].value;
-		if (!prio_val || prio_val > core->dt->allowed_clks_tbl_size)
-			prio_val = core->dt->allowed_clks_tbl_size;
-
-		return core->dt->allowed_clks_tbl[prio_val-1].clock_rate;
-	}
-
 	mbpf = msm_vidc_get_mbs_per_frame(inst);
 	fps = msm_vidc_get_fps(inst);
 
@@ -57,7 +48,17 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
 		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;
 
 	/*

+ 2 - 0
driver/vidc/inc/msm_vidc_driver.h

@@ -452,5 +452,7 @@ bool res_is_less_than_or_equal_to(u32 width, u32 height,
 int msm_vidc_get_properties(struct msm_vidc_inst *inst);
 int msm_vidc_create_input_metadata_buffer(struct msm_vidc_inst *inst, u32 buf_fd);
 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_get_input_rate(struct msm_vidc_inst *inst);
 #endif // _MSM_VIDC_DRIVER_H_
 

+ 1 - 0
driver/vidc/inc/msm_vidc_inst.h

@@ -142,6 +142,7 @@ struct msm_vidc_inst {
 	struct list_head                   response_works; /* list of struct response_work */
 	struct list_head                   enc_input_crs;
 	struct list_head                   dmabuf_tracker; /* list of struct msm_memory_dmabuf */
+	struct list_head                   input_timer_list; /* list of struct msm_vidc_input_timer */
 	struct list_head                   caps_list;
 	struct list_head                   children_list; /* struct msm_vidc_inst_cap_entry */
 	struct list_head                   firmware_list; /* struct msm_vidc_inst_cap_entry */

+ 7 - 0
driver/vidc/inc/msm_vidc_internal.h

@@ -66,6 +66,7 @@
 #define DCVS_WINDOW 16
 #define ENC_FPS_WINDOW 3
 #define DEC_FPS_WINDOW 10
+#define INPUT_TIMER_LIST_SIZE 30
 
 #define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
 #define OUTPUT_MPLANE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
@@ -368,6 +369,7 @@ enum msm_vidc_inst_capability_type {
 	POWER_SAVE_MBPS,
 	FRAME_RATE,
 	OPERATING_RATE,
+	INPUT_RATE,
 	SCALE_FACTOR,
 	MB_CYCLES_VSP,
 	MB_CYCLES_VPP,
@@ -893,6 +895,11 @@ struct msm_vidc_timestamps {
 	u64                    rank;
 };
 
+struct msm_vidc_input_timer {
+	struct list_head       list;
+	u64                    time_us;
+};
+
 enum msm_vidc_allow {
 	MSM_VIDC_DISALLOW = 0,
 	MSM_VIDC_ALLOW,

+ 1 - 0
driver/vidc/inc/msm_vidc_memory.h

@@ -26,6 +26,7 @@ enum msm_memory_pool_type {
 	MSM_MEM_POOL_TIMESTAMP,
 	MSM_MEM_POOL_DMABUF,
 	MSM_MEM_POOL_PACKET,
+	MSM_MEM_POOL_BUF_TIMER,
 	MSM_MEM_POOL_MAX,
 };
 

+ 1 - 0
driver/vidc/src/msm_vidc.c

@@ -932,6 +932,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	INIT_LIST_HEAD(&inst->firmware_list);
 	INIT_LIST_HEAD(&inst->enc_input_crs);
 	INIT_LIST_HEAD(&inst->dmabuf_tracker);
+	INIT_LIST_HEAD(&inst->input_timer_list);
 	INIT_LIST_HEAD(&inst->pending_pkts);
 	INIT_LIST_HEAD(&inst->fence_list);
 	for (i = 0; i < MAX_SIGNAL; i++)

+ 55 - 1
driver/vidc/src/msm_vidc_driver.c

@@ -75,6 +75,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
 	{POWER_SAVE_MBPS,                "POWER_SAVE_MBPS"            },
 	{FRAME_RATE,                     "FRAME_RATE"                 },
 	{OPERATING_RATE,                 "OPERATING_RATE"             },
+	{INPUT_RATE,                     "INPUT_RATE"                 },
 	{SCALE_FACTOR,                   "SCALE_FACTOR"               },
 	{MB_CYCLES_VSP,                  "MB_CYCLES_VSP"              },
 	{MB_CYCLES_VPP,                  "MB_CYCLES_VPP"              },
@@ -2352,6 +2353,59 @@ int msm_vidc_calc_window_avg_framerate(struct msm_vidc_inst *inst)
 	return ts_ms ? (1000 * counter) / ts_ms : 0;
 }
 
+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 *prev_timer = NULL;
+	u64 counter = 0;
+	u64 input_timer_sum_us = 0;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	input_timer = msm_memory_pool_alloc(inst, MSM_MEM_POOL_BUF_TIMER);
+	if (!input_timer)
+		return -ENOMEM;
+
+	input_timer->time_us = time_us;
+	INIT_LIST_HEAD(&input_timer->list);
+	list_add_tail(&input_timer->list, &inst->input_timer_list);
+	list_for_each_entry(input_timer, &inst->input_timer_list, list) {
+		if (prev_timer) {
+			input_timer_sum_us += input_timer->time_us - prev_timer->time_us;
+			counter++;
+		}
+		prev_timer = input_timer;
+	}
+
+	if (input_timer_sum_us)
+		inst->capabilities->cap[INPUT_RATE].value =
+			(s32)(DIV64_U64_ROUND_CLOSEST(counter * 1000000,
+				input_timer_sum_us) << 16);
+
+	/* delete the first entry once counter >= INPUT_TIMER_LIST_SIZE */
+	if (counter >= INPUT_TIMER_LIST_SIZE) {
+		input_timer = list_first_entry(&inst->input_timer_list,
+				struct msm_vidc_input_timer, list);
+		list_del_init(&input_timer->list);
+		msm_memory_pool_free(inst, input_timer);
+	}
+
+	return 0;
+}
+
+int msm_vidc_get_input_rate(struct msm_vidc_inst *inst)
+{
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return 0;
+	}
+
+	return inst->capabilities->cap[INPUT_RATE].value >> 16;
+}
+
 static int msm_vidc_insert_sort(struct list_head *head,
 	struct msm_vidc_sort *entry)
 {
@@ -6359,4 +6413,4 @@ int msm_vidc_update_input_meta_buffer_index(struct msm_vidc_inst *inst,
 		rc = -EINVAL;
 	}
 	return rc;
-}
+}

+ 1 - 0
driver/vidc/src/msm_vidc_memory.c

@@ -592,6 +592,7 @@ static const struct msm_vidc_type_size_name buftype_size_name_arr[] = {
 	{MSM_MEM_POOL_DMABUF,     sizeof(struct msm_memory_dmabuf),   "MSM_MEM_POOL_DMABUF"     },
 	{MSM_MEM_POOL_PACKET,     sizeof(struct hfi_pending_packet) + MSM_MEM_POOL_PACKET_SIZE,
 		"MSM_MEM_POOL_PACKET"},
+	{MSM_MEM_POOL_BUF_TIMER,  sizeof(struct msm_vidc_input_timer), "MSM_MEM_POOL_BUF_TIMER" },
 };
 
 int msm_memory_pools_init(struct msm_vidc_inst *inst)

+ 14 - 12
driver/vidc/src/msm_vidc_power.c

@@ -133,12 +133,7 @@ static int msm_vidc_set_buses(struct msm_vidc_inst* inst)
 		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
 	}
-
 	core = inst->core;
-	if (!core || !core->platform || !core->platform->data.bus_bw_nrt) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
 
 	mutex_lock(&core->lock);
 	curr_time_ns = ktime_get_ns();
@@ -154,11 +149,6 @@ static int msm_vidc_set_buses(struct msm_vidc_inst* inst)
 			break;
 		}
 
-		if (!is_realtime_session(inst)) {
-			temp->power.ddr_bw = core->platform->data.bus_bw_nrt[0];
-			temp->power.sys_cache_bw = core->platform->data.bus_bw_nrt[0];
-		}
-
 		total_bw_ddr += temp->power.ddr_bw;
 		total_bw_llcc += temp->power.sys_cache_bw;
 	}
@@ -188,7 +178,7 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
 	struct vidc_bus_vote_data *vote_data;
 	struct v4l2_format *out_f;
 	struct v4l2_format *inp_f;
-	int codec = 0, frame_rate, buf_ts_fps;
+	int codec = 0, frame_rate, buf_ts_fps, input_rate;
 
 	if (!inst || !inst->core || !inst->capabilities) {
 		d_vpr_e("%s: invalid params: %pK\n", __func__, inst);
@@ -238,7 +228,19 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
 			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) {
 		vote_data->domain = MSM_VIDC_ENCODER;
 		vote_data->bitrate = inst->capabilities->cap[BIT_RATE].value;

+ 9 - 1
driver/vidc/src/msm_vidc_vb2.c

@@ -378,6 +378,7 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
 	int rc = 0;
 	struct msm_vidc_inst *inst;
 	u64 timestamp_us = 0;
+	u64 ktime_ns = ktime_get_ns();
 
 	inst = vb2_get_drv_priv(vb2->vb2_queue);
 	if (!inst) {
@@ -410,7 +411,14 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
 		timestamp_us = div_u64(vb2->timestamp, 1000);
 		msm_vidc_set_auto_framerate(inst, timestamp_us);
 	}
-	inst->last_qbuf_time_ns = ktime_get_ns();
+	inst->last_qbuf_time_ns = ktime_ns;
+
+	if (!is_realtime_session(inst) && vb2->type == INPUT_MPLANE) {
+		rc = msm_vidc_update_input_rate(inst, div_u64(ktime_ns, 1000));
+		if (rc)
+			goto unlock;
+	}
+
 	/*
 	 * As part of every qbuf initalise request to true.
 	 * If there are any dynamic controls associated with qbuf,