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

Commit 6c200033 authored by George Shen's avatar George Shen
Browse files

msm: cvp: Support releasing persistent buffer



CVP firmware introduced new feature to support releasing user
allocated persistent buffers. Added support in kernel.

Change-Id: Ifcd35c328ebfbb961247bf45e2e72222bd3e425b
Signed-off-by: default avatarGeorge Shen <sqiao@codeaurora.org>
parent 059aa413
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -77,7 +77,14 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = {
		.type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS,
		.buf_offset = HFI_PERSIST_BUFFERS_OFFSET,
		.buf_num = HFI_PERSIST_BUF_NUM,
		.resp = HAL_SESSION_PERSIST_CMD_DONE,
		.resp = HAL_SESSION_PERSIST_SET_DONE,
	},
	{
		.size = 0xffffffff,
		.type = HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS,
		.buf_offset = 0,
		.buf_num = 0,
		.resp = HAL_SESSION_PERSIST_REL_DONE,
	},
	{
		.size = HFI_DS_CMD_SIZE,
@@ -2847,7 +2854,8 @@ static void **get_session_id(struct msm_cvp_cb_info *info)
	case HAL_SESSION_DME_FRAME_CMD_DONE:
	case HAL_SESSION_ICA_FRAME_CMD_DONE:
	case HAL_SESSION_FD_FRAME_CMD_DONE:
	case HAL_SESSION_PERSIST_CMD_DONE:
	case HAL_SESSION_PERSIST_SET_DONE:
	case HAL_SESSION_PERSIST_REL_DONE:
	case HAL_SESSION_FD_CONFIG_CMD_DONE:
	case HAL_SESSION_MODEL_BUF_CMD_DONE:
	case HAL_SESSION_PROPERTY_INFO:
+5 −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 __H_CVP_HFI_H__
@@ -96,6 +96,8 @@
	(HFI_CMD_SESSION_CVP_START + 0x053)
#define HFI_CMD_SESSION_CVP_FD_FRAME\
	(HFI_CMD_SESSION_CVP_START + 0x054)
#define HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS\
	(HFI_CMD_SESSION_CVP_START + 0x055)
#define  HFI_CMD_SESSION_CVP_ICA_FRAME\
	(HFI_CMD_SESSION_CVP_START + 0x100)
#define  HFI_CMD_SESSION_CVP_ICA_CONFIG\
@@ -140,6 +142,8 @@
	(HFI_MSG_SESSION_CVP_START + 0x036)
#define  HFI_MSG_SESSION_CVP_FD\
	(HFI_MSG_SESSION_CVP_START + 0x037)
#define  HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS\
	(HFI_MSG_SESSION_CVP_START + 0x038)

#define CVP_IFACEQ_MAX_PKT_SIZE       1024
#define CVP_IFACEQ_MED_PKT_SIZE       768
+3 −2
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 __CVP_HFI_API_H__
@@ -248,7 +248,8 @@ enum hal_command_response {
	HAL_SESSION_DCM_CONFIG_CMD_DONE,
	HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE,
	HAL_SESSION_FD_CONFIG_CMD_DONE,
	HAL_SESSION_PERSIST_CMD_DONE,
	HAL_SESSION_PERSIST_SET_DONE,
	HAL_SESSION_PERSIST_REL_DONE,
	HAL_SESSION_MODEL_BUF_CMD_DONE,
	HAL_SESSION_ICA_FRAME_CMD_DONE,
	HAL_SESSION_FD_FRAME_CMD_DONE,
+6 −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.
 */

#include <linux/bitops.h>
@@ -385,6 +385,10 @@ static int hfi_process_session_cvp_operation_config(u32 device_id,
	if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS)
		signal = get_signal_from_pkt_type(
				HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS);
	else if (pkt->packet_type ==
			HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS)
		signal = get_signal_from_pkt_type(
			HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS);
	else if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS)
		signal = get_signal_from_pkt_type(
				HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS);
@@ -608,6 +612,7 @@ int cvp_hfi_process_msg_packet(u32 device_id,
		break;
	case HFI_MSG_SESSION_CVP_OPERATION_CONFIG:
	case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS:
	case HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS:
	case HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS:
		pkt_func =
			(pkt_func_def)hfi_process_session_cvp_operation_config;
+109 −3
Original line number Diff line number Diff line
@@ -595,6 +595,104 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst,
	return rc;
}

static int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst,
	struct cvp_kmd_hfi_packet *in_pkt,
	unsigned int offset, unsigned int buf_num)
{
	struct cvp_buf_type *buf;
	struct cvp_hfi_cmd_session_hdr *cmd_hdr;
	struct cvp_internal_buf *cbuf, *dummy;
	u64 ktid;
	int i, rc = 0;

	if (!offset || !buf_num)
		return 0;

	cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt;
	ktid = cmd_hdr->client_data.kdata;

	for (i = 0; i < buf_num; i++) {
		buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset];
		offset += sizeof(*buf) >> 2;
		mutex_lock(&inst->persistbufs.lock);
		list_for_each_entry_safe(cbuf, dummy, &inst->persistbufs.list,
				list) {
			if (cbuf->ktid == ktid) {
				list_del(&cbuf->list);
				dprintk(CVP_DBG,
					"unmap persist: %x %d %d %#x",
					hash32_ptr(inst->session),
					cbuf->smem.fd,
					cbuf->smem.size,
					cbuf->smem.device_addr);
				msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
				kfree(cbuf);
				rc = 1;
				break;
			}
		}
		mutex_unlock(&inst->persistbufs.lock);
		if (!rc) {
			dprintk(CVP_ERR, "%s, failed unmapi %llx\n",
				__func__, ktid);
			rc = -EFAULT;
			break;
		}
		rc = 0;
	}
	return rc;
}

