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

Commit 4a1ec086 authored by Ruofei Ma's avatar Ruofei Ma
Browse files

msm: cvp: dynamic buffer map support



Handle buffer mapping and cache operations dynamically in cvp driver.

Change-Id: Id860552d4c6348881a42181230f3d95dad04b7bf
Signed-off-by: default avatarRuofei Ma <ruofeim@codeaurora.org>
parent 20a985e5
Loading
Loading
Loading
Loading
+10 −2
Original line number Original line Diff line number Diff line
@@ -573,8 +573,8 @@ struct cvp_hfi_client {
	u32 transaction_id;
	u32 transaction_id;
	u32 data1;
	u32 data1;
	u32 data2;
	u32 data2;
	u32 data3;
	u32 kdata1;
	u32 data4;
	u32 kdata2;
	u32 reserved1;
	u32 reserved1;
	u32 reserved2;
	u32 reserved2;
};
};
@@ -637,6 +637,14 @@ struct cvp_session_release_buffers_packet_d {
	u32 buffer_idx;
	u32 buffer_idx;
};
};


struct cvp_hfi_cmd_session_hdr {
	u32 size;
	u32 packet_type;
	u32 session_id;
	struct cvp_hfi_client client_data;
	u32 stream_idx;
};

struct cvp_hfi_msg_session_hdr {
struct cvp_hfi_msg_session_hdr {
	u32 size;
	u32 size;
	u32 packet_type;
	u32 packet_type;
+328 −55
Original line number Original line Diff line number Diff line
@@ -8,14 +8,6 @@
#include <synx_api.h>
#include <synx_api.h>
#include "cvp_core_hfi.h"
#include "cvp_core_hfi.h"


#define MSM_CVP_NOMINAL_CYCLES		(444 * 1000 * 1000)
#define MSM_CVP_UHD60E_VPSS_CYCLES	(111 * 1000 * 1000)
#define MSM_CVP_UHD60E_ISE_CYCLES	(175 * 1000 * 1000)
#define MAX_CVP_VPSS_CYCLES		(MSM_CVP_NOMINAL_CYCLES - \
		MSM_CVP_UHD60E_VPSS_CYCLES)
#define MAX_CVP_ISE_CYCLES		(MSM_CVP_NOMINAL_CYCLES - \
		MSM_CVP_UHD60E_ISE_CYCLES)

void print_cvp_internal_buffer(u32 tag, const char *str,
void print_cvp_internal_buffer(u32 tag, const char *str,
		struct msm_cvp_inst *inst, struct msm_cvp_internal_buffer *cbuf)
		struct msm_cvp_inst *inst, struct msm_cvp_internal_buffer *cbuf)
{
{
@@ -99,7 +91,7 @@ static int msm_cvp_get_session_info(struct msm_cvp_inst *inst,
	return rc;
	return rc;
}
}


static int msm_cvp_session_get_iova_addr(
static int msm_cvp_session_get_iova_addr_d(
	struct msm_cvp_inst *inst,
	struct msm_cvp_inst *inst,
	struct msm_cvp_internal_buffer **cbuf_ptr,
	struct msm_cvp_internal_buffer **cbuf_ptr,
	unsigned int search_fd, unsigned int search_size,
	unsigned int search_fd, unsigned int search_size,
@@ -117,16 +109,6 @@ static int msm_cvp_session_get_iova_addr(
		}
		}
	}
	}
	mutex_unlock(&inst->cvpcpubufs.lock);
	mutex_unlock(&inst->cvpcpubufs.lock);
	if (!found) {
		mutex_lock(&inst->cvpdspbufs.lock);
		list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) {
			if (cbuf->buf.fd == search_fd) {
				found = true;
				break;
			}
		}
		mutex_unlock(&inst->cvpdspbufs.lock);
	}
	if (!found)
	if (!found)
		return -ENOENT;
		return -ENOENT;


