/*******************************************************************************
* Copyright (C) Marvell International Ltd. and its affiliates
*
* Marvell GPL License Option
*
* If you received this File from Marvell, you may opt to use, redistribute and/or
* modify this File in accordance with the terms and conditions of the General
* Public License Version 2, June 1991 (the "GPL License"), a copy of which is
* available along with the File in the license.txt file or by writing to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
* on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
*
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
* WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
* DISCLAIMED.  The GPL License provides additional details about this warranty
* disclaimer.
********************************************************************************/

#define _THINVPP_API_C_

#include "Galois_memmap.h"
#include "GaloisDmaMap.h"
#include "galois_io.h"
#include "global.h"

#include "avpll.h"
#include "thinvpp.h"
#include "vpp_be_hdmitx.h"
#include "bcm_cmds.h"
#include "util.h"
#include "gpio.h"

#define bTST(x, b) (((x) >> (b)) & 1)

static int MV_THINVPP_SetHdmiVideoFmt(int color_fmt, int bit_depth, int pixel_rept);
void THINVPP_BCMBUF_HardwareTrans_Direct(int block, unsigned int *start, int size);

unsigned MV_REG_GET(unsigned addr)
{
        return *(volatile unsigned volatile *)(addr);
}

void MV_REG_SET(unsigned addr, unsigned val)
{
        *(volatile unsigned volatile *)(addr) = val;
}

void MV_REG_AND(unsigned addr, unsigned val)
{
        val = val & (*(volatile unsigned volatile *)(addr));
        *(volatile unsigned volatile *)(addr) = val;
}

void MV_REG_ORR(unsigned addr, unsigned val)
{
        val = val | (*(volatile unsigned volatile *)(addr));
        *(volatile unsigned volatile *)(addr) = val;
}

void MV_REG_MASK(unsigned addr, unsigned mask, unsigned val)
{
        val = (mask & (*(volatile unsigned volatile *)(addr))) | val;
        *(volatile unsigned volatile *)(addr) = val;
}

void delay_10ns(int delay)
{
	int i;

	for (i=0; i<delay; i++) {
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	__asm__ __volatile__ ("MOV r0, r0"	"\n\t" :::"r0");
	}
}

static int GetVCOFreq(int resID, int bit_depth)
{
	if (resID == RES_RESET)
		return (-1);

	int avpll_freq_index, deep_color_index;

	if (m_resinfo_table[resID].freq <= 25200) {
		avpll_freq_index = 0;
	} else if ((m_resinfo_table[resID].freq == 27000) || (m_resinfo_table[resID].freq == 27027)) {
		avpll_freq_index = 1;
	} else if ((m_resinfo_table[resID].freq == 74250) || (m_resinfo_table[resID].freq == 74176)) {
		avpll_freq_index = 3;
	} else if ((m_resinfo_table[resID].freq == 148500) || (m_resinfo_table[resID].freq == 148352)) {
		avpll_freq_index = 5;
	} else
		return (-1);

	if (bit_depth == OUTPUT_BIT_DEPTH_12BIT)
		deep_color_index = 2;
	else if (bit_depth == OUTPUT_BIT_DEPTH_10BIT)
		deep_color_index = 1;
	else if (bit_depth == OUTPUT_BIT_DEPTH_8BIT)
		deep_color_index = 0;
	else
		return (-1);

	return (diag_getVCOFreq(deep_color_index, avpll_freq_index));
}

static int NeedAVPLL_PPM1K(int resID)
{
	int frame_rate;
	int ret;

	frame_rate = m_resinfo_table[resID].frame_rate;
	if (m_resinfo_table[resID].type == TYPE_SD) {
		/* for SD resolution */
		if ((frame_rate == FRAME_RATE_59P94) || (frame_rate == FRAME_RATE_50))
			ret = 0;
		else
			ret = 1;
	} else {
		/* for HD resolution */
		if ((frame_rate == FRAME_RATE_59P94) || (frame_rate == FRAME_RATE_29P97) || (frame_rate == FRAME_RATE_23P98) || (frame_rate == FRAME_RATE_119P88) || (frame_rate == FRAME_RATE_47P96))
			ret = 0;
		else
			ret = 1;;
	}

	return ret;
}

