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

Commit bbca9aa4 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Update video-CVP interaction call flow"

parents d168b1da 5becaa46
Loading
Loading
Loading
Loading
+308 −125
Original line number Diff line number Diff line
@@ -257,7 +257,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst)
	int rc = 0;
	struct msm_cvp_external *cvp;
	struct cvp_kmd_arg *arg;
	struct v4l2_format *f;
	struct v4l2_format *fmt;
	struct cvp_kmd_usecase_desc desc;
	struct cvp_kmd_request_power power;
	const u32 fps_max = CVP_FRAME_RATE_MAX;
@@ -271,7 +271,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst)
	memset(&desc, 0, sizeof(struct cvp_kmd_usecase_desc));
	memset(&power, 0, sizeof(struct cvp_kmd_request_power));

	f = &inst->fmts[INPUT_PORT].v4l2_fmt;
	fmt = &inst->fmts[INPUT_PORT].v4l2_fmt;
	desc.fullres_width = cvp->width;
	desc.fullres_height = cvp->height;
	desc.downscale_width = cvp->ds_width;
@@ -279,7 +279,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst)
	desc.is_downscale = cvp->downscale;
	desc.fps = min(cvp->frame_rate >> 16, fps_max);
	desc.op_rate = cvp->operating_rate >> 16;
	desc.colorfmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat);
	desc.colorfmt = msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat);
	rc = msm_cvp_est_cycles(&desc, &power);
	if (rc) {
		dprintk(VIDC_ERR, "%s: estimate failed\n", __func__);
@@ -514,8 +514,6 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;
	struct cvp_kmd_arg *arg;
	struct msm_cvp_session_release_persist_buffers_packet persist2_packet;

	if (!inst || !inst->cvp) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
@@ -538,41 +536,6 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst)
	if (cvp->persist2_buffer.dbuf) {
		print_cvp_buffer(VIDC_HIGH, "free: persist2_buffer",
			inst, &cvp->persist2_buffer);
		memset(&persist2_packet, 0, sizeof(struct
			msm_cvp_session_release_persist_buffers_packet));
		persist2_packet.size = sizeof(struct
			msm_cvp_session_release_persist_buffers_packet);
		persist2_packet.packet_type =
			HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS;
		persist2_packet.session_id = cvp->session_id;
		persist2_packet.cvp_op = CVP_DME;
		fill_cvp_buffer(&persist2_packet.persist2_buffer,
				&cvp->persist2_buffer);

		arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
		if (arg) {
			arg->type = CVP_KMD_HFI_PERSIST_CMD;
			arg->buf_offset = offsetof(struct
			msm_cvp_session_release_persist_buffers_packet,
				persist1_buffer) / sizeof(u32);
			arg->buf_num = (sizeof(struct
			msm_cvp_session_release_persist_buffers_packet) -
				(arg->buf_offset * sizeof(u32))) /
				sizeof(struct msm_cvp_buffer_type);
			memcpy(&(arg->data.pbuf_cmd), &persist2_packet,
			sizeof(struct
			msm_cvp_session_release_persist_buffers_packet));
			rc = msm_cvp_private(cvp->priv,
				CVP_KMD_HFI_PERSIST_CMD, arg);
			if (rc)
				print_cvp_buffer(VIDC_ERR,
					"release failed: persist2_buffer",
					inst, &cvp->persist2_buffer);
			kfree(arg);
		} else {
			dprintk(VIDC_ERR, "%s: alloc failed\n", __func__);
		}

		rc = msm_cvp_free_buffer(inst, &cvp->persist2_buffer);
		if (rc)
			print_cvp_buffer(VIDC_ERR,
@@ -581,12 +544,12 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst)
	}
}

static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
static int msm_cvp_set_persist_buffer(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;
	struct cvp_kmd_arg *arg;
	struct msm_cvp_session_set_persist_buffers_packet persist2_packet;
	struct msm_cvp_session_set_persist_buffers_packet persist2_packet = {0};

	if (!inst || !inst->cvp || !inst->cvp->arg) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
@@ -594,22 +557,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
	}
	cvp = inst->cvp;
	arg = cvp->arg;
	dprintk(VIDC_HIGH, "%s:\n", __func__);

	cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE;
	rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false);
	if (rc) {
		print_cvp_buffer(VIDC_ERR,
			"allocate failed: persist2_buffer",
			inst, &cvp->persist2_buffer);
		goto error;
	}
	print_cvp_buffer(VIDC_HIGH, "alloc: persist2_buffer",
			inst, &cvp->persist2_buffer);

	/* set buffer */
	memset(&persist2_packet, 0,
		sizeof(struct msm_cvp_session_set_persist_buffers_packet));
	persist2_packet.size =
		sizeof(struct msm_cvp_session_set_persist_buffers_packet);
	persist2_packet.packet_type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS;