static int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst,
	struct cvp_kmd_hfi_packet *in_pkt,
	unsigned int offset, unsigned int buf_num)
{
	struct cvp_hfi_cmd_session_hdr *cmd_hdr;
	struct cvp_internal_buf *cbuf, *dummy;
	u64 ktid;
	struct cvp_buf_type *buf;
	int i, rc = 0;

	if (!offset || !buf_num)
		return 0;

	cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt;
	ktid = atomic64_inc_return(&inst->core->kernel_trans_id);
	ktid &= (FENCE_BIT - 1);
	cmd_hdr->client_data.kdata = ktid;

	for (i = 0; i < buf_num; i++) {
		buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset];
		offset += sizeof(*buf) >> 2;

		/* Validate buffer descriptor */
		if (buf->fd  <= 0 || !buf->size)
			continue;

		mutex_lock(&inst->persistbufs.lock);
		list_for_each_entry_safe(cbuf, dummy, &inst->persistbufs.list,
				list) {
			if (cbuf->smem.fd == buf->fd &&
					cbuf->smem.size == buf->size &&
					cbuf->buffer_ownership == CLIENT) {
				rc = 1;
				break;
			}
		}
		mutex_unlock(&inst->persistbufs.lock);
		if (!rc) {
			dprintk(CVP_ERR, "%s No persist buf %d found\n",
				__func__, buf->fd);
			rc = -EFAULT;
			break;
		}
		buf->fd = cbuf->smem.device_addr;
		cbuf->ktid = ktid;
		rc = 0;
	}
	return rc;
}

static int msm_cvp_map_user_persist(struct msm_cvp_inst *inst,
	struct cvp_kmd_hfi_packet *in_pkt,
	unsigned int offset, unsigned int buf_num)
@@ -728,7 +826,7 @@ static int msm_cvp_session_process_hfi(
	unsigned int in_offset,
	unsigned int in_buf_num)
{
	int pkt_idx, rc = 0;
	int pkt_idx, pkt_type, rc = 0;
	struct cvp_hfi_device *hdev;
	unsigned int offset, buf_num, signal;
	struct cvp_session_queue *sq;
@@ -777,8 +875,11 @@ static int msm_cvp_session_process_hfi(
		buf_num = in_buf_num;
	}

	if (in_pkt->pkt_data[1] == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS)
	pkt_type = in_pkt->pkt_data[1];
	if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS)
		rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num);
	else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS)
		rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num);
	else
		rc = msm_cvp_map_buf(inst, in_pkt, offset, buf_num);

@@ -796,13 +897,18 @@ static int msm_cvp_session_process_hfi(

	if (signal != HAL_NO_RESP) {
		rc = wait_for_sess_signal_receipt(inst, signal);
		if (rc)
		if (rc) {
			dprintk(CVP_ERR,
				"%s: wait for signal failed, rc %d %d, %x %d\n",
				__func__, rc,
				in_pkt->pkt_data[0],
				in_pkt->pkt_data[1],
				signal);
			goto exit;
		}
		if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS)
			rc = msm_cvp_unmap_user_persist(inst, in_pkt,
					offset, buf_num);

	}
exit:
Loading