/*
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * Copyright(c) 2018 NXP. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.GPL.
 *
 * BSD LICENSE
 *
 * Copyright(c) 2018 NXP. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include "vpu_encoder_rpc.h"

void rpc_init_shared_memory_encoder(struct shared_addr *This,
		unsigned long long base_phy_addr,
		void *base_virt_addr,
		u_int32 total_size,
		u32 *actual_size)
{
	pENC_RPC_HOST_IFACE pSharedInterface;
	unsigned int phy_addr;
	unsigned int i;
	unsigned int temp_addr;
	BUFFER_DESCRIPTOR_TYPE *pSharedCmdBufDescPtr;
	BUFFER_DESCRIPTOR_TYPE *pSharedMsgBufDescPtr;
	pMEDIA_ENC_API_CONTROL_INTERFACE pEncCtrlInterface;

	This->shared_mem_phy = base_phy_addr;
	This->shared_mem_vir = base_virt_addr;
	This->base_offset = (unsigned long long)(base_virt_addr - base_phy_addr);

	pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
	This->pSharedInterface = pSharedInterface;

	pSharedInterface->FwExecBaseAddr = base_phy_addr;
	pSharedInterface->FwExecAreaSize = total_size;

	pSharedCmdBufDescPtr = (BUFFER_DESCRIPTOR_TYPE *)&pSharedInterface->StreamCmdBufferDesc;
	pSharedMsgBufDescPtr = (BUFFER_DESCRIPTOR_TYPE *)&pSharedInterface->StreamMsgBufferDesc;

	phy_addr = base_phy_addr + sizeof(ENC_RPC_HOST_IFACE);
	This->cmd_mem_phy = phy_addr;
	This->cmd_mem_vir = This->shared_mem_vir + sizeof(ENC_RPC_HOST_IFACE);

	pSharedCmdBufDescPtr->wptr = phy_addr;
	pSharedCmdBufDescPtr->rptr = pSharedCmdBufDescPtr->wptr;
	pSharedCmdBufDescPtr->start = pSharedCmdBufDescPtr->wptr;
	pSharedCmdBufDescPtr->end = pSharedCmdBufDescPtr->start + CMD_SIZE;

	phy_addr += CMD_SIZE;
	This->msg_mem_phy = phy_addr;
	This->msg_mem_vir = This->cmd_mem_vir + CMD_SIZE;

	pSharedMsgBufDescPtr->wptr = phy_addr;
	pSharedMsgBufDescPtr->rptr = pSharedMsgBufDescPtr->wptr;
	pSharedMsgBufDescPtr->start = pSharedMsgBufDescPtr->wptr;
	pSharedMsgBufDescPtr->end = pSharedMsgBufDescPtr->start + MSG_SIZE;

	phy_addr += MSG_SIZE;

	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
		pSharedInterface->pEncCtrlInterface[i] = phy_addr;
		phy_addr += sizeof(MEDIA_ENC_API_CONTROL_INTERFACE);
	}

	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
		temp_addr = pSharedInterface->pEncCtrlInterface[i];
		pEncCtrlInterface = (pMEDIA_ENC_API_CONTROL_INTERFACE)(temp_addr + This->base_offset);
		pEncCtrlInterface->pEncYUVBufferDesc = phy_addr;
		phy_addr += sizeof(MEDIAIP_ENC_YUV_BUFFER_DESC);
		pEncCtrlInterface->pEncStreamBufferDesc = phy_addr;
		phy_addr += sizeof(BUFFER_DESCRIPTOR_TYPE);
		pEncCtrlInterface->pEncExpertModeParam = phy_addr;
		phy_addr += sizeof(MEDIAIP_ENC_EXPERT_MODE_PARAM);
		pEncCtrlInterface->pEncParam = phy_addr;
		phy_addr += sizeof(MEDIAIP_ENC_PARAM);
		pEncCtrlInterface->pEncMemPool = phy_addr;
		phy_addr += sizeof(MEDIAIP_ENC_MEM_POOL);
		pEncCtrlInterface->pEncEncodingStatus = phy_addr;
		phy_addr += sizeof(ENC_ENCODING_STATUS);
		pEncCtrlInterface->pEncDSAStatus = phy_addr;
		phy_addr += sizeof(ENC_DSA_STATUS_t);
	}
	if (actual_size)
		*actual_size = phy_addr - base_phy_addr;
}

void rpc_set_system_cfg_value_encoder(void *Interface, u_int32 regs_base, u_int32 core_id)
{
	pENC_RPC_HOST_IFACE pSharedInterface;
	MEDIAIP_FW_SYSTEM_CONFIG *pSystemCfg;

	pSharedInterface = (pENC_RPC_HOST_IFACE)Interface;
	pSystemCfg = &pSharedInterface->sSystemCfg;
	pSystemCfg->uNumWindsors = 1;
	pSystemCfg->uWindsorIrqPin[0x0][0x0] = 0x4; // PAL_IRQ_WINDSOR_LOW
	pSystemCfg->uWindsorIrqPin[0x0][0x1] = 0x5; // PAL_IRQ_WINDSOR_HI
	pSystemCfg->uMaloneBaseAddress[0] = (unsigned int)(regs_base + 0x180000);
	if (core_id == 0)
		pSystemCfg->uWindsorBaseAddress[0] = (unsigned int)(regs_base + 0x800000);
	else
		pSystemCfg->uWindsorBaseAddress[0] = (unsigned int)(regs_base + 0xa00000);
	pSystemCfg->uMaloneBaseAddress[0x1] = 0x0;
	pSystemCfg->uHifOffset[0x0] = 0x1C000;
	pSystemCfg->uHifOffset[0x1] = 0x0;

	pSystemCfg->uDPVBaseAddr = 0x0;
	pSystemCfg->uDPVIrqPin = 0x0;
	pSystemCfg->uPixIfBaseAddr = (unsigned int)(regs_base + 0x180000 + 0x20000);
	pSystemCfg->uFSLCacheBaseAddr[0] = (unsigned int)(regs_base + 0x60000);
	pSystemCfg->uFSLCacheBaseAddr[1] = (unsigned int)(regs_base + 0x68000);
}

u_int32 rpc_MediaIPFW_Video_buffer_space_check_encoder(BUFFER_DESCRIPTOR_TYPE *pBufDesc,
	BOOL bFull,
	u_int32 uSize,
	u_int32 *puUpdateAddress)
{
	u_int32 uPtr1;
	u_int32 uPtr2;
	u_int32 start;
	u_int32 end;
	u_int32 uTemp;

	/* bFull is FALSE when send message, write data   */
	/* bFull is TRUE when process commands, read data */
	uPtr1 = (bFull) ? pBufDesc->rptr : pBufDesc->wptr;
	uPtr2 = (bFull) ? pBufDesc->wptr : pBufDesc->rptr;

	if (uPtr1 == uPtr2) {
		if (bFull)
			/* No data at all to read */
			return 0;
		else {
			/* wrt pointer equal to read pointer thus the     */
			/* buffer is completely empty for further writes  */
			start = pBufDesc->start;
			end   = pBufDesc->end;
			/* The address to be returned in this case is for */
			/* the updated write pointer.                     */
			uTemp = uPtr1 + uSize;
			if (uTemp >= end)
				uTemp += (start - end);
			*puUpdateAddress = uTemp;
			return (end - start);
		}
	} else if (uPtr1 < uPtr2) {
		/* return updated rd pointer address                */
		/* In this case if size was too big - we expect the */
		/* external ftn to compare the size against the     */
		/* space returned.
		 */
		*puUpdateAddress = uPtr1 + uSize;
		return (uPtr2 - uPtr1);
	}
	/* We know the system has looped!! */
	start = pBufDesc->start;
	end   = pBufDesc->end;
	uTemp  = uPtr1 + uSize;
	if (uTemp >= end)
		uTemp += (start - end);
	*puUpdateAddress = uTemp;
	return ((end - uPtr1) + (uPtr2 - start));
}

static void rpc_update_cmd_buffer_ptr_encoder(BUFFER_DESCRIPTOR_TYPE *pCmdDesc)
{
	u_int32 uWritePtr;

	/*avoid sw reset fail*/
	mb();
	uWritePtr = pCmdDesc->wptr + 4;
	if (uWritePtr >= pCmdDesc->end)
		uWritePtr = pCmdDesc->start;
	pCmdDesc->wptr = uWritePtr;
}

void rpc_send_cmd_buf_encoder(struct shared_addr *This,
		u_int32 idx,
		u_int32 cmdid,
		u_int32 cmdnum,
		u_int32 *local_cmddata)
{
	pENC_RPC_HOST_IFACE pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
	BUFFER_DESCRIPTOR_TYPE *pCmdDesc = &pSharedInterface->StreamCmdBufferDesc;
	u_int32 *cmddata;
	u_int32 i;
	u_int32 *cmdword = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->wptr - pCmdDesc->start);

	*cmdword = 0;
	*cmdword |= ((idx & 0x000000ff) << 24);
	*cmdword |= ((cmdnum & 0x000000ff) << 16);
	*cmdword |= ((cmdid & 0x00003fff) << 0);
	rpc_update_cmd_buffer_ptr_encoder(pCmdDesc);

	for (i = 0; i < cmdnum; i++) {
		cmddata = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->wptr - pCmdDesc->start);
		*cmddata = local_cmddata[i];
		rpc_update_cmd_buffer_ptr_encoder(pCmdDesc);
	}
}

u_int32 rpc_MediaIPFW_Video_message_check_encoder(struct shared_addr *This)
{
	u_int32 uSpace;
	u_int32 uIgnore;
	pENC_RPC_HOST_IFACE pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
	BUFFER_DESCRIPTOR_TYPE *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
	u_int32 msgword;
	u_int32 msgnum;

	uSpace = rpc_MediaIPFW_Video_buffer_space_check_encoder(pMsgDesc, TRUE, 0, &uIgnore);
	uSpace = (uSpace >> 2);
	if (uSpace) {
		/* get current msgword word */
		msgword      = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->rptr - pMsgDesc->start));
		/* Find the number of additional words */
		msgnum  = ((msgword & 0x00ff0000) >> 16);

		/*
		 * * Check the number of message words against
		 * * 1) a limit - some sort of maximum or at least
		 * * the size of the SW buffer the message is read into
		 * * 2) The space reported (where space is write ptr - read ptr in 32bit words)
		 * * It must be less than space (as opposed to <=) because
		 * * the message itself is not included in msgword
		 */
		if (msgnum < VID_API_MESSAGE_LIMIT) {
			if (msgnum < uSpace)
				return API_MSG_AVAILABLE;
			else
				return API_MSG_INCOMPLETE;
		} else
			return API_MSG_BUFFER_ERROR;
	}
	return API_MSG_UNAVAILABLE;
}

static void rpc_update_msg_buffer_ptr_encoder(BUFFER_DESCRIPTOR_TYPE *pMsgDesc)
{
	u_int32 uReadPtr;

	uReadPtr = pMsgDesc->rptr + 4;
	if (uReadPtr >= pMsgDesc->end)
		uReadPtr = pMsgDesc->start;
	pMsgDesc->rptr = uReadPtr;
}

u32 rpc_read_msg_u32(struct shared_addr *shared_mem)
{
	u32 msgword;
	u32 *ptr = NULL;
	pENC_RPC_HOST_IFACE iface = NULL;
	BUFFER_DESCRIPTOR_TYPE *msg_buf = NULL;

	if (!shared_mem)
		return 0;

	iface = shared_mem->pSharedInterface;
	msg_buf = &iface->StreamMsgBufferDesc;
	ptr = shared_mem->msg_mem_vir + msg_buf->rptr - msg_buf->start;
	rpc_update_msg_buffer_ptr_encoder(msg_buf);
	msgword = *ptr;

	return msgword;
}

int rpc_read_msg_array(struct shared_addr *shared_mem, u32 *buf, u32 number)
{
	int i;
	u32 val;

	if (!shared_mem)
		return -EINVAL;

	for (i = 0; i < number; i++) {
		val = rpc_read_msg_u32(shared_mem);
		if (buf)
			buf[i] = val;
	}

	return 0;
}

int rpc_get_msg_header(struct shared_addr *shared_mem, struct msg_header *msg)
{
	u32 msgword;

	if (!shared_mem || !msg)
		return -EINVAL;

	msgword = rpc_read_msg_u32(shared_mem);
	msg->idx = ((msgword & 0xff000000) >> 24);
	msg->msgnum = ((msgword & 0x00ff0000) >> 16);
	msg->msgid = ((msgword & 0x00003fff) >> 0);

	return 0;
}

static void *phy_to_virt(u_int32 src, unsigned long long offset)
{
	void *result;

	result = (void *)(src + offset);
	return result;
}

#define GET_CTRL_INTERFACE_MEMBER(shared_mem, index, name, member) \
	do {\
		pENC_RPC_HOST_IFACE iface = shared_mem->pSharedInterface; \
		pMEDIA_ENC_API_CONTROL_INTERFACE ctrl_interface =\
			phy_to_virt(iface->pEncCtrlInterface[index],\
					shared_mem->base_offset);\
		name = phy_to_virt(ctrl_interface->member,\
				shared_mem->base_offset);\
	} while (0)

pMEDIAIP_ENC_YUV_BUFFER_DESC rpc_get_yuv_buffer_desc(
		struct shared_addr *shared_mem, int index)
{
	pMEDIAIP_ENC_YUV_BUFFER_DESC desc = NULL;

	GET_CTRL_INTERFACE_MEMBER(shared_mem, index, desc, pEncYUVBufferDesc);

	return desc;
}

pBUFFER_DESCRIPTOR_TYPE rpc_get_stream_buffer_desc(
		struct shared_addr *shared_mem, int index)
{
	pBUFFER_DESCRIPTOR_TYPE desc = NULL;

	GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
				desc, pEncStreamBufferDesc);

	return desc;
}

pMEDIAIP_ENC_EXPERT_MODE_PARAM rpc_get_expert_mode_param(
		struct shared_addr *shared_mem, int index)
{
	pMEDIAIP_ENC_EXPERT_MODE_PARAM param = NULL;

	GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
				param, pEncExpertModeParam);

	return param;
}

pMEDIAIP_ENC_PARAM rpc_get_enc_param(
		struct shared_addr *shared_mem, int index)
{
	pMEDIAIP_ENC_PARAM param = NULL;

	GET_CTRL_INTERFACE_MEMBER(shared_mem, index, param, pEncParam);

	return param;
}

pMEDIAIP_ENC_MEM_POOL rpc_get_mem_pool(
		struct shared_addr *shared_mem, int index)
{
	pMEDIAIP_ENC_MEM_POOL pool = NULL;

	GET_CTRL_INTERFACE_MEMBER(shared_mem, index, pool, pEncMemPool);

	return pool;
}

pENC_ENCODING_STATUS rpc_get_encoding_status(
		struct shared_addr *shared_mem, int index)
{
	pENC_ENCODING_STATUS encoding_status = NULL;

	GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
				encoding_status, pEncEncodingStatus);

	return encoding_status;
}

pENC_DSA_STATUS_t rpc_get_dsa_status(struct shared_addr *shared_mem, int index)
{
	pENC_DSA_STATUS_t dsa_status = NULL;

	GET_CTRL_INTERFACE_MEMBER(shared_mem, index, dsa_status, pEncDSAStatus);

	return dsa_status;
}

void rpc_set_print_buffer(struct shared_addr *shared_mem,
				unsigned long print_phy_addr, u32 size)
{
	pENC_RPC_HOST_IFACE pSharedInterface;
	pBUFFER_DESCRIPTOR_TYPE debugBufDesc;


	pSharedInterface = shared_mem->pSharedInterface;
	debugBufDesc = &pSharedInterface->DebugBufferDesc;

	debugBufDesc->start = print_phy_addr;
	debugBufDesc->end = debugBufDesc->start + size;
	debugBufDesc->wptr = debugBufDesc->rptr = debugBufDesc->start;
}
