// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * Copyright (c) 2021 MediaTek Inc.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/uuid.h>
#include <linux/tee_drv.h>
#include <linux/slab.h>
#include <utpa2_Types.h>
#include <utpa2_DMX.h>
#include <linux/delay.h>

#include "mtk_iommu_dtv_api.h"

#include "mtk_dmx_common.h"
#include "mtk_dmx_log.h"
#include "mtk_dmx_riu.h"
#include "mtk_dmx_rm.h"
#include "mtk_dmx_tee_if.h"
#include "mtk_dmx_tee_comm.h"
#include "mtk_dmx_pvr.h"

#define DMX_TA_UUID				UUID_INIT(0x7a7c8b61, 0x5d74, 0x4b6c, \
								0xb2, 0xa9, 0x92, 0xe4, \
								0x9c, 0xe8, 0x66, 0xbd)

#define REC_TA_UUID				UUID_INIT(0x4e501575, 0xee69, 0x4eee, \
								0x94, 0xe1, 0x26, 0xb9, \
								0xed, 0x96, 0xc8, 0x5a)

#define PVR_NUM						4
#define PLAY_TA_UUID			UUID_INIT(0x48645567, 0x9cc5, 0x4c44, \
								0x80, 0x1c, 0x75, 0x84, \
								0xff, 0xf2, 0xc6, 0x3b)

#define DMX_ADDR_SHIFT				32
#define BITS_PER_U32				(sizeof(u32) * 8)

#define TEE_COMMON_ARG_LENGTH			16
#define TZ_CACHE_LINE_SIZE			64
#define TZ_CACHE_LINE_SIZE_MSK	(TZ_CACHE_LINE_SIZE - 1)
#define TZ_CACHE_ALIGN(x)		(((x) + TZ_CACHE_LINE_SIZE_MSK) & ~TZ_CACHE_LINE_SIZE_MSK)

#define IS_TLV_FORMAT(fmt)	((fmt) == AESDMA_DATA_FORMAT_TLV)



typedef enum {
	DMX_TA_CMD_NULL,
	DMX_TA_CMD_LOAD_FW,
	DMX_TA_CMD_SET_VQ_BUF,
	DMX_TA_CMD_SET_PVR_BUF,
	DMX_TA_CMD_SET_FILEIN_BUF,
	DMX_TA_CMD_GET_PVR_WPTR,
	DMX_TA_CMD_SET_MMFI_BUF,
	DMX_TA_CMD_SET_PVR_SRC,
	DMX_TA_CMD_BIND_PIPEID,
	DMX_TA_CMD_GET_PIPEID,
} dmx_ta_cmd_type_t;

typedef enum {
	DMX_TA_PIPE_TSPFW	= 0x00000001,
	DMX_TA_PIPE_TSPVQ	= 0x00000002,
	DMX_TA_PIPE_PVR0	= 0x80000000,
	DMX_TA_PIPE_PVR1	= 0x80000001,
	DMX_TA_PIPE_PVR2	= 0x80000002,
	DMX_TA_PIPE_PVR3	= 0x80000003,
	DMX_TA_PIPE_FILE0	= 0x40000000,
	DMX_TA_PIPE_FILE1	= 0x40000001,
	DMX_TA_PIPE_FILE2	= 0x40000002,
	DMX_TA_PIPE_MMFI0	= 0x41000000,
	DMX_TA_PIPE_MMFI1	= 0x41000001,
	DMX_TA_PIPE_NULL	= 0xFFFFFFFF
} dmx_ta_pipe_type_t;

typedef enum {
	REC_TA_CMD_GET_PIPELINE_ID,
	REC_TA_CMD_CONFIGURE,
	REC_TA_CMD_OPERATE,
	REC_TA_CMD_RELEASE
} rec_ta_cmd_type_t;

typedef union fixed_size_pointer {
	void *ptr;
	u32 val;
	u64 sizer;
} fixed_size_pointer;

typedef struct {
	u32 ui4Command;
	fixed_size_pointer apvArgument[TEE_COMMON_ARG_LENGTH];
	u32 ui4Length[TEE_COMMON_ARG_LENGTH];
	bool abWrite[TEE_COMMON_ARG_LENGTH];
	u8 ui1Size;
} TEE_COMMON_ARG_T;

struct dmx_tee_context {
	bool dmx_inited;
	bool rec_inited;
	bool play_inited;
	u32 dmx_ta_session_id;
	u32 rec_ta_session_id;
	struct pvr_encrypt_config encrypt_cfg[PVR_NUM];
	u32 play_ta_session_id;
};

static DECLARE_RWSEM(tee_rwsem);
static struct dmx_tee_context dmx_tee_ctx;

static inline bool _is_dmx_ta_tee_ctx_inited(void)
{
	bool ret;

	down_read(&tee_rwsem);
	ret = dmx_tee_ctx.dmx_inited;
	up_read(&tee_rwsem);
	return ret;
}

static inline bool _is_rec_ta_tee_ctx_inited(void)
{
	bool ret;

	down_read(&tee_rwsem);
	ret = dmx_tee_ctx.rec_inited;
	up_read(&tee_rwsem);
	return ret;
}

static inline bool _is_play_ta_tee_ctx_inited(void)
{
	bool ret;

	down_read(&tee_rwsem);
	ret = dmx_tee_ctx.play_inited;
	up_read(&tee_rwsem);
	return ret;
}

static inline u32 _dmx_tee_get_dmx_ta_session_id(void)
{
	u32 session_id;

	down_read(&tee_rwsem);
	session_id = dmx_tee_ctx.dmx_ta_session_id;
	up_read(&tee_rwsem);
	return session_id;
}

static inline u32 _dmx_tee_get_rec_ta_session_id(void)
{
	u32 session_id;

	down_read(&tee_rwsem);
	session_id = dmx_tee_ctx.rec_ta_session_id;
	up_read(&tee_rwsem);
	return session_id;
}

