#include <windows.h>
#include <bsp.h>
//#include <bsp_cfg.h>
#include <register_map.h>
#include <assert.h>
#include <ceddk.h>

#include "dcs.h"
#include "dsim.h"
#include "dsi_init.h"

static DSIM_Infor* g_oDSIMInfor;

#define MIPI_MSG(x) DBGMSG(DISP_USR3,x);

//#define Vector_DSI
#ifdef Vector_DSI
#define DSIM_Outp32(sfr, uTemp)    {MIPI_MSG((_T("Outp1w\t0x%x\t0xh%x;\r\n"), (DWORD)(&g_oDSIMInfor->m_pBaseAddr->sfr), (uTemp))); Outp32(&g_oDSIMInfor->m_pBaseAddr->sfr, uTemp);}
static DWORD Vector_Inp32(DWORD sfr)
{
    DWORD uTemp = (*(volatile DWORD *)(sfr));
    MIPI_MSG((_T("Inp1w\t0x%x\n"),uTemp));
    return uTemp;
}
#define DSIM_Inp32(sfr)            Vector_Inp32((DWORD)(&g_oDSIMInfor->m_pBaseAddr->sfr))
#else
#define DSIM_Outp32(sfr, uTemp)    Outp32(&g_oDSIMInfor->m_pBaseAddr->sfr, uTemp)
#define DSIM_Outp16(sfr, uTemp)    Outp16(&g_oDSIMInfor->m_pBaseAddr->sfr, uTemp)
#define DSIM_Outp8(sfr, uTemp)    Outp8(&g_oDSIMInfor->m_pBaseAddr->sfr, uTemp)
#define DSIM_Inp32(sfr)            Inp32(&g_oDSIMInfor->m_pBaseAddr->sfr)
#define DSIM_Inp16(sfr)            Inp16(&g_oDSIMInfor->m_pBaseAddr->sfr)
#define DSIM_Inp8(sfr)            Inp8(&g_oDSIMInfor->m_pBaseAddr->sfr)
#endif

// to build in Eboot
BYTE pInfor_mem[sizeof(DSIM_Infor)];
BYTE pMainDispConf_mem[sizeof(DDI_Configuration)];
BYTE pSubDispConf_mem[sizeof(DDI_Configuration)];
BYTE oDSIConfiguration_mem[sizeof(DSIM_Configuration)];

//////////
// Function Name : DSIM_DefaultLinkAndPhy
// Function Description :
//   This function reads Status of DSIM
// Input :     DDI_Configuration : Configuration of DDI to Initialize DSI
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
DSIM_Configuration DSIM_DefaultLinkAndPhy(void)
{
    DSIM_Configuration oReturnPara;

    #if ( DSIM_Version == DSIM_1_02)
    oReturnPara.m_ucDSIM_Version = TRUE;                //EOT Packet Genration
    #elif ( DSIM_Version == DSIM_1_00)
    oReturnPara.m_ucPacketThreshold = FALSE;            //Tx Packet Fifo Threshold Enable
    oReturnPara.m_usThresholdLevel = 0x0;
    #endif
    //Porch Option
    oReturnPara.m_ucAutoVerticalCnt = FALSE;            //Auto Vertical Cnt Mode        //chandolp shouldbe TRUE?
    oReturnPara.m_ucHSE = TRUE;                        //Horizontal Sync Evnet Mode    //chandolp shouldbe TRUE?
    oReturnPara.m_ucHFP = FALSE;                        //Discard Horizontal Front Porch Time
    oReturnPara.m_ucHBP = FALSE;                        //Discard Horizontal Back Porch Time
    oReturnPara.m_ucHSA = FALSE;                        //Discard Horizontal Sync Area Timing
    //Data Lane
    oReturnPara.m_eNoDataLane = DataLane_2;            //Number of Data Lane using DSI Master

    //Pll PMS & Frequency Band
    oReturnPara.m_bPllBypass = FALSE;                    //Pll Bypass
    // PLL Clock = (MIPI_FIN * M) / (M * 2^S)        27MHz
    #if (1 == 0)                // 100.125MHz
    oReturnPara.m_ucP = 3;
    oReturnPara.m_usM = 100;
    oReturnPara.m_ucS = 3;
    #elif (1 == 0)            // 150MHz
    oReturnPara.m_ucP = 4;
    oReturnPara.m_usM = 100;
    oReturnPara.m_ucS = 2;
    #elif (1 == 1)            // 200.25MHz
    oReturnPara.m_ucP = 3;
    oReturnPara.m_usM = 100;
    oReturnPara.m_ucS = 2;
    #elif(1== 0)                // 250MHz
    oReturnPara.m_ucP = 12;
    oReturnPara.m_usM = 250;
    oReturnPara.m_ucS = 1;
    #elif(1== 0)                // 300MHz
    oReturnPara.m_ucP = 4;
    oReturnPara.m_usM = 100;
    oReturnPara.m_ucS = 1;
    #elif(1== 0)                // 349.5MHz
    oReturnPara.m_ucP = 12;
    oReturnPara.m_usM = 350;
    oReturnPara.m_ucS = 1;
    #elif (1 == 0)            // 400.5MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 267;
    oReturnPara.m_ucS = 1;
    #elif(1== 0)                // 450MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 300;
    oReturnPara.m_ucS = 1;
    #elif(1== 0)                // 500MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 333;
    oReturnPara.m_ucS = 1;
    #elif(1== 0)                // 550MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 183;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 600MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 200;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 651MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 217;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 699MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 233;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 750MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 250;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 801MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 267;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 849MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 283;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 900MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 300;
    oReturnPara.m_ucS = 0;
    #elif(1== 0)                // 951MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 317;
    oReturnPara.m_ucS = 0;
    #else                    // 999MHz
    oReturnPara.m_ucP = 9;
    oReturnPara.m_usM = 333;
    oReturnPara.m_ucS = 0;
    #endif
    //Pll Stable Time
    #if (1 == 1)
    oReturnPara.m_uPllStableTime = (1000000 * 400);            // D-PHY PLL Stable Time Spec : Min=200usec ~ Max 400usec
    #endif
    //Byte clock and Escape Clock
    oReturnPara.m_eByteclk = DSIM_ByteClkSrc_DPhy;    //Byte Clk source
    oReturnPara.m_dEscClk = 9 * 1000000;            //Escape clk : 10MHz
    //BTA Counter
    oReturnPara.m_usAutoBTACnt = 0xff;                //Auto Stop State to BTA Change Count 0 ~ 0xfff
    oReturnPara.m_ucBTATimeOut = 0xff;                //BTA Time Out 0 ~ 0xff
    oReturnPara.m_usRxTimeOut = 0xffff;                //LP Rx Time Out 0 ~ 0xffff

    #if (DPHY_Version == DPHY_45n)
    oReturnPara.m_uPhyTunnig1 = (0x4 << 5);            //45n Phy AFC Mode Code at 12MHz
    #endif

    oReturnPara.m_eIsrPriority[0] = ErrContentLP0;
    oReturnPara.m_eIsrPriority[1] = ErrContnetLP1;
    oReturnPara.m_eIsrPriority[2] = ErrSync0;
    oReturnPara.m_eIsrPriority[3] = ErrSync1;
    oReturnPara.m_eIsrPriority[4] = ErrSync2;
    oReturnPara.m_eIsrPriority[5] = ErrControl0;
    oReturnPara.m_eIsrPriority[6] = ErrControl1;
    oReturnPara.m_eIsrPriority[7] = ErrControl2;
    oReturnPara.m_eIsrPriority[8] = ErrEscLane0;
    oReturnPara.m_eIsrPriority[9] = ErrEscLane1;
    oReturnPara.m_eIsrPriority[10] = ErrEscLane2;
    oReturnPara.m_eIsrPriority[11] = ErrRxECC;
    oReturnPara.m_eIsrPriority[12] = ErrRxCRC ;
    oReturnPara.m_eIsrPriority[13] = BTAAckTimeOut;
    oReturnPara.m_eIsrPriority[14] = LPDRTimeOut;
    oReturnPara.m_eIsrPriority[15] = RxAck;
    oReturnPara.m_eIsrPriority[16] = RxTE;
    oReturnPara.m_eIsrPriority[17] = RxDatDone;
    oReturnPara.m_eIsrPriority[18] = BusTunrOver;
    oReturnPara.m_eIsrPriority[19] = SwRstRelease;
    oReturnPara.m_eIsrPriority[20] = PllStable;
    oReturnPara.m_eIsrPriority[21] = FrameDone;
    oReturnPara.m_eIsrPriority[22] = SFRFifoEmpty;
    oReturnPara.m_eIsrPriority[23] = ErrControl3;
    oReturnPara.m_eIsrPriority[24] = ErrSync3;
    oReturnPara.m_eIsrPriority[25] = ErrEscLane3;

    return oReturnPara;
}

//////////
// Function Name : DSIM_GetStatus
// Function Description :
//   This function reads Status of DSIM
// Input :     NONE
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
DSIM_Infor* DSIM_Create(DSIM_Configuration  oDSIConfiguration, DDI_Configuration* pMainDispConf, MIPIDSI_REG* pDSIMReg, DDI_Configuration* pSubDispConf, BYTE ucIntrEn)
{
    PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};