static void VPP_dhub_sem_clear(void)
{
	int instat;

	HDL_semaphore *pSemHandle = thinvpp_obj->pSemHandle;

	instat = semaphore_chk_full(pSemHandle, -1);

	if (bTST(instat, avioDhubSemMap_vpp_vppCPCB0_intr)){
		semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr, 1);
		semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr);
	}else if (bTST(instat, avioDhubSemMap_vpp_vppCPCB2_intr)){
		semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB2_intr, 1);
		semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB2_intr);
	}

	return;
}


/***********************************************
* FUNCTION: create a VPP object
* PARAMS: base_addr - VPP object base address
*         *handle - pointer to object handle
* RETURN: MV_THINVPP_OK - succeed
*         MV_THINVPP_EUNCONFIG - not initialized
***********************************************/
int MV_THINVPP_Create(int base_addr, unsigned options)
{
	if (!(thinvpp_obj = (THINVPP_OBJ *)THINVPP_MALLOC(sizeof(THINVPP_OBJ)))){
		return (MV_THINVPP_ENOMEM);
	}

	THINVPP_MEMSET(thinvpp_obj, 0, sizeof(THINVPP_OBJ));

	thinvpp_obj->options = options;
	thinvpp_obj->base_addr = base_addr;

	/* create VBI BCM buffer */
	if (THINVPP_BCMBUF_Create(&(thinvpp_obj->vbi_bcm_buf[0]), BCM_BUFFER_SIZE) != MV_THINVPP_OK){
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}

	if (!(thinvpp_obj->options & THINVPP_OPTION_SHOWLOGO))
		return (MV_THINVPP_OK);

	if (THINVPP_BCMBUF_Create(&(thinvpp_obj->vbi_bcm_buf[1]), BCM_BUFFER_SIZE) != MV_THINVPP_OK){
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}


	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}
	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}

	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}
	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[1]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}

	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[0]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[1]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}
	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[1]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[0]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}

	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_3].vbi_bcm_cfgQ[0]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[1]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}
	if (THINVPP_CFGQ_Create(&(thinvpp_obj->dv[CPCB_3].vbi_bcm_cfgQ[1]), DMA_CMD_BUFFER_SIZE) != MV_THINVPP_OK) {
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_bcm_cfgQ[0]));
		THINVPP_FREE(thinvpp_obj);
		return (MV_THINVPP_ENOMEM);
	}

	return (MV_THINVPP_OK);
}

/***********************************************
* FUNCTION: destroy a VPP object
* PARAMS: handle - VPP object handle
* RETURN: MV_THINVPP_OK - succeed
*         MV_THINVPP_EUNCONFIG - not initialized
*         MV_THINVPP_ENODEV - no device
*         MV_THINVPP_ENOMEM - no memory
***********************************************/
int MV_THINVPP_Destroy(void)
{
	if (thinvpp_obj == NULL)
		return (MV_THINVPP_ENODEV);

	/* free BCM buffer memory */
	THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[0]));
	if (thinvpp_obj->options & THINVPP_OPTION_SHOWLOGO)
	{
		THINVPP_BCMBUF_Destroy(&(thinvpp_obj->vbi_bcm_buf[1]));

		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[1]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_bcm_cfgQ[0]));
		THINVPP_CFGQ_Destroy(&(thinvpp_obj->dv[CPCB_3].vbi_bcm_cfgQ[1]));
	}

	/* free vpp object memory */
	THINVPP_FREE(thinvpp_obj);
	thinvpp_obj = NULL;

	return (MV_THINVPP_OK);
}

/***************************************
* FUNCTION: VPP reset
* INPUT: NONE
* RETURN: NONE
**************************************/
int MV_THINVPP_Reset(void)
{
	unsigned i;
	unsigned reg;

	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	// reset VPP object variable
	thinvpp_obj->status = STATUS_INACTIVE;

	/* reset planes */
	for (i=FIRST_PLANE; i<MAX_NUM_PLANES; i++){
		thinvpp_obj->plane[i].status = STATUS_INACTIVE;
		thinvpp_obj->plane[i].mode = -1; // invalid
		thinvpp_obj->plane[i].srcfmt = -1; // invalid
		thinvpp_obj->plane[i].order = -1; // invalid

		thinvpp_obj->plane[i].actv_win.x = 0;
		thinvpp_obj->plane[i].actv_win.y = 0;
		thinvpp_obj->plane[i].actv_win.width = 0;
		thinvpp_obj->plane[i].actv_win.height = 0;

		thinvpp_obj->plane[i].ref_win = thinvpp_obj->plane[i].actv_win;
	}

	/* reset channels */
	for (i=FIRST_CHAN; i<MAX_NUM_CHANS; i++) {
		thinvpp_obj->chan[i].status = STATUS_INACTIVE;
		thinvpp_obj->chan[i].dvID = -1; // invalid
		thinvpp_obj->chan[i].dvlayerID = -1; // invalid
		thinvpp_obj->chan[i].zorder = -1; // invalid

		thinvpp_obj->chan[i].disp_win.x = 0;
		thinvpp_obj->chan[i].disp_win.y = 0;
		thinvpp_obj->chan[i].disp_win.width = 0;
		thinvpp_obj->chan[i].disp_win.height = 0;
	}

	/* reset DVs */
	for (i=FIRST_CPCB; i<MAX_NUM_CPCBS; i++) {
		thinvpp_obj->dv[i].status = STATUS_INACTIVE;
		thinvpp_obj->dv[i].output_res = RES_INVALID; // invalid
		thinvpp_obj->dv[i].num_of_vouts = 0;
		thinvpp_obj->dv[i].vbi_num = 0;
	}

	/* reset VOUTs */
	for (i=FIRST_VOUT; i<MAX_NUM_VOUTS; i++) {
		thinvpp_obj->vout[i].status = STATUS_INACTIVE;
		thinvpp_obj->vout[i].dvID = -1; // invalid
	}

	/* reset VBI BCM buffer */
	THINVPP_BCMBUF_Reset(&thinvpp_obj->vbi_bcm_buf[0]);
	thinvpp_obj->pVbiBcmBuf = &(thinvpp_obj->vbi_bcm_buf[0]);
	if (thinvpp_obj->options & THINVPP_OPTION_SHOWLOGO)
	{
		THINVPP_BCMBUF_Reset(&thinvpp_obj->vbi_bcm_buf[1]);
		thinvpp_obj->pVbiBcmBufCpcb[CPCB_1] = &(thinvpp_obj->vbi_bcm_buf[0]);
		thinvpp_obj->pVbiBcmBufCpcb[CPCB_3] = &(thinvpp_obj->vbi_bcm_buf[0]);

		thinvpp_obj->dv[CPCB_1].curr_cpcb_vbi_dma_cfgQ = &(thinvpp_obj->dv[CPCB_1].vbi_dma_cfgQ[0]);
		thinvpp_obj->dv[CPCB_3].curr_cpcb_vbi_dma_cfgQ = &(thinvpp_obj->dv[CPCB_3].vbi_dma_cfgQ[0]);
		thinvpp_obj->dv[CPCB_1].curr_cpcb_vbi_bcm_cfgQ = &(thinvpp_obj->dv[CPCB_1].vbi_bcm_cfgQ[0]);
		thinvpp_obj->dv[CPCB_3].curr_cpcb_vbi_bcm_cfgQ = &(thinvpp_obj->dv[CPCB_3].vbi_bcm_cfgQ[0]);
	}

	/* reset dHub cmdQ */
	#if (BERLIN_CHIP_VERSION != BERLIN_BG2CD_A0)
	for (i = 0; i < (VPP_NUM_OF_CHANNELS - 1); i++)
	#else // (BERLIN_CHIP_VERSION != BERLIN_BG2CD_A0)
	for (i = 0; i < avioDhubChMap_vpp_SPDIF_W; i++)
	#endif // (BERLIN_CHIP_VERSION != BERLIN_BG2CD_A0)
		thinvpp_obj->dhub_cmdQ[i] = 0;

	SM_GPIO_PortWrite(1, 1); // set SM GPIO port 1 to high, this is input/output control of SM GPIO port 7

	reg = 0xf7f70068;
	if (0 != (0x3c & MV_REG_GET(reg)))
	{
		// BE_HDMIPHY_EnableTmds:
		MV_REG_AND(reg, ~0x3c); // SET32HDMI_ctrl_PD_TX(regData,0);
		MV_REG_ORR(reg, 0x02); // SET32HDMI_ctrl_RESET_TX(regData,1);
		MV_REG_AND(reg, ~0x02); // SET32HDMI_ctrl_RESET_TX(regData,0);
		MV_REG_AND(reg, ~0x01); // SET32HDMI_ctrl_PD_IREF(regData, VPP_HDMI_PHY_PD_IREF_VAL);
	}

	MV_REG_SET(0xf7f644c0, 0x01); // BE_HDMITX_EnablePhyFifo:
	MV_REG_MASK(reg, ~(0x0fff<<15), (0x249<<15)); // SET32HDMI_ctrl_DAMP(regData, value);
	MV_REG_MASK(reg + 4, ~0x0fff, 0x249); // SET32HDMI_ctrl_EAMP(regData, value);

	THINVPP_BCMBUF_HardwareTrans_Direct(1, cmd_THINVPP_Reset, sizeof(cmd_THINVPP_Reset));


	return (MV_THINVPP_OK);
}

/***************************************
* FUNCTION: VPP profile configuration
* INPUT: NONE
* RETURN: NONE
**************************************/
int MV_THINVPP_Config(void)
{
	int i;

	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	/* VPP module has been configured */
	if (thinvpp_obj->status == STATUS_ACTIVE)
		return (MV_THINVPP_OK);

	thinvpp_obj->pSemHandle = dhub_semaphore(&VPP_dhubHandle.dhub);

	/* config planes */
	/* set plane's DMA channel ID */
	i = PLANE_MAIN;
	thinvpp_obj->plane[i].dmaRID = avioDhubChMap_vpp_MV_R; // inline read DMA
	thinvpp_obj->plane[i].dmaRdhubID = (int)(&VPP_dhubHandle);
	thinvpp_obj->plane[i].offline_dmaWID = avioDhubChMap_vpp_MV_FRC_W; // offline write-back DMA
	thinvpp_obj->plane[i].offline_dmaWdhubID = (int)(&VPP_dhubHandle);
	thinvpp_obj->plane[i].offline_dmaRID = avioDhubChMap_vpp_MV_FRC_R; // offline readd-back DMA
	thinvpp_obj->plane[i].offline_dmaRdhubID = (int)(&VPP_dhubHandle);

	/* config channels */
	#if LOGO_ENABLE_MAIN
	thinvpp_obj->chan[CHAN_MAIN].dvID = CPCB_1; //#if LOGO_ENABLE_MAIN
	#endif
	#if LOGO_ENABLE_PIP
	thinvpp_obj->chan[CHAN_PIP].dvID = CPCB_1;
	#endif
	thinvpp_obj->chan[CHAN_AUX].dvID = CPCB_3;

	#if LOGO_ENABLE_MAIN
	thinvpp_obj->chan[CHAN_MAIN].zorder = CPCB_ZORDER_7; //#if LOGO_ENABLE_MAIN
	#endif
	#if LOGO_ENABLE_PIP
	thinvpp_obj->chan[CHAN_PIP].zorder = CPCB_ZORDER_2;
	#endif
	thinvpp_obj->chan[CHAN_AUX].zorder = CPCB_ZORDER_1;

	// for B0, channel connection with CPCB is fixed
	#if LOGO_ENABLE_MAIN
	thinvpp_obj->chan[CHAN_MAIN].dvlayerID = CPCB1_PLANE_1; //#if LOGO_ENABLE_MAIN
	#endif
	#if LOGO_ENABLE_PIP
	thinvpp_obj->chan[CHAN_PIP].dvlayerID = CPCB1_PLANE_2;
	#endif
	thinvpp_obj->chan[CHAN_AUX].dvlayerID = CPCB1_PLANE_1; // PLANE-1 of CPCB-2

	#if LOGO_ENABLE_MAIN
	#if LOGO_ENABLE_PIP || ((BERLIN_CHIP_VERSION != BERLIN_BG2CD_A0) && (BERLIN_CHIP_VERSION != BERLIN_BG2CDP))
	thinvpp_obj->dv[CPCB_1].num_of_chans = 2;
	thinvpp_obj->dv[CPCB_1].chanID[0] = CHAN_MAIN;
	thinvpp_obj->dv[CPCB_1].chanID[1] = CHAN_PIP;
	#else
	thinvpp_obj->dv[CPCB_1].num_of_chans = 1;
	thinvpp_obj->dv[CPCB_1].chanID[0] = CHAN_MAIN;
	#endif
	#else
	#if LOGO_ENABLE_PIP
	thinvpp_obj->dv[CPCB_1].num_of_chans = 1;
	thinvpp_obj->dv[CPCB_1].chanID[0] = CHAN_PIP;
	#else
	thinvpp_obj->dv[CPCB_1].num_of_chans = 0;
	#endif
	#endif
	thinvpp_obj->dv[CPCB_1].num_of_vouts = 2;
	thinvpp_obj->dv[CPCB_1].voutID[0] = VOUT_HDMI;
	thinvpp_obj->dv[CPCB_1].voutID[1] = VOUT_HD;

	#if (BERLIN_CHIP_VERSION != BERLIN_BG2CD_A0) && (BERLIN_CHIP_VERSION != BERLIN_BG2CDP)
	thinvpp_obj->dv[CPCB_3].num_of_chans = 1;
	thinvpp_obj->dv[CPCB_3].chanID[0] = CHAN_AUX;
	thinvpp_obj->dv[CPCB_3].num_of_vouts = 1;
	thinvpp_obj->dv[CPCB_3].voutID[0] = VOUT_SD;
	#else // (BERLIN_CHIP_VERSION != BERLIN_BG2CD_A0)
	thinvpp_obj->dv[CPCB_3].num_of_chans = 0;
	#endif // (BERLIN_CHIP_VERSION != BERLIN_BG2CD_A0)

	/* config VOUTs */
	thinvpp_obj->vout[VOUT_HDMI].dvID = CPCB_1;
	thinvpp_obj->vout[VOUT_HD].dvID = CPCB_1;
	thinvpp_obj->vout[VOUT_SD].dvID = CPCB_3;

	THINVPP_BCMBUF_HardwareTrans_Direct(1, cmd_THINVPP_Config, sizeof(cmd_THINVPP_Config));

	if (thinvpp_obj->options & THINVPP_OPTION_SHOWLOGO)
	{

		#if 1 //((BERLIN_CHIP_VERSION == BERLIN_BG2CDP) && (BERLIN_CHIP_VERSION_EXT >= BERLIN_BG2CDP_A0_EXT))
		//CDP A0 only has Q0 and Q1, but trigger event keeps same
		BCM_SCHED_SetMux(BCM_SCHED_Q0, 0); /* CPCB0 VBI -> Q0 */
		BCM_SCHED_SetMux(BCM_SCHED_Q1, 3); /* CPCB0 VDE -> Q1 */
		#else
		BCM_SCHED_SetMux(BCM_SCHED_Q0, 0); /* CPCB0 VBI -> Q0 */
		BCM_SCHED_SetMux(BCM_SCHED_Q1, 1); /* CPCB1 VBI -> Q1 */
		BCM_SCHED_SetMux(BCM_SCHED_Q2, 2); /* CPCB2 VBI -> Q2 */
		BCM_SCHED_SetMux(BCM_SCHED_Q3, 3); /* CPCB0 VDE -> Q3 */
		BCM_SCHED_SetMux(BCM_SCHED_Q4, 4); /* CPCB1 VDE -> Q4 */
		BCM_SCHED_SetMux(BCM_SCHED_Q5, 5); /* CPCB2 VDE -> Q5 */
		#endif
	}

	/* set VPP module to be configured */
	thinvpp_obj->status = STATUS_ACTIVE;
	return (MV_THINVPP_OK);
}

/*******************************************************************
* FUNCTION: set CPCB or DV output resolution
* INPUT: cpcbID - CPCB(for Berlin) or DV(for Galois) id
*        resID - id of output resolution
*        bit_depth - HDMI deep color bit depth
* RETURN: MV_THINVPP_OK - SUCCEED
*         MV_EBADPARAM - invalid parameters
*         MV_EUNCONFIG - VPP not configured or plane not active
*         MV_EFRAMEQFULL - frame queue is full
* Note: this function has to be called before enabling a plane
*       which belongs to that CPCB or DV.
*******************************************************************/
int MV_THINVPP_SetCPCBOutputResolution(int cpcbID, int resID, int bit_depth)
{
	int vco_freq;
	int ppm1k_en;
	int     avpll_freq_index;
	int     deep_color_index;
	float     ovsmp_index;
	(void)vco_freq;

	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	if (resID<FIRST_RES || resID>=MAX_NUM_RESS)
		return (MV_THINVPP_EBADPARAM);

	if (thinvpp_obj->status == STATUS_INACTIVE){
		/* VPP module is not configured */
		return (MV_THINVPP_EUNCONFIG);
	}

	if (cpcbID<FIRST_CPCB || cpcbID>=MAX_NUM_CPCBS)
		return (MV_THINVPP_EBADPARAM);

	vco_freq = GetVCOFreq(resID, bit_depth);

	if (resID == RES_RESET)
		return (MV_THINVPP_OK);

	/* set CPCB new resolution */
	if (m_resinfo_table[resID].freq <= 25200) {
		avpll_freq_index = 0;
		ovsmp_index = 4.0;
	} else if ((m_resinfo_table[resID].freq == 27000) || (m_resinfo_table[resID].freq == 27027)) {
		avpll_freq_index = 1;
		ovsmp_index = 4.0;
	} else if ((m_resinfo_table[resID].freq == 74250) || (m_resinfo_table[resID].freq == 74176)) {
		avpll_freq_index = 3;
		ovsmp_index = 2.0;
	} else if ((m_resinfo_table[resID].freq == 148500) || (m_resinfo_table[resID].freq == 148352)) {
		avpll_freq_index = 5;
		ovsmp_index = 1.0;
	} else {
		return (MV_THINVPP_EBADPARAM);
	}

	if (bit_depth == OUTPUT_BIT_DEPTH_12BIT)
		deep_color_index = 2;
	else if (bit_depth == OUTPUT_BIT_DEPTH_10BIT)
		deep_color_index = 1;
	else if (bit_depth == OUTPUT_BIT_DEPTH_8BIT)
		deep_color_index = 0;
	else
		return (MV_THINVPP_EBADPARAM);

	ppm1k_en = NeedAVPLL_PPM1K(resID);

	if (cpcbID == CPCB_1)
		diag_videoFreq_A(avpll_freq_index, deep_color_index, ppm1k_en, ovsmp_index, 6);
	else if (cpcbID == CPCB_2)
		diag_videoFreq_A(avpll_freq_index, deep_color_index, ppm1k_en, ovsmp_index, 5);
	else if (cpcbID == CPCB_3)
		diag_videoFreq_B(avpll_freq_index, 2 /* always set to 12-bit for AUX */, ppm1k_en, ovsmp_index, 6);

	delay_10ns(2000000);

	thinvpp_obj->dv[cpcbID].output_res = resID;
	THINVPP_BCMBUF_HardwareTrans_Direct(1, cmd_THINVPP_SetCPCBOutputResolution, sizeof(cmd_THINVPP_SetCPCBOutputResolution));

	if (cpcbID == CPCB_1)
		MV_THINVPP_SetHdmiVideoFmt(OUTPUT_COLOR_FMT_RGB888, bit_depth, 1);

	/* set DV status to active */
	thinvpp_obj->dv[cpcbID].status = STATUS_ACTIVE;

	return (MV_THINVPP_OK);
}

int MV_THINVPP_IsCPCBActive(int cpcbID)
{
	int vtotal;

	if (cpcbID == CPCB_1) {
		vtotal = (GLB_REG_READ32(MEMMAP_VPP_REG_BASE+(CPCB0_VT_H << 2)) & 0x0ff);
		vtotal <<= 8;
		vtotal |= (GLB_REG_READ32(MEMMAP_VPP_REG_BASE+(CPCB0_VT_L << 2)) & 0x0ff);
	} else if (cpcbID == CPCB_3) {
		vtotal = (GLB_REG_READ32(MEMMAP_VPP_REG_BASE+(CPCB2_VT_H << 2)) & 0x0ff);
		vtotal <<= 8;
		vtotal |= (GLB_REG_READ32(MEMMAP_VPP_REG_BASE+(CPCB2_VT_L << 2)) & 0x0ff);
	} else
		vtotal = 0;

	return (vtotal);
}




int MV_THINVPP_SetMainRefWindow(const VPP_WIN *win)
{
	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	if (!win)
		return (MV_THINVPP_EBADPARAM);

	#if LOGO_ENABLE_MAIN
	thinvpp_obj->plane[PLANE_MAIN].ref_win = *win;
	#else
	thinvpp_obj->plane[PLANE_PIP].ref_win = *win;
	#endif
	return (MV_THINVPP_OK);
}

int MV_THINVPP_SetMainDisplayFrame(VBUF_INFO *pinfo)
{
	PLANE *plane;

	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	if (!pinfo)
		return (MV_THINVPP_EBADPARAM);

	#if LOGO_ENABLE_MAIN
	plane = &(thinvpp_obj->plane[PLANE_MAIN]);
	#else
	plane = &(thinvpp_obj->plane[PLANE_PIP]);
	#endif
	plane->pinfo = pinfo;

	plane->actv_win.x = pinfo->m_active_left;
	plane->actv_win.y = pinfo->m_active_top;
	plane->actv_win.width  = pinfo->m_active_width;
	plane->actv_win.height = pinfo->m_active_height;

	return (MV_THINVPP_OK);
}

/******************************************************************************
* FUNCTION: open a window of a video/graphics plane for display.
*           the window is defined in end display resolution
* INPUT: planeID - id of a video/grahpics plane
*        *win - pointer to a vpp window struct
*        *attr - pointer to a vpp window attribute struct
* RETURN: MV_THINVPP_OK - SUCCEED
*         MV_EBADPARAM - invalid parameters
*         MV_EUNCONFIG - VPP not configured
*         MV_EUNSUPPORT - plane not connected in configuration
*         MV_ECMDQFULL - command queue is full
******************************************************************************/
int MV_THINVPP_OpenDispWindow(int planeID, const VPP_WIN *win, const VPP_WIN_ATTR *attr)
{
	int chanID;
	int cpcbID;
	PLANE *plane;
	CHAN *chan;

	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	if (planeID<FIRST_PLANE || planeID>=MAX_NUM_PLANES)
		return (MV_THINVPP_EBADPARAM);

	if (!win)
		return (MV_THINVPP_EBADPARAM);

	if ((win->width<=0) || (win->height<=0))
		return (MV_THINVPP_EBADPARAM);

	if (thinvpp_obj->status == STATUS_INACTIVE){
		/* VPP module is not configured */
		return (MV_THINVPP_EUNCONFIG);
	}

	plane = &(thinvpp_obj->plane[planeID]);
	chanID = planeID;
	chan = &(thinvpp_obj->chan[chanID]);
	cpcbID = chan->dvID;

	/* update video/graphics channel display window */
	chan->disp_win.x = win->x;
	chan->disp_win.y = win->y;
	chan->disp_win.width = win->width;
	chan->disp_win.height = win->height;

	if (plane->ref_win.width == 0)
		plane->ref_win.width = chan->disp_win.width;
	if (plane->ref_win.height == 0)
		plane->ref_win.height = chan->disp_win.height;

	if (attr){
		chan->disp_win_attr.bgcolor = attr->bgcolor;
		chan->disp_win_attr.alpha = attr->alpha;
	} else {
		chan->disp_win_attr.bgcolor = DEFAULT_BGCOLOR;
		chan->disp_win_attr.alpha = DEFAULT_ALPHA;
	}
	/* set video/graphics plane & channel in active status */
	plane->status = STATUS_ACTIVE;
	chan->status = STATUS_ACTIVE;
	THINVPP_Enable_ISR_Interrupt(thinvpp_obj, cpcbID, 1);
	VPP_dhub_sem_clear();

	return (MV_THINVPP_OK);
}

int MV_THINVPP_CloseDispWindow(void)
{
	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	/* wait for CPCB TG reset done */
	thinvpp_obj->plane[PLANE_MAIN].status = STATUS_STOP;
	thinvpp_obj->plane[PLANE_PIP].status = STATUS_STOP;
	thinvpp_obj->plane[PLANE_AUX].status = STATUS_STOP;

	while(thinvpp_obj->plane[PLANE_MAIN].status != STATUS_INACTIVE);

	return (MV_THINVPP_OK);
}

int MV_THINVPP_Stop(void)
{
	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	/* wait for CPCB TG reset done */
	MV_REG_AND(0xf7f70068, ~(0x0fff<<15)); // SET32HDMI_ctrl_DAMP(regData, value);
	MV_REG_AND(0xf7f70068 + 4, ~0x0fff); // SET32HDMI_ctrl_EAMP(regData, value);

	thinvpp_obj->dv[CPCB_1].status = STATUS_STOP;
	thinvpp_obj->dv[CPCB_3].status = STATUS_STOP;
	//    if (thinvpp_obj->plane[PLANE_MAIN].status != STATUS_INACTIVE)
	while(thinvpp_obj->dv[CPCB_1].status != STATUS_INACTIVE);

	// disable CPCB VBI interrupts
	THINVPP_Enable_ISR_Interrupt(thinvpp_obj, CPCB_1, 0);
	THINVPP_Enable_ISR_Interrupt(thinvpp_obj, CPCB_3, 0);
	VPP_dhub_sem_clear();

	return (MV_THINVPP_OK);
}

/********************************************************************************
* FUNCTION: Set Hdmi Video format
* INPUT: color_fmt - color format (RGB, YCbCr 444, 422)
*      : bit_depth - 8/10/12 bit color
*      : pixel_rept - 1/2/4 repetitions of pixel
* RETURN: MV_THINVPP_OK - SUCCEED
*         MV_EBADPARAM - invalid parameters
*         MV_EUNCONFIG - VPP not configured
*         MV_THINVPP_ENODEV - no device
*         MV_EUNSUPPORT - channel not connected in configuration
*         MV_THINVPP_EBADCALL - channel not connected to DV1
*         MV_ECMDQFULL - command queue is full
********************************************************************************/
int MV_THINVPP_SetHdmiVideoFmt(int color_fmt, int bit_depth, int pixel_rept)
{
	int     cpcbID;
	int     resID;
	int     instat;
	int     avpll_freq_index;
	int     deep_color_index;
	float   freq_factor;
	int ppm1k_en;
	(void)color_fmt;

	if (!thinvpp_obj)
		return (MV_THINVPP_ENODEV);

	if ((cpcbID = CPCB_OF_VOUT(thinvpp_obj, VOUT_HDMI)) == CPCB_INVALID) {
		/* Output is not connected to any DV in configuration */
		return (MV_THINVPP_EUNSUPPORT);
	}

	/* Configure AVPLL */
	resID = thinvpp_obj->dv[cpcbID].output_res;
	if (resID == RES_INVALID)
		return (MV_THINVPP_EBADPARAM);

	if ((m_resinfo_table[resID].freq == 25200) || (m_resinfo_table[resID].freq == 25175)) {
		avpll_freq_index = 0;
	} else if ((m_resinfo_table[resID].freq == 27000) || (m_resinfo_table[resID].freq == 27027)) {
		avpll_freq_index = 1;
		if (pixel_rept == 2) {
			if (m_resinfo_table[resID].scan != SCAN_INTERLACED)
				avpll_freq_index = 2;
			} else if (pixel_rept == 4) {
			if (m_resinfo_table[resID].scan != SCAN_INTERLACED)
				avpll_freq_index = 4;
			else
				avpll_freq_index = 2;
		}
	} else if ((m_resinfo_table[resID].freq == 74250) || (m_resinfo_table[resID].freq == 74176)) {
		avpll_freq_index = 3;
	} else if ((m_resinfo_table[resID].freq == 148500) || (m_resinfo_table[resID].freq == 148352)) {
		if (resID == RES_1080I60 || resID == RES_1080I5994 || resID == RES_1080I50)
			avpll_freq_index = 3;
		else
			avpll_freq_index = 5;
	} else {
		return (MV_THINVPP_EBADPARAM);
	}

	if (bit_depth == OUTPUT_BIT_DEPTH_12BIT) {
		deep_color_index = 2;
		freq_factor = 15.0;
	} else if (bit_depth == OUTPUT_BIT_DEPTH_10BIT) {
		deep_color_index = 1;
		freq_factor = 12.5;
	} else if (bit_depth == OUTPUT_BIT_DEPTH_8BIT) {
		deep_color_index = 0;
		freq_factor = 10.0;
	} else {
		return (MV_THINVPP_EBADPARAM);
	}

	ppm1k_en = NeedAVPLL_PPM1K(resID);

	diag_videoFreq_A(avpll_freq_index, deep_color_index, ppm1k_en, freq_factor, 7);

	delay_10ns(2000000);

	semaphore_pop(thinvpp_obj->pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr, 1);
	semaphore_clr_full(thinvpp_obj->pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr);
	do {
		instat = semaphore_chk_full(thinvpp_obj->pSemHandle, -1);
	} while (!(bTST(instat, avioDhubSemMap_vpp_vppCPCB0_intr)));

	THINVPP_BCMBUF_HardwareTrans_Direct(1, cmd_THINVPP_SetHdmiVideoFmt, sizeof(cmd_THINVPP_SetHdmiVideoFmt));

	return (MV_THINVPP_OK);
}