static int _dmx_tee_set_pvr_encrypt_config(int pvr_eng_id, struct pvr_encrypt_config *cfg)
{
	size_t size = offsetof(struct pvr_encrypt_config, pid_num);

	if (pvr_eng_id >= PVR_NUM) {
		MTK_DMX_ERR("eng id out-of-range\n");
		return -EINVAL;
	}

	down_write(&tee_rwsem);
	memcpy(&dmx_tee_ctx.encrypt_cfg[pvr_eng_id], cfg, size);
	up_write(&tee_rwsem);

	return 0;
}

static int _dmx_tee_get_pvr_encrypt_config(int pvr_eng_id, struct pvr_encrypt_config *cfg)
{
	size_t size = offsetof(struct pvr_encrypt_config, pid_num);

	if (pvr_eng_id >= PVR_NUM) {
		MTK_DMX_ERR("eng id out-of-range\n");
		return -EINVAL;
	}

	down_read(&tee_rwsem);
	memcpy(cfg, &dmx_tee_ctx.encrypt_cfg[pvr_eng_id], size);
	up_read(&tee_rwsem);

	return 0;
}

static inline u32 _dmx_tee_get_play_ta_session_id(void)
{
	u32 session_id;
	int ret;

	down_read(&tee_rwsem);
	if (dmx_tee_ctx.play_ta_session_id == 0) {
		ret = mtk_dmx_tee_cmd_open_session(&dmx_tee_ctx.play_ta_session_id, PLAY_TA_UUID);
		if (ret < 0) {
			MTK_DMX_ERR("open playta session fail\n");
			return 0;
		}
	}

	session_id = dmx_tee_ctx.play_ta_session_id;

	up_read(&tee_rwsem);
	return session_id;
}

static int _dmx_ta_tee_init_context(void)
{
	int ret = 0;

	if (dmx_tee_ctx.dmx_ta_session_id != 0)
		return 0;

	down_write(&tee_rwsem);

	ret = mtk_dmx_tee_cmd_open_ctx();
	if (ret < 0) {
		MTK_DMX_ERR("open tee ctx fail\n");
		goto FAIL;
	}

	ret = mtk_dmx_tee_cmd_open_session(&dmx_tee_ctx.dmx_ta_session_id, DMX_TA_UUID);
	if (ret < 0) {
		MTK_DMX_ERR("open dmxta session fail\n");
		goto FAIL;
	}

	dmx_tee_ctx.dmx_inited = true;
	up_write(&tee_rwsem);

	MTK_DMX_DEBUG("dmx tee init ctx\n");
	return 0;

FAIL:
	up_write(&tee_rwsem);
	return -EFAULT;
}

static int _rec_ta_tee_init_context(void)
{
	int ret = 0;

	if (dmx_tee_ctx.rec_ta_session_id != 0)
		return 0;

	down_write(&tee_rwsem);

	ret = mtk_dmx_tee_cmd_open_ctx();
	if (ret < 0) {
		MTK_DMX_ERR("open tee ctx fail\n");
		goto FAIL;
	}


	ret = mtk_dmx_tee_cmd_open_session(&dmx_tee_ctx.rec_ta_session_id, REC_TA_UUID);
	if (ret < 0) {
		MTK_DMX_ERR("open recta session fail\n");
		goto FAIL;
	}

	dmx_tee_ctx.rec_inited = true;
	up_write(&tee_rwsem);

	MTK_DMX_DEBUG("dmx tee init ctx\n");
	return 0;

FAIL:
	up_write(&tee_rwsem);
	return -EFAULT;
}

static int _play_ta_tee_init_context(void)
{
	int ret = 0;

	if (dmx_tee_ctx.play_ta_session_id != 0)
		return 0;

	down_write(&tee_rwsem);

	ret = mtk_dmx_tee_cmd_open_ctx();
	if (ret < 0) {
		MTK_DMX_ERR("open tee ctx fail\n");
		goto FAIL;
	}

	ret = mtk_dmx_tee_cmd_open_session(&dmx_tee_ctx.play_ta_session_id, PLAY_TA_UUID);
	if (ret < 0) {
		MTK_DMX_ERR("open playta session fail\n");
		goto FAIL;
	}

	dmx_tee_ctx.play_inited = true;
	up_write(&tee_rwsem);

	MTK_DMX_DEBUG("dmx tee init ctx\n");
	return 0;

FAIL:
	up_write(&tee_rwsem);
	return -EFAULT;
}



static int __attribute__((unused)) _dmx_tee_exit_context(void)
{
	int ret;

	down_write(&tee_rwsem);

	if (dmx_tee_ctx.play_ta_session_id != 0) {
		ret = mtk_dmx_tee_cmd_close_session(dmx_tee_ctx.play_ta_session_id);
		if (ret < 0) {
			MTK_DMX_ERR("close play ta session fail\n");
			goto FAIL;
		}
		dmx_tee_ctx.play_inited = false;
	}

	if (dmx_tee_ctx.rec_ta_session_id != 0) {
		ret = mtk_dmx_tee_cmd_close_session(dmx_tee_ctx.rec_ta_session_id);
		if (ret < 0) {
			MTK_DMX_ERR("close rec ta session fail\n");
			goto FAIL;
		}
		dmx_tee_ctx.rec_inited = false;

	}

	if (dmx_tee_ctx.dmx_ta_session_id != 0) {
		ret = mtk_dmx_tee_cmd_close_session(dmx_tee_ctx.dmx_ta_session_id);
		if (ret < 0) {
			MTK_DMX_ERR("close dmx ta session fail\n");
			goto FAIL;
		}
		dmx_tee_ctx.dmx_inited = false;
	}

	ret = mtk_dmx_tee_cmd_close_ctx();
	if (ret < 0) {
		MTK_DMX_ERR("close tee ctx fail\n");
		goto FAIL;
	}

	up_write(&tee_rwsem);
	return 0;

FAIL:
	up_write(&tee_rwsem);
	return -EFAULT;
}