//    DSIM_Infor* pInfor = (DSIM_Infor*) malloc(sizeof(DSIM_Infor));
    DSIM_Infor* pInfor = (DSIM_Infor *)pInfor_mem;
    pInfor = (DSIM_Infor*)memset(pInfor, 0, sizeof(DSIM_Infor));

    g_oDSIMInfor = pInfor;
    //SFR
    pInfor->m_pBaseAddr = (DSIM_SFR *)pDSIMReg;

    //Main Display
    //pInfor->m_pMainDispConfiguration = (DDI_Configuration*) malloc(sizeof(DDI_Configuration));
    pInfor->m_pMainDispConfiguration = (DDI_Configuration*)pMainDispConf_mem;
    memcpy(pInfor->m_pMainDispConfiguration, pMainDispConf, sizeof(DDI_Configuration));

    //Sub Display (Optional)
    if ( pSubDispConf != NULL)
    {
        //pInfor->m_pSubDispConfiguration = (DDI_Configuration*) malloc(sizeof(DDI_Configuration));
        pInfor->m_pSubDispConfiguration = (DDI_Configuration*)pSubDispConf_mem;
        memcpy(pInfor->m_pSubDispConfiguration, pSubDispConf, sizeof(DDI_Configuration));
    }
    else
    {
        pInfor->m_pSubDispConfiguration = NULL;
        pInfor->m_uSubDispFrameAddr = 0;
    }

    //pInfor->m_oDSIConfiguration = (DSIM_Configuration*) malloc(sizeof(DSIM_Configuration));
    pInfor->m_oDSIConfiguration = (DSIM_Configuration*)oDSIConfiguration_mem;
    memcpy(pInfor->m_oDSIConfiguration, &oDSIConfiguration, sizeof(DSIM_Configuration));

    // Lane Selection
    if( oDSIConfiguration.m_eNoDataLane == DataLane_1)
        pInfor->m_eDataLane = (DSIM_LANE)Lane_Data0;
    else if( oDSIConfiguration.m_eNoDataLane == DataLane_2)
        pInfor->m_eDataLane = (DSIM_LANE)(Lane_Data0 | Lane_Data1);
    else if( oDSIConfiguration.m_eNoDataLane == DataLane_3)
        pInfor->m_eDataLane = (DSIM_LANE)(Lane_Data0 | Lane_Data1 | Lane_Data2);
    else if( oDSIConfiguration.m_eNoDataLane == DataLane_4)
        pInfor->m_eDataLane = (DSIM_LANE)(Lane_Data0 | Lane_Data1 | Lane_Data2 | Lane_Data3);

    DSIM_SWReset(DSIM_SwRst);
    DSIM_InitHeaderFifo(pInfor);

    if( ucIntrEn )            // Interrupt Enable
    {
        DSIM_EnIntr(pInfor, ucIntrEn);
    }
    pInfor->m_eState = DSIM_State_Init;
    return pInfor;
}

//////////
// Function Name : DSIM_GetStatus
// Function Description :
//   This function reads Status of DSIM
// Input :     NONE
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
void DSIM_Destory(DSIM_Infor* pInfor)
{
//    INTC_Disable(NUM_MIPI_DSI);
    //Enter ULPS State
    if(!DSIM_SetStopState(pInfor))
    {
        DSIM_ForceDPhyStopState(1);
        Delay(1000);
        DSIM_ForceDPhyStopState(0);
        pInfor->m_eState = DSIM_State_Stop;
    }
    DSIM_SetULPS(pInfor);

    //free(pInfor->m_oDSIConfiguration);
    //free(pInfor->m_pMainDispConfiguration);
    //if ( pInfor->m_pSubDispConfiguration != NULL)
    //    free(pInfor->m_pSubDispConfiguration);

    DSIM_EnPll(0);                //Disable PLL

    //free(pInfor);

//    DSIM_EnDSIMaster(0);
//    DSIM_EnDPhy(0);

    g_oDSIMInfor = NULL;
}
/*---------------------------------- APIs of  ---------------------------------*/
//////////
// Function Name : DSIM_InitLink
// Function Description :
//   This function reads Status of DSIM
// Input :     DDI_Configuration : Configuration of DDI to Initialize DSI
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
BYTE  DSIM_InitLink(DSIM_Infor* pInfor)
{
    if ( pInfor->m_eState == DSIM_State_Init)
    {
        DWORD uTimeOut = 100;
        WORD usEscDiv = 0;
        DSIM_InitFifoPointer((DSIM_Fifo)0x1f);
        DSIM_SWReset(DSIM_FuncRst);

        #if (DPHY_Version == DPHY_45n)
        DSIM_SetPhyTunning(pInfor->m_oDSIConfiguration->m_uPhyTunnig1);            //Phy Tunning     for 45n
        #endif

        // Main Display
        DSIM_SetMainDispResolution(pInfor->m_pMainDispConfiguration->m_01uVertiSize, pInfor->m_pMainDispConfiguration->m_00uHoriSize);                                // Display Resolution
        if( pInfor->m_pMainDispConfiguration->m_40eInterface == DSIM_Video )            //Video Mode Transfer
        {
            DSIM_SetMainDispVPorch(pInfor->m_pMainDispConfiguration->m_44usCmdAllowLen, pInfor->m_pMainDispConfiguration->m_04usVFront, pInfor->m_pMainDispConfiguration->m_03usVBack);    // Vporch
            DSIM_SetMainDispHPorch(pInfor->m_pMainDispConfiguration->m_06usHFront, pInfor->m_pMainDispConfiguration->m_05usHBack);                                // Hporch
            DSIM_SetMainDispSyncArea(pInfor->m_pMainDispConfiguration->m_07usVertiSync, pInfor->m_pMainDispConfiguration->m_08usHoriSync);                        // Sync
        }
        else        //Command Mode Transfer
        {
            //Sub Display
            if( pInfor->m_pSubDispConfiguration != NULL)
                DSIM_SetSubDispResolution(pInfor->m_pSubDispConfiguration->m_01uVertiSize, pInfor->m_pSubDispConfiguration->m_00uHoriSize);
        }
        //DSI Configuartion
        DSIM_InitConfiguration(pInfor->m_pMainDispConfiguration, pInfor->m_pSubDispConfiguration, pInfor->m_oDSIConfiguration);
        //Payload Fifo Threshold  - Is it really removed?
        #if (DSIM_Version == DSIM_R03 )
        if ( pInfor->m_oDSIConfiguration->m_ucPacketThreshold )
            DSIM_FIFOThreshold(pInfor->m_oDSIConfiguration->m_usThresholdLevel);
        #endif
        DSIM_EnLane(Lane_Clock, 1);
        DSIM_EnLane(pInfor->m_eDataLane, 1);
        //Set Clock Configuration
        DSIM_SetClock(pInfor, TRUE);
        //make Phy Stop state and wait 100us ~ 1ms
        DSIM_ForceDPhyStopState(1);
        Delay(1000);
        DSIM_ForceDPhyStopState(0);
        //Check Clock and Data Lane State is Stop State

        while(!(DSIM_IsLaneState(Lane_Clock) == LaneState_Stop) && !(DSIM_IsLaneState(pInfor->m_eDataLane) == LaneState_Stop))
        {
            uTimeOut--;
            if (uTimeOut == 0)
            {
                MIPI_MSG((_T("DSI Master State is not Stop State!!! \nPlease Check initialization process\n")));
                return FALSE;
                break;
            }
        }
        if (uTimeOut != 0)
            MIPI_MSG((_T("Initialization of DSI Master is successful \nDSI Master State is Stop State\n")));
        pInfor->m_eState = DSIM_State_Stop;
        //BTA Sequence Counters
        DSIM_SetStopStateCounter(pInfor->m_oDSIConfiguration->m_usAutoBTACnt);
        DSIM_SetBTATimeOut(pInfor->m_oDSIConfiguration->m_ucBTATimeOut);
        DSIM_SetLPDRTimeOut(pInfor->m_oDSIConfiguration->m_usRxTimeOut);

        return TRUE;
    }
    else
    {
        MIPI_MSG((_T("DSI master is already init!\n")));
        return FALSE;
    }
}

//////////
// Function Name : DSIM_SetLPDT
// Function Description :
//   This function change Status of DSIM STM to Low Power Data Transmission State
// Input :     DSIM_Infor* : Address of
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
BYTE DSIM_SetLPDT(DSIM_Infor* pInfor)
{
    if( pInfor->m_eState == DSIM_State_Stop ||  pInfor->m_eState == DSIM_State_HSDT )
    {
        pInfor->m_eState = DSIM_State_LPDT;
        DSIM_SetDataMode(Transfer_ByLCDC, DSIM_State_LPDT);
        return TRUE;
    }
    else
        return FALSE;
}

//////////
// Function Name : DSIM_SetLPDT
// Function Description :
//   This function change Status of DSIM STM to Ultra Low Power State(ULPS)
// Input :     DSIM_Infor* : Address of
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
BYTE DSIM_SetULPS(DSIM_Infor* pInfor)
{
    DWORD uTimeOut = 50;
    if( pInfor->m_eState == DSIM_State_Stop)
    {
        do
        {
            DSIM_ULPSRequest(ULPS_Entry, 1);
            Delay(10);
            DSIM_ULPSRequest(ULPS_Entry, 0);
            Delay(10);            //wait for what?
            if (uTimeOut-- == 0)
            {
                MIPI_MSG((_T("Time Out Error!!\n")));
                return FALSE;
            }
        }while(!(DSIM_IsLaneState(Lane_Clock) == LaneState_ULPS) || !(DSIM_IsLaneState(pInfor->m_eDataLane) == LaneState_ULPS));
        DSIM_SetClock(pInfor, FALSE);
         pInfor->m_eState = DSIM_State_ULPS;
        return TRUE;
    }
    else
        return FALSE;
}

//////////
// Function Name : DSIM_SetHSDT
// Function Description :
//   This function change Status of DSIM STM to High Speed Data Transmission State
// Input :     DSIM_Infor* : Address of
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
BYTE DSIM_SetHSDT(DSIM_Infor* pInfor)
{
    if( pInfor->m_eState == DSIM_State_Stop)
    {

        pInfor->m_eState = DSIM_State_HSDT;
        DSIM_EnHSClk(1);
        return TRUE;
    }
    else
        return FALSE;
}

//////////
// Function Name : DSIM_SetBTA
// Function Description :
//   This function change Status of DSIM STM to Bus Turn Around State
// Input :     DSIM_Infor* : Address of
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
BYTE DSIM_SetBTA(DSIM_Infor* pInfor)
{
    if (DSIM_IsDirection())
    {
        MIPI_MSG((_T("Data Lane is already Backward Direction\n")));
        return TRUE;
    }

    if( pInfor->m_eState == DSIM_State_Stop)
    {
        DSIM_ClrIntr((DSIM_IntSrc)(BusTunrOver | BTAAckTimeOut));

        DSIM_ForceBTA();
        while(!DSIM_IsState(BusTunrOver))
        {
            if ( DSIM_IsState(BTAAckTimeOut) )
            {
                MIPI_MSG((_T("Time Out!! BTA Ack in not received\n")));
                return FALSE;
            }
        }
        pInfor->m_eState = DSIM_State_BTA;
        return TRUE;
    }
    else
        return FALSE;
}

