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

Commit 16e915e5 authored by abhikran's avatar abhikran Committed by George Shen
Browse files

msm: cvp: Add support for buffer registration with CDSP



Adding support of cvp buffer registration and deregistration
with CDSP. This is needed for opendsp path as iova address
should be shared with CDSP to be used during HFI packetization.
Updating suspend, resume and shutdown API to use cvp dsp
communication layer.
Also, updating debug messages to use dprintk instead of
pr_info.

Change-Id: I956195d010e5e806c3e5467394a4c2494953ec10
Signed-off-by: default avatarabhikran <abhikran@codeaurora.org>
Signed-off-by: default avatarGeorge Shen <sqiao@codeaurora.org>
parent f0bccf66
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@
#include <linux/soc/qcom/smem.h>
#include <soc/qcom/subsystem_restart.h>
#include <linux/dma-mapping.h>
#include <linux/fastcvpd.h>
#include "hfi_packetization.h"
#include "msm_cvp_debug.h"
#include "cvp_core_hfi.h"
@@ -317,7 +316,7 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags)
	}

	dprintk(CVP_DBG, "%s: suspend dsp\n", __func__);
	rc = fastcvpd_video_suspend(flags);
	rc = cvp_dsp_suspend(flags);
	if (rc) {
		dprintk(CVP_ERR, "%s: dsp suspend failed with error %d\n",
			__func__, rc);
@@ -342,7 +341,7 @@ static int __dsp_resume(struct venus_hfi_device *device, u32 flags)
	}

	dprintk(CVP_DBG, "%s: resume dsp\n", __func__);
	rc = fastcvpd_video_resume(flags);
	rc = cvp_dsp_resume(flags);
	if (rc) {
		dprintk(CVP_ERR,
			"%s: dsp resume failed with error %d\n",
@@ -368,7 +367,7 @@ static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags)
	}

	dprintk(CVP_DBG, "%s: shutdown dsp\n", __func__);
	rc = fastcvpd_video_shutdown(flags);
	rc = cvp_dsp_shutdown(flags);
	if (rc) {
		dprintk(CVP_ERR,
			"%s: dsp shutdown failed with error %d\n",
+41 −4
Original line number Diff line number Diff line
@@ -494,11 +494,18 @@ static int msm_cvp_register_buffer(struct msm_cvp_inst *inst,
	bool found;
	struct hfi_device *hdev;
	struct msm_cvp_internal_buffer *cbuf;
	struct hal_session *session;

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

	session = (struct hal_session *)inst->session;
	if (!session) {
		dprintk(CVP_ERR, "%s: invalid session\n", __func__);
		return -EINVAL;
	}
	hdev = inst->core->device;
	print_client_buffer(CVP_DBG, "register", inst, buf);

@@ -538,6 +545,17 @@ static int msm_cvp_register_buffer(struct msm_cvp_inst *inst,
		goto exit;
	}

	if (buf->index) {
		rc = cvp_dsp_register_buffer((uint32_t)cbuf->smem.device_addr,
			buf->index, buf->size, hash32_ptr(session));
		if (rc) {
			dprintk(CVP_ERR,
				"%s: failed dsp registration for fd=%d rc=%d",
				__func__, buf->fd, rc);
			goto exit;
		}
	}

	return rc;

exit:
@@ -559,11 +577,18 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
	bool found;
	struct hfi_device *hdev;
	struct msm_cvp_internal_buffer *cbuf;
	struct hal_session *session;

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

	session = (struct hal_session *)inst->session;
	if (!session) {
		dprintk(CVP_ERR, "%s: invalid session\n", __func__);
		return -EINVAL;
	}
	hdev = inst->core->device;
	print_client_buffer(CVP_DBG, "unregister", inst, buf);

@@ -573,10 +598,6 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
		if (cbuf->buf.fd == buf->fd &&
			cbuf->buf.offset == buf->offset) {
			found = true;
			if (cbuf->smem.device_addr)
				msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
			list_del(&cbuf->list);
			kfree(cbuf);
			break;
		}
	}
@@ -586,6 +607,22 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
		return -EINVAL;
	}

	if (buf->index) {
		rc = cvp_dsp_deregister_buffer((uint32_t)cbuf->smem.device_addr,
			buf->index, buf->size, hash32_ptr(session));
		if (rc) {
			dprintk(CVP_ERR,
				"%s: failed dsp registration for fd = %d rc=%d",
				__func__, buf->fd, rc);
		}
	}

	if (cbuf->smem.device_addr)
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);

	list_del(&cbuf->list);
	kfree(cbuf);

	return rc;
}

