Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ac86f48 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Refactor bandwidth management"

parents eacc0e65 83d09279
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -1230,8 +1230,7 @@ static void hfi_process_session_abort_done(msm_vidc_callback callback,
}

static void hfi_process_sys_idle(msm_vidc_callback callback,
		u32 device_id, struct hal_session *session,
		struct hfi_msg_sys_idle_packet *pkt)
		u32 device_id, struct hfi_msg_sys_idle_packet *pkt)
{
	struct msm_vidc_cb_cmd_done cmd_done = {0};
	cmd_done.device_id = device_id;
+79 −60
Original line number Diff line number Diff line
@@ -274,7 +274,7 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core)
	mutex_unlock(&core->lock);

	rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, vote_data,
			vote_data_count, core->idle_time.fb_err_level);
			vote_data_count, core->idle_stats.fb_err_level);
	if (rc)
		dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);

@@ -956,27 +956,34 @@ static void handle_sys_idle(enum command_response cmd, void *data)
{
	struct msm_vidc_cb_cmd_done *response = data;
	struct msm_vidc_core *core = NULL;
	int rc = 0;

	if (!response) {
		rc = -EINVAL;
		goto exit;
	}

	if (response) {
	core = get_vidc_core(response->device_id);
	if (!core) {
		dprintk(VIDC_ERR, "Received IDLE with invalid core\n");
		rc = -EINVAL;
		goto exit;
	}

	dprintk(VIDC_DBG, "SYS_IDLE received for core %p\n", core);
		if (core) {
	if (core->resources.dynamic_bw_update) {
				struct timeval tv;
		mutex_lock(&core->lock);
				do_gettimeofday(&tv);
				core->idle_time.start_idle_time =
					(tv.tv_sec * 1000000 + (tv.tv_usec));
				dprintk(VIDC_DBG,
					"%s: start_idle_time %llu us\n",
					__func__,
					core->idle_time.start_idle_time);
				core->idle_time.core_in_idle = true;
		core->idle_stats.start_time = ktime_get();
		dprintk(VIDC_DBG, "%s: start idle time %llu us\n",
				__func__, ktime_to_us(
					core->idle_stats.start_time));
		core->idle_stats.idle = true;
		mutex_unlock(&core->lock);
	}
		} else
			dprintk(VIDC_ERR, "Core is NULL when sys_idle rxed\n");
	}

exit:
	if (rc)
		dprintk(VIDC_WARN, "Failed to handle idle message\n");
}

static void handle_session_error(enum command_response cmd, void *data)
@@ -2958,61 +2965,58 @@ exit:

