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

Commit 39655cba authored by Ravi Kiran Vonteddu's avatar Ravi Kiran Vonteddu
Browse files

msm: vidc: update bus bandwidth based on venus idle time



Calculate venus core idle time and send the feedback
error level to the bus manager.
Based on the feedback error level, update msm bus of
any bus congestion.

Change-Id: If9d37eb4b8fb7700a17e65492cfea4b042fb7fcd
Signed-off-by: default avatarRavi Kiran Vonteddu <rvontedd@codeaurora.org>
parent e1ce01c5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ Optional properties:
  power collapsible = 0x2 (if the driver should disable the clock if no load)
- qcom,use-non-secure-pil = A bool indicating which type of pil to use to load
  the fw.
- qcom,use_dynamic_bw_update = A bool indicating whether dynamic bandwidth
  update request should be sent to msm bus or not.
- qcom,fw-bias = The address at which venus fw is loaded (manually).

Example:
@@ -161,5 +163,6 @@ Example:
			};
		};
		qcom,use-non-secure-pil;
		qcom,use_dynamic_bw_update;
		qcom,fw-bias = <0xe000000>;
	};
+12 −0
Original line number Diff line number Diff line
@@ -1229,6 +1229,15 @@ static void hfi_process_session_abort_done(msm_vidc_callback callback,
	callback(SESSION_ABORT_DONE, &cmd_done);
}

static void hfi_process_sys_idle(msm_vidc_callback callback,
		u32 device_id, struct hal_session *session,
		struct hfi_msg_sys_idle_packet *pkt)
{
	struct msm_vidc_cb_cmd_done cmd_done = {0};
	cmd_done.device_id = device_id;
	callback(SYS_IDLE, &cmd_done);
}

static void hfi_process_session_get_seq_hdr_done(msm_vidc_callback callback,
		u32 device_id, struct hal_session *session,
	struct hfi_msg_session_get_sequence_header_done_packet *pkt)
@@ -1419,6 +1428,9 @@ u32 hfi_process_msg_packet(msm_vidc_callback callback, u32 device_id,
			(session_pkt_func_def)hfi_process_session_abort_done;
		break;
	case HFI_MSG_SYS_IDLE:
		sys_pkt_func =
			(sys_pkt_func_def)hfi_process_sys_idle;
		break;
	case HFI_MSG_SYS_PC_PREP_DONE:
		break;
	default:
+93 −1
Original line number Diff line number Diff line
@@ -272,7 +272,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);
			vote_data_count, core->idle_time.fb_err_level);
	if (rc)
		dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);

@@ -949,6 +949,30 @@ static void handle_session_flush(enum command_response cmd, void *data)
	}
}

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;

	if (response) {
		core = get_vidc_core(response->device_id);
		dprintk(VIDC_DBG, "SYS_IDLE received for core %p\n", core);
		if (core && 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;
			mutex_unlock(&core->lock);
		} else
			dprintk(VIDC_ERR, "Core is NULL when sys_idle rxed\n");
	}
}

static void handle_session_error(enum command_response cmd, void *data)
{
	struct msm_vidc_cb_cmd_done *response = data;
@@ -1624,6 +1648,9 @@ void handle_cmd_response(enum command_response cmd, void *data)
	case SESSION_RELEASE_BUFFER_DONE:
		handle_session_release_buf_done(cmd, data);
		break;
	case SYS_IDLE:
		handle_sys_idle(cmd, data);
		break;
	default:
		dprintk(VIDC_ERR, "response unhandled\n");
		break;
@@ -2588,6 +2615,67 @@ exit:
				inst->state, state);
	return rc;
}

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;
	struct msm_vidc_core *core;

	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);

	if (idle_time->avg_idle_time == 0)
		idle_time->fb_err_level = 3;
	else
		idle_time->fb_err_level = 0;

	if (idle_time->fb_err_level != idle_time->prev_fb_err_level) {
		idle_time->prev_fb_err_level = idle_time->fb_err_level;
		if (msm_comm_vote_bus(core)) {
			dprintk(VIDC_WARN,
			"Failed to scale DDR bus. Performance might be impacted\n");
		}
	}
	return rc;
}

int msm_comm_qbuf(struct vb2_buffer *vb)
{
	int rc = 0;
@@ -2717,6 +2805,8 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
				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)
@@ -2744,6 +2834,8 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
				&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].
+1 −0
Original line number Diff line number Diff line
@@ -211,6 +211,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_inst {
+3 −0
Original line number Diff line number Diff line
@@ -660,6 +660,9 @@ int read_platform_resources_from_dt(
	of_property_read_u32(pdev->dev.of_node,
			"qcom,ocmem-size", &res->ocmem_size);

	res->dynamic_bw_update = of_property_read_bool(pdev->dev.of_node,
			"qcom,use_dynamic_bw_update");

	rc = msm_vidc_load_freq_table(res);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to load freq table: %d\n", rc);
Loading