+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
#include "msm_cvp_common.h"
#include "msm_cvp_clocks.h"
#include "msm_cvp_debug.h"

#include "msm_cvp_dsp.h"
int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct msm_cvp_arg *arg);
int msm_cvp_session_init(struct msm_cvp_inst *inst);
int msm_cvp_session_deinit(struct msm_cvp_inst *inst);
+172 −37
Original line number Diff line number Diff line
@@ -21,39 +21,50 @@
#define STATUS_DEINIT 1
#define STATUS_OK 2
#define STATUS_SSR 3
#define CVP_DSP_MAX_RESERVED 5

struct cvpd_cmd_msg {
struct cvp_dsp_cmd_msg {
	uint32_t cmd_msg_type;
	int32_t ret_val;
	uint64_t msg_ptr;
	uint32_t msg_ptr_len;
	uint32_t iova_buff_addr;
	uint32_t buff_index;
	uint32_t buf_size;
	uint32_t buff_size;
	uint32_t session_id;
	uint32_t context;
	int64_t ddr_type;
	uint32_t reserved[CVP_DSP_MAX_RESERVED];
};

struct cvpd_rsp_msg {
	uint32_t context;
struct cvp_dsp_rsp_msg {
	uint32_t cmd_msg_type;
	int32_t ret_val;
	uint32_t reserved[CVP_DSP_MAX_RESERVED];
};

struct cvp_dsp_rsp_context {
	struct completion work;
};

struct cvp_dsp_apps {
	struct rpmsg_device *chan;
	struct mutex smd_mutex;
	struct mutex reg_buffer_mutex;
	struct mutex dereg_buffer_mutex;
	int rpmsg_register;
	uint32_t cdsp_state;
	uint32_t cvp_shutdown;
	struct completion reg_buffer_work;
	struct completion dereg_buffer_work;
	struct completion shutdown_work;
};

static struct completion work;

static struct cvp_dsp_apps gfa_cv;

static struct cvpd_cmd_msg cmd_msg;
static struct cvp_dsp_cmd_msg cmd_msg;

static struct cvpd_rsp_msg cmd_msg_rsp;
static struct cvp_dsp_rsp_msg cmd_msg_rsp;

static int cvp_dsp_send_cmd(void *msg, uint32_t len)
{
@@ -82,7 +93,8 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev)
	int destVMperm[SRC_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC };

	if (strcmp(rpdev->dev.parent->of_node->name, "cdsp")) {
		pr_err("%s: Failed to probe rpmsg device.Node name:%s\n",
		dprintk(CVP_ERR,
			"%s: Failed to probe rpmsg device.Node name:%s\n",
			__func__, rpdev->dev.parent->of_node->name);
		err = -EINVAL;
		goto bail;
@@ -100,14 +112,16 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev)
			msg_ptr_len, srcVM, DEST_VM_NUM, destVM,
			destVMperm, SRC_VM_NUM);
		if (err) {
			pr_err("%s: Failed to hyp_assign. err=%d\n",
			dprintk(CVP_ERR,
				"%s: Failed to hyp_assign. err=%d\n",
				__func__, err);
			return err;
		}
		err = cvp_dsp_send_cmd_hfi_queue(
			(phys_addr_t *)msg_ptr, msg_ptr_len);
		if (err) {
			pr_err("%s: Failed to send HFI Queue address. err=%d\n",
			dprintk(CVP_ERR,
				"%s: Failed to send HFI Queue address. err=%d\n",
				__func__, err);
			goto bail;
		}
@@ -116,7 +130,8 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev)
		mutex_unlock(&me->smd_mutex);
	}