@@ -634,8 +582,32 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
		print_cvp_buffer(VIDC_ERR,
			"set failed: persist2_buffer",
			inst, &cvp->persist2_buffer);
	}

	return rc;
}

static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;

	if (!inst || !inst->cvp) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
		return -EINVAL;
	}
	cvp = inst->cvp;

	cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE;
	rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false);
	if (rc) {
		print_cvp_buffer(VIDC_ERR,
			"allocate failed: persist2_buffer",
			inst, &cvp->persist2_buffer);
		goto error;
	}
	print_cvp_buffer(VIDC_HIGH, "alloc: persist2_buffer",
			inst, &cvp->persist2_buffer);

	/* allocate one output buffer for internal use */
	cvp->output_buffer.size = HFI_DME_OUTPUT_BUFFER_SIZE;
@@ -812,6 +784,69 @@ static int msm_cvp_reference_management(struct msm_vidc_inst *inst)
	return rc;
}

static int msm_vidc_cvp_session_start(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp = NULL;
	struct cvp_kmd_session_control *ctrl = NULL;
	struct cvp_kmd_arg *arg = NULL;

	if (!inst || !inst->cvp || !inst->cvp->arg) {
		dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
		return -EINVAL;
	}
	cvp = inst->cvp;
	arg = cvp->arg;

	memset(arg, 0, sizeof(struct cvp_kmd_arg));
	arg->type = CVP_KMD_SESSION_CONTROL;
	ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl;
	ctrl->ctrl_type = SESSION_START;

	rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg);
	if (rc) {
		dprintk(VIDC_ERR,
			"%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n",
			__func__, rc);
		return rc;
	}

	return rc;
}

static int msm_vidc_cvp_session_stop(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp = NULL;
	struct cvp_kmd_session_control *ctrl = NULL;
	struct cvp_kmd_arg *arg = NULL;

	if (!inst || !inst->cvp || !inst->cvp->arg) {
		dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
		return -EINVAL;
	}

	cvp = inst->cvp;
	arg = cvp->arg;

	memset(arg, 0, sizeof(struct cvp_kmd_arg));

	arg->type = CVP_KMD_SESSION_CONTROL;

	ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl;
	ctrl->ctrl_type = SESSION_STOP;

	rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg);
	if (rc) {
		dprintk(VIDC_ERR,
			"%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n",
			__func__, rc);
		return rc;
	}

	return rc;
}

static int msm_cvp_frame_process(struct msm_vidc_inst *inst,
		struct msm_vidc_buffer *mbuf)
{
@@ -982,7 +1017,37 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst,
	return rc;
}

static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst)
static int msm_vidc_cvp_session_delete(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp = NULL;
	struct cvp_kmd_session_control *ctrl = NULL;
	struct cvp_kmd_arg *arg = NULL;

	if (!inst || !inst->cvp || !inst->cvp->arg) {
		dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
		return -EINVAL;
	}
	cvp = inst->cvp;
	arg = cvp->arg;

	memset(arg, 0, sizeof(struct cvp_kmd_arg));
	arg->type = CVP_KMD_SESSION_CONTROL;
	ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl;
	ctrl->ctrl_type = SESSION_DELETE;

	rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg);
	if (rc) {
		dprintk(VIDC_ERR,
			"%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n",
			__func__, rc);
		return rc;
	}

	return rc;
}

static int msm_cvp_mem_deinit(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;
@@ -998,6 +1063,32 @@ static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst)
	msm_cvp_deinit_context_buffers(inst);
	msm_cvp_deinit_downscale_buffers(inst);

	cvp->priv = NULL;
	kfree(cvp->arg);
	cvp->arg = NULL;
	kfree(inst->cvp);
	inst->cvp = NULL;

	return rc;
}

static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst)
{
	int rc = 0;

	if (!inst || !inst->cvp) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
		return -EINVAL;
	}

	rc = msm_vidc_cvp_session_stop(inst);
	if (rc) {
		dprintk(VIDC_ERR, "%s: cvp stop failed with error %d\n",
			__func__, rc);
	}

	msm_vidc_cvp_session_delete(inst);

	return rc;
}

@@ -1014,15 +1105,10 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst)

	dprintk(VIDC_HIGH, "%s: cvp session %#x\n", __func__, cvp->session_id);
	rc = msm_cvp_close(cvp->priv);
	if (rc)
	if (rc) {
		dprintk(VIDC_ERR,
			"%s: cvp close failed with error %d\n", __func__, rc);
	cvp->priv = NULL;

	kfree(cvp->arg);
	cvp->arg = NULL;
	kfree(inst->cvp);
	inst->cvp = NULL;
	}

	return rc;
}
@@ -1040,18 +1126,46 @@ int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst)

	msm_vidc_cvp_deinit(inst);
	msm_vidc_cvp_close(inst);
	msm_cvp_mem_deinit(inst);

	return 0;
}