int msm_comm_compute_idle_time(struct msm_vidc_inst *inst)
{
	u64 curr_time = 0;
	struct timeval tv;
	int j = 0;
	u32 idx = 0;
	int rc = 0;
	struct msm_vidc_idle_time *idle_time;
	int j = 0, rc = 0, last_sample_index = 0;
	struct msm_vidc_idle_stats *idle_stats;
	struct msm_vidc_core *core;
	const ktime_t zero_ktime = ktime_set(0, 0);
	ktime_t cumulative_idle_time = zero_ktime;
	u64 temp;

	if (!inst || !inst->core) {
		dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
		return -EINVAL;
	}

	core = inst->core;

	mutex_lock(&core->lock);
	do_gettimeofday(&tv);
	curr_time = (tv.tv_sec * 1000000 + tv.tv_usec);
	idle_time = &inst->core->idle_time;
	idx = idle_time->idx;

	if (idle_time->core_in_idle) {
		idle_time->core_idle_times[idx] =
			(curr_time - idle_time->start_idle_time);
	} else {
		idle_time->core_idle_times[idx] = 0;
	}
	idle_time->array_size++;
	if (idle_time->array_size > IDLE_TIME_WINDOW_SIZE)
		idle_time->array_size = IDLE_TIME_WINDOW_SIZE;

	for (j = 0; j < idle_time->array_size; j++)
		idle_time->avg_idle_time +=
			idle_time->core_idle_times[j];

	do_div(idle_time->avg_idle_time, idle_time->array_size);
	idle_time->core_in_idle = 0;
	idle_time->idx++;
	idle_time->idx %= IDLE_TIME_WINDOW_SIZE;
	dprintk(VIDC_DBG, "%s:core_idle_times %llu us avg_idle_time %llu us\n",
		__func__,
		idle_time->core_idle_times[idx],
		idle_time->avg_idle_time);
	mutex_unlock(&core->lock);
	idle_stats = &core->idle_stats;
	last_sample_index = idle_stats->last_sample_index;

	if (idle_time->avg_idle_time == 0)
		idle_time->fb_err_level = 3;
	else
		idle_time->fb_err_level = 0;
	idle_stats->samples[last_sample_index] = idle_stats->idle ?
		ktime_sub(ktime_get(), idle_stats->start_time) : zero_ktime;

	idle_stats->sample_count++;
	if (idle_stats->sample_count > IDLE_TIME_WINDOW_SIZE)
		idle_stats->sample_count = IDLE_TIME_WINDOW_SIZE;

	for (j = 0; j < idle_stats->sample_count; j++) {
		cumulative_idle_time = ktime_add(cumulative_idle_time,
			idle_stats->samples[j]);
	}

	temp = ktime_to_ns(cumulative_idle_time);
	do_div(temp, idle_stats->sample_count);
	idle_stats->avg_idle_time = ns_to_ktime(temp);

	idle_stats->idle = true;
	idle_stats->last_sample_index++;
	idle_stats->last_sample_index %= sizeof(idle_stats->samples);
	dprintk(VIDC_DBG, "%s: Idle stats: current %llu us, average %llu us\n",
		__func__, ktime_to_us(idle_stats->samples[last_sample_index]),
		ktime_to_us(idle_stats->avg_idle_time));
	mutex_unlock(&core->lock);

	if (idle_time->fb_err_level != idle_time->prev_fb_err_level) {
		idle_time->prev_fb_err_level = idle_time->fb_err_level;
	idle_stats->fb_err_level = ktime_compare(idle_stats->avg_idle_time,
			zero_ktime) == 0 ? 3 : 0;
	if (idle_stats->fb_err_level != idle_stats->prev_fb_err_level) {
		idle_stats->prev_fb_err_level = idle_stats->fb_err_level;
		if (msm_comm_vote_bus(core)) {
			dprintk(VIDC_WARN,
			"Failed to scale DDR bus. Performance might be impacted\n");
		}
	}

	return rc;
}

@@ -3088,6 +3092,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
			rc = -EINVAL;
			goto err_bad_input;
		}

		if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
			frame_data.buffer_type = HAL_BUFFER_INPUT;
			if (vb->v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS) {
@@ -3095,6 +3100,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
				dprintk(VIDC_DBG,
					"Received EOS on output capability\n");
			}

			if (vb->v4l2_buf.flags &
				V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP) {
				frame_data.flags |=
@@ -3102,21 +3108,25 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
				dprintk(VIDC_DBG,
					"Received buff with 601to709 clamp\n");
			}

			if (vb->v4l2_buf.flags &
					V4L2_QCOM_BUF_FLAG_CODECCONFIG) {
				frame_data.flags |= HAL_BUFFERFLAG_CODECCONFIG;
				dprintk(VIDC_DBG,
					"Received CODECCONFIG on output cap\n");
			}

			if (vb->v4l2_buf.flags &
					V4L2_QCOM_BUF_FLAG_DECODEONLY) {
				frame_data.flags |= HAL_BUFFERFLAG_DECODEONLY;
				dprintk(VIDC_DBG,
					"Received DECODEONLY on output cap\n");
			}

			if (vb->v4l2_buf.flags &
				V4L2_QCOM_BUF_TIMESTAMP_INVALID)
				frame_data.timestamp = LLONG_MAX;

			if (vb->v4l2_buf.flags &
					V4L2_QCOM_BUF_TS_DISCONTINUITY) {
				frame_data.flags |=
@@ -3124,12 +3134,14 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
				dprintk(VIDC_DBG,
					"Received TS_DISCONTINUE on output\n");
			}

			if (vb->v4l2_buf.flags & V4L2_QCOM_BUF_TS_ERROR) {
				frame_data.flags |=
					HAL_BUFFERFLAG_TS_ERROR;
				dprintk(VIDC_DBG,
					"Received TS_ERROR on output cap\n");
			}

			extra_idx =
				EXTRADATA_IDX(inst->fmts[OUTPUT_PORT]->
					num_planes);
