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

Commit 1c2d2f82 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 operating rate handling"

parents b06709ca 501be798
Loading
Loading
Loading
Loading
+31 −6
Original line number Diff line number Diff line
@@ -413,7 +413,16 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
		.minimum = 0,
		.maximum = INT_MAX,
		.default_value = 0,
		.step = OPERATING_FRAME_RATE_STEP,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
		.name = "Set Decoder Frame rate",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 0,
		.maximum = INT_MAX,
		.default_value = 0,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE,
@@ -1127,11 +1136,27 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		}
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
		if (((ctrl->val >> 16) < inst->capability.frame_rate.min ||
			(ctrl->val >> 16) > inst->capability.frame_rate.max) &&
			ctrl->val != INT_MAX) {
			dprintk(VIDC_ERR, "Invalid operating rate %u\n",
				(ctrl->val >> 16));
			rc = -ENOTSUPP;
		} else if (ctrl->val == INT_MAX) {
			dprintk(VIDC_DBG,
				"inst(%pK) Request for turbo mode\n", inst);
			inst->clk_data.turbo_mode = true;
		} else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) {
			dprintk(VIDC_ERR, "Failed to set operating rate\n");
			rc = -ENOTSUPP;
		} else {
			dprintk(VIDC_DBG,
				"inst(%pK) operating rate changed from %d to %d\n",
				inst, inst->clk_data.operating_rate >> 16,
					ctrl->val >> 16);
			inst->clk_data.operating_rate = ctrl->val;
			inst->clk_data.turbo_mode = false;
		}
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE:
		if (ctrl->val ==
+30 −6
Original line number Diff line number Diff line
@@ -909,7 +909,16 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.minimum = 0,
		.maximum = INT_MAX,
		.default_value = 0,
		.step = OPERATING_FRAME_RATE_STEP,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
		.name = "Set Encoder Frame rate",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 0,
		.maximum = INT_MAX,
		.default_value = 0,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE,
@@ -1825,12 +1834,27 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		}
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
		if (((ctrl->val >> 16) < inst->capability.frame_rate.min ||
			 (ctrl->val >> 16) > inst->capability.frame_rate.max) &&
			  ctrl->val != INT_MAX) {
			dprintk(VIDC_ERR, "Invalid operating rate %u\n",
				(ctrl->val >> 16));
			rc = -ENOTSUPP;
		} else if (ctrl->val == INT_MAX) {
			dprintk(VIDC_DBG, "inst(%pK) Request for turbo mode\n",
				inst);
			inst->clk_data.turbo_mode = true;
		} else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) {
			dprintk(VIDC_ERR, "Failed to set operating rate\n");
			rc = -ENOTSUPP;
		} else {
			dprintk(VIDC_DBG,
				"inst(%pK) operating rate changed from %d to %d\n",
				inst, inst->clk_data.operating_rate >> 16,
				ctrl->val >> 16);
			inst->clk_data.operating_rate = ctrl->val;

			inst->clk_data.turbo_mode = false;
		}
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE:
	{
+4 −0
Original line number Diff line number Diff line
@@ -179,6 +179,10 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl)
	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.slice_bytes);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE:
	case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.frame_rate);
		break;
	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
	case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
	case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE:
+66 −43
Original line number Diff line number Diff line
@@ -569,6 +569,12 @@ static int msm_vidc_set_clocks(struct msm_vidc_core *core)
	mutex_lock(&core->lock);
	list_for_each_entry(temp, &core->instances, list) {
		freq += temp->clk_data.curr_freq;
		if (temp->clk_data.turbo_mode) {
			dprintk(VIDC_PROF,
				"Found an instance with Turbo request\n");
			freq = msm_vidc_max_freq(core);
			break;
		}
	}
	for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) {
		rate = allowed_clks_tbl[i].clock_rate;
@@ -587,19 +593,22 @@ static int msm_vidc_set_clocks(struct msm_vidc_core *core)
	return rc;
}