static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
static int msm_vidc_cvp_session_create(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp = NULL;
	struct cvp_kmd_session_control *ctrl = NULL;
	struct cvp_kmd_arg *arg = NULL;

	if (!inst || !inst->cvp || !inst->cvp->arg) {
		dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
		return -EINVAL;
	}
	cvp = inst->cvp;
	arg = cvp->arg;

	memset(arg, 0, sizeof(struct cvp_kmd_arg));
	arg->type = CVP_KMD_SESSION_CONTROL;
	ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl;
	ctrl->ctrl_type = SESSION_CREATE;

	rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg);
	if (rc) {
		dprintk(VIDC_ERR,
			"%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n",
			__func__, rc);
		return rc;
	}

	return rc;
}

static int msm_vidc_cvp_getsessioninfo(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;
	struct v4l2_format *f;
	struct cvp_kmd_arg *arg;
	struct msm_cvp_dme_basic_config_packet *dmecfg;
	u32 color_fmt;

	if (!inst || !inst->cvp || !inst->cvp->arg) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
@@ -1059,35 +1173,45 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
	}
	cvp = inst->cvp;
	arg = cvp->arg;
	cvp->framecount = 0;
	cvp->metadata_available = false;
	f = &inst->fmts[INPUT_PORT].v4l2_fmt;
	cvp->width = f->fmt.pix_mp.width;
	cvp->height = f->fmt.pix_mp.height;
	cvp->frame_rate = inst->clk_data.frame_rate;
	cvp->operating_rate = inst->clk_data.operating_rate;
	color_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat);

	/* enable downscale always */
	cvp->downscale = true;
	rc = msm_cvp_init_downscale_resolution(inst);
	if (rc)
	memset(arg, 0, sizeof(struct cvp_kmd_arg));
	arg->type = CVP_KMD_GET_SESSION_INFO;
	rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SESSION_INFO, arg);
	if (rc) {
		dprintk(VIDC_ERR, "%s: get_session_info failed\n", __func__);
		goto error;
	}
	cvp->session_id = arg->data.session.session_id;
	dprintk(VIDC_HIGH, "%s: cvp session id %#x\n",
		__func__, cvp->session_id);

	dprintk(VIDC_HIGH,
		"%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d fps %d op_rate %d\n",
		__func__, f->fmt.pix_mp.pixelformat,
		cvp->width, cvp->height, cvp->downscale,
		cvp->ds_width, cvp->ds_height,
		cvp->frame_rate >> 16, cvp->operating_rate >> 16);

	rc = msm_cvp_set_priority(inst);
	if (rc)
	rc = msm_cvp_get_version_info(inst);
	if (rc) {
		dprintk(VIDC_ERR, "%s: get_version_info failed\n", __func__);
		goto error;
	}
	return rc;

	rc = msm_cvp_set_clocks_and_bus(inst);
	if (rc)
		goto error;
error:
	msm_vidc_cvp_deinit(inst);
	return rc;
}

static int msm_vidc_cvp_dme_basic_config(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;
	struct cvp_kmd_arg *arg;
	struct msm_cvp_dme_basic_config_packet *dmecfg;
	struct v4l2_format *fmt;
	u32 color_fmt;

	if (!inst || !inst->cvp || !inst->cvp->arg) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
		return -EINVAL;
	}
	cvp = inst->cvp;
	arg = cvp->arg;

	memset(arg, 0, sizeof(struct cvp_kmd_arg));
	arg->type = CVP_KMD_SEND_CMD_PKT;
@@ -1104,8 +1228,11 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
		COLOR_FMT_NV12_UBWC, dmecfg->src_width, dmecfg->src_height);
	if (rc)
		goto error;

	fmt = &inst->fmts[INPUT_PORT].v4l2_fmt;
	color_fmt = msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat);
	dmecfg->fullresbuffer_format = msm_comm_get_hfi_uncompressed(
			f->fmt.pix_mp.pixelformat);
			fmt->fmt.pix_mp.pixelformat);
	dmecfg->fullres_width = cvp->width;
	dmecfg->fullres_height = cvp->height;
	rc = msm_cvp_fill_planeinfo(&dmecfg->fullresbuffer_planeinfo,
@@ -1121,28 +1248,15 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
		goto error;
	}

	rc = msm_cvp_init_downscale_buffers(inst);
	if (rc)
		goto error;
	rc = msm_cvp_init_internal_buffers(inst);
	if (rc)
		goto error;
	rc = msm_cvp_init_context_buffers(inst);
	if (rc)
		goto error;

	return rc;