@@ -145,6 +127,35 @@ static int msm_cvp_session_get_iova_addr(
	return 0;
	return 0;
}
}


static int msm_cvp_session_get_iova_addr(
	struct msm_cvp_inst *inst,
	struct cvp_buf_type *in_buf,
	unsigned int *iova)
{
	struct msm_cvp_internal_buffer *cbuf;

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

	mutex_lock(&inst->cvpcpubufs.lock);
	list_for_each_entry(cbuf, &inst->cvpcpubufs.list, list) {
		if (cbuf->buf.fd == in_buf->fd &&
			cbuf->buf.size == in_buf->size &&
			cbuf->buf.offset == in_buf->offset) {
			*iova = cbuf->smem.device_addr + cbuf->buf.offset;
			print_client_buffer(CVP_DBG, "found", inst, &cbuf->buf);
			mutex_unlock(&inst->cvpcpubufs.lock);
			return 0;
		}
	}
	mutex_unlock(&inst->cvpcpubufs.lock);
	*iova = 0;

	return -ENOENT;
}

static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst,
static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst,
	struct cvp_kmd_buffer *buf)
	struct cvp_kmd_buffer *buf)
{
{
@@ -186,9 +197,8 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst,
		return -EINVAL;
		return -EINVAL;
	}
	}


	cbuf = kzalloc(sizeof(struct msm_cvp_internal_buffer), GFP_KERNEL);
	cbuf = kmem_cache_zalloc(inst->internal_buf_cache, GFP_KERNEL);
	if (!cbuf) {
	if (!cbuf) {
		dprintk(CVP_ERR, "%s: cbuf alloc failed\n", __func__);
		return -ENOMEM;
		return -ENOMEM;
	}
	}