@@ -3139,14 +3151,17 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
					vb->v4l2_planes[extra_idx].m.userptr;
				frame_data.flags |= HAL_BUFFERFLAG_EXTRADATA;
			}

			dprintk(VIDC_DBG,
				"Sending etb to hal: device_addr: 0x%pa, alloc: %d, filled: %d, offset: %d, ts: %lld, flags = 0x%x, v4l2_buf index = %d\n",
				&frame_data.device_addr, frame_data.alloc_len,
				frame_data.filled_len, frame_data.offset,
				frame_data.timestamp, frame_data.flags,
				vb->v4l2_buf.index);

			if (core->resources.dynamic_bw_update)
				msm_comm_compute_idle_time(inst);

			rc = call_hfi_op(hdev, session_etb, (void *)
					inst->session, &frame_data);
			if (!rc)
@@ -3160,6 +3175,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
			frame_data.alloc_len = vb->v4l2_planes[0].length;
			frame_data.buffer_type =
				msm_comm_get_hal_output_buffer(inst);

			extra_idx =
			EXTRADATA_IDX(inst->fmts[CAPTURE_PORT]->num_planes);
			if (extra_idx && (extra_idx < VIDEO_MAX_PLANES) &&
@@ -3169,13 +3185,16 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
				frame_data.extradata_size =
					vb->v4l2_planes[extra_idx].length;
			}

			dprintk(VIDC_DBG,
				"Sending ftb to hal: device_addr: 0x%pa, alloc: %d, buffer_type: %d, ts: %lld, flags = 0x%x, v4l2_buf index = %d\n",
				&frame_data.device_addr, frame_data.alloc_len,
				frame_data.buffer_type, frame_data.timestamp,
				frame_data.flags, vb->v4l2_buf.index);

			if (core->resources.dynamic_bw_update)
				msm_comm_compute_idle_time(inst);

			if (atomic_read(&inst->get_seq_hdr_cnt) &&
			   inst->session_type == MSM_VIDC_ENCODER) {
				seq_hdr.seq_hdr = vb->v4l2_planes[0].
+12 −1
Original line number Diff line number Diff line
@@ -238,6 +238,17 @@ struct msm_vidc_core_capability {
	enum buffer_mode_type buffer_mode[MAX_PORT_NUM];
};

struct msm_vidc_idle_stats {
	bool idle;
	u32 fb_err_level;
	u32 prev_fb_err_level;
	ktime_t start_time;
	ktime_t avg_idle_time;
	u32 last_sample_index;
	u32 sample_count;
	ktime_t samples[IDLE_TIME_WINDOW_SIZE];
};

struct msm_vidc_core {
	struct list_head list;
	struct mutex lock;
@@ -253,7 +264,7 @@ struct msm_vidc_core {
	struct msm_vidc_platform_resources resources;
	u32 enc_codec_supported;
	u32 dec_codec_supported;
	struct msm_vidc_idle_time idle_time;
	struct msm_vidc_idle_stats idle_stats;
};

struct msm_vidc_inst {
+0 −10
Original line number Diff line number Diff line
@@ -121,16 +121,6 @@ struct msm_vidc_platform_resources {
	bool sw_power_collapsible;
};

struct msm_vidc_idle_time {
	bool core_in_idle;
	u32 fb_err_level;
	u32 prev_fb_err_level;
	u32 idx;
	u32 array_size;
	u64 start_idle_time;
	u64 avg_idle_time;
	u64 core_idle_times[IDLE_TIME_WINDOW_SIZE];
};
static inline int is_iommu_present(struct msm_vidc_platform_resources *res)
{
	if (res)
+1 −1
Original line number Diff line number Diff line
@@ -747,7 +747,7 @@ static bool venus_hfi_bus_supports_session(unsigned long sessions_supported,
}

static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *data,
		int num_data, u32 fb_error_level)
		int num_data, int requested_level)
{
	struct {
		struct bus_info *bus;
Loading