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

Commit ca374a6f authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge c55e0884 on remote branch

Change-Id: I1e84309c3201878687897cc157a48789049b5f93
parents 2a334756 c55e0884
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -397,6 +397,15 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
		.default_value = V4L2_MPEG_MSM_VIDC_DISABLE,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT,
		.name = "Low Latency Hint",
		.type = V4L2_CTRL_TYPE_BOOLEAN,
		.minimum = V4L2_MPEG_MSM_VIDC_DISABLE,
		.maximum = V4L2_MPEG_MSM_VIDC_ENABLE,
		.default_value = V4L2_MPEG_MSM_VIDC_DISABLE,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_SUPERFRAME,
		.name = "Superframe",
@@ -928,6 +937,8 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		inst->clk_data.low_latency_mode = !!ctrl->val;
		inst->batch.enable = is_batching_allowed(inst);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT:
		break;
	default:
		s_vpr_e(inst->sid, "Unknown control %#x\n", ctrl->id);
		break;
@@ -1304,6 +1315,32 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst)
	return rc;
}

int msm_vdec_set_seqchng_at_syncframe(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct hfi_device *hdev;
	struct hfi_enable hfi_property;

	if (!inst || !inst->core) {
		d_vpr_e("%s: invalid params %pK\n", __func__, inst);
		return -EINVAL;
	}
	hdev = inst->core->device;
	hfi_property.enable = is_low_latency_hint(inst);

	if (!hfi_property.enable)
		return 0;

	s_vpr_h(inst->sid, "%s: %#x\n", __func__, hfi_property.enable);
	rc = call_hfi_op(hdev, session_set_property, inst->session,
		HFI_PROPERTY_PARAM_VDEC_SEQCHNG_AT_SYNCFRM, &hfi_property,
		sizeof(hfi_property));
	if (rc)
		s_vpr_e(inst->sid, "%s: set property failed\n", __func__);

	return rc;
}

int msm_vdec_set_conceal_color(struct msm_vidc_inst *inst)
{
	int rc = 0;
@@ -1439,6 +1476,9 @@ int msm_vdec_set_properties(struct msm_vidc_inst *inst)
		rc = msm_vdec_set_conceal_color(inst);
		if (rc)
			goto exit;
		rc = msm_vdec_set_seqchng_at_syncframe(inst);
		if (rc)
			goto exit;
	}

	rc = msm_vdec_set_color_format(inst);
+76 −0
Original line number Diff line number Diff line
@@ -944,6 +944,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.default_value = 3,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET,
		.name = "Chroma QP Index Offset",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = -12,
		.maximum = 0,
		.default_value = 0,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_VBV_DELAY,
		.name = "Set Vbv Delay",
@@ -1978,6 +1987,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
	case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE:
	case V4L2_CID_MPEG_VIDEO_VBV_DELAY:
	case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS:
	case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET:
	case V4L2_CID_MPEG_VIDC_SUPERFRAME:
		s_vpr_h(sid, "Control set: ID : 0x%x Val : %d\n",
			ctrl->id, ctrl->val);
@@ -3369,6 +3379,69 @@ int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst)
	return rc;
}

int msm_venc_set_chroma_qp_offset(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct hfi_device *hdev;
	struct v4l2_ctrl *chr;
	struct v4l2_ctrl *ctrl_cs;
	struct hfi_chroma_qp_offset chroma_qp;
	struct v4l2_format *f;
	u32 codec, width, height, mbpf;

	if (!inst || !inst->core) {
		d_vpr_e("%s: invalid params %pK\n", __func__, inst);
		return -EINVAL;
	}
	hdev = inst->core->device;

	chr = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET);
	if (chr->val != -12)
		return 0;

	f = &inst->fmts[INPUT_PORT].v4l2_fmt;
	width = f->fmt.pix_mp.width;
	height = f->fmt.pix_mp.height;
	mbpf = NUM_MBS_PER_FRAME(width, height);
	ctrl_cs = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE);
	codec = get_v4l2_codec(inst);

	/**
	 * Set chroma qp offset to HEVC & VBR_CFR rc
	 * 10 bit: only BT2020
	 *  8 bit: only mbpf >= num_mbs(7680, 3840)
	 */
	if (codec != V4L2_PIX_FMT_HEVC ||
		inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
		return 0;

	if ((inst->bit_depth == MSM_VIDC_BIT_DEPTH_10 &&
		ctrl_cs->val != MSM_VIDC_BT2020) ||
		(inst->bit_depth == MSM_VIDC_BIT_DEPTH_8 &&
		mbpf < NUM_MBS_PER_FRAME(7680, 3840)))
		return 0;

	/**
	 * client sets one chroma offset only in range [-12, 0]
	 * firmware expects chroma cb offset and cr offset in
	 * range [0, 12], firmware subtracts 12 from driver set values.
	 */
	chroma_qp.chroma_offset = (chr->val + 12) << 16 | (chr->val + 12);
	s_vpr_h(inst->sid, "%s: %x\n", __func__, chroma_qp.chroma_offset);

	/* TODO: Remove this check after firmware support added for 8-bit */
	if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_8)
		return 0;

	rc = call_hfi_op(hdev, session_set_property, inst->session,
		HFI_PROPERTY_PARAM_HEVC_PPS_CB_CR_OFFSET, &chroma_qp,
		sizeof(chroma_qp));
	if (rc)
		s_vpr_e(inst->sid, "%s: set property failed\n", __func__);

	return rc;
}

int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst)
{
	int rc = 0;
@@ -4711,6 +4784,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst)
	if (rc)
		goto exit;
	rc = msm_venc_set_video_csc(inst);
	if (rc)
		goto exit;
	rc = msm_venc_set_chroma_qp_offset(inst);
	if (rc)
		goto exit;
	rc = msm_venc_set_blur_resolution(inst);