int mtk_dmx_tee_if_load_fw(void)
{
	int ret;
	u32 dmx_ta_session_id;
	DMX_TEE_BUF_Param dmx_ta_param;

	if (!_is_dmx_ta_tee_ctx_inited())
		_dmx_ta_tee_init_context();

	dmx_ta_session_id = _dmx_tee_get_dmx_ta_session_id();
	if (!dmx_ta_session_id) {
		MTK_DMX_ERR("dmx ta session id invalid\n");
		return -EFAULT;
	}

	memset(&dmx_ta_param, 0, sizeof(dmx_ta_param));
	ret = mtk_dmx_tee_cmd_invoke_cmd(
		dmx_ta_session_id,
		DMX_TA_CMD_LOAD_FW,
		&dmx_ta_param,
		sizeof(dmx_ta_param));
	if (ret < 0) {
		MTK_DMX_ERR("load tsp fw fail\n");
		return -EFAULT;
	}

	return 0;
}

int mtk_dmx_tee_if_set_vq(void)
{
	int ret;
	u32 dmx_ta_session_id;
	DMX_TEE_BUF_Param dmx_ta_param;

	if (!_is_dmx_ta_tee_ctx_inited())
		_dmx_ta_tee_init_context();

	dmx_ta_session_id = _dmx_tee_get_dmx_ta_session_id();
	if (!dmx_ta_session_id) {
		MTK_DMX_ERR("dmx ta session id invalid\n");
		return -EFAULT;
	}

	memset(&dmx_ta_param, 0, sizeof(dmx_ta_param));
	ret = mtk_dmx_tee_cmd_invoke_cmd(
		dmx_ta_session_id,
		DMX_TA_CMD_SET_VQ_BUF,
		&dmx_ta_param,
		sizeof(dmx_ta_param));
	if (ret < 0) {
		MTK_DMX_ERR("set vq buffer fail\n");
		return -EFAULT;
	}

	return 0;
}

int mtk_dmx_tee_if_lock_pvr_buffer(int pvr_eng_id, u32 pipeline_id, struct mem_info *pvr_buffer)
{
	int ret;
	u32 dmx_ta_session_id;
	DMX_TEE_BUF_Param dmx_ta_param;
	if (!_is_dmx_ta_tee_ctx_inited())
		_dmx_ta_tee_init_context();

	dmx_ta_session_id = _dmx_tee_get_dmx_ta_session_id();
	if (!dmx_ta_session_id) {
		MTK_DMX_ERR("dmx ta session id invalid\n");
		return -EFAULT;
	}

	memset(&dmx_ta_param, 0, sizeof(dmx_ta_param));
	dmx_ta_param.u32PipelineId = (MS_U32)pipeline_id;

	dmx_ta_param.u32PipeId = DMX_TA_PIPE_PVR0 + pvr_eng_id;
	ret = mtk_dmx_tee_cmd_invoke_cmd(
		dmx_ta_session_id,
		DMX_TA_CMD_BIND_PIPEID,
		&dmx_ta_param,
		sizeof(dmx_ta_param));
	if (ret < 0) {
		MTK_DMX_ERR("bind pipeline id fail\n");
		return -EFAULT;
	}

	MTK_DMX_INFO("[PVR][auth] eng id %d. paddr %llx, size %x\n",
		pvr_eng_id, pvr_buffer->paddr, pvr_buffer->size);

	ret = mtkd_iommu_buffer_authorize(
		PVR_BUF_ID,
		pvr_buffer->paddr,
		pvr_buffer->size,
		pipeline_id);

	if (ret < 0) {
		MTK_DMX_ERR("authorize buffer fail\n");
		return -EFAULT;
	}

	memset(&dmx_ta_param, 0, sizeof(dmx_ta_param));
	dmx_ta_param.u32EngId = pvr_eng_id;
	dmx_ta_param.u32Opt = 0;
	dmx_ta_param.u32BufAddr = (MS_U32)pvr_buffer->paddr;
	dmx_ta_param.u32BufAddr_H = (MS_U32)(pvr_buffer->paddr >> DMX_ADDR_SHIFT);
	dmx_ta_param.u32BufSize = pvr_buffer->size;
	ret = mtk_dmx_tee_cmd_invoke_cmd(
		dmx_ta_session_id,
		DMX_TA_CMD_SET_PVR_BUF,
		&dmx_ta_param,
		sizeof(dmx_ta_param));
	if (ret < 0) {
		MTK_DMX_ERR("set pvr buffer fail\n");
		return -EFAULT;
	}

	return 0;
}

int mtk_dmx_tee_if_unlock_pvr_buffer(int pvr_eng_id, struct mem_info *pvr_buffer)
{
	int ret;

	MTK_DMX_INFO("[PVR][unauth] eng id %d. paddr %llx, size %x\n",
		pvr_eng_id, pvr_buffer->paddr, pvr_buffer->size);
	if (!pvr_buffer->paddr) {
		MTK_DMX_INFO("pvr buffer addr is null, no unauthorize buffer\n");
		return 0;
	}
	ret = mtkd_iommu_buffer_unauthorize(pvr_buffer->paddr);
	if (ret < 0) {
		MTK_DMX_ERR("un-authorize buffer fail\n");
		return -EFAULT;
	}

	return 0;
}