error:
	msm_vidc_cvp_deinit(inst);
	return rc;
}

static int msm_vidc_cvp_open(struct msm_vidc_inst *inst)
static int msm_cvp_mem_init(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;
	struct cvp_kmd_arg *arg;
	struct v4l2_format *fmt;

	if (!inst) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
@@ -1162,37 +1276,102 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst)
		inst->cvp = NULL;
		return -ENOMEM;
	}
	arg = cvp->arg;

	cvp->framecount = 0;
	cvp->metadata_available = false;
	fmt = &inst->fmts[INPUT_PORT].v4l2_fmt;
	cvp->width = fmt->fmt.pix_mp.width;
	cvp->height = fmt->fmt.pix_mp.height;
	cvp->frame_rate = inst->clk_data.frame_rate;
	cvp->operating_rate = inst->clk_data.operating_rate;

	/* enable downscale always */
	cvp->downscale = true;
	rc = msm_cvp_init_downscale_resolution(inst);
	if (rc)
		goto error;

	dprintk(VIDC_HIGH,
		"%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d fps %d op_rate %d\n",
		__func__, fmt->fmt.pix_mp.pixelformat,
		cvp->width, cvp->height, cvp->downscale,
		cvp->ds_width, cvp->ds_height,
		cvp->frame_rate >> 16, cvp->operating_rate >> 16);

	rc = msm_cvp_init_downscale_buffers(inst);
	if (rc)
		goto error;
	rc = msm_cvp_init_internal_buffers(inst);
	if (rc)
		goto error;
	rc = msm_cvp_init_context_buffers(inst);
	if (rc)
		goto error;

	return rc;

error:
	msm_cvp_mem_deinit(inst);
	return rc;
}

static int msm_vidc_cvp_open(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_cvp_external *cvp;

	if (!inst || !inst->cvp) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
		return -EINVAL;
	}
	cvp = inst->cvp;

	dprintk(VIDC_HIGH, "%s: opening cvp\n", __func__);
	cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP);
	if (!cvp->priv) {
		dprintk(VIDC_ERR, "%s: failed to open cvp session\n", __func__);
		rc = -EINVAL;
		goto error;
	}

	memset(arg, 0, sizeof(struct cvp_kmd_arg));
	arg->type = CVP_KMD_GET_SESSION_INFO;
	rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SESSION_INFO, arg);
	if (rc) {
		dprintk(VIDC_ERR, "%s: get_session_info failed\n", __func__);
		goto error;
	return rc;
}
	cvp->session_id = arg->data.session.session_id;
	dprintk(VIDC_HIGH, "%s: cvp session id %#x\n",
		__func__, cvp->session_id);

	rc = msm_cvp_get_version_info(inst);
	if (rc) {
		dprintk(VIDC_ERR, "%s: get_version_info failed\n", __func__);
static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
{
	int rc;

	rc = msm_cvp_set_priority(inst);
	if (rc)
		goto error;

	rc = msm_vidc_cvp_session_create(inst);
	if (rc)
		return rc;

	rc = msm_vidc_cvp_getsessioninfo(inst);
	if (rc)
		return rc;

	rc = msm_cvp_set_clocks_and_bus(inst);
	if (rc)
		goto error;

	rc = msm_vidc_cvp_dme_basic_config(inst);
	if (rc)
		goto error;

	rc = msm_cvp_set_persist_buffer(inst);
	if (rc)
		goto error;

	rc = msm_vidc_cvp_session_start(inst);
	if (rc)
		goto error;
	}

	return 0;

error:
	msm_vidc_cvp_close(inst);
	msm_vidc_cvp_deinit(inst);
	return rc;
}

@@ -1205,6 +1384,10 @@ int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst)
		return -EINVAL;
	}

	rc = msm_cvp_mem_init(inst);
	if (rc)
		return rc;

	rc = msm_vidc_cvp_open(inst);
	if (rc)
		return rc;
+2 −2
Original line number Diff line number Diff line
@@ -786,11 +786,11 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst)
		allowed = true;
	} else {
		dprintk(VIDC_HIGH,
			"%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d\n",
			"%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d superframe %d\n",
			__func__, core->resources.cvp_external,
			cvp_disable->val, inst->prop.extradata_ctrls,
			inst->rc_type, inst->clk_data.is_legacy_cbr,
			is_secure_session(inst));
			is_secure_session(inst), superframe_enable->val);
		allowed = false;
	}
exit: