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

Commit 9b1aca77 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: update bus bandwidth based on venus idle time"

parents 38e5f4a1 39655cba
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