	pr_info("%s: Successfully probed. cdsp_state=%d cvp_shutdown=%d\n",
	dprintk(CVP_INFO,
		"%s: Successfully probed. cdsp_state=%d cvp_shutdown=%d\n",
		__func__, cdsp_state, cvp_shutdown);
bail:
	return err;
@@ -130,17 +145,36 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev)
	me->chan = NULL;
	me->cdsp_state = STATUS_SSR;
	mutex_unlock(&me->smd_mutex);
	pr_info("%s: CDSP SSR triggered\n", __func__);
	dprintk(CVP_INFO,
		"%s: CDSP SSR triggered\n", __func__);
}

static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev,
	void *data, int len, void *priv, u32 addr)
{
	int *rpmsg_resp = (int *)data;

	cmd_msg_rsp.ret_val = *rpmsg_resp;
	complete(&work);
	struct cvp_dsp_rsp_msg *dsp_response =
		(struct cvp_dsp_rsp_msg *)data;
	struct cvp_dsp_apps *me = &gfa_cv;

	dprintk(CVP_DBG,
		"%s: cmd_msg_type=0x%x dsp_response->ret_val =0x%x\n"
		, __func__, dsp_response->cmd_msg_type, dsp_response->ret_val);
	switch (dsp_response->cmd_msg_type) {
	case CVP_DSP_REGISTER_BUFFER:
		complete(&me->reg_buffer_work);
		break;
	case CVP_DSP_DEREGISTER_BUFFER:
		complete(&me->dereg_buffer_work);
		break;
	case CVP_DSP_SHUTDOWN:
		complete(&me->shutdown_work);
		break;
	default:
		dprintk(CVP_ERR,
		"%s: Invalid cmd_msg_type received from dsp: %d\n",
		__func__, dsp_response->cmd_msg_type);
		break;
	}
	return 0;
}