+4 −3
Original line number Diff line number Diff line
@@ -418,10 +418,11 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
	}

	/*
	 * set perf mode for image session buffers so that
	 * they will be processed quickly
	 * set perf mode for image and thumbnail session buffers
	 * so that they will be processed quickly
	 */
	if (is_grid_session(inst) && b->type == INPUT_MPLANE)
	if ((is_grid_session(inst) || is_thumbnail_session(inst))
		&& b->type == INPUT_MPLANE)
		b->flags |= V4L2_BUF_FLAG_PERF_MODE;

	q = msm_comm_get_vb2q(inst, b->type);
+49 −28
Original line number Diff line number Diff line
@@ -1072,19 +1072,29 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc)

int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
{
	bool disable_hfr_dcvs = false;

	if (!inst || !inst->core) {
		d_vpr_e("%s: Invalid args: %pK\n", __func__, inst);
		return -EINVAL;
	}
	if (inst->core->platform_data->vpu_ver == VPU_VERSION_IRIS2_1) {
		/* 720p@240 encode */
		if (is_encode_session(inst) && msm_vidc_get_fps(inst) >= 240
			&& msm_vidc_get_mbs_per_frame(inst) >= 3600)
			disable_hfr_dcvs = true;
	}

	inst->clk_data.dcvs_mode =
		!(msm_vidc_clock_voting ||
			!inst->core->resources.dcvs ||
			inst->flags & VIDC_THUMBNAIL ||
			is_low_latency_hint(inst) ||
			inst->clk_data.low_latency_mode ||
			inst->batch.enable ||
			is_turbo_session(inst) ||
		  inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ);
			inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ ||
			disable_hfr_dcvs);

	s_vpr_hp(inst->sid, "DCVS %s: %pK\n",
		inst->clk_data.dcvs_mode ? "enabled" : "disabled", inst);
@@ -1092,6 +1102,40 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
	return 0;
}

void msm_dcvs_reset(struct msm_vidc_inst *inst)
{
	struct msm_vidc_format *fmt;
	struct clock_data *dcvs;

	if (!inst) {
		d_vpr_e("%s: Invalid params\n", __func__);
		return;
	}

	dcvs = &inst->clk_data;
	if (inst->session_type == MSM_VIDC_ENCODER) {
		fmt = &inst->fmts[INPUT_PORT];
	} else if (inst->session_type == MSM_VIDC_DECODER) {
		fmt = &inst->fmts[OUTPUT_PORT];
	} else {
		s_vpr_e(inst->sid, "%s: invalid session type %#x\n",
			__func__, inst->session_type);
		return;
	}

	dcvs->min_threshold = fmt->count_min;
	dcvs->max_threshold =
		min((fmt->count_min + DCVS_DEC_EXTRA_OUTPUT_BUFFERS),
			fmt->count_actual);

	dcvs->dcvs_window =
		dcvs->max_threshold < dcvs->min_threshold ? 0 :
			dcvs->max_threshold - dcvs->min_threshold;
	dcvs->nom_threshold = dcvs->min_threshold +
				(dcvs->dcvs_window ?
				 (dcvs->dcvs_window / 2) : 0);
}

int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst)
{
	int rc = 0, j = 0;
@@ -1137,8 +1181,6 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst)
	struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
	u64 total_freq = 0, rate = 0, load;
	int cycles;
	struct clock_data *dcvs;
	struct msm_vidc_format *fmt;

	if (!inst || !inst->core || !inst->clk_data.entry) {
		d_vpr_e("%s: Invalid args: Inst = %pK\n",
@@ -1148,35 +1190,14 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst)
	s_vpr_h(inst->sid, "Init DCVS Load\n");

	core = inst->core;
	dcvs = &inst->clk_data;
	load = msm_comm_get_inst_load_per_core(inst, LOAD_POWER);
	cycles = inst->clk_data.entry->vpp_cycles;
	allowed_clks_tbl = core->resources.allowed_clks_tbl;
	if (inst->session_type == MSM_VIDC_ENCODER) {
		cycles = inst->flags & VIDC_LOW_POWER ?
			inst->clk_data.entry->low_power_cycles :
			cycles;

		fmt = &inst->fmts[INPUT_PORT];
	} else if (inst->session_type == MSM_VIDC_DECODER) {
		fmt = &inst->fmts[OUTPUT_PORT];
	} else {
		s_vpr_e(inst->sid, "%s: invalid session type %#x\n",
			__func__, inst->session_type);
		return;
	}

	dcvs->min_threshold = fmt->count_min;
	dcvs->max_threshold =
		min((fmt->count_min + DCVS_DEC_EXTRA_OUTPUT_BUFFERS),
			fmt->count_actual);
	if (inst->session_type == MSM_VIDC_ENCODER &&
		inst->flags & VIDC_LOW_POWER)
		cycles = inst->clk_data.entry->low_power_cycles;

	dcvs->dcvs_window =
		dcvs->max_threshold < dcvs->min_threshold ? 0 :
			dcvs->max_threshold - dcvs->min_threshold;
	dcvs->nom_threshold = dcvs->min_threshold +
				(dcvs->dcvs_window ?
				 (dcvs->dcvs_window / 2) : 0);
	msm_dcvs_reset(inst);

	total_freq = cycles * load;

+2 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _MSM_VIDC_CLOCKS_H_
@@ -8,6 +8,7 @@
#include "msm_vidc_internal.h"

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_dcvs_try_enable(struct msm_vidc_inst *inst);
Loading