int mtk_dmx_tee_if_pvr_encrypt_config(int pvr_eng_id, struct pvr_encrypt_config *cfg)
{
	int ret;
	u32 rec_ta_session_id;
	u8 index = 0;
	size_t len;
	TEE_COMMON_ARG_T *rec_ta_param;
	u64 keyToken = cfg->key_token;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));

	if (!_is_rec_ta_tee_ctx_inited())
		_rec_ta_tee_init_context();

	rec_ta_session_id = _dmx_tee_get_rec_ta_session_id();
	if (!rec_ta_session_id) {
		MTK_DMX_ERR("rec ta session id invalid\n");
		return -EFAULT;
	}

	if (cfg->pid_num >= PID_INFO_MAX_NUM) {
		MTK_DMX_ERR("pid num out-of-range\n");
		return -EFAULT;
	}

	len = cfg->pid_num * sizeof(struct pvr_pid_info);

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// keytoken
	serialized_buf_size += TZ_CACHE_ALIGN(len);		// pid info

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	rec_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u32);
	rec_ta_param->abWrite[index] = 1;
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	index++;

	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &keyToken, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	rec_ta_param->apvArgument[index].val = cfg->format;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	rec_ta_param->apvArgument[index].val = cfg->type;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	rec_ta_param->apvArgument[index].val = cfg->pid_num;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = len;
	rec_ta_param->abWrite[index] = 1;
	memcpy(rec_ta_param->apvArgument[index].ptr, cfg->pid_info, len);
	index++;

	rec_ta_param->ui4Command = REC_TA_CMD_CONFIGURE;
	rec_ta_param->ui1Size = index;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		rec_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);
	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail\n");
		kfree(serialized_buf);
		return -EFAULT;
	}

	kfree(serialized_buf);

	_dmx_tee_set_pvr_encrypt_config(pvr_eng_id, cfg);

	return 0;
}

int mtk_dmx_tee_if_pvr_tlv_encrypt_buffer(int pvr_eng_id, struct pvr_encrypt_param *param)
{
	int ret;
	u32 rec_ta_session_id;
	u8 index = 0, index_job_done = 0;
	size_t len, meta_size;
	void *metadata;
	struct pvr_encrypt_config cfg;
	TEE_COMMON_ARG_T *rec_ta_param;
	u64 keyToken = param->key_token;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	struct pvr_tlv_metadata *metadata_ptr;
	bool bIsPrevDone = 0;
	u32 counter = 0;
	u32 *result = NULL;

	if (param->index_num > PVR_METADATA_MAX_NUM) {
		MTK_DMX_ERR("Max index number is %u\n", PVR_METADATA_MAX_NUM);
		return -EFAULT;
	}

	if (!_is_rec_ta_tee_ctx_inited())
		_rec_ta_tee_init_context();

	rec_ta_session_id = _dmx_tee_get_rec_ta_session_id();
	if (!rec_ta_session_id) {
		MTK_DMX_ERR("rec ta session id invalid\n");
		return -EFAULT;
	}

	memset(&cfg, 0, sizeof(struct pvr_encrypt_config));
	_dmx_tee_get_pvr_encrypt_config(pvr_eng_id, &cfg);

	meta_size = (IS_TLV_FORMAT(cfg.format)) ?
		sizeof(struct pvr_tlv_metadata) : sizeof(struct pvr_ts_metadata);
	len = PVR_METADATA_MAX_NUM * meta_size;

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// keytoken
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// src addr
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// dst addr
	serialized_buf_size += TZ_CACHE_ALIGN(len);			// pvr metadata
	if (IS_TLV_FORMAT(cfg.format)) {
		serialized_buf_size += TZ_CACHE_ALIGN(sizeof(bool));// is prev finish
		serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// pvr start addr
		serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// end addr
	}
	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	rec_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	// result
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u32);
	rec_ta_param->abWrite[index] = 1;
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	result = (u32 *)rec_ta_param->apvArgument[index].ptr;
	index++;

	// keytoken
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &keyToken, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// src addr
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &param->src_addr, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// dst addr
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &param->dst_addr, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// pvr metadata
	rec_ta_param->apvArgument[index].val = param->size;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = len;
	rec_ta_param->abWrite[index] = 1;
	//memset(rec_ta_param->apvArgument[index].ptr, 0, len);
	metadata = rec_ta_param->apvArgument[index].ptr;
	index++;

	serialized_buf_offset += TZ_CACHE_ALIGN(len);

	// prev Job done
	index_job_done = index;
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(bool);
	rec_ta_param->abWrite[index] = 1;
	memcpy(rec_ta_param->apvArgument[index].ptr, &bIsPrevDone, sizeof(bool));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(bool));
	index++;

	// pvr start addr
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &param->start_addr, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// pvr end addr
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &param->end_addr, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// buffer size
	rec_ta_param->apvArgument[index].val = param->buf_size;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	// last block flag
	rec_ta_param->apvArgument[index].val = param->flag;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	metadata_ptr = (struct pvr_tlv_metadata *)(param->metadata);
	memcpy(metadata, param->metadata, sizeof(struct pvr_tlv_metadata));
	MTK_DMX_DEBUG("set input parameter mask:%x addr:%llx size:%llx\n",
		metadata_ptr->mask, metadata_ptr->buf_addr, metadata_ptr->buf_size);

	rec_ta_param->ui4Command = REC_TA_CMD_OPERATE;
	rec_ta_param->ui1Size = index;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		rec_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail\n");
		kfree(serialized_buf);
		return -EFAULT;
	}


	bIsPrevDone = *(bool*)rec_ta_param->apvArgument[index_job_done].ptr;
	MTK_DMX_INFO("bIsPrevDone = %d, index_job_done = %d\n", bIsPrevDone, index_job_done);

	while (bIsPrevDone != true) {
		msleep(ASYNC_WAIT_ENCRYPT);
		ret = mtk_dmx_tee_cmd_invoke_cmd(
			rec_ta_session_id,
			0,
			serialized_buf,
			serialized_buf_size);

		if (ret < 0) {
			MTK_DMX_ERR("invoke cmd fail\n");
			kfree(serialized_buf);
			return -EFAULT;
		}

		if (result != NULL && *result) {
			MTK_DMX_ERR("Invoke cmd for query job done failed, ret: %d\n", *result);
			kfree(serialized_buf);
			return -EFAULT;
		}

		bIsPrevDone = *(bool*)rec_ta_param->apvArgument[index_job_done].ptr;
		counter++;
		MTK_DMX_INFO("bIsPrevDone = %d, index_job_done = %d counter:%d\n",
					bIsPrevDone, index_job_done, counter);
		if (counter > ASYNC_WAIT_ENCRYPT_TIMEOUT) {
			MTK_DMX_ERR("bIsPrevDone = %d, index_job_done = %d counter:%d timeout\n",
				bIsPrevDone, index_job_done, counter);
			counter = 0;
		}
	}

	memcpy(param->metadata, metadata, param->index_num * meta_size);

	kfree(serialized_buf);

	return 0;
}

int mtk_dmx_tee_if_pvr_ts_encrypt_buffer(int pvr_eng_id, struct pvr_encrypt_param *param)
{
	int ret;
	u32 rec_ta_session_id;
	u8 index = 0;
	size_t len, meta_size;
	void *metadata;
	struct pvr_encrypt_config cfg;
	TEE_COMMON_ARG_T *rec_ta_param;
	u64 keyToken = param->key_token;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));

	if (param->index_num > PVR_METADATA_MAX_NUM) {
		MTK_DMX_ERR("Max index number is %u\n", PVR_METADATA_MAX_NUM);
		return -EFAULT;
	}

	if (!_is_rec_ta_tee_ctx_inited())
		_rec_ta_tee_init_context();

	rec_ta_session_id = _dmx_tee_get_rec_ta_session_id();
	if (!rec_ta_session_id) {
		MTK_DMX_ERR("rec ta session id invalid\n");
		return -EFAULT;
	}

	memset(&cfg, 0, sizeof(struct pvr_encrypt_config));
	_dmx_tee_get_pvr_encrypt_config(pvr_eng_id, &cfg);

	meta_size = (IS_TLV_FORMAT(cfg.format)) ?
		sizeof(struct pvr_tlv_metadata) : sizeof(struct pvr_ts_metadata);
	len = PVR_METADATA_MAX_NUM * meta_size;

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// keytoken
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// src addr
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// dst addr
	serialized_buf_size += TZ_CACHE_ALIGN(len);		// pvr metadata

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	rec_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	// result
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u32);
	rec_ta_param->abWrite[index] = 1;
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	index++;

	// keytoken
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &keyToken, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// src addr
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &param->src_addr, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// dst addr
	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &param->dst_addr, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	// pvr metadata
	rec_ta_param->apvArgument[index].val = param->size;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = len;
	rec_ta_param->abWrite[index] = 1;
	//memset(rec_ta_param->apvArgument[index].ptr, 0, len);
	metadata = rec_ta_param->apvArgument[index].ptr;
	index++;

	// pause record flag
	rec_ta_param->apvArgument[index].val = param->flag;
	rec_ta_param->ui4Length[index] = 0;
	rec_ta_param->abWrite[index] = 0;
	index++;

	rec_ta_param->ui4Command = REC_TA_CMD_OPERATE;
	rec_ta_param->ui1Size = index;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		rec_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail\n");
		kfree(serialized_buf);
		return -EFAULT;
	}

	memcpy(param->metadata, metadata, param->index_num * meta_size);

	kfree(serialized_buf);

	return 0;
}

int mtk_dmx_tee_if_pvr_release(int pvr_eng_id, struct pvr_encrypt_param *param)
{
	int ret;
	u32 rec_ta_session_id;
	u8 index = 0;
	TEE_COMMON_ARG_T *rec_ta_param;
	u64 keyToken = param->key_token;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));

	if (!_is_rec_ta_tee_ctx_inited())
		_rec_ta_tee_init_context();

	rec_ta_session_id = _dmx_tee_get_rec_ta_session_id();
	if (!rec_ta_session_id) {
		MTK_DMX_ERR("rec ta session id invalid\n");
		return -EFAULT;
	}

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// keytoken

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	rec_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u32);
	rec_ta_param->abWrite[index] = 1;
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	index++;

	rec_ta_param->apvArgument[index].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	rec_ta_param->ui4Length[index] = sizeof(u64);
	rec_ta_param->abWrite[index] = 0;
	memcpy(rec_ta_param->apvArgument[index].ptr, &keyToken, sizeof(u64));
	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	index++;

	rec_ta_param->ui4Command = REC_TA_CMD_RELEASE;
	rec_ta_param->ui1Size = index;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		rec_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);
	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail\n");
		kfree(serialized_buf);
		return -EFAULT;
	}

	kfree(serialized_buf);

	return 0;
}


int mtk_dmx_tee_if_play_lock_buffer(int eng_id, u32 pipeline_id, struct mem_info *filein_buffer)
{
	int ret;
	u32 dmx_ta_session_id;
	DMX_TEE_BUF_Param dmx_ta_param;

	if (!_is_dmx_ta_tee_ctx_inited())
		_dmx_ta_tee_init_context();

	dmx_ta_session_id = _dmx_tee_get_dmx_ta_session_id();
	if (!dmx_ta_session_id) {
		MTK_DMX_ERR("dmx ta session id invalid\n");
		return -EFAULT;
	}

	memset(&dmx_ta_param, 0, sizeof(dmx_ta_param));
	dmx_ta_param.u32PipelineId = (MS_U32)pipeline_id;
	if (eng_id == 0)
		dmx_ta_param.u32PipeId = DMX_TA_PIPE_FILE0 + eng_id;
	else
		dmx_ta_param.u32PipeId = DMX_TA_PIPE_MMFI0 + (eng_id - 1);
	ret = mtk_dmx_tee_cmd_invoke_cmd(
		dmx_ta_session_id,
		DMX_TA_CMD_BIND_PIPEID,
		&dmx_ta_param,
		sizeof(dmx_ta_param));
	if (ret < 0) {
		MTK_DMX_ERR("bind pipeline id fail\n");
		return -EFAULT;
	}

	MTK_DMX_INFO("[FILEIN][auth] eng id %d. paddr %llx, size %x, pipeline: %x\n",
		eng_id, filein_buffer->paddr, filein_buffer->size, pipeline_id);

	ret = mtkd_iommu_buffer_authorize(
		MMFI_BUF_ID,
		filein_buffer->paddr,
		filein_buffer->size,
		pipeline_id);
	if (ret < 0) {
		MTK_DMX_ERR("authorize buffer fail\n");
		return -EFAULT;
	}

	ret = mtk_dmx_tee_if_play_set_buffer(eng_id, filein_buffer->paddr, filein_buffer->size);
	if (ret < 0) {
		MTK_DMX_ERR("set filein buffer fail\n");
		return -EFAULT;
	}

	return 0;
}