@@ -205,8 +215,9 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst,
	}
	}


	if (buf->index) {
	if (buf->index) {
		rc = cvp_dsp_register_buffer((uint32_t)cbuf->smem.device_addr,
		rc = cvp_dsp_register_buffer(hash32_ptr(session), buf->fd,
			buf->index, buf->size, hash32_ptr(session));
			 buf->size, buf->offset, buf->index,
			(uint32_t)cbuf->smem.device_addr);
		if (rc) {
		if (rc) {
			dprintk(CVP_ERR,
			dprintk(CVP_ERR,
				"%s: failed dsp registration for fd=%d rc=%d",
				"%s: failed dsp registration for fd=%d rc=%d",
@@ -229,7 +240,7 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst,
exit:
exit:
	if (cbuf->smem.device_addr)
	if (cbuf->smem.device_addr)
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
	kfree(cbuf);
	kmem_cache_free(inst->internal_buf_cache, cbuf);
	cbuf = NULL;
	cbuf = NULL;


	return rc;
	return rc;
@@ -286,11 +297,11 @@ static int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst,
	list_del(&cbuf->list);
	list_del(&cbuf->list);
	mutex_unlock(&inst->cvpdspbufs.lock);
	mutex_unlock(&inst->cvpdspbufs.lock);


	kfree(cbuf);
	kmem_cache_free(inst->internal_buf_cache, cbuf);
	return rc;
	return rc;
}
}


static int msm_cvp_map_buf_cpu(struct msm_cvp_inst *inst,
static int msm_cvp_map_buf_cpu_d(struct msm_cvp_inst *inst,
	unsigned int fd,
	unsigned int fd,
	unsigned int size,
	unsigned int size,
	struct msm_cvp_internal_buffer **cbuf_ptr)
	struct msm_cvp_internal_buffer **cbuf_ptr)
@@ -318,12 +329,10 @@ static int msm_cvp_map_buf_cpu(struct msm_cvp_inst *inst,
		return -EINVAL;
		return -EINVAL;
	}
	}


	cbuf = kzalloc(sizeof(struct msm_cvp_internal_buffer), GFP_KERNEL);
	cbuf = kmem_cache_zalloc(inst->internal_buf_cache, GFP_KERNEL);
	if (!cbuf)
	if (!cbuf)
		return -ENOMEM;
		return -ENOMEM;


	memset(cbuf, 0, sizeof(struct msm_cvp_internal_buffer));

	cbuf->buf.fd = fd;
	cbuf->buf.fd = fd;
	cbuf->buf.size = size;
	cbuf->buf.size = size;
	/* HFI doesn't have buffer type, set it as HAL_BUFFER_INPUT */
	/* HFI doesn't have buffer type, set it as HAL_BUFFER_INPUT */
@@ -349,12 +358,179 @@ static int msm_cvp_map_buf_cpu(struct msm_cvp_inst *inst,
exit:
exit:
	if (cbuf->smem.device_addr)
	if (cbuf->smem.device_addr)
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
	kfree(cbuf);
	kmem_cache_free(inst->internal_buf_cache, cbuf);
	cbuf = NULL;
	cbuf = NULL;


	return rc;
	return rc;
}
}


static void __msm_cvp_cache_operations(struct msm_cvp_internal_buffer *cbuf)
{
	enum smem_cache_ops cache_op;

	if (!cbuf) {
		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
		return;
	}

	switch (cbuf->buf.type) {
	case CVP_KMD_BUFTYPE_INPUT:
		cache_op = SMEM_CACHE_CLEAN;
		break;
	case CVP_KMD_BUFTYPE_OUTPUT:
		cache_op = SMEM_CACHE_INVALIDATE;
		break;
	default:
		cache_op = SMEM_CACHE_CLEAN_INVALIDATE;
	}

	msm_cvp_smem_cache_operations(cbuf->smem.dma_buf, cache_op,
				cbuf->buf.offset, cbuf->buf.size);
}

static int msm_cvp_map_buf_cpu(struct msm_cvp_inst *inst,
				struct cvp_buf_type *in_buf,
				u32 *iova,
				struct msm_cvp_frame *frame)
{
	int rc = 0;
	struct msm_cvp_internal_buffer *cbuf;
	struct msm_cvp_frame_buf *frame_buf;

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

	rc = msm_cvp_session_get_iova_addr(inst, in_buf, iova);
	if (!rc && *iova != 0)
		return 0;

	cbuf = kmem_cache_zalloc(inst->internal_buf_cache, GFP_KERNEL);
	if (!cbuf)
		return -ENOMEM;

	cbuf->buf.fd = in_buf->fd;
	cbuf->buf.size = in_buf->size;
	cbuf->buf.offset = in_buf->offset;
	cbuf->buf.flags = in_buf->flags;
	cbuf->buf.type = CVP_KMD_BUFTYPE_INPUT | CVP_KMD_BUFTYPE_OUTPUT;

	/* HFI doesn't have buffer type, set it as HAL_BUFFER_INPUT */
	cbuf->smem.buffer_type = HAL_BUFFER_INPUT;
	cbuf->smem.fd = cbuf->buf.fd;
	cbuf->smem.size = cbuf->buf.size;
	cbuf->smem.flags = 0;
	cbuf->smem.offset = 0;
	rc = msm_cvp_smem_map_dma_buf(inst, &cbuf->smem);
	if (rc) {
		print_client_buffer(CVP_ERR, "map failed", inst, &cbuf->buf);
		goto exit;
	}

	mutex_lock(&inst->cvpcpubufs.lock);
	list_add_tail(&cbuf->list, &inst->cvpcpubufs.list);
	mutex_unlock(&inst->cvpcpubufs.lock);

	__msm_cvp_cache_operations(cbuf);

	*iova = cbuf->smem.device_addr + cbuf->buf.offset;

	frame_buf = kmem_cache_zalloc(inst->frame_buf_cache, GFP_KERNEL);
	if (!frame_buf) {
		rc = -ENOMEM;
		goto exit2;
	}

	memcpy(&frame_buf->buf, in_buf, sizeof(frame_buf->buf));

	mutex_lock(&frame->bufs.lock);
	list_add_tail(&frame_buf->list, &frame->bufs.list);
	mutex_unlock(&frame->bufs.lock);

	print_client_buffer(CVP_DBG, "map", inst, &cbuf->buf);
	return rc;

exit2:
	if (cbuf->smem.device_addr)
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
	mutex_lock(&inst->cvpcpubufs.lock);
	list_del(&cbuf->list);
	mutex_unlock(&inst->cvpcpubufs.lock);
exit:
	kmem_cache_free(inst->internal_buf_cache, cbuf);
	cbuf = NULL;

	return rc;
}

static void __unmap_buf(struct msm_cvp_inst *inst,
		struct msm_cvp_frame_buf *frame_buf)
{
	struct msm_cvp_internal_buffer *cbuf, *dummy;
	struct cvp_buf_type *buf;

	if (!inst || !frame_buf) {
		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
		return;
	}

	buf = &frame_buf->buf;
	mutex_lock(&inst->cvpcpubufs.lock);
	list_for_each_entry_safe(cbuf, dummy, &inst->cvpcpubufs.list, list) {
		if (cbuf->buf.fd == buf->fd &&
			cbuf->buf.size == buf->size &&
			cbuf->buf.offset == buf->offset) {
			list_del(&cbuf->list);
			msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
			print_client_buffer(CVP_DBG, "unmap", inst, &cbuf->buf);
			kmem_cache_free(inst->internal_buf_cache, cbuf);
			break;
		}
	}
	mutex_unlock(&inst->cvpcpubufs.lock);
}

void msm_cvp_unmap_buf_cpu(struct msm_cvp_inst *inst, u64 ktid)
{
	struct msm_cvp_frame *frame, *dummy1;
	struct msm_cvp_frame_buf *frame_buf, *dummy2;
	bool found;

	if (!inst) {
		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
		return;
	}

	dprintk(CVP_DBG, "%s: unmap frame %llu\n", __func__, ktid);
	found = false;
	mutex_lock(&inst->frames.lock);
	list_for_each_entry_safe(frame, dummy1, &inst->frames.list, list) {
		if (frame->ktid == ktid) {
			found = true;
			list_del(&frame->list);
			mutex_lock(&frame->bufs.lock);
			list_for_each_entry_safe(frame_buf, dummy2,
						&frame->bufs.list, list) {
				list_del(&frame_buf->list);
				__unmap_buf(inst, frame_buf);
				kmem_cache_free(inst->frame_buf_cache,
						frame_buf);
			}
			mutex_unlock(&frame->bufs.lock);
			DEINIT_MSM_CVP_LIST(&frame->bufs);
			kmem_cache_free(inst->frame_cache, frame);
			break;
		}
	}
	mutex_unlock(&inst->frames.lock);

	if (!found) {
		dprintk(CVP_WARN, "%s frame %#llx not found!\n",
				__func__, ktid);
	}
}

static bool _cvp_msg_pending(struct msm_cvp_inst *inst,
static bool _cvp_msg_pending(struct msm_cvp_inst *inst,
			struct cvp_session_queue *sq,
			struct cvp_session_queue *sq,
			struct cvp_session_msg **msg)
			struct cvp_session_msg **msg)
@@ -392,6 +568,7 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst,
	struct cvp_kmd_session_control *sc;
	struct cvp_kmd_session_control *sc;
	struct msm_cvp_inst *s;
	struct msm_cvp_inst *s;
	int rc = 0;
	int rc = 0;
	u32 version;


	if (!inst) {
	if (!inst) {
		dprintk(CVP_ERR, "%s invalid session\n", __func__);
		dprintk(CVP_ERR, "%s invalid session\n", __func__);
@@ -414,6 +591,9 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst,
		goto exit;
		goto exit;
	}
	}


	version = (get_hfi_version() & HFI_VERSION_MINOR_MASK)
				>> HFI_VERSION_MINOR_SHIFT;

	if (msg == NULL) {
	if (msg == NULL) {
		dprintk(CVP_DBG,
		dprintk(CVP_DBG,
			"%s: session deleted, queue state %d, msg cnt %d\n",
			"%s: session deleted, queue state %d, msg cnt %d\n",
@@ -429,6 +609,16 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst,
		}
		}
		spin_unlock(&sq->lock);
		spin_unlock(&sq->lock);
	} else {
	} else {
		if (version >= 1) {
			u64 ktid;
			u32 kdata1, kdata2;

			kdata1 = msg->pkt.client_data.kdata1;
			kdata2 = msg->pkt.client_data.kdata2;
			ktid = ((u64)kdata2 << 32) | kdata1;
			msm_cvp_unmap_buf_cpu(inst, ktid);
		}

		memcpy(out_pkt, &msg->pkt,
		memcpy(out_pkt, &msg->pkt,
			sizeof(struct cvp_hfi_msg_session_hdr));
			sizeof(struct cvp_hfi_msg_session_hdr));
		kmem_cache_free(inst->session_queue.msg_cache, msg);
		kmem_cache_free(inst->session_queue.msg_cache, msg);
@@ -447,13 +637,35 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst,
	struct cvp_buf_desc *buf_ptr;
	struct cvp_buf_desc *buf_ptr;
	struct cvp_buf_type *new_buf;
	struct cvp_buf_type *new_buf;
	int i, rc = 0;
	int i, rc = 0;
	struct cvp_hfi_device *hdev = inst->core->device;
	u32 version;
	struct iris_hfi_device *hfi = hdev->hfi_device_data;
	unsigned int iova;
	u32 version = hfi->version;
	u64 ktid;
	struct msm_cvp_frame *frame;


	version = get_hfi_version();
	version = (version & HFI_VERSION_MINOR_MASK) >> HFI_VERSION_MINOR_SHIFT;
	version = (version & HFI_VERSION_MINOR_MASK) >> HFI_VERSION_MINOR_SHIFT;


	if (offset != 0 && buf_num != 0) {
	if (version >= 1 && buf_num) {
		struct cvp_hfi_cmd_session_hdr *cmd_hdr;

		cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt;
		ktid = atomic64_inc_return(&inst->core->kernel_trans_id);
		cmd_hdr->client_data.kdata1 = (u32)ktid;
		cmd_hdr->client_data.kdata2 = (u32)(ktid >> 32);

		frame = kmem_cache_zalloc(inst->frame_cache, GFP_KERNEL);
		if (!frame)
			return -ENOMEM;

		INIT_MSM_CVP_LIST(&frame->bufs);
		frame->ktid = ktid;
	} else {
		frame = NULL;
	}

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

	for (i = 0; i < buf_num; i++) {
	for (i = 0; i < buf_num; i++) {
		buf_ptr = (struct cvp_buf_desc *)
		buf_ptr = (struct cvp_buf_desc *)
				&in_pkt->pkt_data[offset];
				&in_pkt->pkt_data[offset];
@@ -465,16 +677,45 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst,
		if (!buf_ptr->fd)
		if (!buf_ptr->fd)
			continue;
			continue;


			rc = msm_cvp_session_get_iova_addr(inst, &cbuf,
		if (version >= 1) {
			new_buf = (struct cvp_buf_type *)buf_ptr;
			rc = msm_cvp_map_buf_cpu(inst, new_buf, &iova, frame);
			if (rc) {
				struct msm_cvp_frame_buf *frame_buf, *dummy;

				dprintk(CVP_ERR,
					"%s: buf %d register failed.\n",
					__func__, i);

				list_for_each_entry_safe(frame_buf,
					dummy, &frame->bufs.list, list) {
					list_del(&frame_buf->list);
					__unmap_buf(inst, frame_buf);
					kmem_cache_free(
					inst->frame_buf_cache,
					frame_buf);
				}
				DEINIT_MSM_CVP_LIST(&frame->bufs);
				kmem_cache_free(inst->frame_cache,
						frame);
				return rc;
			}
			new_buf->fd = iova;
		} else {
			rc = msm_cvp_session_get_iova_addr_d(inst,
						&cbuf,
						buf_ptr->fd,
						buf_ptr->fd,
						buf_ptr->size,
						buf_ptr->size,
						&buf_ptr->fd,
						&buf_ptr->fd,
						&buf_ptr->size);
						&buf_ptr->size);

			if (rc == -ENOENT) {
			if (rc == -ENOENT) {
				dprintk(CVP_DBG, "%s map buf fd %d size %d\n",
				dprintk(CVP_DBG,
					"%s map buf fd %d size %d\n",
					__func__, buf_ptr->fd,
					__func__, buf_ptr->fd,
					buf_ptr->size);
					buf_ptr->size);
				rc = msm_cvp_map_buf_cpu(inst, buf_ptr->fd,
				rc = msm_cvp_map_buf_cpu_d(inst,
						buf_ptr->fd,
						buf_ptr->size, &cbuf);
						buf_ptr->size, &cbuf);
				if (rc || !cbuf) {
				if (rc || !cbuf) {
					dprintk(CVP_ERR,
					dprintk(CVP_ERR,
@@ -490,11 +731,21 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst,
				__func__, i, rc);
				__func__, i, rc);
				return rc;
				return rc;
			}
			}
			msm_cvp_smem_cache_operations(cbuf->smem.dma_buf,
			msm_cvp_smem_cache_operations(
					cbuf->smem.dma_buf,
					SMEM_CACHE_CLEAN_INVALIDATE,
					SMEM_CACHE_CLEAN_INVALIDATE,
					0, buf_ptr->size);
					0, buf_ptr->size);
		}
		}
	}
	}


	if (frame != NULL) {
		mutex_lock(&inst->frames.lock);
		list_add_tail(&frame->list, &inst->frames.list);
		mutex_unlock(&inst->frames.lock);
		dprintk(CVP_DBG, "%s: map frame %llu\n", __func__, ktid);
	}

	return rc;
	return rc;
}
}


@@ -844,7 +1095,7 @@ static int msm_cvp_session_process_hfi_fence(
	if (!s)
	if (!s)
		return -ECONNRESET;
		return -ECONNRESET;


	fence_thread_data = kmem_cache_alloc(inst->fence_data_cache,
	fence_thread_data = kmem_cache_zalloc(inst->fence_data_cache,
			GFP_KERNEL);
			GFP_KERNEL);
	if (!fence_thread_data) {
	if (!fence_thread_data) {
		dprintk(CVP_ERR, "%s: fence_thread_data alloc failed\n",
		dprintk(CVP_ERR, "%s: fence_thread_data alloc failed\n",
@@ -1132,12 +1383,7 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
		return -EINVAL;
		return -EINVAL;
	}
	}


	print_client_buffer(CVP_DBG, "unregister", inst, buf);

	if (!buf->index) {
	if (!buf->index) {
		dprintk(CVP_INFO,
			"%s CPU path unregister buffer is deprecated!\n",
			__func__);
		return 0;
		return 0;
	}
	}


@@ -1483,6 +1729,8 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst)
	int rc = 0;
	int rc = 0;
	struct cvp_hal_session *session;
	struct cvp_hal_session *session;
	struct msm_cvp_internal_buffer *cbuf, *dummy;
	struct msm_cvp_internal_buffer *cbuf, *dummy;
	struct msm_cvp_frame *frame, *dummy1;
	struct msm_cvp_frame_buf *frame_buf, *dummy2;


	if (!inst || !inst->core) {
	if (!inst || !inst->core) {
		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
@@ -1516,6 +1764,7 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst)
				inst, &cbuf->buf);
				inst, &cbuf->buf);
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
		list_del(&cbuf->list);
		list_del(&cbuf->list);
		kmem_cache_free(inst->internal_buf_cache, cbuf);
	}
	}
	mutex_unlock(&inst->cvpcpubufs.lock);
	mutex_unlock(&inst->cvpcpubufs.lock);


@@ -1535,9 +1784,33 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst)


		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
		msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem);
		list_del(&cbuf->list);
		list_del(&cbuf->list);
		kmem_cache_free(inst->internal_buf_cache, cbuf);
	}
	}
	mutex_unlock(&inst->cvpdspbufs.lock);
	mutex_unlock(&inst->cvpdspbufs.lock);


	mutex_lock(&inst->frames.lock);
	list_for_each_entry_safe(frame, dummy1, &inst->frames.list, list) {
		list_del(&frame->list);
		mutex_lock(&frame->bufs.lock);
		list_for_each_entry_safe(frame_buf, dummy2, &frame->bufs.list,
									list) {
			struct cvp_buf_type *buf = &frame_buf->buf;

			dprintk(CVP_ERR,
				"%s: %x : fd %d off %d size %d flags 0x%x\n",
				"remove from frame list",
				hash32_ptr(inst->session),
				buf->fd, buf->offset, buf->size, buf->flags);

			list_del(&frame_buf->list);
			kmem_cache_free(inst->frame_buf_cache, frame_buf);
		}
		mutex_unlock(&frame->bufs.lock);
		DEINIT_MSM_CVP_LIST(&frame->bufs);
		kmem_cache_free(inst->frame_cache, frame);
	}
	mutex_unlock(&inst->frames.lock);

	msm_cvp_comm_free_freq_table(inst);
	msm_cvp_comm_free_freq_table(inst);


	return rc;
	return rc;
+16 −0
Original line number Original line Diff line number Diff line
@@ -296,6 +296,8 @@ void *msm_cvp_open(int core_id, int session_type)
	INIT_MSM_CVP_LIST(&inst->persistbufs);
	INIT_MSM_CVP_LIST(&inst->persistbufs);
	INIT_MSM_CVP_LIST(&inst->cvpcpubufs);
	INIT_MSM_CVP_LIST(&inst->cvpcpubufs);
	INIT_MSM_CVP_LIST(&inst->cvpdspbufs);
	INIT_MSM_CVP_LIST(&inst->cvpdspbufs);
	INIT_MSM_CVP_LIST(&inst->frames);

	init_waitqueue_head(&inst->event_handler.wq);
	init_waitqueue_head(&inst->event_handler.wq);


	kref_init(&inst->kref);
	kref_init(&inst->kref);
@@ -311,6 +313,9 @@ void *msm_cvp_open(int core_id, int session_type)
	inst->clk_data.core_id = CVP_CORE_ID_DEFAULT;
	inst->clk_data.core_id = CVP_CORE_ID_DEFAULT;
	inst->deprecate_bitmask = 0;
	inst->deprecate_bitmask = 0;
	inst->fence_data_cache = KMEM_CACHE(msm_cvp_fence_thread_data, 0);
	inst->fence_data_cache = KMEM_CACHE(msm_cvp_fence_thread_data, 0);
	inst->frame_cache = KMEM_CACHE(msm_cvp_frame, 0);
	inst->frame_buf_cache = KMEM_CACHE(msm_cvp_frame_buf, 0);
	inst->internal_buf_cache = KMEM_CACHE(msm_cvp_internal_buffer, 0);


	for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
	for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
		i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
		i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
@@ -362,7 +367,13 @@ void *msm_cvp_open(int core_id, int session_type)
	DEINIT_MSM_CVP_LIST(&inst->cvpcpubufs);
	DEINIT_MSM_CVP_LIST(&inst->cvpcpubufs);
	DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
	DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
	DEINIT_MSM_CVP_LIST(&inst->freqs);
	DEINIT_MSM_CVP_LIST(&inst->freqs);
	DEINIT_MSM_CVP_LIST(&inst->frames);

	kmem_cache_destroy(inst->fence_data_cache);
	kmem_cache_destroy(inst->fence_data_cache);
	kmem_cache_destroy(inst->frame_cache);
	kmem_cache_destroy(inst->frame_buf_cache);
	kmem_cache_destroy(inst->internal_buf_cache);

	kfree(inst);
	kfree(inst);
	inst = NULL;
	inst = NULL;
err_invalid_core:
err_invalid_core:
@@ -405,7 +416,12 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst)
	DEINIT_MSM_CVP_LIST(&inst->cvpcpubufs);
	DEINIT_MSM_CVP_LIST(&inst->cvpcpubufs);
	DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
	DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
	DEINIT_MSM_CVP_LIST(&inst->freqs);
	DEINIT_MSM_CVP_LIST(&inst->freqs);
	DEINIT_MSM_CVP_LIST(&inst->frames);

	kmem_cache_destroy(inst->fence_data_cache);
	kmem_cache_destroy(inst->fence_data_cache);
	kmem_cache_destroy(inst->frame_cache);
	kmem_cache_destroy(inst->frame_buf_cache);
	kmem_cache_destroy(inst->internal_buf_cache);


	mutex_destroy(&inst->sync_lock);
	mutex_destroy(&inst->sync_lock);
	mutex_destroy(&inst->lock);
	mutex_destroy(&inst->lock);