@@ -148,7 +182,7 @@ int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
	uint32_t size_in_bytes)
{
	int err;
	struct cvpd_cmd_msg local_cmd_msg;
	struct cvp_dsp_cmd_msg local_cmd_msg;
	struct cvp_dsp_apps *me = &gfa_cv;
	int srcVM[SRC_VM_NUM] = {VMID_HLOS};
	int destVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
@@ -163,22 +197,25 @@ int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
	cmd_msg.msg_ptr_len = (size_in_bytes);
	mutex_unlock(&me->smd_mutex);

	pr_debug("%s :: address of buffer, PA=0x%pK  size_buff=%d\n",
	dprintk(CVP_DBG,
		"%s :: address of buffer, PA=0x%pK  size_buff=%d\n",
		__func__, phys_addr, size_in_bytes);

	err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr,
		local_cmd_msg.msg_ptr_len, srcVM, SRC_VM_NUM, destVM,
		destVMperm, DEST_VM_NUM);
	if (err) {
		pr_err("%s: Failed in hyp_assign. err=%d\n",
		dprintk(CVP_ERR,
			"%s: Failed in hyp_assign. err=%d\n",
			__func__, err);
		return err;
	}

	err = cvp_dsp_send_cmd
			 (&local_cmd_msg, sizeof(struct cvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
	if (err != 0)
		pr_err("%s: cvp_dsp_send_cmd failed with err=%d\n",
		dprintk(CVP_ERR,
			"%s: cvp_dsp_send_cmd failed with err=%d\n",
			__func__, err);
	else {
		mutex_lock(&me->smd_mutex);
@@ -193,7 +230,7 @@ int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
int cvp_dsp_suspend(uint32_t session_flag)
{
	int err = 0;
	struct cvpd_cmd_msg local_cmd_msg;
	struct cvp_dsp_cmd_msg local_cmd_msg;
	struct cvp_dsp_apps *me = &gfa_cv;
	uint32_t cdsp_state;

@@ -206,9 +243,10 @@ int cvp_dsp_suspend(uint32_t session_flag)

	local_cmd_msg.cmd_msg_type = CVP_DSP_SUSPEND;
	err = cvp_dsp_send_cmd
			 (&local_cmd_msg, sizeof(struct cvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
	if (err != 0)
		pr_err("%s: cvp_dsp_send_cmd failed with err=%d\n",
		dprintk(CVP_ERR,
			"%s: cvp_dsp_send_cmd failed with err=%d\n",
			__func__, err);

	return err;
@@ -217,7 +255,7 @@ int cvp_dsp_suspend(uint32_t session_flag)
int cvp_dsp_resume(uint32_t session_flag)
{
	int err;
	struct cvpd_cmd_msg local_cmd_msg;
	struct cvp_dsp_cmd_msg local_cmd_msg;
	struct cvp_dsp_apps *me = &gfa_cv;
	uint32_t cdsp_state;

@@ -230,9 +268,10 @@ int cvp_dsp_resume(uint32_t session_flag)

	local_cmd_msg.cmd_msg_type = CVP_DSP_RESUME;
	err = cvp_dsp_send_cmd
			 (&local_cmd_msg, sizeof(struct cvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
	if (err != 0)
		pr_err("%s: cvp_dsp_send_cmd failed with err=%d\n",
		dprintk(CVP_ERR,
			"%s: cvp_dsp_send_cmd failed with err=%d\n",
			__func__, err);

	return err;
@@ -242,19 +281,20 @@ int cvp_dsp_shutdown(uint32_t session_flag)
{
	struct cvp_dsp_apps *me = &gfa_cv;
	int err, local_cmd_msg_rsp;
	struct cvpd_cmd_msg local_cmd_msg;
	struct cvp_dsp_cmd_msg local_cmd_msg;
	int srcVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
	int destVM[SRC_VM_NUM] = {VMID_HLOS};
	int destVMperm[SRC_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC };

	local_cmd_msg.cmd_msg_type = CVP_DSP_SHUTDOWN;
	err = cvp_dsp_send_cmd
			 (&local_cmd_msg, sizeof(struct cvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
	if (err != 0)
		pr_err("%s: cvp_dsp_send_cmd failed with err=%d\n",
		dprintk(CVP_ERR,
			"%s: cvp_dsp_send_cmd failed with err=%d\n",
			__func__, err);

	wait_for_completion(&work);
	wait_for_completion(&me->shutdown_work);

	mutex_lock(&me->smd_mutex);
	me->cvp_shutdown = STATUS_SSR;
@@ -267,18 +307,106 @@ int cvp_dsp_shutdown(uint32_t session_flag)
			local_cmd_msg.msg_ptr_len, srcVM, DEST_VM_NUM,
			destVM,	destVMperm, SRC_VM_NUM);
		if (err) {
			pr_err("%s: Failed to hyp_assign. err=%d\n",
			dprintk(CVP_ERR,
				"%s: Failed to hyp_assign. err=%d\n",
				__func__, err);
			return err;
		}
	} else {
		pr_err("%s: Skipping hyp_assign as CDSP sent invalid response=%d\n",
		dprintk(CVP_ERR,
			"%s: Skipping hyp_assign as CDSP sent invalid response=%d\n",
			__func__, local_cmd_msg_rsp);
	}

	return err;
}

int cvp_dsp_register_buffer(uint32_t iova_buff_addr,
	uint32_t buff_index, uint32_t buff_size,
	uint32_t session_id)
{
	struct cvp_dsp_cmd_msg local_cmd_msg;
	int err;
	struct cvp_dsp_apps *me = &gfa_cv;

	local_cmd_msg.cmd_msg_type = CVP_DSP_REGISTER_BUFFER;
	local_cmd_msg.iova_buff_addr = iova_buff_addr;
	local_cmd_msg.buff_index = buff_index;
	local_cmd_msg.buff_size = buff_size;
	local_cmd_msg.session_id = session_id;
	dprintk(CVP_DBG,
		"%s: cmd_msg_type=0x%x, iova_buff_addr=0x%x buff_index=0x%x\n",
		__func__, local_cmd_msg.cmd_msg_type, iova_buff_addr,
		local_cmd_msg.buff_index);
	dprintk(CVP_DBG,
		"%s: buff_size=0x%x session_id=0x%x\n",
		__func__, local_cmd_msg.buff_size, local_cmd_msg.session_id);

	mutex_lock(&me->reg_buffer_mutex);
	err = cvp_dsp_send_cmd
			 (&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
	if (err != 0) {
		dprintk(CVP_ERR,
			"%s: cvp_dsp_send_cmd failed with err=%d\n",
			__func__, err);
		mutex_unlock(&me->reg_buffer_mutex);
		return err;
	}

	dprintk(CVP_DBG,
		"%s: calling wait_for_completion work=%pK\n",
		__func__, &me->reg_buffer_work);
	wait_for_completion(&me->reg_buffer_work);
	mutex_unlock(&me->reg_buffer_mutex);
	dprintk(CVP_DBG,
			"%s: done calling wait_for_completion\n", __func__);

	return err;
}

int cvp_dsp_deregister_buffer(uint32_t iova_buff_addr,
	uint32_t buff_index, uint32_t buff_size,
	uint32_t session_id)
{
	struct cvp_dsp_cmd_msg local_cmd_msg;
	int err;
	struct cvp_dsp_apps *me = &gfa_cv;

	local_cmd_msg.cmd_msg_type = CVP_DSP_DEREGISTER_BUFFER;
	local_cmd_msg.iova_buff_addr = iova_buff_addr;
	local_cmd_msg.buff_index = buff_index;
	local_cmd_msg.buff_size = buff_size;
	local_cmd_msg.session_id = session_id;
	dprintk(CVP_DBG,
		"%s: cmd_msg_type=0x%x, iova_buff_addr=0x%x buff_index=0x%x\n",
		__func__, local_cmd_msg.cmd_msg_type, iova_buff_addr,
		local_cmd_msg.buff_index);
	dprintk(CVP_DBG,
			"%s: buff_size=0x%x session_id=0x%x\n",
		__func__, local_cmd_msg.buff_size, local_cmd_msg.session_id);

	mutex_lock(&me->dereg_buffer_mutex);
	err = cvp_dsp_send_cmd
			 (&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
	if (err != 0) {
		dprintk(CVP_ERR,
			"%s: cvp_dsp_send_cmd failed with err=%d\n",
			__func__, err);
		mutex_unlock(&me->dereg_buffer_mutex);
		return err;
	}

	dprintk(CVP_DBG,
			"%s: calling wait_for_completion work=%pK\n",
			__func__, &me->dereg_buffer_work);
	wait_for_completion(&me->dereg_buffer_work);
	dprintk(CVP_DBG,
			"%s: done calling wait_for_completion\n", __func__);
	mutex_unlock(&me->dereg_buffer_mutex);

	return err;
}

static const struct rpmsg_device_id cvp_dsp_rpmsg_match[] = {
	{ CVP_APPS_DSP_GLINK_GUID },
	{ },
@@ -299,13 +427,18 @@ static int __init cvp_dsp_device_init(void)
	struct cvp_dsp_apps *me = &gfa_cv;
	int err;

	init_completion(&work);
	mutex_init(&me->smd_mutex);
	mutex_init(&me->reg_buffer_mutex);
	mutex_init(&me->dereg_buffer_mutex);
	init_completion(&me->shutdown_work);
	init_completion(&me->reg_buffer_work);
	init_completion(&me->dereg_buffer_work);
	me->cvp_shutdown = STATUS_INIT;
	me->cdsp_state = STATUS_INIT;
	err = register_rpmsg_driver(&cvp_dsp_rpmsg_client);
	if (err) {
		pr_err("%s : register_rpmsg_driver failed with err %d\n",
		dprintk(CVP_ERR,
			"%s : register_rpmsg_driver failed with err %d\n",
			__func__, err);
		goto register_bail;
	}
@@ -325,6 +458,8 @@ static void __exit cvp_dsp_device_exit(void)
	me->cvp_shutdown = STATUS_DEINIT;
	me->cdsp_state = STATUS_DEINIT;
	mutex_destroy(&me->smd_mutex);
	mutex_destroy(&me->reg_buffer_mutex);
	mutex_destroy(&me->dereg_buffer_mutex);
	if (me->rpmsg_register == 1)
		unregister_rpmsg_driver(&cvp_dsp_rpmsg_client);
}
+25 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#define MSM_CVP_DSP_H

#include <linux/types.h>
#include "msm_cvp_debug.h"

#define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp"
#define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp"
@@ -51,5 +52,29 @@ int cvp_dsp_resume(uint32_t session_flag);
 */
int cvp_dsp_shutdown(uint32_t session_flag);

/*
 * API to register iova buffer address with CDSP
 *
 * @iova_buff_addr: IOVA buffer address
 * @buff_index:     buffer index
 * @buff_size:      size in bytes of cvp buffer
 * @session_id:     cvp session id
 */
int cvp_dsp_register_buffer(uint32_t iova_buff_addr,
	uint32_t buff_index, uint32_t buff_size,
	uint32_t session_id);

/*
 * API to de-register iova buffer address from CDSP
 *
 * @iova_buff_addr: IOVA buffer address
 * @buff_index:     buffer index
 * @buff_size:      size in bytes of cvp buffer
 * @session_id:     cvp session id
 */
int cvp_dsp_deregister_buffer(uint32_t iova_buff_addr,
	uint32_t buff_index, uint32_t buff_size,
	uint32_t session_id);

#endif // MSM_CVP_DSP_H