//////////
// Function Name : DSIM_SetBTA
// Function Description :
//   This function change Status of DSIM STM to Bus Turn Around State
// Input :     DSIM_Infor* : Address of
// Output : DSIMStatus : DSIM Status Structure
// Version : v0.0
BYTE DSIM_SetStopState(DSIM_Infor* pInfor)
{
    DWORD uTimeout = 100;
    switch(pInfor->m_eState)
    {
        case DSIM_State_HSDT:
            pInfor->m_eState = DSIM_State_Stop;
            DSIM_EnHSClk(0);
            return TRUE;
        case DSIM_State_LPDT:
            DSIM_SetDataMode(Transfer_ByLCDC, DSIM_State_HSDT);
            pInfor->m_eState = DSIM_State_Stop;
            return TRUE;
        case DSIM_State_ULPS:
            do
            {
                DSIM_SetClock(pInfor, TRUE);
                DSIM_ULPSRequest(ULPS_Exit, 1);
                Delay(10);
                DSIM_ULPSRequest(ULPS_Exit, 0);
                Delay(1000);
                uTimeout--;
                if( uTimeout == 0)
                    break;
            }while(!(DSIM_IsLaneState(pInfor->m_eDataLane) == LaneState_Stop));
            if( uTimeout != 0)
            {
                pInfor->m_eState = DSIM_State_Stop;
                return TRUE;
            }
            else
            {
                return FALSE;
            }
        case DSIM_State_BTA:
            return TRUE;
        default:
            return FALSE;
    }
}

//////////
// Function Name : DSIM_Power
// Function Description :
//   This function Command Tranfer /Disable D-Phy
// Input :     DSIM_DataID - Packet ID
//            uData0 - Short Packet : Data0/Long Packet : Start Address of Transfer Data
//            uData1 - Short Packet : Data0/Long Packet : Size of Transfer Data
// Output : None
// Version : v0.0
void DSIM_Power(DSIM_Infor* pInfor, BYTE ucEn)
{
    // nothing to do.
}

//////////
// Function Name : DSIM_SetClock
// Function Description :
//   This function Command Tranfer /Disable D-Phy
// Input :     DSIM_DataID - Packet ID
//            uData0 - Short Packet : Data0/Long Packet : Start Address of Transfer Data
//            uData1 - Short Packet : Data0/Long Packet : Size of Transfer Data
// Output : None
// Version : v0.0
BYTE DSIM_SetClock(DSIM_Infor* pInfor, BYTE ucEn)
{
    if( ucEn ){
        DWORD usEscDiv;
        double dFin_Pll;
        double dFvco;
        //PLL
        DSIM_EnPllBypass(pInfor->m_oDSIConfiguration->m_bPllBypass);
        dFin_Pll = (double)(MIPI_FIN) / ((double)pInfor->m_oDSIConfiguration->m_ucP);
        #if (DPHY_Version == DPHY_65n)
        if (dFin_Pll < 2.5*1000*1000 || dFin_Pll > 5*1000*1000 )
        {
            MIPI_MSG((_T("Warning!!\n")));
            MIPI_MSG((_T("Fin_PLL Range is 2.5MHz ~ 5MHz\n")));
            MIPI_MSG((_T("Fin_PLL of MIPI DPHY Pll is %3.3fMHz\n"),(dFin_Pll/1000000)));
        }
        #elif ( DPHY_Version == DPHY_45n )
        if (dFin_Pll < 6*1000*1000 || dFin_Pll > 12*1000*1000 )
        {
            MIPI_MSG((_T("Warning!!\n")));
            MIPI_MSG((_T("Fin_PLL Range is 6MHz ~ 12MHz\n")));
            MIPI_MSG((_T("Fin_PLL of MIPI DPHY Pll is %3.3fMHz\n"),(dFin_Pll/1000000)));
            DSIM_EnAFC(0x0, 0x0);
        }
        else
        {
            if (dFin_Pll < 7*1000000)		
                DSIM_EnAFC(1, 0x1);
            else if (dFin_Pll < 8*1000000)	
                DSIM_EnAFC(1, 0x0);
            else if (dFin_Pll < 9*1000000)	
                DSIM_EnAFC(1, 0x3);		
            else if (dFin_Pll < 10*1000000)	
                DSIM_EnAFC(1, 0x2);
            else if (dFin_Pll < 11*1000000)	
                DSIM_EnAFC(1, 0x5);
            else 							
                DSIM_EnAFC(1, 0x4);		
        }
        #endif
        dFvco = (double)(MIPI_FIN * (double)pInfor->m_oDSIConfiguration->m_usM) / ((double)pInfor->m_oDSIConfiguration->m_ucP);
        if( dFvco < 500000000 || dFvco > 1000000000)
        {
            MIPI_MSG((_T("Warning!!\n")));
            MIPI_MSG((_T("Fvco Range is 500MHz ~ 1000MHz\n")));
            MIPI_MSG((_T("Fvco of MIPI DPHY Pll is %3.3fMHz\n"),(dFvco/1000000)));
        }
        pInfor->m_dHSClk = (double)((MIPI_FIN * (double)pInfor->m_oDSIConfiguration->m_usM) / ((double)pInfor->m_oDSIConfiguration->m_ucP * (double)(1 << (pInfor->m_oDSIConfiguration->m_ucS))));
        if ((DWORD) pInfor->m_dHSClk < 100*1000000)            pInfor->m_ucFreqBand = 0x0;
        else if ((DWORD) pInfor->m_dHSClk < 120*1000000)        pInfor->m_ucFreqBand = 0x1;
        else if ((DWORD) pInfor->m_dHSClk < 170*1000000)        pInfor->m_ucFreqBand = 0x2;
        else if ((DWORD) pInfor->m_dHSClk < 220*1000000)        pInfor->m_ucFreqBand = 0x3;
        else if ((DWORD) pInfor->m_dHSClk < 270*1000000)        pInfor->m_ucFreqBand = 0x4;
        else if ((DWORD) pInfor->m_dHSClk < 320*1000000)        pInfor->m_ucFreqBand = 0x5;
        else if ((DWORD) pInfor->m_dHSClk < 390*1000000)        pInfor->m_ucFreqBand = 0x6;
        else if ((DWORD) pInfor->m_dHSClk < 450*1000000)        pInfor->m_ucFreqBand = 0x7;
        else if ((DWORD) pInfor->m_dHSClk < 510*1000000)        pInfor->m_ucFreqBand = 0x8;
        else if ((DWORD) pInfor->m_dHSClk < 560*1000000)        pInfor->m_ucFreqBand = 0x9;
        else if ((DWORD) pInfor->m_dHSClk < 640*1000000)        pInfor->m_ucFreqBand = 0xa;
        else if ((DWORD) pInfor->m_dHSClk < 690*1000000)        pInfor->m_ucFreqBand = 0xb;
        else if ((DWORD) pInfor->m_dHSClk < 770*1000000)        pInfor->m_ucFreqBand = 0xc;
        else if ((DWORD) pInfor->m_dHSClk < 870*1000000)        pInfor->m_ucFreqBand = 0xd;
        else if ((DWORD) pInfor->m_dHSClk < 950*1000000)        pInfor->m_ucFreqBand = 0xe;
        else                                                 pInfor->m_ucFreqBand = 0xf;

        //Byte CLK
        if( pInfor->m_oDSIConfiguration->m_eByteclk == DSIM_ByteClkSrc_DPhy )
            pInfor->m_dByteClk = pInfor->m_dHSClk / 8;
            //pInfor->m_dByteClk = pInfor->m_dHSClk;            //for Test
        else if ( pInfor->m_oDSIConfiguration->m_eByteclk == DSIM_ByteClkSrc_ExtCLK_Divided_By4 )
            pInfor->m_dByteClk = MIPI_FIN / 4;
        else if ( pInfor->m_oDSIConfiguration->m_eByteclk == DSIM_ByteClkSrc_ExtCLK )
            pInfor->m_dByteClk = MIPI_FIN;

        if ( !(pInfor->m_oDSIConfiguration->m_bPllBypass) )        //Pll Eanble
        {
            //PMS Value
            DSIM_SetPllPMS(pInfor->m_oDSIConfiguration->m_ucP, pInfor->m_oDSIConfiguration->m_usM, pInfor->m_oDSIConfiguration->m_ucS);
            //Freq Band
            DSIM_PllFreqBand(pInfor->m_ucFreqBand);
            //Stable Time
            DSIM_PllStatbleTime(pInfor->m_oDSIConfiguration->m_uPllStableTime);
            // Enable Pll
            MIPI_MSG((_T("Fout of MIPI DPHY PLL is %3.2fMHz\n"),pInfor->m_dHSClk / 1000000));
            DSIM_EnPll(1);
        }

        else
        {

        }
        //Escaspe Mode Clock
        //Byte Clock Source
        DSIM_SetByteClockSrc(pInfor->m_oDSIConfiguration->m_eByteclk);
        MIPI_MSG((_T("Bit Clock is %2.3fMHz\n"), pInfor->m_dByteClk / 1000000));
        MIPI_MSG((_T("Escape clock that User's need is %2.3fMHz\n"),pInfor->m_oDSIConfiguration->m_dEscClk / 1000000));
        //Escape clock divider
        usEscDiv = (WORD)(pInfor->m_dByteClk / (pInfor->m_oDSIConfiguration->m_dEscClk));
        if (pInfor->m_dByteClk/(usEscDiv) > pInfor->m_oDSIConfiguration->m_dEscClk)
            usEscDiv += 1;
        pInfor->m_oDSIConfiguration->m_dEscClk = pInfor->m_dByteClk/(usEscDiv);
        //Enable Byte clk & Escape clock
        DSIM_EnByteClock(TRUE);
        DSIM_SetEscClkPrs(1, usEscDiv);
        MIPI_MSG((_T("Escape clock Divider is 0x%x\n"),usEscDiv));
        MIPI_MSG((_T("Escape clock is %2.3fMHz\n"),(pInfor->m_oDSIConfiguration->m_dEscClk)/1000000));
        //enable EscClk on Lane
        DSIM_EnEscClkOnLane(Lane_Clock,1);
        DSIM_EnEscClkOnLane(pInfor->m_eDataLane,1);
    }

    else    {
        DSIM_EnEscClkOnLane(Lane_Clock,0);
        DSIM_EnEscClkOnLane(pInfor->m_eDataLane,0);
        DSIM_SetEscClkPrs(0, 0);
        DSIM_EnByteClock(0);
        if ( !(pInfor->m_oDSIConfiguration->m_bPllBypass) )
            DSIM_EnPll(0);
        else
        {
        }
    }
    return 0;   //chandolp
}
/*---------------------------------- APIs of DSI Command Transfer and Response------------------------*/
//////////
// Function Name : DSIM_CpuTransferMode
// Function Description :
//   This function select cpu tx mode high speed or low power
// Input :     DSIM_DataID - Packet ID
//            uData0 - Short Packet : Data0/Long Packet : Start Address of Transfer Data
//            uData1 - Short Packet : Data0/Long Packet : Size of Transfer Data
// Output : None
// Version : v0.0
void DSIM_CpuTransferMode(DSIM_Infor* pInfor, BYTE bMode)
{
    if ( bMode )
        DSIM_SetDataMode(Transfer_ByCPU, DSIM_State_HSDT);
    else
        DSIM_SetDataMode(Transfer_ByCPU, DSIM_State_LPDT);
}

//////////
// Function Name : DSIM_Cmd
// Function Description :
//   This function Command Tranfer /Disable D-Phy
// Input :     DSIM_DataID - Packet ID
//            uData0 - Short Packet : Data0/Long Packet : Start Address of Transfer Data
//            uData1 - Short Packet : Data0/Long Packet : Size of Transfer Data
// Output : None
// Version : v0.0
BYTE DSIM_WrData(DSIM_Infor* pInfor, DSIM_DataID eDataID, DWORD uData0, DWORD uData1)
{
    DWORD uTimeOut = DSIM_TIMEOUT_MS;
    BYTE bReturn = 0;
    BYTE bWaitFifoState = 1;
    double dDelay;
    DWORD uDelay;

    if ( pInfor == NULL )
        return FALSE;

    if ( pInfor->m_eState == DSIM_State_ULPS || pInfor->m_eState == DSIM_State_BTA )
        return FALSE;

    dDelay = 1000000 / pInfor->m_oDSIConfiguration->m_dEscClk;
    uDelay = (DWORD) (1000 * dDelay);
    Delay(uDelay);

//    MIPI_MSG((_T("DSIM CMD OUT:0x%x\n"),uData0));

    switch(eDataID)
    {
        //Short Packet Type///////////////////////////////////////////////////////
        //Packet Types for Command
        case GenShortWrNoPara:
        case GenShortWr1Para:
        case GenShortWr2Para:
        case DCSWrNoPara:
        case DCSWr1para:
        case SetMaxRtnPktsize:
            while(!(DSIM_GetFifoState() & SFRHeaderEmpty) && bWaitFifoState)
            {
                if (( uTimeOut--) >0 )
                    Delay(1);
                else
                {
                    MIPI_MSG((_T("SFR Hearder Fifo is not empty!! #1\n")));
                    return FALSE;
                }
            }
            DSIM_WrTxHeader((BYTE)eDataID, (BYTE) uData0,  (BYTE) uData1);
            if ( uData0 == 0x35 )        //SET_TEAR_ON
                return DSIM_ProcessResponse(pInfor, eDataID);
            else
                return TRUE;
        //General Command
        case CMOff:
        case CMOn:
        case ShutDown:
        case TurnOn:
            while(!(DSIM_GetFifoState() & SFRHeaderEmpty) && bWaitFifoState)
            {
                if (( uTimeOut--) >0 )
                    Delay(1);
                else
                {
                    MIPI_MSG((_T("SFR Hearder Fifo is not empty!! #2\n")));
                    return FALSE;
                }
            }
            DSIM_WrTxHeader((BYTE)eDataID, 0, 0);
            return TRUE;
        //Packet Types for Video Data - for test Data transfer through Bus
        case VSyncStart:
        case VSyncEnd:
        case HSyncStart:
        case HSyncEnd:
        case EotPkt:
            return TRUE;
        //short and responce
        //Packet Types for Command
        case GenRd1Para:
        case GenRd2Para:
        case GenRdNoPara:
        case DCSRdNoPara:
            while(!(DSIM_GetFifoState() & SFRHeaderEmpty) && bWaitFifoState)
            {
                if (( uTimeOut--) >0 )
                    Delay(1);
                else
                {
                    MIPI_MSG((_T("SFR Hearder Fifo is not empty!! #3\n")));
                    return FALSE;
                }
            }
            DSIM_ClrIntr(AllofIntr);
            DSIM_WrTxHeader((BYTE)eDataID, (BYTE) uData0,  (BYTE) uData1);
            while(!(DSIM_GetFifoState() & SFRHeaderEmpty))
            {
                if (( uTimeOut--) >0 )
                    Delay(1);
                else
                {
                    MIPI_MSG((_T("SFR Hearder Fifo is not empty!! #4\n")));
                    return FALSE;
                }
            }
            Delay(uDelay * 2);
            return DSIM_ProcessResponse(pInfor, eDataID);
        //Long Packet Type///////////////////////////////////////////////////////
        //Null Packet
        case NullPkt:
        case BlankingPkt:
            return TRUE;
        //Packet Types for Command
        case GenLongWr:
        case DCSLongWr:
            while(!(DSIM_GetFifoState() & SFRHeaderEmpty) && bWaitFifoState)
            {
                if (( uTimeOut--) >0 )
                    Delay(1);
                else
                {
                    MIPI_MSG((_T("SFR Hearder Fifo is not empty!! #5\n")));
                    return FALSE;
                }
            }
            {
                //Aling Data Word
                DWORD uCnt;

                //DWORD* pWordPtr = (DWORD*)malloc((uData1+3)/4*4);
                BYTE pWordPtr_mem[1024];
                DWORD* pWordPtr = (DWORD *)pWordPtr_mem;
                memset(pWordPtr,0,(uData1+3)/4*4*4);
                memcpy(pWordPtr,(BYTE *) uData0,uData1);
                // Put data into Payload FIFO
                for( uCnt = 0;uCnt < uData1/4;uCnt++)
                {
                    DSIM_WrTxData(pWordPtr[uCnt]);
                }
                if(uData1%4)
                    DSIM_WrTxData(pWordPtr[uCnt]);
                //free(pWordPtr);
                // Put Data into Header FIFO
                DSIM_WrTxHeader((BYTE)eDataID, (BYTE) (uData1 & 0xff00 >> 8),  (BYTE) (uData1 & 0xff));
            };
            return TRUE;
        //Packet Types for Video Data - for test Data transfer through Bus
        case RGB565Packed:
        case RGB666Packed:
        case RGB666Loosly:
        case RGB888Packed:
            return TRUE;
        default:
            MIPI_MSG((_T("The Data ID 0x%2x  is not supported current DSI Spec\n"), eDataID));
            return FALSE;
    }
}



//////////
// Function Name : DSIM_ProcessResponse
// Function Description :
//   This function shows Resonse error flag.
// Input :     DSIM_DataID : ID of Data type
// Output : BYTE -    True : valid sequence and data
//                    False : invalid data or invalid sequence
// Version : v0.0
BYTE DSIM_ProcessResponse(DSIM_Infor* pInfor, DSIM_DataID eId)
{
    DSIM_ShortPktHeader eAckPkt;
    DWORD uTimeOut = DSIM_TIMEOUT_MS;
    BYTE ucIsReadType = eId & 0x0f;
    BYTE bForceBTA = 1;
    if ( ucIsReadType == GenRdNoPara ||ucIsReadType == GenRd1Para ||ucIsReadType == GenRd2Para || ucIsReadType == DCSRdNoPara)
        ucIsReadType = 0x1;
    else
        ucIsReadType = 0x0;
    while (1)
    {
        // case 0: end without error : see spec v1.01.00 r05 1344 line
        if ( !(ucIsReadType) && DSIM_IsState(RxAck))
        {
            MIPI_MSG((_T("RX ACK!!\n")));
            DSIM_ClrIntr(RxAck);
            return TRUE;
        }
        // case 1: non-read but, any data ? --> bad news
        if ( !(ucIsReadType) && DSIM_IsState(RxDatDone) )
        {
            if (DSIM_PopRxHeader(pInfor, &eAckPkt) == sizeof(eAckPkt))
            {
                if (DSIM_GetRxHeaderType(&eAckPkt)==Ack )
                {
                    DSIM_ShowErrorReportInPacket(&eAckPkt);
                    return FALSE;
                }
                else
                {
                    MIPI_MSG((_T("Can't be here\n")));
                //    assert(0);
                }
            }
        }
        // case 2: read case
        if ( (ucIsReadType) && DSIM_IsState(RxDatDone) )
        {
            if (DSIM_PopRxHeader(pInfor, &eAckPkt) == sizeof(eAckPkt))
            {
                if (DSIM_GetRxHeaderType(&eAckPkt) == Ack )
                {
                    DSIM_ShowErrorReportInPacket(&eAckPkt);
                    // multi bit ecc
                    if (DSIM_GetErrorReportInPacket(&eAckPkt) & EccMulti)
                    {
                        if (DSIM_WaitState(ErrRxECC))
                            return FALSE;
                    }
                    // all flag except single ecc means failed
                    else if (DSIM_GetErrorReportInPacket(&eAckPkt) & ~(EccSingle) )
                        return FALSE;
                    else if (DSIM_GetErrorReportInPacket(&eAckPkt) & (EccSingle))
                        return TRUE;

                }
                else
                {
                    DSIM_PushHD(pInfor, &eAckPkt);    // valid data
                    return TRUE;
                }
            }
        }
        // case 4: Read Time Out
        if ( ucIsReadType && DSIM_IsState(LPDRTimeOut))
        {
            MIPI_MSG((_T("RX timeout \n")));
            DSIM_ClrIntr(LPDRTimeOut);
            return FALSE;
        }
        // case 4: BTA Time Out
        if ( ucIsReadType && DSIM_IsState(BTAAckTimeOut))
        {
            MIPI_MSG((_T("BTA Time Out\n")));
            DSIM_ClrIntr(BTAAckTimeOut);
            return FALSE;
        }

        if (( uTimeOut--) >0 )
            Delay(1);
        else
        {
            if ( ucIsReadType && bForceBTA )
            {
                MIPI_MSG((_T("FORCE BTA!!\n")));
                bForceBTA = 0;
                uTimeOut = DSIM_TIMEOUT_MS;
                DSIM_ForceBTA();
            }
            else
            {
                MIPI_MSG((_T("SW timeout \n")));
                return FALSE;
            }
        }
    }
}
/*---------------------------------- Header Parser of DSI Rx Data ---------------------------------*/
//////////
// Function Name : DSIM_PopRxPayload
// Function Description :
//   This function extracts Rx Data from Rx Short Packet from DSIM_PopRxHeader function called.
// Input :     DSIM_ShortPktHeader* : Address of Rx Short Packet poped from FIFO
//            BYTE* : Buffer address for Returned Data extrated from Rx Short Packet
//            DWORD :
// Output : DWORD : size of Returned data
// Version : v0.0
DWORD DSIM_PopRxPayload(DSIM_ShortPktHeader *pHead,BYTE* pBuf,DWORD size)
{
    if(pHead == NULL)
    {
        MIPI_MSG((_T("DSIM_PopRxPayload Exception!\r\n")));
        assert(0);
        return 0;
    }

    switch(DSIM_GetRxHeaderType(pHead))
    {
        case Ack:
            return FALSE;
        case GenShort1B:
        case DcsShort1B:
            pBuf[0] = pHead->_inter.data.data0;
            return 1;
        case GenShort2B:
        case DcsShort2B:
            pBuf[0] = pHead->_inter.data.data0;
            pBuf[1] = pHead->_inter.data.data1;
            return 2;
        case GenLong:
        case DcsLong:
            {
                DWORD toRead = DSIM_GetRxPayloadDataSize(pHead);
                DWORD nread=0;
                DWORD temp;
                if (toRead > size)
                {
                    MIPI_MSG((_T("Buffer small! remainder will be thrown away buddy!\n")));
                }
                if (toRead % (sizeof(DWORD)))
                {
                    toRead = (toRead+sizeof(DWORD)) & 0xFFFFFFFC;
                }
                while(toRead != nread || !(DSIM_GetFifoState() & DSIM_RxDataEmpty))
                {
                    nread+=sizeof(DWORD);
                    // fifo rx not empty
                    temp = DSIM_RdRxData();
                    if (nread >= size)
                    {
                        *((DWORD*)pBuf) = temp;
                        MIPI_MSG((_T("Payload : 0x%.8x\n"),temp));
                        pBuf+=sizeof(DWORD);
                        Delay(1);        //wait 1ms
                    }
                }
                return nread;
            }
    }
    return 0;
}


//////////
// Function Name : DSIM_GetRxHeaderType
// Function Description :
//   This function extracts Rx Response Type from Rx Short Packet from DSIM_PopRxHeader function called.
// Input :     DSIM_ShortPktHeader* : Address of Rx Short Packet poped from FIFO
// Output : DSIM_Response : Type of Rx Data
// Version : v0.0
DSIM_Response DSIM_GetRxHeaderType(DSIM_ShortPktHeader *pHead)
{
    // pHead should not be NULL
    if( pHead == NULL)
    {
        assert(0);
		return (DSIM_Response)0;
    }

    return (DSIM_Response)(pHead->id & 0x3F);
}

//////////
// Function Name : DSIM_GetRxPayloadDataSize
// Function Description :
//   This function extracts Recieving word count from Packet Header.
// Input :     DSIM_ShortPktHeader* : Address of Rx Short Packet poped from FIFO
// Output : WORD : size of Returned data
// Version : v0.0
DWORD DSIM_GetRxPayloadDataSize(DSIM_ShortPktHeader *pHead)
{
    if( pHead == NULL)
    {
        assert(0);
        return 0;
    }
    switch(DSIM_GetRxHeaderType(pHead))
    {
        case Ack:
        case GenShort1B:
        case GenShort2B:
        case DcsShort1B:
        case DcsShort2B:
            return 0;
        case GenLong:
        case DcsLong:
            return (((*(DWORD *)pHead) & 0xffff00) >> 8);
            //return pHead->_inter.word_count;
        default:
            return 0;
    }
}

//////////
// Function Name : DSIM_ShowResponseFlagInfo
// Function Description :
//   This function show Resonse flag.
// Input :     DSIM_ShortPktHeader* : Address of Rx Short Packet poped from FIFO
// Output : None
// Version : v0.0
void DSIM_ShowResponseFlagInfo(DSIM_ShortPktHeader *pPacket)
{
    MIPI_MSG((_T("Response Flag is \n")));

    if ((pPacket->id & 0x3F) == Ack)
        MIPI_MSG((_T("ERROR_REPORT \n")));

    if ( (pPacket->id & 0x3F) == EoTp )
        MIPI_MSG((_T("End of Packet \n")));

    if ( (pPacket->id & 0x3F) == GenShort1B )
        MIPI_MSG((_T("GenShort1B \n")));

    if ( (pPacket->id & 0x3F) == GenShort2B )
        MIPI_MSG((_T("GenShort2B \n")));

    if ( (pPacket->id & 0x3F) == GenLong )
        MIPI_MSG((_T("GenLong \n")));

    if ( (pPacket->id & 0x3F) == DcsShort2B )
        MIPI_MSG((_T("DcsShort2B \n")));

    if ( (pPacket->id & 0x3F) == DcsShort1B )
        MIPI_MSG((_T("DcsShort1B \n")));

    if ( (pPacket->id & 0x3F) == DcsShort2B )
        MIPI_MSG((_T("DcsShort2B \n")));

    if ( (pPacket->id & 0x3F) == DcsLong )
        MIPI_MSG((_T("DCSLong \n")));

}

//////////
// Function Name : DSIM_GetErrorReportInPacket
// Function Description :
//   This function extracts Error Report In Packet count from Packet Header.
// Input :     DSIM_ShortPktHeader* : Address of Rx Short Packet poped from FIFO
// Output : WORD : size of Returned data
// Version : v0.0
DSIM_Error DSIM_GetErrorReportInPacket(DSIM_ShortPktHeader *pHead)
{
    // pHead should not be NULL
    assert(pHead);

    switch(DSIM_GetRxHeaderType(pHead))
    {
        case GenLong:
        case DcsLong:
        case GenShort1B:
        case GenShort2B:
        case DcsShort1B:
        case DcsShort2B:
            return (DSIM_Error)(0);
        case Ack:
            return (DSIM_Error)(((*(DWORD *)pHead) & 0xffff00) >> 8);
            //return pHead->_inter.word_count;
        default:
            return (DSIM_Error)(0);
    }
}


//////////
// Function Name : DSIM_ShowResponseFlagInfo
// Function Description :
//   This function shows Resonse error flag.
// Input :     DSIM_ShortPktHeader* : Address of Rx Short Packet poped from FIFO
// Output : None
// Version : v0.0
void DSIM_ShowErrorReportInPacket(DSIM_ShortPktHeader *pPacket)
{
    if (DSIM_GetErrorReportInPacket(pPacket) & Sot)
        MIPI_MSG((_T("SOT_ERROR\n")));

    if (DSIM_GetErrorReportInPacket(pPacket) & SotTSync)
        MIPI_MSG((_T("SOT_SYNC_ERROR\n")));

    if (DSIM_GetErrorReportInPacket(pPacket) & EotSync)
        MIPI_MSG((_T("EOT_SYNC_ERROR\n")));

    if (DSIM_GetErrorReportInPacket(pPacket) & ESCEntry) {
        MIPI_MSG((_T("ESCAPE_MODE_ENTRY_COMMAND_ERROR\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & LPTSync) {
        MIPI_MSG((_T("LOWPOWER_TRANSIT_SYNC_ERROR\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & HSTimeout) {
        MIPI_MSG((_T("HS_RECEIVE_TIMEOUT_ERROR\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & FalseControl) {
        MIPI_MSG((_T("FALSE_CONTROL_ERROR\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & EccSingle) {
        MIPI_MSG((_T("ECC_ERROR_SINGLE\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & EccMulti) {
        MIPI_MSG((_T("ECC_ERROR_MULTI\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & CheckSum) {
        MIPI_MSG((_T("CHECKSUM_ERROR\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & DataType) {
        MIPI_MSG((_T("DATATYPE_NOT_RECOGNIZED\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & VC) {
        MIPI_MSG((_T("VCHANNEL_INVALID\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & Length) {
        MIPI_MSG((_T("VCHANNEL_INVALID\n")));
    }
    if (DSIM_GetErrorReportInPacket(pPacket) & Protocol) {
        MIPI_MSG((_T("PROTOCOL_VIOLATION\n")));
    }

}
/*---------------------------------- Fifo Apis of DSI Rx Data ---------------------------------*/
// Function Name : DSIM_PopRxHeader
// Function Description :
//   This function pop Rx Header from S/W contructed FIFO  in memory or DSI H/W Rx FIFO
// Input :     DSIM_ShortPktHeader* : memory Address of Data poped from FIFO
// Output : DWORD : size of Header
// Version : v0.0
DWORD DSIM_PopRxHeader(DSIM_Infor* pInfor, DSIM_ShortPktHeader *pHead)
{
    if ( !DSIM_IsHeaderFifoEmpty(pInfor))
    {
        DSIM_PopHD(pInfor, pHead);
        return sizeof(DWORD);
    }

    if ( !(DSIM_GetFifoState() & DSIM_RxDataEmpty) )
    {
        // fifo rx not empty
        *((DWORD*)pHead) = DSIM_RdRxData();
        MIPI_MSG((_T("Header : 0x%.8x\n"),*((DWORD*)(pHead))));
        DSIM_ShowResponseFlagInfo(pHead);
        return sizeof(DWORD);
    }
    else         // Fifo is Empty
        return 0;
}

//////////
// Function Name : DSIM_PushHD
// Function Description :
//   This function push Rx Short Packet Data into fifo.
// Input :     DSIM_Infor* : informaition data of DSI
//            DSIM_ShortPktHeader* : Data to store fifo
// Output : BYTE -    True : success
//                    False : fail
// Version : v0.0
BYTE DSIM_PushHD(DSIM_Infor* pInfor, DSIM_ShortPktHeader *pHead)
{
    int maxIdx = -1;
    int emptyIdx = 0;
    DWORD uCnt0;
    for (uCnt0 = 0;uCnt0 < DSIM_HEADER_FIFO_SZ;uCnt0++)
    {
        if (pInfor->m_HeaderFifoIndex[uCnt0] >= 0)
        {
            if (maxIdx < pInfor->m_HeaderFifoIndex[uCnt0])
                maxIdx = pInfor->m_HeaderFifoIndex[uCnt0];
        }
    }

    pInfor->m_HeaderFifoIndex[emptyIdx] = maxIdx+1;
    pInfor->m_oHeaderFifo[emptyIdx] = *pHead;
    return TRUE;
}

//////////
// Function Name : DSIM_PushHD
// Function Description :
//   This function push Rx Short Packet Data into fifo.
// Input :     DSIM_Infor* : informaition data of DSI
//            DSIM_ShortPktHeader* : Data to store fifo
// Output : BYTE -    True : success
//                    False : fail
// Version : v0.0
BYTE DSIM_PopHD(DSIM_Infor* pInfor, DSIM_ShortPktHeader *pHead)
{
    int minIdx = -1;
    DWORD uCnt0;
    for (uCnt0 = 0;uCnt0 < DSIM_HEADER_FIFO_SZ; uCnt0++)            //check Current Header fifo index
    {
        if (pInfor->m_HeaderFifoIndex[uCnt0] >= 0)
        {
            if (minIdx < 0 || minIdx > pInfor->m_HeaderFifoIndex[uCnt0])
                minIdx = uCnt0;                                    // Get max index
        }
    }
    if (minIdx<0)                 // if upper process is failed, return FALSE
    {
        MIPI_MSG((_T("Empty Header FIFO\n")));
        return FALSE;
    }
    *pHead = pInfor->m_oHeaderFifo[minIdx];
    pInfor->m_HeaderFifoIndex[minIdx] = -1;                    // set index -1 : fifo directed that index is empty
    return TRUE;
}

//////////
// Function Name : DSIM_PushHD
// Function Description :
//   This function push Rx Short Packet Data into fifo.
// Input :     DSIM_Infor* : informaition data of DSI
//            DSIM_ShortPktHeader* : Data to store fifo
// Output : BYTE -    True : success
//                    False : fail
// Version : v0.0
BYTE DSIM_InitHeaderFifo(DSIM_Infor* pInfor)
{
    DWORD uCnt0;
    for (uCnt0 = 0;uCnt0 <DSIM_HEADER_FIFO_SZ;uCnt0++)
    {
        pInfor->m_HeaderFifoIndex[uCnt0] = -1;
    }
    return TRUE;
}

//////////
// Function Name : DSIM_PushHD
// Function Description :
//   This function push Rx Short Packet Data into fifo.
// Input :     DSIM_Infor* : informaition data of DSI
//            DSIM_ShortPktHeader* : Data to store fifo
// Output : BYTE -    True : success
//                    False : fail
// Version : v0.0
BYTE DSIM_IsHeaderFifoEmpty(DSIM_Infor* pInfor)
{
    DWORD uCnt0;
    for (uCnt0 = 0;uCnt0 <DSIM_HEADER_FIFO_SZ;uCnt0++)
    {
        if (pInfor->m_HeaderFifoIndex[uCnt0] > 0)
            return FALSE;
    }
    return TRUE;
}


//////////
// Function Name : DSIM_EnIntr
// Function Description :
//   This function enables interrupt controller to interrupt of DSIM.
// Input :
// Output :
// Version : v0.0
void DSIM_EnIntr(DSIM_Infor* pInfor, BYTE ucEn)
{
    if (ucEn)
    {
//        INTC_SetVectAddr(NUM_MIPI_DSI,Isr_DSIM);
        DSIM_ClrIntr(AllofIntr);
        DSIM_SetIntrMask(AllofIntr, 1);            //Mask all interrupt source
//        INTC_Enable(NUM_MIPI_DSI);
    }
    else
    {
//        INTC_Disable(NUM_MIPI_DSI);
    }
}

//////////
// Function Name : DSIM_SetIsrCallBack
// Function Description :
//   This function registers Call back Function of Interrupt source
// Input :     None
// Output : None
// Version : v0.0
void DSIM_SetIsrCallBack(DSIM_Infor* pInfor, DSIM_IntSrc eIntSrc, void (*fnCallBack)(DWORD), DWORD CallbackVar)
{
    DWORD uCnt0;
    DWORD uInterruptEnable = 0;
    for ( uCnt0 = 0;uCnt0 < 32;uCnt0++)
    {
        uInterruptEnable = 1 << uCnt0;
        if(uInterruptEnable & (DWORD) eIntSrc)
        {
            DSIM_ClrIntr((DSIM_IntSrc)(uInterruptEnable));
            pInfor->m_fnCallback[uCnt0] = fnCallBack;
            pInfor->m_uCallbackVar[uCnt0] = CallbackVar;
            if ( fnCallBack )
            {
                DSIM_SetIntrMask((DSIM_IntSrc)(uInterruptEnable), 0);        // Unmasked
            }
            else
            {
                DSIM_SetIntrMask((DSIM_IntSrc)(uInterruptEnable), 1);        // Masked
            }

        }
    }
}
/*---------------------------------- APIs of DSIM State---------------------------------*/
//////////
// Function Name : DSIM_IsState
// Function Description :
//   This function query state.
// Input :     DSIM_IntSrc - Status Bit
// Output : None
// Version : v0.0
BYTE DSIM_IsState(DSIM_IntSrc eIntSrc)
{
    DSIM_Infor* pInfor = g_oDSIMInfor;
    DWORD uCnt0;
    DWORD uState = (DWORD) DSIM_GetIntrMask();        //Mask State
    if ( DSIM_GetIntrState() & eIntSrc)
    {
        DSIM_ClrIntr(eIntSrc);                            //clear
        return TRUE;
    }
    else
    {
        for ( uCnt0 = 0;uCnt0 < 32;uCnt0++)            //when state bit is cleared in the isr, some sequence is wrong.
        {
            if (  eIntSrc & (1 << uCnt0))
            {
                if (pInfor->m_bSetState[uCnt0])
                {
                    pInfor->m_bSetState[uCnt0] = FALSE;        //clear
                    return TRUE;
                }
                else
                    return FALSE;
            }
        }
    }
    return FALSE;   //chandolp
}

//////////
// Function Name : DSIM_WaitState
// Function Description :
//   This function wait Interrupt.
// Input :     DSIM_IntSrc - Clear Interrupt bit
// Output : None
// Version : v0.0
BYTE DSIM_WaitState(DSIM_IntSrc  eIntSrc)
{
    DSIM_Infor* pInfor = g_oDSIMInfor;
    DWORD uTimeOut = DSIM_TIMEOUT_MS;
    while (1)
    {
        if ( DSIM_IsState(eIntSrc) )
        {
            return TRUE;
        }
        if ((uTimeOut--)==0)
        {
            MIPI_MSG((_T("Wait State -Timeout\n")));
            return FALSE;
        }
        else
            Delay(1);
    }
    /* timeout */
    return FALSE;
}

/*---------------------------------- APIs of DSIM_STATUS ---------------------------------*/
//////////
// Function Name : DSIM_IsPllStable
// Function Description :
//   This function return Pll Stable status
// Input :     NONE
// Output : BYTE - D-Phy Pll Stable
// Version : v0.0
BYTE DSIM_IsPllStable(void)
{
    return (BYTE) (DSIM_Inp32(rDSIM_STATUS) & (1 << 31) >> 31);
}

//////////
// Function Name : DSIM_IsSwResetRelease
// Function Description :
//   This function return Pll Stable status
// Input :     NONE
// Output : BYTE - SW Reset Release
// Version : v0.0
BYTE DSIM_IsSwRstRelease(void)
{
    return (BYTE) (DSIM_Inp32(rDSIM_STATUS) & (1 << 29) >> 29);
}

// Function Name : DSIM_IsDirection
// Function Description :
//   This function return Data Direction
// Input :     NONE
// Output : BYTE - SW Reset Release
// Version : v0.0
BYTE DSIM_IsDirection(void)
{
    return (BYTE) (DSIM_Inp32(rDSIM_STATUS) & (1 << 16) >> 16);
}

//////////
// Function Name : DSIM_IsLaneState
// Function Description :
//   This function return Pll Stable status
// Input :     DSIM_LANE - one of DSI Lane
// Output : DSIM_LaneState - Lane State
// Version : v0.0
DSIM_LaneState DSIM_IsLaneState(DSIM_LANE eLane)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_STATUS);
    if(eLane == Lane_Clock)        //Clock Lane
    {
        if (uTemp & (1 << 9))
            return LaneState_ULPS;
        else if (uTemp & (1 << 8))
            return LaneState_Stop;
        else if (uTemp & (1 << 10))
            return LaneState_HsReady;
        else
        {
            MIPI_MSG((_T("Clcock Lane State is Unkown\n")));
            return (DSIM_LaneState) (-1);
        }
    }
    else if ( eLane & Lane_All )
    {

        if ((uTemp & 0x7ff) ^ (((eLane & 0xf) << 4) | (1 << 9)))
            return LaneState_ULPS;
        else if ((uTemp & 0x7ff) ^ (((eLane & 0xf) << 0) | (1 << 8)))
            return LaneState_Stop;
        else
        {
            MIPI_MSG((_T("Lane State is Unkown\n")));
            return (DSIM_LaneState) (-1);
        }
    }
    else     if ( eLane & Lane_DataAll )//Data Lane
    {
        if (uTemp & (eLane << 4))
            return LaneState_ULPS;
        else if (uTemp & (eLane << 0))
            return LaneState_Stop;
        else
        {
            MIPI_MSG((_T("Data Lane State is Unkown\n")));
            return (DSIM_LaneState) (-1);
        }
    }
    return (DSIM_LaneState) (-1);  //chandolp
}

/*---------------------------------- APIs of DSIM_SWRST ---------------------------------*/
//////////
// Function Name : DSIM_SWReset
// Function Description :
//   This function reset DSIM SFR Resgister.
// Input :     eRst - kind of reset : Function/All SFR
// Output : None
// Version : v0.0
void DSIM_SWReset(DSIM_Rst eRst)
{
    DSIM_Outp32(rDSIM_SWRST, (DWORD) eRst);
}

/*---------------------------------- APIs of DSIM_CLKCTRL ---------------------------------*/
//////////
// Function Name : DSIM_EnHSClk
// Function Description :
//   This function enable High Speed Clock on the Clock Lane
// Input :     usEn - Enable
// Output : None
// Version : v0.0
void DSIM_EnHSClk(BYTE bEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL) & ~(1 << 31);
    uTemp |= bEn << 31;
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}

//////////
// Function Name : DSIM_SetEscapeClkPrs
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetEscClkPrs(BYTE bEn, DWORD usPrsVal)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL) & ~(1 << 28) & ~(0xffff);
    uTemp |= bEn << 28;
    if( bEn )
        uTemp |= usPrsVal;
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}

//////////
// Function Name : DSIM_EnEscapeClkPrs
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_EnEscClkPrs(BYTE bEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL) & ~(1 << 28);
    uTemp |= bEn << 28;
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}

//////////
// Function Name : DSIM_EnEscapeClkPrs
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetEscClkPrsVal(WORD usPrsVal)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL) & ~(0xffff);
    uTemp |= usPrsVal;
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}

//////////
// Function Name : DSIM_EnPllBypass
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_EnPllBypass(BYTE bEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL) & ~(1 << 27);
    uTemp |= bEn << 27;
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}

//////////
// Function Name : DSIM_SelByteClock
// Function Description :
//   This function select Source of  Byte Clock.
// Input :     eSrc - Source of Byte Clock
// Output : None
// Version : v0.0
void DSIM_SetByteClockSrc(DSIM_ByteClkSrc eSrc)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL) & ~(0x3 << 25);
    uTemp |= (DWORD) eSrc << 25;
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}

//////////
// Function Name : DSIM_EnByteClock
// Function Description :
//   This function enable Byte Clock.
// Input :     bEn - enable Byte Clock
// Output : None
// Version : v0.0
void DSIM_EnByteClock(BYTE bEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL) & ~(1 << 24);
    uTemp |= bEn << 24;
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}


//////////
// Function Name : DSIM_EnByteClock
// Function Description :
//   This function enable Byte Clock.
// Input :     bEn - enable Byte Clock
// Output : None
// Version : v0.0
void DSIM_EnEscClkOnLane(DSIM_LANE eLaneSel, BYTE ucEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CLKCTRL);
    if (ucEn){
        if ( eLaneSel == Lane_Clock ) uTemp |= 1 << 19;
        if ( eLaneSel & Lane_Data0 ) uTemp |= 1 << 20;
        if ( eLaneSel & Lane_Data1 ) uTemp |= 1 << 21;
        if ( eLaneSel & Lane_Data2 ) uTemp |= 1 << 22;
        if ( eLaneSel & Lane_Data2 ) uTemp |= 1 << 23;
    }
    else{
        if ( eLaneSel == Lane_Clock ) uTemp &= ~(1 << 19);
        if ( eLaneSel & Lane_Data0 ) uTemp &= ~(1 << 20);
        if ( eLaneSel & Lane_Data1 ) uTemp &= ~(1 << 21);
        if ( eLaneSel & Lane_Data2 ) uTemp &= ~(1 << 22);
        if ( eLaneSel & Lane_Data2 ) uTemp &= ~(1 << 23);
    }
    DSIM_Outp32(rDSIM_CLKCTRL, uTemp);
}


/*---------------------------------- APIs of DSIM_TIMEOUT---------------------------------*/
//////////
// Function Name : DSIM_SetBTATimeOut
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetBTATimeOut(BYTE ucTimeOut)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_TIMEOUT) & ~(0xff << 16);
    uTemp |= (ucTimeOut << 16);
    DSIM_Outp32(rDSIM_TIMEOUT, uTemp);
}

//////////
// Function Name : DSIM_SetLPDRTimeOut
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetLPDRTimeOut(WORD usTimeOut)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_TIMEOUT) & ~(0xffff << 0);
    uTemp |= (usTimeOut << 0);
    DSIM_Outp32(rDSIM_TIMEOUT, uTemp);
}
/*---------------------------------- APIs of DSIM_CONFIG---------------------------------*/
//////////
// Function Name : DSIM_SetEOTVer
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_InitConfiguration(DDI_Configuration* pMainDispConf, DDI_Configuration* pSubDispConf, DSIM_Configuration* oConfiguration)
{
    DWORD uDSIM_CONFIG =
                        #if ( DSIM_Version == DSIM_1_02 )
                        (oConfiguration->m_ucDSIM_Version << 28 ) |                //EOT Packet Genration
                        #elif (DSIM_Version == DSIM_1_00 )
                        (oConfiguration->m_ucPacketThreshold << 28 ) |
                        #endif
                        ((BYTE)pMainDispConf->m_43eVideoModeType << 26) |
                        ((BYTE)pMainDispConf->m_40eInterface << 25) |    //DSI Interface
                        (oConfiguration->m_ucAutoVerticalCnt << 24) |    //Auto Vertical Cnt Mode
                        (oConfiguration->m_ucHSE << 23) |            //Horizontal Sync Event
                        (oConfiguration->m_ucHFP << 22) |            //Discard Horizontal Front Porch Time
                        (oConfiguration->m_ucHBP << 21) |            //Discard Horizontal Back Porch Time
                        (oConfiguration->m_ucHSA << 20) |            //Discard Horizontal Sync Area Timing
                        ((BYTE) pMainDispConf->m_42eCh << 18)    |        //Main Virtual Channel Number
                        ((BYTE) pMainDispConf->m_41ePixel << 12) |        //Main Virtual Channel Pixel Format
                        ((BYTE) oConfiguration->m_eNoDataLane << 5);    //Number of Data Lane using DSI Master

    if (    pSubDispConf != NULL )
    {
        uDSIM_CONFIG |=     ((BYTE) pSubDispConf->m_42eCh << 16) |    //Sub Virtual Channel Number
                        ((BYTE) pMainDispConf->m_41ePixel << 8 );        //Sub Virtual Channel Pixel Format
    }
    DSIM_Outp32(rDSIM_CONFIG, uDSIM_CONFIG);
}

//////////
// Function Name : DSIM_EnLane
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_EnLane(DSIM_LANE eLane, BYTE ucEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_CONFIG);
    if( eLane == Lane_Clock )
    {
        if ( ucEn )
            uTemp |= (1 << 0);
        else
            uTemp &=  ~(1 << 0);
    }
    else
    {
        if ( ucEn )
            uTemp |= (eLane << 1);
        else
            uTemp &=  ~(eLane << 1);
    }
    DSIM_Outp32(rDSIM_CONFIG, uTemp);
}

/*---------------------------------- APIs of DSIM_ESCMODE---------------------------------*/
//////////
// Function Name : DSIM_SetStopStateCounter
// Function Description :
//  This function set counter value to enter BTA State from Stop State when Read Packet is transmitted
//    or "Set_Tear_On" Command that want data from Peri
// Input :     uCntVal - Stop Cnt Value
// Output : None
// Version : v0.0
void DSIM_SetStopStateCounter(WORD uCntVal)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_ESCMODE) & ~( 0x7ff << 21 );
    uTemp |= ((uCntVal & 0x7ff) << 21);
    DSIM_Outp32(rDSIM_ESCMODE, uTemp);
}

//////////
// Function Name : DSIM_SetStopDPhy
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_ForceDPhyStopState(BYTE ucEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_ESCMODE) & ~( 0x1 << 20 );
    uTemp |= ((ucEn & 0x1 )<< 20);
    DSIM_Outp32(rDSIM_ESCMODE, uTemp);

}

//////////
// Function Name : DSIM_SetStopDPhy
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_ForceBTA(void)
{
    DSIM_Outp32(rDSIM_ESCMODE, (DSIM_Inp32(rDSIM_ESCMODE) | ( 0x1 << 16 )));
    Delay(1000);
    DSIM_Outp32(rDSIM_ESCMODE, (DSIM_Inp32(rDSIM_ESCMODE) & ~( 0x1 << 16 )));
}

//////////
// Function Name : DSIM_SetDataMode
// Function Description :
//   This function change Data Transfer Mode LPDT bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetDataMode(DSIM_Transfer eData,DSIM_State eState)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_ESCMODE);
    if ( eState == DSIM_State_LPDT)
        uTemp |= eData;
    else if ( eState == DSIM_State_HSDT)
        uTemp &= ~eData;
    else
        assert('0');
    DSIM_Outp32(rDSIM_ESCMODE, uTemp);
}

//////////
// Function Name : DSIM_SetFifoLPDTMode
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_ResetTrigger(void)
{
    DSIM_Outp32(rDSIM_ESCMODE, (DSIM_Inp32(rDSIM_ESCMODE) | ( 0x1 << 4 )));
}

//////////
// Function Name : DSIM_SetFifoLPDTMode
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_ULPSRequest(DSIM_UlpsReques ucRequest, BYTE ucBitSet)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_ESCMODE);

    if ( ucRequest == ULPS_Entry)        // Entry request
    {
        if ( ucBitSet )
            uTemp |= (1 << 1) | (1 << 3);
        else
            uTemp &= ~(1 << 1) & ~(1 << 3);
    }
    else                 // Exit request
    {
        if ( ucBitSet )
            uTemp |= (1 << 0) |(1 << 2);
        else
            uTemp &= ~(1 << 0) & ~(1 << 2);
    }


    DSIM_Outp32(rDSIM_ESCMODE, uTemp);
}

/*---------------------------------- APIs of DSIM_MDRESOL---------------------------------*/
//////////
// Function Name : DSIM_SetMainDispResolution
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetMainDispResolution(DWORD usVertiResol, DWORD usHorResol)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_MDRESOL) & ~( 1 << 31);
    DSIM_Outp32(rDSIM_MDRESOL, uTemp);
    uTemp &= ~(0x7ff << 16) & ~(0x7ff << 0);
    uTemp |=(((usVertiResol) & 0x7ff) << 16) | (((usHorResol)& 0x7ff) << 0);
    DSIM_Outp32(rDSIM_MDRESOL, uTemp);
    uTemp |= ( 1 << 31 );
    DSIM_Outp32(rDSIM_MDRESOL, uTemp);
}

/*---------------------------------- APIs of DSIM_MVPORCH---------------------------------*/
//////////
// Function Name : DSIM_SetMainDispVPorch
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetMainDispVPorch(WORD usCmdAllow, WORD usFront, WORD usBack)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_MVPORCH) & ~(0xf << 28) & ~(0x7ff << 16) & ~(0x7ff << 0);
    uTemp |=((usCmdAllow & 0xf) << 28) | ((usFront & 0x7ff) << 16) | ((usBack & 0x7ff) << 0);
    DSIM_Outp32(rDSIM_MVPORCH, uTemp);
}