+14 −7
Original line number Original line Diff line number Diff line
@@ -34,7 +34,11 @@ struct cvp_dsp_cmd_msg {
	uint32_t buff_size;
	uint32_t buff_size;
	uint32_t session_id;
	uint32_t session_id;
	int32_t ddr_type;
	int32_t ddr_type;
	uint32_t reserved[CVP_DSP_MAX_RESERVED];
	uint32_t buff_fd;
	uint32_t buff_offset;
	uint32_t reserved0;
	uint32_t reserved1;
	uint32_t reserved2;
};
};


struct cvp_dsp_rsp_msg {
struct cvp_dsp_rsp_msg {
@@ -336,19 +340,22 @@ int cvp_dsp_shutdown(uint32_t session_flag)
	return err;
	return err;
}
}


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


	local_cmd_msg.cmd_msg_type = CVP_DSP_REGISTER_BUFFER;
	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;
	local_cmd_msg.session_id = session_id;
	local_cmd_msg.buff_fd = buff_fd;
	local_cmd_msg.buff_size = buff_size;
	local_cmd_msg.buff_offset = buff_offset;
	local_cmd_msg.buff_index = buff_index;
	local_cmd_msg.iova_buff_addr = iova_buff_addr;

	dprintk(CVP_DBG,
	dprintk(CVP_DBG,
		"%s: cmd_msg_type=0x%x, iova_buff_addr=0x%x buff_index=0x%x\n",
		"%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,
		__func__, local_cmd_msg.cmd_msg_type, iova_buff_addr,
+8 −6
Original line number Original line Diff line number Diff line
@@ -55,14 +55,16 @@ int cvp_dsp_shutdown(uint32_t session_flag);
/*
/*
 * API to register iova buffer address with CDSP
 * 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
 * @session_id:     cvp session id
 * @buff_fd:        buffer fd
 * @buff_size:      size in bytes of cvp buffer
 * @buff_offset:    buffer offset
 * @buff_index:     buffer index
 * @iova_buff_addr: IOVA buffer address
 */
 */
int cvp_dsp_register_buffer(uint32_t iova_buff_addr,
int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd,
	uint32_t buff_index, uint32_t buff_size,
			uint32_t buff_size, uint32_t buff_offset,
	uint32_t session_id);
			uint32_t buff_index, uint32_t iova_buff_addr);


/*
/*
 * API to de-register iova buffer address from CDSP
 * API to de-register iova buffer address from CDSP
Loading