int mtk_dmx_tee_if_play_unlock_buffer(int eng_id, struct mem_info *filein_buffer)
{
	int ret = 0;

	MTK_DMX_INFO("[FILEIN][unauth] eng id %d. paddr %llx, size %x\n",
		eng_id, filein_buffer->paddr, filein_buffer->size);

	if (!filein_buffer->paddr) {
		MTK_DMX_INFO("filein buffer addr is null, no unauthorize buffer\n");
		return 0;
	}
	ret = mtkd_iommu_buffer_unauthorize(filein_buffer->paddr);
	if (ret < 0) {
		MTK_DMX_ERR("un-authorize buffer fail\n");
		return -EFAULT;
	}

	return 0;
}

int mtk_dmx_tee_if_play_set_buffer(int eng_id, u64 srcPA, u32 size)
{
	int ret;
	u32 dmx_ta_session_id;
	DMX_TEE_BUF_Param dmx_ta_param;
	int cmd = DMX_TA_CMD_SET_FILEIN_BUF;
	int eng_id_set = eng_id;

	if (!_is_dmx_ta_tee_ctx_inited())
		_dmx_ta_tee_init_context();

	dmx_ta_session_id = _dmx_tee_get_dmx_ta_session_id();
	if (!dmx_ta_session_id) {
		MTK_DMX_ERR("dmx ta session id invalid\n");
		return -EFAULT;
	}

	if (eng_id > 0) {
		eng_id_set = eng_id - 1;
		cmd = DMX_TA_CMD_SET_MMFI_BUF;
	}

	// set addr and size
	memset(&dmx_ta_param, 0, sizeof(dmx_ta_param));
	dmx_ta_param.u32EngId = eng_id_set;
	dmx_ta_param.u32Opt = 0;
	dmx_ta_param.u32BufAddr = (MS_U32)srcPA;
	dmx_ta_param.u32BufAddr_H = (MS_U32)(srcPA >> DMX_ADDR_SHIFT);
	dmx_ta_param.u32BufSize = size;
	ret = mtk_dmx_tee_cmd_invoke_cmd(
		dmx_ta_session_id,
		cmd,
		&dmx_ta_param,
		sizeof(dmx_ta_param));
	if (ret < 0) {
		MTK_DMX_ERR("set filein addr size fail\n");
		return -EFAULT;
	}
	return 0;
}

int mtk_dmx_tee_if_play_getPipelineId(u64 keyToken, uint32_t *pipelineId, uint32_t *encryption_type)
{
	int ret;
	u32 play_ta_session_id;
	TEE_COMMON_ARG_T *play_ta_param;
	u32 *out_pipelineId = NULL;
	u32 *out_encryption_type = NULL;
	u32 *result = NULL;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = 0;
	if (!_is_play_ta_tee_ctx_inited())
		_play_ta_tee_init_context();

	play_ta_session_id = _dmx_tee_get_play_ta_session_id();
	if (!play_ta_session_id) {
		MTK_DMX_ERR("play ta session id invalid\n");
		return -EFAULT;
	}

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));		// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));		// token
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// addr of pipelineId
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// addr of enc_type 

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	// pointer allocated place
	play_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	play_ta_param->ui4Command = E_SECURE_PLAY_CA_CMD_GET_PIPELINE_ID;
	play_ta_param->ui1Size = 0;

	serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//result
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	result = play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//token
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &keyToken, sizeof(u64));
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//addr of pipeid
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, pipelineId, sizeof(u32));
	out_pipelineId = play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//addr of enc_type 
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, encryption_type, sizeof(u32));
	out_encryption_type = play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		play_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail, ret 0x%X\n", ret);
		kfree(serialized_buf);
		return -EFAULT;
	}

	if(result !=0 && *result != 0) {
		MTK_DMX_ERR("invoke cmd result fail (0x%X)\n", *result);
		kfree(serialized_buf);
		return -EFAULT;
	}

	*pipelineId = *out_pipelineId;
	*encryption_type = *out_encryption_type;

	kfree(serialized_buf);
	return 0;
}

int mtk_dmx_tee_if_play_decrypt_config(u64 keyToken, int32_t dataFormat, int32_t encryptType
	, uint64_t srcPA, uint32_t srcSize, uint64_t destPA, uint32_t destSize)
{
	int ret;
	u32 *result = NULL;
	u32 play_ta_session_id;
	TEE_COMMON_ARG_T *play_ta_param;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = 0;

	if (!_is_play_ta_tee_ctx_inited())
		_play_ta_tee_init_context();

	play_ta_session_id = _dmx_tee_get_play_ta_session_id();
	if (!play_ta_session_id) {
		MTK_DMX_ERR("play ta session id invalid\n");
		return -EFAULT;
	}

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// token
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// src addr
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// dest addr

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	play_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;
	play_ta_param->ui4Command = E_SECURE_PLAY_CA_CMD_CONFIGURE;
	play_ta_param->ui1Size = 0;

	serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//result
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	result = (u32*)play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//token
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &keyToken, sizeof(u64));
	play_ta_param->ui1Size++;

	play_ta_param->apvArgument[play_ta_param->ui1Size].val = dataFormat;
	play_ta_param->ui4Length[play_ta_param->ui1Size] = 0;
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	play_ta_param->ui1Size++;

	play_ta_param->apvArgument[play_ta_param->ui1Size].val = encryptType;
	play_ta_param->ui4Length[play_ta_param->ui1Size] = 0;
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &srcPA, sizeof(u64));
	play_ta_param->ui1Size++;

	play_ta_param->apvArgument[play_ta_param->ui1Size].val = srcSize;
	play_ta_param->ui4Length[play_ta_param->ui1Size] = 0;
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &destPA, sizeof(u64));
	play_ta_param->ui1Size++;

	play_ta_param->apvArgument[play_ta_param->ui1Size].val = destSize;
	play_ta_param->ui4Length[play_ta_param->ui1Size] = 0;
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	play_ta_param->ui1Size++;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		play_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);
	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail (0x%X)\n", ret);
		kfree(serialized_buf);
		return -EFAULT;
	}

	if(result !=0 && *result != 0) {
		MTK_DMX_ERR("invoke cmd result fail (0x%X)\n", *result);
		kfree(serialized_buf);
		return -EFAULT;
	}

	kfree(serialized_buf);
	return 0;
}

int mtk_dmx_tee_if_play_decrypt_first_block(u64 keyToken, u64 srcAddr, u64 destAddr, uint32_t dataSize, struct secure_play_tlv_meta *pFristBlockMeta)
{
	int ret;
	u32 play_ta_session_id;
	TEE_COMMON_ARG_T *play_ta_param;
	u8 *serialized_buf = NULL;
	u32 *result = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));

	// if (param->index_num > PVR_METADATA_MAX_NUM) {
	//	MTK_DMX_ERR("Max index number is %u\n", PVR_METADATA_MAX_NUM);
	//	return -EFAULT;
	// }

	if (!_is_play_ta_tee_ctx_inited())
		_play_ta_tee_init_context();

	play_ta_session_id = _dmx_tee_get_play_ta_session_id();
	if (!play_ta_session_id) {
		MTK_DMX_ERR("play ta session id invalid\n");
		return -EFAULT;
	}

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// token
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// src addr
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// dst addr
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(struct secure_play_tlv_meta)); // metadata

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	play_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;
	play_ta_param->ui4Command = E_SECURE_PLAY_CA_CMD_OPERATE_FIRST_BLOCK;
	play_ta_param->ui1Size = 0;

	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//token
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &keyToken, sizeof(u64));
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//src
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &srcAddr, sizeof(u64));
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//dest
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &destAddr, sizeof(u64));
	play_ta_param->ui1Size++;

	play_ta_param->apvArgument[play_ta_param->ui1Size].val = dataSize;//size
	play_ta_param->ui4Length[play_ta_param->ui1Size] = 0;
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//meta
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(struct secure_play_tlv_meta);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	memset(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, 0, sizeof(struct secure_play_tlv_meta));
	play_ta_param->ui1Size++;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		play_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail, ret %d\n", ret);
		kfree(serialized_buf);
		return -EFAULT;
	}

	if(result !=0 && *result != 0) {
		MTK_DMX_ERR("invoke cmd result fail (0x%X)\n", *result);
		kfree(serialized_buf);
		return -EFAULT;
	}

	memcpy(pFristBlockMeta, (struct secure_play_tlv_meta *)play_ta_param->apvArgument[5].ptr, sizeof(struct secure_play_tlv_meta));

	kfree(serialized_buf);
	return 0;
}


int mtk_dmx_tee_if_play_decrypt_normal(u64 keyToken, u64 srcAddr, u64 destAddr, uint32_t dataSize, bool *pIsPrevDone)
{
	int ret;
	u32 play_ta_session_id;
	TEE_COMMON_ARG_T *play_ta_param;
	u32 *result = NULL;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));

	// if (param->index_num > PVR_METADATA_MAX_NUM) {
	//	MTK_DMX_ERR("Max index number is %u\n", PVR_METADATA_MAX_NUM);
	//	return -EFAULT;
	// }

	if (!_is_play_ta_tee_ctx_inited())
		_play_ta_tee_init_context();

	play_ta_session_id = _dmx_tee_get_play_ta_session_id();
	if (!play_ta_session_id) {
		MTK_DMX_ERR("play ta session id invalid\n");
		return -EFAULT;
	}


	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));	// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// token
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// src addr
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));	// dst addr
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(bool));	// is prev finish

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	play_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;
	play_ta_param->ui4Command = E_SECURE_PLAY_CA_CMD_OPERATE_NORNAL;
	play_ta_param->ui1Size = 0;

	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	result = (u32*)play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//token
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &keyToken, sizeof(u64));
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//src
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &srcAddr, sizeof(u64));
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u64));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//dest
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &destAddr, sizeof(u64));
	play_ta_param->ui1Size++;

	play_ta_param->apvArgument[play_ta_param->ui1Size].val = dataSize;//size
	play_ta_param->ui4Length[play_ta_param->ui1Size] = 0;
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(bool));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(bool);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	play_ta_param->ui1Size++;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		play_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail, ret %d\n", ret);
		kfree(serialized_buf);
		return -EFAULT;
	}

	if(result !=0 && *result != 0) {
		MTK_DMX_ERR("invoke cmd result fail (0x%X)\n", *result);
		kfree(serialized_buf);
		return -EFAULT;
	}

	*pIsPrevDone = *(bool*)play_ta_param->apvArgument[5].ptr;

	kfree(serialized_buf);
	return 0;
}

int mtk_dmx_tee_if_play_release(u64 keyToken)
{
	int ret;
	u32 play_ta_session_id;
	TEE_COMMON_ARG_T *play_ta_param;
	u32 *result = NULL;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = 0;
	if (!_is_play_ta_tee_ctx_inited())
		_play_ta_tee_init_context();

	play_ta_session_id = _dmx_tee_get_play_ta_session_id();
	if (!play_ta_session_id) {
		MTK_DMX_ERR("play ta session id invalid\n");
		return -EFAULT;
	}


	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));		// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));		// token

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	// pointer allocated place
	play_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	play_ta_param->ui4Command = E_SECURE_PLAY_CA_CMD_RELEASE;
	play_ta_param->ui1Size = 0;

	serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//result
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	result = (u32*)play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//token
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &keyToken, sizeof(u64));
	play_ta_param->ui1Size++;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		play_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail, ret 0x%X\n", ret);
		kfree(serialized_buf);
		return -EFAULT;
	}

	if(result !=0 && *result != 0) {
		MTK_DMX_ERR("invoke cmd result fail (0x%X)\n", *result);
		kfree(serialized_buf);
		return -EFAULT;
	}

	kfree(serialized_buf);
	return 0;
}

int mtk_dmx_tee_if_play_securesetting(u64 keyToken)
{
	int ret;
	u32 play_ta_session_id;
	TEE_COMMON_ARG_T *play_ta_param;
	u32 *result = NULL;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = 0;
	if (!_is_play_ta_tee_ctx_inited())
		_play_ta_tee_init_context();

	play_ta_session_id = _dmx_tee_get_play_ta_session_id();
	if (!play_ta_session_id) {
		MTK_DMX_ERR("play ta session id invalid\n");
		return -EFAULT;
	}

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));		// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));		// token

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	// pointer allocated place
	play_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	play_ta_param->ui4Command = E_SECURE_PLAY_CA_CMD_SECURE_SETTING;
	play_ta_param->ui1Size = 0;

	serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//result
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	result = (u32*)play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//token
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 0;
	memcpy(play_ta_param->apvArgument[play_ta_param->ui1Size].ptr, &keyToken, sizeof(u64));
	play_ta_param->ui1Size++;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		play_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail, ret 0x%X\n", ret);
		kfree(serialized_buf);
		return -EFAULT;
	}

	if(result !=0 && *result != 0) {
		MTK_DMX_ERR("invoke cmd result fail (0x%X)\n", *result);
		kfree(serialized_buf);
		return -EFAULT;
	}

	kfree(serialized_buf);
	return 0;
}


int mtk_dmx_tee_if_play_genkeytoken(u64* keyToken)
{
	int ret;
	u32 play_ta_session_id;
	TEE_COMMON_ARG_T *play_ta_param;
	u64 *out_keytoken = NULL;
	u32 *result = NULL;
	u8 *serialized_buf = NULL;
	u32 serialized_buf_size = 0;
	u32 serialized_buf_offset = 0;
	if (!_is_play_ta_tee_ctx_inited())
		_play_ta_tee_init_context();

	play_ta_session_id = _dmx_tee_get_play_ta_session_id();
	if (!play_ta_session_id) {
		MTK_DMX_ERR("play ta session id invalid\n");
		return -EFAULT;
	}

	serialized_buf_size = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u32));		// result
	serialized_buf_size += TZ_CACHE_ALIGN(sizeof(u64));		// token

	serialized_buf = kmalloc(serialized_buf_size, GFP_ATOMIC);
	if (!serialized_buf) {
		MTK_DMX_ERR("out-of-memory\n");
		return -ENOMEM;
	}

	memset(serialized_buf, 0, serialized_buf_size);

	// pointer allocated place
	play_ta_param = (TEE_COMMON_ARG_T *)serialized_buf;

	play_ta_param->ui4Command = E_SECURE_PLAY_CA_CMD_GEN_KEYTOKEN;
	play_ta_param->ui1Size = 0;

	serialized_buf_offset = TZ_CACHE_ALIGN(sizeof(TEE_COMMON_ARG_T));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//result
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u32);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	result = (u32*)play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	serialized_buf_offset += TZ_CACHE_ALIGN(sizeof(u32));
	play_ta_param->apvArgument[play_ta_param->ui1Size].ptr = (u8 *)(serialized_buf + serialized_buf_offset);//token
	play_ta_param->ui4Length[play_ta_param->ui1Size] = sizeof(u64);
	play_ta_param->abWrite[play_ta_param->ui1Size] = 1;
	out_keytoken = play_ta_param->apvArgument[play_ta_param->ui1Size].ptr;
	play_ta_param->ui1Size++;

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		play_ta_session_id,
		0,
		serialized_buf,
		serialized_buf_size);

	if (ret < 0) {
		MTK_DMX_ERR("invoke cmd fail, ret 0x%X\n", ret);
		kfree(serialized_buf);
		return -EFAULT;
	}

	if(result !=0 && *result != 0) {
		MTK_DMX_ERR("invoke cmd result fail (0x%X)\n", *result);
		kfree(serialized_buf);
		return -EFAULT;
	}

	*keyToken = *out_keytoken;

	kfree(serialized_buf);
	return 0;
}

int mtk_dmx_tee_if_manage_pipeline(struct dmxta_pipeline_id *pipeline_id)
{
	int ret;
	u32 dmx_ta_session_id;

	if (!_is_dmx_ta_tee_ctx_inited())
		_dmx_ta_tee_init_context();

	dmx_ta_session_id = _dmx_tee_get_dmx_ta_session_id();
	if (!dmx_ta_session_id) {
		MTK_DMX_ERR("dmx ta session id invalid\n");
		return -EFAULT;
	}

	ret = mtk_dmx_tee_cmd_invoke_cmd(
		dmx_ta_session_id,
		DMX_TA_CMD_GET_PIPEID,
		pipeline_id,
		sizeof(struct dmxta_pipeline_id));
	if (ret < 0) {
		MTK_DMX_ERR("set vq buffer fail\n");
		return -EFAULT;
	}

	return 0;
}