/*---------------------------------- APIs of DSIM_MHPORCH---------------------------------*/
//////////
// Function Name : DSIM_SetMainDispVPorch
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetMainDispHPorch(WORD usFront, WORD usBack)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_MHPORCH) & ~(0xffff << 16) & ~(0xffff << 0);
    uTemp |=(usFront  << 16) | (usBack << 0);
    DSIM_Outp32(rDSIM_MHPORCH, uTemp);
}
//////////
// Function Name : DSIM_SetMainDispVPorch
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetMainDispSyncArea(WORD usVeri, WORD usHori)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_MSYNC) & ~(0x3ff << 22) & ~(0xffff << 0);
    uTemp |=((usVeri  & 0x3ff)<< 22) | (usHori << 0);
    DSIM_Outp32(rDSIM_MSYNC, uTemp);
}

/*---------------------------------- APIs of DSIM_SDRESOL---------------------------------*/
//////////
// Function Name : DSIM_SetSubDispResolution
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetSubDispResolution(DWORD usVerti, DWORD usHori)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_SDRESOL) & ~( 1 << 31);
    DSIM_Outp32(rDSIM_SDRESOL, uTemp);
    uTemp &= ~(0x7ff << 16) & ~(0x7ff << 0);
    uTemp |=((usVerti & 0x7ff) << 16) | ((usHori & 0x7ff) << 0);
    DSIM_Outp32(rDSIM_SDRESOL ,uTemp);
    uTemp |= ( 1 << 31 );
    DSIM_Outp32(rDSIM_SDRESOL, uTemp);
}

