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

Commit 5f86b412 authored by Vikash Garodia's avatar Vikash Garodia
Browse files

msm: vdec: Update power resources with updated operating rate



Client may choose to configure the session to TURBO mode and
reset it on per frame basis. For such clients, video driver
need not wait for next buffer to scale the power resources.
Doing so, it would lead to a case of high power during the
time video hardware remains idle after processing a frame.
Update the video power resource in alignment with operating
rate to achieve power benefits.

Change-Id: I521ef569cb1ca9287b9b5627d90daacc2051082d
Signed-off-by: default avatarVikash Garodia <vgarodia@codeaurora.org>
parent e5c1ae80
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
 */

#include "msm_cvp_internal.h"
@@ -233,14 +233,14 @@ static int msm_cvp_scale_clocks_and_bus(struct msm_vidc_inst *inst)
		return -EINVAL;
	}

	rc = msm_vidc_set_clocks(inst->core, inst->sid);
	rc = msm_vidc_set_clocks(inst->core, inst->sid, false);
	if (rc) {
		s_vpr_e(inst->sid, "%s: failed set_clocks for inst %pK\n",
			__func__, inst);
		goto exit;
	}

	rc = msm_comm_vote_bus(inst);
	rc = msm_comm_vote_bus(inst, false);
	if (rc) {
		s_vpr_e(inst->sid,
			"%s: failed vote_bus for inst %pK\n", __func__, inst);
+10 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/slab.h>
@@ -927,6 +927,15 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
	case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
		if (!is_valid_operating_rate(inst, ctrl->val))
			break;
		/*
		 * reset the resources like clock and bus as per the updated
		 * flag. When switch from TURBO to normal, need not wait for
		 * next qbuf to scale down the resources.
		 */
		if ((inst->flags & VIDC_TURBO) && (ctrl->val != INT_MAX)) {
			inst->flags &= ~VIDC_TURBO;
			msm_comm_reset_clocks_and_bus(inst);
		}
		inst->flags &= ~VIDC_TURBO;
		if (ctrl->val == INT_MAX)
			inst->flags |= VIDC_TURBO;
+32 −13
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

#include "msm_vidc_common.h"
@@ -274,7 +274,7 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst,
	return 0;
}

int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid)
int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid, bool force_reset)
{
	int rc = 0;
	struct msm_vidc_inst *inst = NULL;
@@ -306,7 +306,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid)
		}
		mutex_unlock(&inst->registeredbufs.lock);

		if ((!filled_len || !device_addr) &&
		if ((!filled_len || !device_addr) && !force_reset &&
			(inst->session_type != MSM_VIDC_CVP)) {
			s_vpr_l(sid, "%s: no input\n", __func__);
			continue;
@@ -333,7 +333,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid)
	return rc;
}

int msm_comm_vote_bus(struct msm_vidc_inst *inst)
int msm_comm_vote_bus(struct msm_vidc_inst *inst, bool force_reset)
{
	int rc = 0;
	struct msm_vidc_core *core;
@@ -368,7 +368,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst)
	}
	mutex_unlock(&inst->registeredbufs.lock);

	if ((!filled_len || !device_addr) &&
	if ((!filled_len || !device_addr) && !force_reset &&
		(inst->session_type != MSM_VIDC_CVP)) {
		s_vpr_l(inst->sid, "%s: no input\n", __func__);
		return 0;
@@ -457,7 +457,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst)
		call_core_op(core, calc_bw, vote_data);
	}

	rc = msm_comm_set_buses(core, inst->sid);
	rc = msm_comm_set_buses(core, inst->sid, force_reset);

	return rc;
}
@@ -877,7 +877,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst,
	return (unsigned long) freq;
}

int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid)
int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid, bool force_reset)
{
	struct hfi_device *hdev;
	unsigned long freq_core_1 = 0, freq_core_2 = 0, rate = 0;
@@ -915,7 +915,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid)
		}
		mutex_unlock(&inst->registeredbufs.lock);

		if (!filled_len || !device_addr) {
		if ((!filled_len || !device_addr) && !force_reset) {
			s_vpr_l(sid, "%s: no input\n", __func__);
			continue;
		}
@@ -988,7 +988,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid)
	return rc;
}

int msm_comm_scale_clocks(struct msm_vidc_inst *inst)
int msm_comm_scale_clocks(struct msm_vidc_inst *inst, bool force_reset)
{
	struct msm_vidc_buffer *temp, *next;
	unsigned long freq = 0;
@@ -1013,7 +1013,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst)
	}
	mutex_unlock(&inst->registeredbufs.lock);

	if (!filled_len || !device_addr) {
	if ((!filled_len || !device_addr) && !force_reset) {
		s_vpr_l(inst->sid, "%s: no input\n", __func__);
		return 0;
	}
@@ -1032,7 +1032,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst)
		msm_dcvs_scale_clocks(inst, freq);
	}

	msm_vidc_set_clocks(inst->core, inst->sid);
	msm_vidc_set_clocks(inst->core, inst->sid, force_reset);

	return 0;
}
@@ -1055,13 +1055,13 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc)
		inst->active = true;
	}

	if (msm_comm_scale_clocks(inst)) {
	if (msm_comm_scale_clocks(inst, false)) {
		s_vpr_e(inst->sid,
			"Failed to scale clocks. May impact performance\n");
	}

	if (do_bw_calc) {
		if (msm_comm_vote_bus(inst)) {
		if (msm_comm_vote_bus(inst, false)) {
			s_vpr_e(inst->sid,
				"Failed to scale DDR bus. May impact perf\n");
		}
@@ -1070,6 +1070,25 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc)
	return 0;
}

int msm_comm_reset_clocks_and_bus(struct msm_vidc_inst *inst)
{
	if (!inst) {
		d_vpr_e("%s: invalid params %pK\n", __func__, inst);
		return -EINVAL;
	}

	if (msm_comm_scale_clocks(inst, true)) {
		s_vpr_e(inst->sid,
			"Failed to reset clocks. May impact performance\n");
	}

	if (msm_comm_vote_bus(inst, true)) {
		s_vpr_e(inst->sid,
			"Failed to reset DDR bus. May impact perf\n");
	}
	return 0;
}

int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
{
	bool disable_hfr_dcvs = false;
+4 −3
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
 */

#ifndef _MSM_VIDC_CLOCKS_H_
@@ -9,8 +9,8 @@

void msm_clock_data_reset(struct msm_vidc_inst *inst);
void msm_dcvs_reset(struct msm_vidc_inst *inst);
int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid);
int msm_comm_vote_bus(struct msm_vidc_inst *inst);
int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid, bool force_reset);
int msm_comm_vote_bus(struct msm_vidc_inst *inst, bool force_reset);
int msm_dcvs_try_enable(struct msm_vidc_inst *inst);
bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height);
bool res_is_greater_than(u32 width, u32 height, u32 ref_width, u32 ref_height);
@@ -21,6 +21,7 @@ bool res_is_greater_than_or_equal_to(u32 width, u32 height,
int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst);
int msm_vidc_get_fps(struct msm_vidc_inst *inst);
int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc);
int msm_comm_reset_clocks_and_bus(struct msm_vidc_inst *inst);
int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst);
int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst);
int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst);