//
// Copyright (c) Samsung Electronics. Co. LTD.  All rights reserved.
//
//
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:    stda_tvout_if.c

Abstract:       Implementation of TVout I/F Middle Level S/W
                This module implements Middle Level TVout I/F control

Functions:


Notes:


--*/

#include <windows.h>
#include <bsp_cfg.h>    // for reference HCLK, ECLK
#include <register_map.h>
#include "tvout_global.h"
#include "stda_common.h"
#include "stda_context.h"
#include "stda_resource.h"
#include "stda_tvout_if.h"
#include "tvout_board_dep.h"
#include "stda_hdmi.h"

//#define HDMI_HW_CONFIRM

/*============================================================================*/
// Pre-defined functions
/*============================================================================*/

static BOOL STDA_TVoutIF_init_param(PBYTE pBufIn);
static BOOL STDA_TVoutIF_init_vm_reg(void);
static BOOL STDA_TVoutIF_init_sd_reg(void);
static BOOL STDA_TVoutIF_init_hd_reg(void);
static BOOL STDA_TVoutIF_get_info(PBYTE pBufOut);
static BOOL STDA_TVoutIF_init_syscon_reg(void);
static BOOL STDA_TVoutIF_init_hd_video_mode();

/*

static VOID HPDHandle(DWORD state)
{
	STDAContext *pCtxt = STDA_get_context();
	if (state)
	{
		RETAILMSG(1,(_T("[%s] HPD Plug!!! \n\r"),TEXT(__FUNCTION__)));
	}
	else
	{
		RETAILMSG(1,(_T("[%s] HPD Unplug !!! \n\r"),TEXT(__FUNCTION__)));
//		STDA_resource_compare_GRP0(pCtxt->dwOccupantGRP0);
//		STDA_Grp_stop();
//		STDA_resource_release_GRP0(pCtxt->dwOccupantGRP0);
//		STDA_TVoutIF_stop();
	}
}

*/


/*
static BOOL STDA_TVoutIF_init_hd_video_reg(void);
*/
/*============================================================================*/

BOOL
STDA_TVoutIF_API_Proc
(DWORD hOpenContext,
 DWORD dwCode,
 PBYTE pBufIn,
 DWORD dwLenIn,
 PBYTE pBufOut,
 DWORD dwLenOut,
 PDWORD pdwActualOut)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	DBGMSG(TV_USR4,(_T("[TVOUT] ++STDA_TVoutIF_API_Proc(0x%x)\n\r"),dwCode));

	if(dwCode == STDA_TVOUT_GET_INFO)
	{
		return STDA_TVoutIF_get_info(pBufOut);
	}

	if(!STDA_resource_compare_TVout_interface(hOpenContext))
	{
		return FALSE;
	}

	switch(dwCode)
	{
		case STDA_TVOUT_INIT_INTERFACE_PARAM:
			if(pPMCtxt->bTVoutOutputEnable)
			{
				DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : TVout is already running status\n\r")));
				return FALSE;
			}
				return STDA_TVoutIF_init_param(pBufIn);
			break;
		case STDA_TVOUT_START:
			if(!(pPMCtxt->bTvOutputParam))
			{
				DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : must not start TVoutIF before initializing TVoutIF parameters\n\r")));
				return FALSE;
			}
			if(pPMCtxt->bTVoutOutputEnable)
			{
				DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : TVoutIF is already running\n\r")));
				return FALSE;
			}
			if(!STDA_TVoutIF_start())
			{
				STDA_TVoutIF_stop();
				return FALSE;
			}
			break;
		case STDA_TVOUT_STOP:
			if(!(pPMCtxt->bTVoutOutputEnable))
			{
				DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : TVoutIF is not running\n\r")));
				return FALSE;
			}
			if(pPMCtxt->bVPLayerEnable || pPMCtxt->bGRPLayerEnable[0] || pPMCtxt->bGRPLayerEnable[1])
			{
				DBGMSG(TV_USR1,(_T("[TVRES:ERR] STDA_TVoutIF_API_Proc() : Some layers still show, have to all layers off\r\n")));
				return FALSE;
			}

			return STDA_TVoutIF_stop();
			break;

//		case STDA_TVOUT_GET_INFO:
//			break;
		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : invalid dwCode parameter(%d)\n\r"),dwCode));
			return FALSE;
			break;
	}

	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_API_Proc(0x%08x)\n\r"),dwCode));

	return TRUE;
}

static BOOL
STDA_TVoutIF_init_param
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	TVOUT_OUTPUT_IF *ptTVoutIF = (TVOUT_OUTPUT_IF*)pBufIn;

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_TVoutIF_init_param()\n\r")));

	DBGMSG(TV_FUNC,(_T("[TVOUT]++STDA_TVoutIF_init_param(%d,%d)\n\r"),ptTVoutIF->outMode,ptTVoutIF->dispMode));
	if(ptTVoutIF->outMode > TVOUT_OUTPUT_HDMI_YCBCR ||
		ptTVoutIF->outMode < TVOUT_OUTPUT_COMPOSITE)
	{
		DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : invalid ptTVoutIF->outMode parameter(%d)\n\r"),ptTVoutIF->outMode));
		pPMCtxt->bTvOutputParam = FALSE;
		return FALSE;
	}


	memcpy((void *)&(pPMCtxt->tTvOutputParam), (const void *)ptTVoutIF,sizeof(TVOUT_OUTPUT_IF));

	if(pPMCtxt->bTvOutputParam)
	{
		DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_API_Proc() : Default values are already updated\n\r")));
		return TRUE;
	}

	//Initialize GRPx Layer Parameters to Default Values
	pPMCtxt->grpBurst = VM_BURST_16;
	pPMCtxt->grpEndian = TVOUT_LITTLE_ENDIAN_MODE;

	// Initialize BG Layer Parameters to Default Values
	pPMCtxt->tBGColor[0].uiColorY = 0;
	pPMCtxt->tBGColor[0].uiColorCb = 128;
	pPMCtxt->tBGColor[0].uiColorCr = 128;
	pPMCtxt->tBGColor[1].uiColorY= 0;
	pPMCtxt->tBGColor[1].uiColorCb = 128;
	pPMCtxt->tBGColor[1].uiColorCr = 128;
	pPMCtxt->tBGColor[2].uiColorY= 0;
	pPMCtxt->tBGColor[2].uiColorCb = 128;
	pPMCtxt->tBGColor[2].uiColorCr = 128;

	// Initialize Video Mixer Parameters to Default Values
	pPMCtxt->bVMCscCoefDefault = TRUE;

	// Initialize SDout Parameters to Default Values
	pPMCtxt->sdoutSyncPin = SDOUT_SYNC_SIG_YG;
	pPMCtxt->tSDoutVbi.bWssCVBS = TRUE;
//	pPMCtxt->tSDoutVbi.captionCVBS = SDOUT_INS_OTHERS;
	pPMCtxt->tSDoutVbi.captionCVBS = SDOUT_INS_2;
	pPMCtxt->tSDoutVbi.bWssYSideo = TRUE;
	pPMCtxt->tSDoutVbi.captionYSideo = SDOUT_INS_OTHERS;
	pPMCtxt->tSDoutVbi.bCgmsaRGB = TRUE;
	pPMCtxt->tSDoutVbi.bWssRGB = TRUE;
	pPMCtxt->tSDoutVbi.captionRGB = SDOUT_INS_OTHERS;
	pPMCtxt->tSDoutVbi.bCgmsaYPbPr = TRUE;
	pPMCtxt->tSDoutVbi.bWssYPbPr = TRUE;
	pPMCtxt->tSDoutVbi.captionYPbPr = SDOUT_INS_OTHERS;
	pPMCtxt->tSDoutOffsetGain[0].channel = SDOUT_CHANNEL_0;
	pPMCtxt->tSDoutOffsetGain[0].uiOffset = 0;
	pPMCtxt->tSDoutOffsetGain[0].uiGain = 0x800;
	pPMCtxt->tSDoutOffsetGain[1].channel = SDOUT_CHANNEL_1;
	pPMCtxt->tSDoutOffsetGain[1].uiOffset = 0;
	pPMCtxt->tSDoutOffsetGain[1].uiGain = 0x800;
	pPMCtxt->tSDoutOffsetGain[2].channel = SDOUT_CHANNEL_2;
	pPMCtxt->tSDoutOffsetGain[2].uiOffset = 0;
	pPMCtxt->tSDoutOffsetGain[2].uiGain = 0x800;
	pPMCtxt->tSDoutDelay.uiDelayY = 0x00;
	pPMCtxt->tSDoutDelay.uiOffsetVideoStart = 0xfa;
	pPMCtxt->tSDoutDelay.uiOffsetVideoEnd = 0x00;
	pPMCtxt->bSDoutColorSubCarrierPhaseAdjustment = FALSE;

	pPMCtxt->tSDoutBriHueSat.bBriHueSatAdj = FALSE;
	pPMCtxt->tSDoutBriHueSat.uiGainBrightness = 0x80;
	pPMCtxt->tSDoutBriHueSat.uiOffsetBrightness = 0x00;
	pPMCtxt->tSDoutBriHueSat.uiGain0CbHueSaturation = 0x00;
	pPMCtxt->tSDoutBriHueSat.uiGain1CbHueSaturation = 0x00;
	pPMCtxt->tSDoutBriHueSat.uiGain0CrHueSaturation = 0x00;
	pPMCtxt->tSDoutBriHueSat.uiGain1CrHueSaturation = 0x00;
	pPMCtxt->tSDoutBriHueSat.uiOffsetCbHueSaturation = 0x00;
	pPMCtxt->tSDoutBriHueSat.uiOffsetCrHueSaturation = 0x00;
	pPMCtxt->bSDoutYPbPrComp = FALSE;
	pPMCtxt->tSDoutRGBCompen.bRGBcolorCompensation = FALSE;
	pPMCtxt->tSDoutRGBCompen.uiMaxRGBCube = 0xeb;
	pPMCtxt->tSDoutRGBCompen.uiMinRGBCube = 0x10;
	pPMCtxt->tSDoutCVBSCompen.bCVBSCcolorCompensaton = FALSE;
	pPMCtxt->tSDoutCVBSCompen.uiYLowerMid = 0x200;
	pPMCtxt->tSDoutCVBSCompen.uiYBottom = 0x000;
	pPMCtxt->tSDoutCVBSCompen.uiYTop = 0x3ff;
	pPMCtxt->tSDoutCVBSCompen.uiYUpperMid = 0x200;
	pPMCtxt->tSDoutCVBSCompen.uiRadius = 0x1ff;
	pPMCtxt->tSDoutSvideoCompen.bYCcolorCompensaton = FALSE;
	pPMCtxt->tSDoutSvideoCompen.uiYTop = 0x3ff;
	pPMCtxt->tSDoutSvideoCompen.uiYBottom = 0x000;
	pPMCtxt->tSDoutSvideoCompen.uiYCCylinder = 0x1ff;
	pPMCtxt->tSDoutCompPorch.ui525Back = 0x8a;
	pPMCtxt->tSDoutCompPorch.ui525Front = 0x359;
	pPMCtxt->tSDoutCompPorch.ui625Back = 0x96;
	pPMCtxt->tSDoutCompPorch.ui625Front = 0x35c;
	pPMCtxt->tSDoutRGBSync.syncType = SDOUT_VESA_RGB_SYNC_COMPOSITE;
	pPMCtxt->tSDoutRGBSync.vsyncActive = TVOUT_POL_ACTIVE_HIGH;
	pPMCtxt->tSDoutRGBSync.hsyncActive = TVOUT_POL_ACTIVE_HIGH;
	pPMCtxt->tSDoutXtalkCC[0].channel = SDOUT_CHANNEL_0;
	pPMCtxt->tSDoutXtalkCC[0].uiCoeff2 = 0;
	pPMCtxt->tSDoutXtalkCC[0].uiCoeff1 = 0;
	pPMCtxt->tSDoutXtalkCC[1].channel = SDOUT_CHANNEL_1;
	pPMCtxt->tSDoutXtalkCC[1].uiCoeff2 = 0;
	pPMCtxt->tSDoutXtalkCC[1].uiCoeff1 = 0;
	pPMCtxt->tSDoutXtalkCC[2].channel = SDOUT_CHANNEL_2;
	pPMCtxt->tSDoutXtalkCC[2].uiCoeff2 = 0;
	pPMCtxt->tSDoutXtalkCC[2].uiCoeff1 = 0;
	pPMCtxt->tSDoutClosedCapt.uiDisplayCC = 0;
	pPMCtxt->tSDoutClosedCapt.uiNonDisplayCC = 0;
	pPMCtxt->tSDoutWSS525.copyPermit = SDO_525_COPY_PERMIT;
	pPMCtxt->tSDoutWSS525.mvPsp = SDO_525_MV_PSP_OFF;
	pPMCtxt->tSDoutWSS525.copyInfo = SDO_525_COPY_INFO;
	pPMCtxt->tSDoutWSS525.bAnalogOn = FALSE;
	pPMCtxt->tSDoutWSS525.displayRatio = SDO_525_4_3_NORMAL;
	pPMCtxt->tSDoutWSS625.bSurrounfSound = FALSE;
	pPMCtxt->tSDoutWSS625.bCopyright = FALSE;
	pPMCtxt->tSDoutWSS625.bCopyProtection = FALSE;
	pPMCtxt->tSDoutWSS625.bTextSubtitles = FALSE;
	pPMCtxt->tSDoutWSS625.openSubtitles = SDO_625_NO_OPEN_SUBTITLES;
	pPMCtxt->tSDoutWSS625.cameraFilm = SDO_625_CAMERA;
	pPMCtxt->tSDoutWSS625.colorEncoding = SDO_625_NORMAL_PAL;
	pPMCtxt->tSDoutWSS625.bHelperSignal = FALSE;
	pPMCtxt->tSDoutWSS625.displayRatio = SDO_625_4_3_FULL_576;
	pPMCtxt->tSDoutCGMS525.copyPermit = SDO_525_COPY_PERMIT;
	pPMCtxt->tSDoutCGMS525.mvPsp = SDO_525_MV_PSP_OFF;
	pPMCtxt->tSDoutCGMS525.copyInfo = SDO_525_COPY_INFO;
	pPMCtxt->tSDoutCGMS525.bAnalogOn = FALSE;
	pPMCtxt->tSDoutCGMS525.displayRatio = SDO_525_4_3_NORMAL;
	pPMCtxt->tSDoutCGMS625.bSurrounfSound = FALSE;
	pPMCtxt->tSDoutCGMS625.bCopyright = FALSE;
	pPMCtxt->tSDoutCGMS625.bCopyProtection = FALSE;
	pPMCtxt->tSDoutCGMS625.bTextSubtitles = FALSE;
	pPMCtxt->tSDoutCGMS625.openSubtitles = SDO_625_NO_OPEN_SUBTITLES;
	pPMCtxt->tSDoutCGMS625.cameraFilm = SDO_625_CAMERA;
	pPMCtxt->tSDoutCGMS625.colorEncoding = SDO_625_NORMAL_PAL;
	pPMCtxt->tSDoutCGMS625.bHelperSignal = FALSE;
	pPMCtxt->tSDoutCGMS625.displayRatio = SDO_625_4_3_FULL_576;

	// Initialize HDMI video Parameters to Default Values
	pPMCtxt->tHdmiVideoBlueScreen.bEn = FALSE;
	pPMCtxt->tHdmiColorRange.ucYMin = 1;
	pPMCtxt->tHdmiColorRange.ucYMax = 254;
	pPMCtxt->tHdmiColorRange.ucCMin = 1;
	pPMCtxt->tHdmiColorRange.ucCMax = 254;
	pPMCtxt->tHdmiAviInfoFrame.transType = HDMI_DO_NOT_TANS;
	pPMCtxt->tHdmiAviInfoFrame.ucCheckSum = 0;
	pPMCtxt->tHdmiAviInfoFrame.pucData = pPMCtxt->ucAviByte;
	pPMCtxt->tHdmiMpgInfoFrame.transType = HDMI_DO_NOT_TANS;
	pPMCtxt->tHdmiMpgInfoFrame.ucCheckSum = 0;
	pPMCtxt->tHdmiMpgInfoFrame.pucData = pPMCtxt->ucMpgByte;
	memset((void *)(pPMCtxt->ucAviByte), 0, 13);
	memset((void *)(pPMCtxt->ucMpgByte), 0, 5);
	pPMCtxt->tHdmiTgCmd.bTimingCorrectionEn = FALSE;
	pPMCtxt->tHdmiTgCmd.bBT656SyncEn = FALSE;
	pPMCtxt->tHdmiTgCmd.bTgEn = FALSE;

	// Initialize HDMI Parameters to Default Values
	pPMCtxt->tHdmiSpdInfoFrame.transType = HDMI_DO_NOT_TANS;
	pPMCtxt->tHdmiSpdInfoFrame.pucSpdHeader = pPMCtxt->ucSpdHeader;
	pPMCtxt->tHdmiSpdInfoFrame.pucSpdData = pPMCtxt->ucSpdData;
	memset((void *)(pPMCtxt->ucSpdHeader), 0, 3);
	memset((void *)(pPMCtxt->ucSpdData), 0, 8);
	pPMCtxt->bHDCPEn = FALSE;

	pPMCtxt->hdmiAudioType = HDMI_AUDIO_NO;
	pPMCtxt->bAudioEn = TRUE;
	pPMCtxt->tHdmiAudioParameter.inputPort  = I2S_PORT;
	pPMCtxt->tHdmiAudioParameter.outPacket = HDMI_ASP;
 	pPMCtxt->tHdmiAudioParameter.formatCode = LPCM_FORMAT;
 	pPMCtxt->tHdmiAudioParameter.channelNum = CH_2;
 	pPMCtxt->tHdmiAudioParameter.sampleFreq = SF_44KHZ;
 	pPMCtxt->tHdmiAudioParameter.wordLength = WORD_16;
 	pPMCtxt->tHdmiAudioParameter.I2SParam.bpc = I2S_BPC_16;
 	pPMCtxt->tHdmiAudioParameter.I2SParam.format = I2S_BASIC;
 	pPMCtxt->tHdmiAudioParameter.I2SParam.clk = I2S_32FS;

	switch(ptTVoutIF->dispMode)
	{
		case TVOUT_NTSC_M:
		case TVOUT_NTSC_443:
			pPMCtxt->tSDoutVideoScaleCfg.componentLevel = SDOUT_LEVEL_75IRE;
			pPMCtxt->tSDoutVideoScaleCfg.componentRatio = SDOUT_VTOS_RATIO_10_4;
			pPMCtxt->tSDoutVideoScaleCfg.compositeLevel = SDOUT_LEVEL_75IRE;
			pPMCtxt->tSDoutVideoScaleCfg.compositeRatio = SDOUT_VTOS_RATIO_10_4;
			break;
		case TVOUT_NTSC_J:
			pPMCtxt->tSDoutVideoScaleCfg.componentLevel = SDOUT_LEVEL_0IRE;
			pPMCtxt->tSDoutVideoScaleCfg.componentRatio = SDOUT_VTOS_RATIO_10_4;
			pPMCtxt->tSDoutVideoScaleCfg.compositeLevel = SDOUT_LEVEL_0IRE;
			pPMCtxt->tSDoutVideoScaleCfg.compositeRatio = SDOUT_VTOS_RATIO_10_4;
			break;
		case TVOUT_PAL_BDGHI:
		case TVOUT_PAL_NC:
		case TVOUT_PAL_60:
			pPMCtxt->tSDoutVideoScaleCfg.componentLevel = SDOUT_LEVEL_0IRE;
			pPMCtxt->tSDoutVideoScaleCfg.componentRatio = SDOUT_VTOS_RATIO_7_3;
			pPMCtxt->tSDoutVideoScaleCfg.compositeLevel = SDOUT_LEVEL_0IRE;
			pPMCtxt->tSDoutVideoScaleCfg.compositeRatio = SDOUT_VTOS_RATIO_7_3;
			break;
		case TVOUT_PAL_M:
		case TVOUT_PAL_N:
			pPMCtxt->tSDoutVideoScaleCfg.componentLevel = SDOUT_LEVEL_75IRE;
			pPMCtxt->tSDoutVideoScaleCfg.componentRatio = SDOUT_VTOS_RATIO_7_3;
			pPMCtxt->tSDoutVideoScaleCfg.compositeLevel = SDOUT_LEVEL_75IRE;
			pPMCtxt->tSDoutVideoScaleCfg.compositeRatio = SDOUT_VTOS_RATIO_7_3;
			break;
		case TVOUT_480P_60_16_9:
		case TVOUT_480P_60_4_3:
		case TVOUT_576P_50_16_9:
		case TVOUT_576P_50_4_3:
		case TVOUT_720P_60:
		case TVOUT_1080I_60:
		case TVOUT_1080P_30:			
		case TVOUT_1080P_60:			
/*
			if(!STDA_TVoutIF_init_avi_frame(ptTVoutIF))
			{
			pPMCtxt->bTvOutputParam = FALSE;
			return FALSE;
			}
*/			
			break;
		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : invalid ptTVoutIF->dispMode parameter(%d)\n\r"),ptTVoutIF->dispMode));
			pPMCtxt->bTvOutputParam = FALSE;
			return FALSE;
			break;
	}

	switch(ptTVoutIF->outMode)
	{
		case TVOUT_OUTPUT_COMPOSITE:
			//pPMCtxt->sdoutOrder = SDOUT_OUTPUT_ORDER_COMPOSITE_Y_C_CVBS;
			pPMCtxt->bSDoutDacOn[2] = FALSE;
			pPMCtxt->bSDoutDacOn[1] = FALSE;
			pPMCtxt->bSDoutDacOn[0] = TRUE;
			break;
		case TVOUT_OUTPUT_HDMI:
			pPMCtxt->tHdmiVideoBlueScreen.ucCbB = 0xFF;
			pPMCtxt->tHdmiVideoBlueScreen.ucYG  = 0;
			pPMCtxt->tHdmiVideoBlueScreen.ucCrR = 0;
			break;
		case TVOUT_OUTPUT_DVI:
			pPMCtxt->tHdmiVideoBlueScreen.ucCbB = 0xFF;
			pPMCtxt->tHdmiVideoBlueScreen.ucYG  = 0;
			pPMCtxt->tHdmiVideoBlueScreen.ucCrR = 0;
			break;
		case TVOUT_OUTPUT_HDMI_YCBCR:
			pPMCtxt->tHdmiVideoBlueScreen.ucCbB = 128;
			pPMCtxt->tHdmiVideoBlueScreen.ucYG  = 0;
			pPMCtxt->tHdmiVideoBlueScreen.ucCrR = 128;
			break;
		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_API_Proc() : invalid ptTVoutIF->outMode parameter(%d)\n\r"),ptTVoutIF->outMode));
			pPMCtxt->bTvOutputParam = FALSE;
			return FALSE;
			break;
	}

	pPMCtxt->bTvOutputParam = TRUE;
/*
	// setup Callback for HDMI HPD
	if (!HPDSetCallback(HPDHandle))
	{
		RETAILMSG(1,(_T("[%s] Fail to set HPD call back !!! \n\r"),TEXT(__FUNCTION__)));
	}
	
*/	
	RETAILMSG(1,(_T("[%s] Setup Callback !!! \n\r"),TEXT(__FUNCTION__)));

	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_init_param()\n\r")));

	return TRUE;
}

BOOL
STDA_TVoutIF_start
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
//	STDAContext *pCtxt = STDA_get_context();

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_TVoutIF_start()\n\r")));


	TVout_board_dep_power_on();

	//I want to TVOUT Drv make D0 level.
	pPMCtxt->powerStateChange = D3;

	//If not D0 -> Go to IOCTL_POWER_SET Ioctl make power status Do and start
	if((pPMCtxt->powerState == D0)||(pPMCtxt->powerState == D3))
	{
		//Test For HDMI
		switch(pPMCtxt->tTvOutputParam.outMode)
		{
			case TVOUT_OUTPUT_HDMI:
			case TVOUT_OUTPUT_DVI:
			case TVOUT_OUTPUT_HDMI_YCBCR:

				if(!STDA_TVoutIF_init_hd_video_mode())
				{
					DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_init_hd_video_mode()\n\r")));
					return FALSE;
				}
				break;
		}

		if(!STDA_TVoutIF_init_syscon_reg())
		{
			return FALSE;
		}

		if(!Tvout_power_get_power_status()) // have not to call another request function simultaneously
		{
			TVout_power_on();
		}
		
#ifdef BSP_USEDVFS
		TVout_dvfs_set_level_fix();
#endif // BSP_USEDVFS



		if(!STDA_TVoutIF_init_vm_reg())
		{
			STDA_TVoutIF_stop();
			return FALSE;
		}

		switch(pPMCtxt->tTvOutputParam.outMode)
		{
			case TVOUT_OUTPUT_COMPOSITE:
				if(!STDA_TVoutIF_init_sd_reg())
				{
					return FALSE;
				}
				break;

			case TVOUT_OUTPUT_HDMI:
			case TVOUT_OUTPUT_DVI:
			case TVOUT_OUTPUT_HDMI_YCBCR:

				if(!STDA_TVoutIF_init_hd_reg())
				{
					return FALSE;
				}

//				if(pPMCtxt->pinStatus != HDMI_HPD_MODE)
				{
					STDA_HDMI_HpdSetMode(HDMI_HPD_MODE,TRUE);
				}

				break;

			default:
				STDA_TVoutIF_stop();
				DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_start() : invalid pPMCtxt->tTvOutputParam.outMode parameter(%d)\n\r"),pPMCtxt->tTvOutputParam.outMode));
				return FALSE;
				break;
		}
	}

	pPMCtxt->bTVoutOutputEnable = TRUE;
//	pPMCtxt->powerState = D0;
	pPMCtxt->powerStateChange = D0;

#ifdef SUPPORT_APM_TVD
	pPMCtxt->bChangePowerState = TRUE;
	DevicePowerNotify(L"TVD0:", D0, POWER_NAME);
#endif

	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_start()\n\r")));

	return TRUE;
}

BOOL
STDA_TVoutIF_stop
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
//	STDAContext *pCtxt = STDA_get_context();
	
	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_TVoutIF_stop()\n\r")));

	if(pPMCtxt->powerState == D0)
	{
		if(Tvout_power_get_power_status())
		{

			VMixer_stop();
			Sleep(20);
			
			switch(pPMCtxt->tTvOutputParam.outMode)
			{
				case TVOUT_OUTPUT_COMPOSITE:
					Sdout_stop();
					break;
				case TVOUT_OUTPUT_HDMI:
				case TVOUT_OUTPUT_DVI:
				case TVOUT_OUTPUT_HDMI_YCBCR:
					
					HDMIStop();

					if(pPMCtxt->bHDCPEn)
					{
						HDCPStop();
					}


					HDMI_TG_OnOff(FALSE);

//					if(pPMCtxt->pinStatus != HDMI_EINT_MODE)
					{
						STDA_HDMI_HpdSetMode(HDMI_EINT_MODE,TRUE);
					}
#if HDMIPHY_ON_OFF	
					SetHDMIPHYOnOff(FALSE);
#endif					
					Tvout_power_set_hdmi_en(FALSE);

					break;

				default:
					DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_stop() : invalid pPMCtxt->tTvOutputParam.outMode parameter(%d)\n\r"),pPMCtxt->tTvOutputParam.outMode));
					return FALSE;
					break;
			}

#ifdef BSP_USEDVFS
			TVout_dvfs_clear_level_fix();
#endif // BSP_USEDVFS

			TVout_power_off();
			Tvout_clk_stop();

//			TVout_power_off();

			TVout_board_dep_power_off();

		}
	}

	pPMCtxt->bTVoutOutputEnable = FALSE;
	pPMCtxt->bTvOutputParam = FALSE;

	pPMCtxt->powerStateChange = D3;
//	pPMCtxt->powerState = D3;

#ifdef SUPPORT_APM_TVD
	pPMCtxt->bChangePowerState = TRUE;	
	DevicePowerNotify(L"TVD0:", D3, POWER_NAME);
#endif
	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_stop()\n\r")));

	return TRUE;
}

static BOOL
STDA_TVoutIF_init_vm_reg
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	VMIXER_ERROR error = 0;

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_TVoutIF_init_vm_reg()\n\r")));

	error = VMixer_initialize_status_reg(pPMCtxt->grpBurst, pPMCtxt->grpEndian);
	if(error != VMIXER_NO_ERROR)
	{
		return FALSE;
	}

	error = VMixer_initialize_display_mode(pPMCtxt->tTvOutputParam.dispMode,
									pPMCtxt->tTvOutputParam.outMode);
	if(error != VMIXER_NO_ERROR)
	{
		return FALSE;
	}

	error = VMixer_initialize_Limit_Para_Cfg(pPMCtxt->uiVMLimitYUpper,
									pPMCtxt->uiVMLimitYLower,
									pPMCtxt->uiVMLimitCUpper,
									pPMCtxt->uiVMLimitCUppe);

	if(error != VMIXER_NO_ERROR)
	{
		return FALSE;
	}

	switch(pPMCtxt->tTvOutputParam.outMode)
	{
		case TVOUT_OUTPUT_COMPOSITE:
			VMixer_initialize_csc_coef_default(VMIXER_CSC_RGB_TO_YUV601_FR);
			break;
		case TVOUT_OUTPUT_HDMI:
		case TVOUT_OUTPUT_DVI:
		case TVOUT_OUTPUT_HDMI_YCBCR:
			switch(pPMCtxt->tTvOutputParam.dispMode)
			{
				case TVOUT_480P_60_16_9:
				case TVOUT_480P_60_4_3:
				case TVOUT_576P_50_16_9:
				case TVOUT_576P_50_4_3:
					VMixer_initialize_csc_coef_default(VMIXER_CSC_RGB_TO_YUV601_FR);
					break;

				case TVOUT_720P_60:
				case TVOUT_1080I_60:
				case TVOUT_1080P_30:
				case TVOUT_1080P_60:					
					VMixer_initialize_csc_coef_default(VMIXER_CSC_RGB_TO_YUV709_FR);
					//VMixer_initialize_csc_coef_default(VMIXER_CSC_RGB_TO_YUV601_FR);
					break;
			}
			
			break;
		break;
		default:
		DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_init_vm_reg() : invalid pPMCtxt->tTvOutputParam.outMode parameter(%d)\n\r"),pPMCtxt->tTvOutputParam.outMode));
		return FALSE;
		break;
    }


	error = VMixer_initialize_bg_color(VMIXER_BG_COLOR_0,
									pPMCtxt->tBGColor[0].uiColorY,
									pPMCtxt->tBGColor[0].uiColorCb,
									pPMCtxt->tBGColor[0].uiColorCr);
	if(error != VMIXER_NO_ERROR)
	{
		return FALSE;
	}

	error = VMixer_initialize_bg_color(VMIXER_BG_COLOR_1,
									pPMCtxt->tBGColor[1].uiColorY,
									pPMCtxt->tBGColor[1].uiColorCb,
									pPMCtxt->tBGColor[1].uiColorCr);
	if(error != VMIXER_NO_ERROR)
	{
		return FALSE;
	}

	error = VMixer_initialize_bg_color(VMIXER_BG_COLOR_2,
									pPMCtxt->tBGColor[2].uiColorY,
									pPMCtxt->tBGColor[2].uiColorCb,
									pPMCtxt->tBGColor[2].uiColorCr);
	if(error != VMIXER_NO_ERROR)
	{
		return FALSE;
	}


    // Initialize All Interrupt
    VMixer_set_underflow_interrupt_enable(VM_VIDEO_LAYER, USE_VMIXER_INTERRUPT);
    VMixer_set_underflow_interrupt_enable(VM_GPR0_LAYER, USE_VMIXER_INTERRUPT);
    VMixer_set_underflow_interrupt_enable(VM_GPR1_LAYER, USE_VMIXER_INTERRUPT);

    VMixer_set_vsync_interrupt_enable(USE_VMIXER_VSYNC_INTERRUPT);

    // Clear All Interrupt Pending
    VMixer_clear_underflow_interrupt(TRUE, TRUE, TRUE, TRUE);

    VMixer_clear_vsync_interrupt();

    VMixer_start();

    DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_init_vm_reg()\n\r")));

    return TRUE;
}

static BOOL
STDA_TVoutIF_init_sd_reg
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	SDOUT_ERROR error = 0;

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_TVoutIF_init_sd_reg()\n\r")));

	Sdout_sw_reset(TRUE);
	// TODO: need to reset deactive?

	error = Sdout_initialize_display_mode(pPMCtxt->tTvOutputParam.dispMode,
	pPMCtxt->tTvOutputParam.outMode);

	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_video_scale_cfg(pPMCtxt->tSDoutVideoScaleCfg.componentLevel,
										pPMCtxt->tSDoutVideoScaleCfg.componentRatio,
										pPMCtxt->tSDoutVideoScaleCfg.compositeLevel,
										pPMCtxt->tSDoutVideoScaleCfg.compositeRatio);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_sync_signal_pin(pPMCtxt->sdoutSyncPin);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_vbi(pPMCtxt->tSDoutVbi.bWssCVBS,
							pPMCtxt->tSDoutVbi.captionCVBS,
							pPMCtxt->tSDoutVbi.bWssYSideo,
							pPMCtxt->tSDoutVbi.captionYSideo,
							pPMCtxt->tSDoutVbi.bCgmsaRGB,
							pPMCtxt->tSDoutVbi.bWssRGB,
							pPMCtxt->tSDoutVbi.captionRGB,
							pPMCtxt->tSDoutVbi.bCgmsaYPbPr,
							pPMCtxt->tSDoutVbi.bWssYPbPr,
							pPMCtxt->tSDoutVbi.captionYPbPr);

	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_offset_gain(pPMCtxt->tSDoutOffsetGain[0].channel,
									pPMCtxt->tSDoutOffsetGain[0].uiOffset,
									pPMCtxt->tSDoutOffsetGain[0].uiGain);

	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_offset_gain(pPMCtxt->tSDoutOffsetGain[1].channel,
									pPMCtxt->tSDoutOffsetGain[1].uiOffset,
									pPMCtxt->tSDoutOffsetGain[1].uiGain);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_offset_gain(pPMCtxt->tSDoutOffsetGain[2].channel,
									pPMCtxt->tSDoutOffsetGain[2].uiOffset,
									pPMCtxt->tSDoutOffsetGain[2].uiGain);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	Sdout_initialize_delay(pPMCtxt->tSDoutDelay.uiDelayY,
						pPMCtxt->tSDoutDelay.uiOffsetVideoStart,
						pPMCtxt->tSDoutDelay.uiOffsetVideoEnd);

	Sdout_initialize_schlock(pPMCtxt->bSDoutColorSubCarrierPhaseAdjustment);


	Sdout_initialize_color_compensaton_onoff	(pPMCtxt->tSDoutBriHueSat.bBriHueSatAdj,
											pPMCtxt->bSDoutYPbPrComp,
											pPMCtxt->tSDoutRGBCompen.bRGBcolorCompensation,
											pPMCtxt->tSDoutSvideoCompen.bYCcolorCompensaton,
											pPMCtxt->tSDoutCVBSCompen.bCVBSCcolorCompensaton);

	Sdout_initialize_brightness_hue_saturation(pPMCtxt->tSDoutBriHueSat.uiGainBrightness,
											pPMCtxt->tSDoutBriHueSat.uiOffsetBrightness,
											pPMCtxt->tSDoutBriHueSat.uiGain0CbHueSaturation,
											pPMCtxt->tSDoutBriHueSat.uiGain1CbHueSaturation,
											pPMCtxt->tSDoutBriHueSat.uiGain0CrHueSaturation,
											pPMCtxt->tSDoutBriHueSat.uiGain1CrHueSaturation,
											pPMCtxt->tSDoutBriHueSat.uiOffsetCbHueSaturation,
											pPMCtxt->tSDoutBriHueSat.uiOffsetCrHueSaturation);

	Sdout_initialize_rgb_color_compensation(pPMCtxt->tSDoutRGBCompen.uiMaxRGBCube,
										pPMCtxt->tSDoutRGBCompen.uiMinRGBCube);

	Sdout_initialize_cvbs_color_compensation	(pPMCtxt->tSDoutCVBSCompen.uiYLowerMid,
											pPMCtxt->tSDoutCVBSCompen.uiYBottom,
											pPMCtxt->tSDoutCVBSCompen.uiYTop,
											pPMCtxt->tSDoutCVBSCompen.uiYUpperMid,
											pPMCtxt->tSDoutCVBSCompen.uiRadius);

	Sdout_initialize_svideo_color_compensation(pPMCtxt->tSDoutSvideoCompen.uiYTop,
											pPMCtxt->tSDoutSvideoCompen.uiYBottom,
											pPMCtxt->tSDoutSvideoCompen.uiYCCylinder);

	Sdout_initialize_component_porch(pPMCtxt->tSDoutCompPorch.ui525Back,
									pPMCtxt->tSDoutCompPorch.ui525Front,
									pPMCtxt->tSDoutCompPorch.ui625Back,
									pPMCtxt->tSDoutCompPorch.ui625Front);

	error = Sdout_initialize_vesa_rgb_sync(pPMCtxt->tSDoutRGBSync.syncType,
										pPMCtxt->tSDoutRGBSync.vsyncActive,
										pPMCtxt->tSDoutRGBSync.hsyncActive);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_channel_xtalk_cancellation_coeff(pPMCtxt->tSDoutXtalkCC[0].channel,
														pPMCtxt->tSDoutXtalkCC[0].uiCoeff2,
														pPMCtxt->tSDoutXtalkCC[0].uiCoeff1);

	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_channel_xtalk_cancellation_coeff(pPMCtxt->tSDoutXtalkCC[1].channel,
														pPMCtxt->tSDoutXtalkCC[1].uiCoeff2,
														pPMCtxt->tSDoutXtalkCC[1].uiCoeff1);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_channel_xtalk_cancellation_coeff(pPMCtxt->tSDoutXtalkCC[2].channel,
														pPMCtxt->tSDoutXtalkCC[2].uiCoeff2,
														pPMCtxt->tSDoutXtalkCC[2].uiCoeff1);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	Sdout_initialize_closed_caption(pPMCtxt->tSDoutClosedCapt.uiDisplayCC,
								pPMCtxt->tSDoutClosedCapt.uiNonDisplayCC);

	error = Sdout_initialize_wss525_data(pPMCtxt->tSDoutWSS525.copyPermit,
									pPMCtxt->tSDoutWSS525.mvPsp,
									pPMCtxt->tSDoutWSS525.copyInfo,
									pPMCtxt->tSDoutWSS525.bAnalogOn,
									pPMCtxt->tSDoutWSS525.displayRatio);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_wss625_data(pPMCtxt->tSDoutWSS625.bSurrounfSound,
									pPMCtxt->tSDoutWSS625.bCopyright,
									pPMCtxt->tSDoutWSS625.bCopyProtection,
									pPMCtxt->tSDoutWSS625.bTextSubtitles,
									pPMCtxt->tSDoutWSS625.openSubtitles,
									pPMCtxt->tSDoutWSS625.cameraFilm,
									pPMCtxt->tSDoutWSS625.colorEncoding,
									pPMCtxt->tSDoutWSS625.bHelperSignal,
									pPMCtxt->tSDoutWSS625.displayRatio);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_cgmsa525_data(pPMCtxt->tSDoutCGMS525.copyPermit,
										pPMCtxt->tSDoutCGMS525.mvPsp,
										pPMCtxt->tSDoutCGMS525.copyInfo,
										pPMCtxt->tSDoutCGMS525.bAnalogOn,
										pPMCtxt->tSDoutCGMS525.displayRatio);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_cgmsa625_data(pPMCtxt->tSDoutCGMS625.bSurrounfSound,
										pPMCtxt->tSDoutCGMS625.bCopyright,
										pPMCtxt->tSDoutCGMS625.bCopyProtection,
										pPMCtxt->tSDoutCGMS625.bTextSubtitles,
										pPMCtxt->tSDoutCGMS625.openSubtitles,
										pPMCtxt->tSDoutCGMS625.cameraFilm,
										pPMCtxt->tSDoutCGMS625.colorEncoding,
										pPMCtxt->tSDoutCGMS625.bHelperSignal,
										pPMCtxt->tSDoutCGMS625.displayRatio);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	// Disable All Interrupt
	Sdout_set_interrupt_enable(USE_SDOUT_INTERRUPT);

	// Clear All Interrupt Pending
	Sdout_clear_interrupt_pending();

	Sdout_start();

//	TVout_power_set_dac_onoff(TRUE);

	error = Sdout_initialize_dac_power_onoff(SDOUT_CHANNEL_0,
										pPMCtxt->bSDoutDacOn[0]);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_dac_power_onoff(SDOUT_CHANNEL_1,
										pPMCtxt->bSDoutDacOn[1]);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	error = Sdout_initialize_dac_power_onoff(SDOUT_CHANNEL_2,
										pPMCtxt->bSDoutDacOn[2]);
	if(error != SDOUT_NO_ERROR)
	{
		return FALSE;
	}

	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_init_sd_reg()\n\r")));

	return TRUE;
}

static BOOL
STDA_TVoutIF_init_hd_reg
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_TVoutIF_init_hd_reg(%d,%d)\n\r"),pPMCtxt->hdmiAudioType,pPMCtxt->bHDCPEn));


#ifdef HDMI_HW_TEST

	HDMI_mixer_test(pPMCtxt->uiHdmiPhyCon);

	HDMI_Enable(TRUE);
	HDMI_TG_OnOff(TRUE);


#else

	Tvout_power_print();
	Tvout_clk_print();


	HDMISetVideoMode(&pPMCtxt->tHdmiVideoParameter);
	HDMI_TG_Setting(pPMCtxt->uiHdmiPhyCon);

	switch(pPMCtxt->tTvOutputParam.outMode)
	{
		case TVOUT_OUTPUT_HDMI:
		case TVOUT_OUTPUT_HDMI_YCBCR:

			switch(pPMCtxt->hdmiAudioType)
			{
				case HDMI_AUDIO_PCM:
					HDMISetAudioMode(&pPMCtxt->tHdmiAudioParameter);
					break;

				case HDMI_AUDIO_NO:
					break;

				default:
					DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_init_hd_reg() : invalid pPMCtxt->hdmiAudioType(%d)\n\r"),pPMCtxt->hdmiAudioType));
					return FALSE;
					break;
			}

			HDMIAudioEnable(pPMCtxt->bAudioEn);

			HDMISetBlueScreenColor(pPMCtxt->tHdmiVideoBlueScreen.ucCbB, pPMCtxt->tHdmiVideoBlueScreen.ucYG, pPMCtxt->tHdmiVideoBlueScreen.ucCrR);

			HDMIStart();
			HDMI_TG_OnOff(TRUE);
			
			break;

		case TVOUT_OUTPUT_DVI:  // DVI doesn't support audio

			HDMISetBlueScreenColor(pPMCtxt->tHdmiVideoBlueScreen.ucCbB, pPMCtxt->tHdmiVideoBlueScreen.ucYG, pPMCtxt->tHdmiVideoBlueScreen.ucCrR);		

			HDMIStart();
			HDMI_TG_OnOff(TRUE);
			
			break;

		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_init_hd_reg() : invalid pPMCtxt->tTvOutputParam.outMode(%d)\n\r"),pPMCtxt->tTvOutputParam.outMode));
			return FALSE;
			break;
	}
#endif

	if(pPMCtxt->bHDCPEn)
	{
		HDCPStart();
	}


	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_init_hd_reg()\n\r")));

	return TRUE;
}

static BOOL
STDA_TVoutIF_init_hd_video_mode()
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	HDMI_ERROR error = 0;

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_TVoutIF_init_hd_video_mode()\n\r")));

	pPMCtxt->tHdmiVideoParameter.colorDepth = HDMI_CD_24;
	pPMCtxt->tHdmiVideoParameter.colorimetry = HDMI_COLORIMETRY_NO_DATA;

	switch(pPMCtxt->tTvOutputParam.outMode)
	{
		case TVOUT_OUTPUT_HDMI_YCBCR:
			pPMCtxt->tHdmiVideoParameter.mode = HDMI;
			pPMCtxt->tHdmiVideoParameter.colorSpace = HDMI_CS_YCBCR444;
			break;

		case TVOUT_OUTPUT_HDMI:
			pPMCtxt->tHdmiVideoParameter.mode = HDMI;
			pPMCtxt->tHdmiVideoParameter.colorSpace = HDMI_CS_RGB;
			break;

		case TVOUT_OUTPUT_DVI:
			pPMCtxt->tHdmiVideoParameter.mode = DVI;
			pPMCtxt->tHdmiVideoParameter.colorSpace = HDMI_CS_RGB;
			break;
			

		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_init_hd_video_mode() : invalid pPMCtxt->tTvOutputParam.outMode parameter(%d)\n\r"),pPMCtxt->tTvOutputParam.outMode));
			return FALSE;
			break;
	}

	switch(pPMCtxt->tTvOutputParam.dispMode)
	{
		case TVOUT_480P_60_16_9:
			pPMCtxt->tHdmiVideoParameter.resolution = v720x480p_60Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
			//Reter to hdmi_internal.h aVideoParams
			pPMCtxt->uiHdmiPhyCon = 1;
			break;

		case TVOUT_480P_60_4_3:
			pPMCtxt->tHdmiVideoParameter.resolution = v720x480p_60Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3;			
			pPMCtxt->uiHdmiPhyCon = 1;
			break;

		case TVOUT_576P_50_16_9:
			pPMCtxt->tHdmiVideoParameter.resolution = v720x576p_50Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
			pPMCtxt->uiHdmiPhyCon = 10;
			break;

		case TVOUT_576P_50_4_3:
			pPMCtxt->tHdmiVideoParameter.resolution = v720x576p_50Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3;			
			pPMCtxt->uiHdmiPhyCon = 10;
			break;

		case TVOUT_720P_60:
			pPMCtxt->tHdmiVideoParameter.resolution = v1280x720p_60Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
			pPMCtxt->uiHdmiPhyCon = 2;
			break;

		case TVOUT_1080I_60:
			pPMCtxt->tHdmiVideoParameter.resolution = v1920x1080i_60Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
			pPMCtxt->uiHdmiPhyCon = 3;
			break;
/*
// ***** CAUTION!!!!!!!  ***** 
// We don't recommand this resolution.
// If you use this resolution , there is some problem like Frame Drop.
// It may ouccur timeimg issue, not system performance.
*/
		case TVOUT_1080P_30:
			pPMCtxt->tHdmiVideoParameter.resolution = v1920x1080p_30Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
			pPMCtxt->uiHdmiPhyCon = 21;
			break;

		case TVOUT_1080P_60:
			pPMCtxt->tHdmiVideoParameter.resolution = v1920x1080p_60Hz;
			pPMCtxt->tHdmiVideoParameter.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
			pPMCtxt->uiHdmiPhyCon = 9;
			break;

		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_init_hd_video_mode() : invalid pPMCtxt->tTvOutputParam.dispMode parameter(%d)\n\r"),pPMCtxt->tTvOutputParam.dispMode));
			return FALSE;
			break;
	}

	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_TVoutIF_init_hd_video_reg()\n\r")));

	return TRUE;
}


static BOOL STDA_TVoutIF_get_info(PBYTE pBufOut)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	pTVOUT_OUTPUT_INFO pInfo = (pTVOUT_OUTPUT_INFO)pBufOut;

	DBGMSG(TV_USR4,(_T("[TVOUT] ++ STDA_TVoutIF_get_info()\n\r")));


	pInfo->dispMode = pPMCtxt->tTvOutputParam.dispMode;
	pInfo->outMode = pPMCtxt->tTvOutputParam.outMode;
	pInfo->bTVon = pPMCtxt->bTVoutOutputEnable;
	pInfo->bVPon = pPMCtxt->bVPLayerEnable;
	pInfo->bGRP0 = pPMCtxt->bGRPLayerEnable[0];
	pInfo->bGRP1 = pPMCtxt->bGRPLayerEnable[1];

	DBGMSG(TV_USR4,(_T("     pInfo->dispMode=[%d]\n\r"),pInfo->dispMode));
	DBGMSG(TV_USR4,(_T("     pInfo->outMode=[%d]\n\r"),pInfo->outMode));
	DBGMSG(TV_USR4,(_T("     pInfo->bTVon=[%d]\n\r"),pInfo->bTVon));
	DBGMSG(TV_USR4,(_T("     pInfo->bVPon=[%d]\n\r"),pInfo->bVPon));
	DBGMSG(TV_USR4,(_T("     pInfo->bGRP0=[%d]\n\r"),pInfo->bGRP0));
	DBGMSG(TV_USR4,(_T("     pInfo->bGRP1=[%d]\n\r"),pInfo->bGRP1));
	
	DBGMSG(TV_USR4,(_T("[TVOUT] --STDA_TVoutIF_get_info()\n\r")));


	return TRUE;

}

static BOOL STDA_TVoutIF_init_syscon_reg(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	TVOUT_CLK_ERROR error = HDMI_NO_ERROR;

	DBGMSG(TV_FUNC,(_T("[STDA] ++STDA_TVoutIF_init_syscon_reg()\r\n")));

//Initalize VPLL
//Masking Src
#if VPLL_ON_OFF
	Tvout_clk_set_clk_mask_onoff(FALSE);

	Tvout_clk_set_clk_src_onoff(TVOUT_CLK_SRCCLK_VCLK_54, TRUE);
	Tvout_clk_initialize_vpll(0x00000e10, VPLL_MDIV, VPLL_PDIV, VPLL_SDIV);

	Tvout_clk_vpll_onoff(TRUE);

	Tvout_clk_set_clk_mask_onoff(TRUE);
#endif

	Tvout_clk_set_clk_src_init();



//TV Blk Clock on
	Tvout_clk_set_tvblock_on_off(TRUE);

	switch(pPMCtxt->tTvOutputParam.outMode)
	{
		case TVOUT_OUTPUT_COMPOSITE:
			Tvout_clk_set_mixer_src(TVOUT_MIXER_CLK_SRCCLK_VCLK_54);

			TVout_power_set_dac_onoff(TRUE);			

			Tvout_clk_set_vp_clk_onoff(TRUE);			
			Tvout_clk_set_vmixer_clk_onoff(TRUE);
			Tvout_clk_set_tvenc_clk_onoff(TRUE);
			
			Tvout_clk_set_hdmi_clk_onoff(TRUE); //For HPD Wake up

			break;
		case TVOUT_OUTPUT_HDMI:
		case TVOUT_OUTPUT_DVI:
		case TVOUT_OUTPUT_HDMI_YCBCR:
			Tvout_clk_set_mixer_src(TVOUT_MIXER_CLK_SRCCLK_HDMI_PHY);

			TVout_clk_set_hdmi_phy_con_onoff();

			Tvout_clk_set_vp_clk_onoff(TRUE);
			Tvout_clk_set_vmixer_clk_onoff(TRUE);

			Tvout_clk_set_hdmi_clk_onoff(TRUE);
			TVout_clk_set_hdmi_i2c_phy_clk_onoff(TRUE);

			Tvout_power_set_hdmi_div(0x96);
			Tvout_power_set_hdmi_en(TRUE);

			SetHDMIPHYOnOff(TRUE);


#ifdef FIX_HDMI_DISPLAY_ISSUE

			TVout_power_off();
			TVout_power_on();

#endif

			Tvout_clk_print();
			Tvout_power_print();
			break;
		default:
			STDA_TVoutIF_stop();
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_TVoutIF_start() : invalid outMode parameter(%d)\n\r"),pPMCtxt->tTvOutputParam.outMode));
			pPMCtxt->bTvOutputParam = FALSE;
			return FALSE;
			break;
	}

	return TRUE;
}

BOOL
STDA_BG_API_Proc
(DWORD hOpenContext,
 DWORD dwCode,
 PBYTE pBufIn,
 DWORD dwLenIn,
 PBYTE pBufOut,
 DWORD dwLenOut,
 PDWORD pdwActualOut)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_BG_API_Proc(0x%x)\n\r"),dwCode));

	if(!(pPMCtxt->bTvOutputParam))
	{
		DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_BG_API_Proc() : must not initialize BG before initializing TVoutIF parameters\n\r")));
		return FALSE;
	}

	if(pPMCtxt->bTVoutOutputEnable)
	{
		DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_BG_API_Proc() : must not initialize BG after TVoutIF is running\n\r")));
		return FALSE;
	}

	if(!STDA_resource_compare_TVout_interface(hOpenContext))
	{
		return FALSE;
	}

	switch(dwCode)
	{
		case STDA_BG_INIT_COLOR:
			memcpy((void *)&(pPMCtxt->tBGColor[0]), (const void *)pBufIn, sizeof(STDA_ARG_BG_COLOR));
			memcpy((void *)&(pPMCtxt->tBGColor[1]),(const void *)pBufIn, sizeof(STDA_ARG_BG_COLOR));
			memcpy((void *)&(pPMCtxt->tBGColor[2]),(const void *)pBufIn, sizeof(STDA_ARG_BG_COLOR));
			break;
		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_BG_API_Proc() : invalid dwCode parameter(%d)\n\r"),dwCode));
			return FALSE;
			break;
	}

	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_BG_API_Proc(0x%08x)\n\r"),dwCode));

	return TRUE;
}



BOOL
STDA_SDout_API_Proc
(DWORD hOpenContext,
 DWORD dwCode,
 PBYTE pBufIn,
 DWORD dwLenIn,
 PBYTE pBufOut,
 DWORD dwLenOut,
 PDWORD pdwActualOut)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	DBGMSG(TV_FUNC,(_T("[TVOUT] ++STDA_SDout_API_Proc(0x%x)\n\r"),dwCode));

	if(!(pPMCtxt->bTvOutputParam))
	{
		DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_SDout_API_Proc() : must not initialize SD before initializing TVoutIF parameters\n\r")));
		return FALSE;
	}

	if(pPMCtxt->bTVoutOutputEnable)
	{
		DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_SDout_API_Proc() : must not initialize SD after TVoutIF is running\n\r")));
		return FALSE;
	}

	if(!STDA_resource_compare_TVout_interface(hOpenContext))
	{
		return FALSE;
	}

	switch(dwCode)
	{
/*
		case STDA_SDOUT_INIT_OUTPUT_ORDER:
		{
			STDA_ARG_SDOUT_ORDER *pOrder = (pSTDA_ARG_SDOUT_ORDER)pBufIn;
			pPMCtxt->sdoutOrder = pOrder->order;
			pPMCtxt->bSDoutDacOn[0] = pOrder->bDac[0];
			pPMCtxt->bSDoutDacOn[1] = pOrder->bDac[1];
			pPMCtxt->bSDoutDacOn[2] = pOrder->bDac[2];
		}
			break;
*/
		default:
			DBGMSG(TV_USR1,(_T("[TVOUT:ERR] STDA_SDout_API_Proc() : invalid dwCode parameter(%d)\n\r"),dwCode));
			return FALSE;
			break;
	}

	DBGMSG(TV_FUNC,(_T("[TVOUT] --STDA_SDout_API_Proc(0x%08x)\n\r"),dwCode));

	return TRUE;
}