/*---------------------------------- APIs of DSIM_INTSRC---------------------------------*/
//////////
// Function Name : DSIM_GetIntrState
// Function Description :
//   This function get Interrupt conditionof DSI master.
// Input :     None
// Output : DSIM_IntSrc - Interrupt Condition
// Version : v0.0
DSIM_IntSrc DSIM_GetIntrState(void)
{
    return (DSIM_IntSrc) DSIM_Inp32(rDSIM_INTSRC);
}

//////////
// Function Name : DSIM_ClrIntr
// Function Description :
//   This function clear Interrupt pending bit that is caused.
// Input :     DSIM_IntSrc - Clear Interrupt bit
// Output : None
// Version : v0.0
void DSIM_ClrIntr(DSIM_IntSrc eIntSrc)
{
    DSIM_Outp32(rDSIM_INTSRC, (DWORD) eIntSrc);
}
/*---------------------------------- APIs of DSIM_INTMSK---------------------------------*/
//////////
// Function Name : DSIM_SetIntrMask
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_SetIntrMask(DSIM_IntSrc eIntSel, BYTE ucMask)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_INTMASK);
    if ( ucMask )

        uTemp |= (DWORD) eIntSel;
    else
        uTemp &= ~((DWORD)eIntSel);
    DSIM_Outp32(rDSIM_INTMASK, uTemp);
}

//////////
// Function Name : DSIM_GetIntrMask
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
DWORD DSIM_GetIntrMask(void)
{
    return DSIM_Inp32(rDSIM_INTMASK);
}

/*---------------------------------- APIs of DSIM_PKTHDR---------------------------------*/
//////////
// Function Name : DSIM_WrTxHeader
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_WrTxHeader( BYTE ucDI, BYTE ucDat0,BYTE ucDat1)
{
    DWORD uTemp = (ucDat1 << 16) | (ucDat0 << 8) | ((ucDI & 0x3f) << 0);
    DSIM_Outp32(rDSIM_PKTHDR, uTemp);
}

/*---------------------------------- APIs of DSIM_PAYLOAD---------------------------------*/
//////////
// Function Name : DSIM_WrTxData
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_WrTxData(DWORD uTxData)
{
    DSIM_Outp32(rDSIM_PAYLOAD, uTxData);
}

/*---------------------------------- APIs of DSIM_RXFIFO---------------------------------*/
//////////
// Function Name : DSIM_WrPacketHeader
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
DWORD DSIM_RdRxData(void)
{
    return DSIM_Inp32(rDSIM_RXFIFO);
}

/*---------------------------------- Hidden SFR--------------------------------------------*/
/*---------------------------------- APIs of DSIM_FIFOTHLD---------------------------------*/
//////////
// Function Name : DSIM_FIFOThreshold
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_FIFOThreshold(WORD usThresholdLevel)
{
    DSIM_Outp32(rDSIM_FIFOTHLD, usThresholdLevel & 0x1ff);
}

/*---------------------------------- Hidden SFR--------------------------------------------*/
/*---------------------------------- APIs of DSIM_FIFOTHLD---------------------------------*/
//////////
// Function Name : DSIM_WrPacketHeader
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
DSIM_FifoState DSIM_GetFifoState(void)
{
    return (DSIM_FifoState) (DSIM_Inp32(rDSIM_FIFOCTRL) & ~(0x1f));
}

//////////
// Function Name : DSIM_InitFifoPointer
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_InitFifoPointer(DSIM_Fifo eFifo)
{
    DWORD uTemp =  DSIM_Inp32(rDSIM_FIFOCTRL);
    DSIM_Outp32(rDSIM_FIFOCTRL, uTemp & ~(eFifo));
    Delay(10);                    //check need to delay
    uTemp |= eFifo;
    DSIM_Outp32(rDSIM_FIFOCTRL, uTemp);
}

/*---------------------------------- Hidden SFR--------------------------------------------*/
/*---------------------------------- APIs of DSIM_MEMACCHR-------------------------------*/
//////////
// Function Name : DSIM_MemControl
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_MemControl(DSIM_Fifo eFifo)
{

}

/*---------------------------------- APIs of DSIM_PLLCTRL-------------------------------*/
//////////
// Function Name : DSIM_PllFreqBand
// Function Description :
//   This function enable bypass input clock of D-PHY PLL.
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_PllFreqBand(BYTE ucFreqBand)
{
    DWORD uTemp =  DSIM_Inp32(rDSIM_PLLCTRL) & ~(0x1f << 24);
    uTemp |= ((ucFreqBand & 0x1f) << 24);
    DSIM_Outp32(rDSIM_PLLCTRL, uTemp);
}

//////////
// Function Name : DSIM_EnPll
// Function Description :
//   This function enable Pll in D-PHY
// Input :     usEn - Enable bypass
// Output : None
// Version : v0.0
void DSIM_EnPll(BYTE ucEn)
{
    DWORD uTemp =  DSIM_Inp32(rDSIM_PLLCTRL) & ~(0x1 << 23);
    uTemp |= ((ucEn & 0x1) << 23);
    DSIM_Outp32(rDSIM_PLLCTRL, uTemp);
}

//////////
// Function Name : DSIM_EnPll
// Function Description :
//   This function set Pll P,M and S value in D-PHY
// Input :     ucPredivider - 1 ~ 63
//            ucMaindivider - 100 ~ 1023        //65n Phy
//            ucScaler - 0, 1, 2, 3, 4, 5
// Output : None
// Version : v0.0
void DSIM_SetPllPMS(BYTE ucPredivider, WORD ucMaindivider, BYTE ucScaler)
{
    DWORD uTemp =  DSIM_Inp32(rDSIM_PLLCTRL) & ~(0x7ffff << 1);
    #if (DPHY_Version == DPHY_65n)
    uTemp |= ((ucPredivider & 0x3f) << 14) | ((ucMaindivider & 0x3ff) << 4) | ((ucScaler & 0x7) << 1);
    #elif (DPHY_Version == DPHY_45n)
    uTemp |= ((ucPredivider & 0x3f) << 13) | ((ucMaindivider & 0x1ff) << 4) | ((ucScaler & 0x7) << 1);
    #endif
    DSIM_Outp32(rDSIM_PLLCTRL, uTemp);
}
#if (DSIM_Version == DSIM_1_00)
//////////
// Function Name : DSIM_EnPll
// Function Description :
//   This function set Pll P,M and S value in D-PHY
// Input :     ucPredivider - 1 ~ 63
//            ucMaindivider - 100 ~ 1023
//            ucScaler - 0, 1, 2, 3, 4, 5
// Output : None
// Version : v0.0
void DSIM_SwapDpDn(BYTE ucSwapEn)
{
    DWORD uTemp =  DSIM_Inp32(rDSIM_PLLCTRL) & ~(1 << 0);
    uTemp |= ucSwapEn & 1;
    DSIM_Outp32(rDSIM_PLLCTRL, uTemp);
}
#endif
/*---------------------------------- APIs of DSIM_PLLTMR-------------------------------*/
//////////
// Function Name : DSIM_PllLockTime
// Function Description :
//   This function set Pll P,M and S value in D-PHY
// Input :     uLockTime - 1 ~ 63
//            ucMaindivider - 100 ~ 1023
//            ucScaler - 0, 1, 2, 3, 4, 5
// Output : None
// Version : v0.0
void DSIM_PllStatbleTime(DWORD uLockTime)
{
    DSIM_Outp32(rDSIM_PLLTMR, uLockTime);
}
#if (DPHY_Version == DPHY_45n)
/*---------------------------------- APIs of DSIM_PHYACCHR-------------------------------*/
//////////
// Function Name : DSIM_SetPhyTunning
// Function Description :
//   This function set Pll P,M and S value in D-PHY
// Input :     uLockTime - 1 ~ 63
//            ucMaindivider - 100 ~ 1023
//            ucScaler - 0, 1, 2, 3, 4, 5
// Output : None
// Version : v0.0
void DSIM_SetPhyTunning(DWORD uTunnigValue)
{
    DSIM_Outp32(rDSIM_PHYACCHR, uTunnigValue);
}

//////////
// Function Name : DSIM_EnAFC
// Function Description :
//   This function En AFC
// Input :     ucEn : Enable/Disable
// Output : None
// Version : v0.0
void DSIM_EnAFC(BYTE ucEn, BYTE ucAFCCode)
{
    DWORD uTemp =  DSIM_Inp32(rDSIM_PHYACCHR);
    if (ucEn)
    {
        uTemp |= (1 << 14);
        uTemp &= ~(0x7<<5);
        uTemp |= (ucAFCCode << 5);
    }
    else
        uTemp &= ~(1 << 14);
    DSIM_Outp32(rDSIM_PHYACCHR, uTemp);
}
/*---------------------------------- APIs of DSIM_PHYACCHR1------------------------------*/
//////////
// Function Name : DSIM_PllLockTime
// Function Description :
//   This function set Pll P,M and S value in D-PHY
// Input :     uLockTime - 1 ~ 63
//            ucMaindivider - 100 ~ 1023
//            ucScaler - 0, 1, 2, 3, 4, 5
// Output : None
// Version : v0.0
void DSIM_DpDnSwap(DSIM_LANE eLane, BYTE ucSwapEn)
{
    DWORD uTemp = DSIM_Inp32(rDSIM_PHYACCHR1);
    if ( eLane & Lane_Clock )
    {
        uTemp &= ~(1 << 1);
        uTemp |= ucSwapEn << 1;
    }

    if ( eLane & (Lane_Data1|Lane_Data2|Lane_Data3|Lane_Data0))
    {
        uTemp &= ~(1 << 0);
        uTemp |= ucSwapEn << 0;
    }
    DSIM_Outp32(rDSIM_PHYACCHR1, uTemp);
}
#endif