int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst)
int msm_vidc_validate_operating_rate(struct msm_vidc_inst *inst,
	u32 operating_rate)
{
	struct v4l2_ctrl *ctrl = NULL;
	struct msm_vidc_inst *temp;
	struct msm_vidc_core *core;
	unsigned long max_freq, freq_left, ops_left, load, cycles, freq = 0;
	unsigned long mbs_per_second;
	int rc = 0;
	u32 curr_operating_rate = 0;

	if (!inst || !inst->core) {
		dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
		return -EINVAL;
	}
	core = inst->core;
	curr_operating_rate = inst->clk_data.operating_rate >> 16;

	mutex_lock(&core->lock);
	max_freq = msm_vidc_max_freq(core);
@@ -614,51 +623,35 @@ int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst)

	freq_left = max_freq - freq;

	list_for_each_entry(temp, &core->instances, list) {

		if (!temp ||
				temp->state < MSM_VIDC_START_DONE ||
				temp->state >= MSM_VIDC_RELEASE_RESOURCES_DONE)
			continue;

		mbs_per_second = msm_comm_get_inst_load_per_core(temp,
	mbs_per_second = msm_comm_get_inst_load_per_core(inst,
		LOAD_CALC_NO_QUIRKS);

		cycles = temp->clk_data.entry->vpp_cycles;
		if (temp->session_type == MSM_VIDC_ENCODER)
			cycles = temp->flags & VIDC_LOW_POWER ?
				temp->clk_data.entry->low_power_cycles :
	cycles = inst->clk_data.entry->vpp_cycles;
	if (inst->session_type == MSM_VIDC_ENCODER)
		cycles = inst->flags & VIDC_LOW_POWER ?
			inst->clk_data.entry->low_power_cycles :
			cycles;

	load = cycles * mbs_per_second;

	ops_left = load ? (freq_left / load) : 0;
		/* Convert remaining operating rate to Q16 format */
		ops_left = ops_left << 16;

		ctrl = v4l2_ctrl_find(&temp->ctrl_handler,
			V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE);
		if (ctrl) {
			dprintk(VIDC_DBG,
				"%s: Before Range = %lld --> %lld\n",
				ctrl->name, ctrl->minimum, ctrl->maximum);
			dprintk(VIDC_DBG,
				"%s: Before Def value = %lld Cur val = %d\n",
				ctrl->name, ctrl->default_value, ctrl->val);
			v4l2_ctrl_modify_range(ctrl, ctrl->minimum,
				ctrl->val + ops_left, ctrl->step,
				ctrl->default_value);
	operating_rate = operating_rate >> 16;

	if ((curr_operating_rate + ops_left) >= operating_rate) {
		dprintk(VIDC_DBG,
				"%s: Updated Range = %lld --> %lld\n",
				ctrl->name, ctrl->minimum, ctrl->maximum);
			"Requestd operating rate is valid %u\n",
			operating_rate);
		rc = 0;
	} else {
		dprintk(VIDC_DBG,
				"%s: Updated Def value = %lld Cur val = %d\n",
				ctrl->name, ctrl->default_value, ctrl->val);
		}
			"Current load is high for requested settings. Cannot set operating rate to %u\n",
			operating_rate);
		rc = -EINVAL;
	}
	mutex_unlock(&core->lock);

	return 0;
	return rc;
}

int msm_comm_scale_clocks(struct msm_vidc_inst *inst)
@@ -980,8 +973,8 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst,
		return 0;
	}
	mbs_per_frame = msm_vidc_get_mbs_per_frame(inst);
	if (mbs_per_frame >= inst->core->resources.max_hq_mbs_per_frame ||
		inst->prop.fps >= inst->core->resources.max_hq_fps) {
	if (mbs_per_frame > inst->core->resources.max_hq_mbs_per_frame ||
		inst->prop.fps > inst->core->resources.max_hq_fps) {
		enable = true;
	}

@@ -1184,7 +1177,37 @@ int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst)

	rc = msm_comm_scale_clocks_and_bus(inst);

	msm_print_core_status(core, VIDC_CORE_ID_1);
	msm_print_core_status(core, VIDC_CORE_ID_2);

	return rc;
}

void msm_print_core_status(struct msm_vidc_core *core, u32 core_id)
{
	struct msm_vidc_inst *inst = NULL;

	dprintk(VIDC_PROF, "Instances running on core %u", core_id);
	mutex_lock(&core->lock);
	list_for_each_entry(inst, &core->instances, list) {

		if (!((inst->clk_data.core_id & core_id) ||
			  (inst->clk_data.core_id & VIDC_CORE_ID_3)))
			continue;

		dprintk(VIDC_PROF,
			"inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s\n",
			inst,
			inst->prop.width[OUTPUT_PORT],
			inst->prop.height[OUTPUT_PORT],
			inst->prop.width[CAPTURE_PORT],
			inst->prop.height[CAPTURE_PORT],
			inst->prop.fps,
			inst->session_type == MSM_VIDC_ENCODER ? "ENC" : "DEC",
			inst->clk_data.work_mode == VIDC_WORK_MODE_1 ?
				"WORK_MODE_1" : "WORK_MODE_2",
			inst->flags & VIDC_LOW_POWER ? "LP" : "HQ",
			inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime");
	}
	mutex_unlock(&core->lock);
}
+3 −1
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@
#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4

void msm_clock_data_reset(struct msm_vidc_inst *inst);
int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst);
int msm_vidc_validate_operating_rate(struct msm_vidc_inst *inst,
	u32 operating_rate);
int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst,
	enum hal_buffer buffer_type);
int msm_dcvs_try_enable(struct msm_vidc_inst *inst);
@@ -31,6 +32,7 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst);
void msm_comm_free_freq_table(struct msm_vidc_inst *inst);
int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst);
int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst);
void msm_print_core_status(struct msm_vidc_core *core, u32 core_id);
void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst,
	u32 device_addr);
void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst);
Loading