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

Commit a70e3301 authored by Vikash Garodia's avatar Vikash Garodia Committed by Anomalchik
Browse files

msm: vidc: Handle perf mode configuration



Host will set the Venus firmware in below modes
1. If the load of current video session exceeds
the venus capability, video driver sets power
save mode for that session.
2. If an usecase is recommended to run in power
save mode to get power benefits, video driver
configures the session in power save mode.
3. If any V4L2 client makes an explicit call to
configure the usecase in a certain perf mode,
video driver sets the same to venus firmware,
unless restricted by core capability.

CRs-Fixed: 1106972
Change-Id: Ib8be6c9af1508389edc9cb6444531c6e711b6a11
Signed-off-by: default avatarVikash Garodia <vgarodia@codeaurora.org>
Signed-off-by: default avatarSanjay Singh <sisanj@codeaurora.org>
parent 2c135a18
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@ value is typically max(latencies of every cluster at all power levels) + 1
- qcom,max-secure-instances = An int containing max number of concurrent secure
  instances supported, accounting for venus and system wide limitations like
  memory, performance etc.
- qcom,power-conf = Indicates the value at which or beyond, a video session
  is configured in low power mode to have power benefits. Value is defined
  interms of HxW of the video session beyond which power benefit is desired.

[Second level nodes]
Context Banks
@@ -229,6 +232,7 @@ Example:
		qcom,qdss-presets = <0xFC307000 0x1000>,
			<0xFC322000 0x1000>;
		qcom,max-hw-load = <1224450>; /* 4k @ 30 + 1080p @ 30*/
		qcom,power-conf = <8294400>; /* WxH - 3840*2160 */
		qcom,never-unload-fw;
		clock-names = "foo_clk", "bar_clk", "baz_clk";
		qcom,clock-configs = <0x3 0x1 0x0>;
+29 −17
Original line number Diff line number Diff line
@@ -1169,9 +1169,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE,
		.name = "Set Encoder performance mode",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY,
		.minimum = V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT,
		.maximum = V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE,
		.default_value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY,
		.default_value = V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT,
		.step = 1,
		.qmenu = NULL,
	},
@@ -1785,9 +1785,10 @@ static int msm_venc_toggle_hier_p(struct msm_vidc_inst *inst, int layers)

static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst)
{
	u32 rc = 0;
	u32 prop_id = 0, power_save_min = 0, power_save_max = 0, inst_load = 0;
	u32 rc = 0, height = 0, width = 0;
	u32 prop_id = 0, hq_max = 0, power_conf = 0, inst_load = 0;
	void *pdata = NULL;
	bool set_by_client = false, enable_low_power = false;
	struct hfi_device *hdev = NULL;
	enum hal_perf_mode venc_mode;
	enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
@@ -1798,19 +1799,33 @@ static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst)
		return -EINVAL;
	}

	hdev = inst->core->device;
	inst_load = msm_comm_get_inst_load(inst, quirks);
	power_save_min = inst->capability.mbs_per_sec_power_save.min;
	power_save_max = inst->capability.mbs_per_sec_power_save.max;
	hq_max = inst->capability.mbs_per_sec.max;
	power_conf = inst->core->resources.power_conf;
	height = inst->prop.height[CAPTURE_PORT];
	width = inst->prop.width[CAPTURE_PORT];

	dprintk(VIDC_DBG,
		"Power Save Mode min mb's %d max mb's %d inst load %d\n",
		power_save_min, power_save_max, inst_load);
	switch (msm_comm_g_ctrl_for_id(inst,
				V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE)) {
		case V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY:
		case V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE:
			set_by_client = true;
			break;
	}

	if (!power_save_min || !power_save_max)
		return rc;
	if (inst_load > hq_max) {
		dprintk(VIDC_INFO, "Setting low power w.r.t core limitation\n");
		enable_low_power = true;
	} else if (!set_by_client) {
		if (power_conf && width * height >= power_conf) {
			dprintk(VIDC_INFO,
				"Setting low power w.r.t system power recommendation\n");
			enable_low_power = true;
		}
	}

	hdev = inst->core->device;
	if (inst_load >= power_save_min) {
	if (enable_low_power) {
		prop_id = HAL_CONFIG_VENC_PERF_MODE;
		venc_mode = HAL_PERF_MODE_POWER_SAVE;
		pdata = &venc_mode;
@@ -3451,9 +3466,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
			break;
		}
		pdata = &venc_mode;

		msm_dcvs_enc_set_power_save_mode(inst,
			ctrl->val == V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
		if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) {
+7 −0
Original line number Diff line number Diff line
@@ -1184,6 +1184,13 @@ int read_platform_resources_from_dt(
		goto err_load_max_hw_load;
	}

	rc = of_property_read_u32(pdev->dev.of_node, "qcom,power-conf",
			&res->power_conf);
	if (rc) {
		dprintk(VIDC_DBG,
			"Failed to read power configuration: %d\n", rc);
	}

	rc = msm_vidc_populate_legacy_context_bank(res);
	if (rc) {
		dprintk(VIDC_ERR,
+1 −0
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ struct msm_vidc_platform_resources {
	uint32_t imem_size;
	enum imem_type imem_type;
	uint32_t max_load;
	uint32_t power_conf;
	struct platform_device *pdev;
	struct regulator_set regulator_set;
	struct clock_set clock_set;
+3 −0
Original line number Diff line number Diff line
@@ -1053,6 +1053,9 @@ enum vl42_mpeg_vidc_video_h264_svc_nal {
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 68)

enum v4l2_mpeg_vidc_video_perf_mode {
#define V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT \
	V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT
	V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT = 0,
	V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY = 1,
	V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE = 2
};