/**
 * @file        hv_comm_shell_hdmi_debug.c
 * @brief       shell source code.
 * @details     This file provides the following functions: \n
 *              (1) shell init and handle \n
 * @author      HiView SoC Software Team
 * @version     1.0.1
 * @date        2022-09-05
 * @copyright   Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par         History:
 * <table>
 * <tr><th>Author                        <th>Date         <th>Change Description
 * <tr><td>HiView SoC Software Team      <td>2022-08-25   <td>create
 * </table>
*/


#ifdef HV_SCALER_DEBUG_VERSION
#include <string.h>
#include "hv_comm_Log.h"
#include "hv_comm_shell_hvconfig.h"
#include "hv_comm_DataType.h"
#include "hv_comm_Assert.h"
#include "hv_comm_Define.h"
#include "hv_vos_Comm.h"
#include "hv_mw_Hdmi.h"
#include "hv_mw_Hdcp.h"
#include "hv_mw_SystemManager.h"
#include "hv_drv_Physical.h"

#define   HDMI_DUMP_OPT_MAX_LEN     7
#define HV_HDMIRX_ADDR_OFFSET          0x1000

#define HV_LOG_BUF_PRINT(...) HV_LOG_BUF(HV_LOG_LEVEL_ERROR, __VA_ARGS__)

extern CHAR8 * GetInputPortState(InputPortState enCurrentPortState);
#ifdef HDMI_DEBUG_EVENT_TIC
extern UINT32  g_uiTickPointList[HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM][E_HDMI_TickPointNum];
extern SHORT16 g_usEventStatstcs[HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM][InputPortEventId_HDMI_Max+1];
#endif
/**
 * @brief  Print the Hdmi Timing for debug.
 * @param[in] Timing Detail Data pointer.
 * @return VOID
 */
extern VOID PrintHdmiTimingPara(VideoTimingParam *pstVideoTiming);

/**
 * @brief  Print the HDMI HDR Parameters for debug.
 * @param[in] HDR pointer to hdmi data.
 * @return VOID
 */
extern VOID PrintHdmiHdrPara(HDRParam *pstHDRPara);
extern VOID PrintHdmiAviColorPara(VideoColorParam *pstClorPara);

void Hv_Shell_Hdmi_Usage()
{
    HV_LOG_ERROR(HDMI,"    hdmidebug [OPTION]");
    HV_LOG_ERROR(HDMI,"        -i [port_index], which HDMI port is operated, 0 for HDMI_0 & 1 for HDMI_1 ...");
    HV_LOG_ERROR(HDMI,"        -d [dump], Dump the details of the HDMI port status and configrations.");
    HV_LOG_ERROR(HDMI,"        -e [Update Edid] 0 Default; 1 FreeSync; 2 PBP; 3 PIP; 4 CTS; 5 TMDS; 6 Test");
    HV_LOG_ERROR(HDMI,"        -g [gearmode] 0 E_LOWGEAR; 1 E_MIDDLEGEAR; 2 E_HIGHGEAR; 3 E_RATIOGEAR; 4 E_DEFAULT");
    HV_LOG_ERROR(HDMI,"        -r [reset] Reset the HDMI. ");
    HV_LOG_ERROR(HDMI,"        -s [show] Show Key Point Tick. ");
    HV_LOG_ERROR(HDMI,"        -w [show] HDMI Event Statics. ");
    HV_LOG_ERROR(HDMI,"        -p [HPD_control] Control the HPD PIN: 0 for Down; 1 for UP . ");
    HV_LOG_ERROR(HDMI,"        -h print the command hdmidebug help info.");
    HV_LOG_ERROR(HDMI,"           For example to dump all the information of hdmi port 0 : ");
    HV_LOG_ERROR(HDMI,"           hdmidebug -i 0 -d all");
}

CHAR8 * GetKeyEventPoint(HdmiRxKeyEventTickPoint enKeyEvent)
{
    if(E_HDMI_CablePlugIn == enKeyEvent)
    {
        return "HDMI_Cable_PlugIn";
    }
    else if(E_HDMI_TrainingDone == enKeyEvent)
    {
        return "HDMI_TrainingDone";
    }
    else if(E_HDMI_TimingStable == enKeyEvent)
    {
        return "HDMI_TimingStable";
    }
    else if(E_HDMI_DPUGetPara == enKeyEvent)
    {
        return "HDMI_DPU_Get_Para";
    }
    else if(E_HDMI_TimingChange == enKeyEvent)
    {
        return "HDMI_TimingChange";
    }
    else if(E_HDMI_SignalLoss == enKeyEvent)
    {
        return "HDMI_Signal_Losst";
    }
    else if(E_HDMI_CablePlugOut == enKeyEvent)
    {
        return "HDMI_CablePlugOut";
    }

    return "Unkown";
}

CHAR8 * GetInterruptEventPoint(InputPortEventId enKeyEvent)
{
    if(InputPortEventId_HDMI_IdleStart == enKeyEvent)
    {
        return "HDMI_IdleStarted";
    }
    else if(InputPortEventId_HDMI_IntGen == enKeyEvent)
    {
        return "HDMI_IntGenerate";
    }
    else if(InputPortEventId_HDMI_PllChange == enKeyEvent)
    {
        return "HDMI_Pll_Changed";
    }
    else if(InputPortEventId_HDMI_5VPlugIn == enKeyEvent)
    {
        return "HDMI_CablePlugIn";
    }
    else if(InputPortEventId_HDMI_5VPlugOut == enKeyEvent)
    {
        return "HDMI_CablPlugOut";
    }
    else if(InputPortEventId_HDMI_HpdSetHigh == enKeyEvent)
    {
        return "HDMI_HpdSetToggl";
    }
    else if(InputPortEventId_HDMI_TimingChange == enKeyEvent)
    {
        return "HDMI_TimingChang";
    }
    else if(InputPortEventId_HDMI_TimingStable == enKeyEvent)
    {
        return "HDMI_TimingStabl";
    }
    else if(InputPortEventId_HDMI_RatioChange == enKeyEvent)
    {
        return "HDMI_RatioChange";
    }
    else if(InputPortEventId_HDMI_FRLRateChange == enKeyEvent)
    {
        return "HDMI_FRLRateChng";
    }
    else if(InputPortEventId_HDMI_GCPAVMutePacket == enKeyEvent)
    {
        return "HDMI_GCP_AV_Mute";
    }
    else if(InputPortEventId_HDMI_AVIPacketChange == enKeyEvent)
    {
        return "HDMI_AVI_Changed";
    }
    else if(InputPortEventId_HDMI_VSIPacketChange == enKeyEvent)
    {
        return "HDMI_VSI_Changed";
    }
    else if(InputPortEventId_HDMI_DRMPacketChange == enKeyEvent)
    {
        return "HDMI_DRM_Changed";
    }
    else if(InputPortEventId_HDMI_SPDChsChanged == enKeyEvent)
    {
        return "HDMI_SPD_Changed";
    }
    else if(InputPortEventId_HDMI_EMPPacketRcv == enKeyEvent)
    {
        return "HDMI_EMP_Changed";
    }
    else if(InputPortEventId_HDMI_PktErrForHdcp == enKeyEvent)
    {
        return "HDMI_PktErrHdcp";
    }
    else if(InputPortEventId_HDMI_GcpCDChg == enKeyEvent)
    {
        return "HDMI_GcpCDChang";
    }
    else if(InputPortEventId_HDMI_TrainDone == enKeyEvent)
    {
        return "HDMI_Train_Done";
    }
    else if(InputPortEventId_HDMI_Max == enKeyEvent)
    {
        return "HDMI_Cable_ISRH";
    }

    return "Unkown";
}

void Hv_Shell_Hdmi_DumpPointStaticsCnt(UINT32 uiPortIndex, UINT32 uiDumpOption)
{
#ifdef HDMI_DEBUG_EVENT_TIC

    UINT32 uiIndex = 0;
    if (uiPortIndex > HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
    {
        HV_LOG_ERROR(HDMI,"invalid Hdmi port index %d\n", uiPortIndex);
        return ;
    }

    for(uiIndex = 0; uiIndex < E_HDMI_TickPointNum; uiIndex++)
    {
        HV_LOG_ERROR(HDMI,"%s : %d", GetKeyEventPoint(uiIndex), g_uiTickPointList[uiPortIndex][uiIndex]);
    }
#endif
    return;
}
void Hv_Shell_Hdmi_DumpEventStaticsCnt(UINT32 uiPortIndex, UINT32 uiDumpOption)
{
#ifdef HDMI_DEBUG_EVENT_TIC

    UINT32 uiIndex = 0;
    if (uiPortIndex > HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
    {
        HV_LOG_ERROR(HDMI,"invalid Hdmi port index %d\n", uiPortIndex);
        return ;
    }

    for(uiIndex = 0; uiIndex <= InputPortEventId_HDMI_Max; uiIndex++)
    {
        HV_LOG_ERROR(HDMI,"%s : %d", GetInterruptEventPoint(uiIndex), g_usEventStatstcs[uiPortIndex][uiIndex]);
    }
#endif
    return;
}

void Hv_Shell_Hdmi_DumpPortData(UINT32 uiPortIndex, UINT32 uiDumpOption)
{
    if (uiPortIndex > HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
    {
        HV_LOG_ERROR(HDMI,"invalid Hdmi port index %d\n", uiPortIndex);
        return ;
    }

    HdmiCtrlData* pstHdmiDataPtr = HV_Mw_HdmiRx_GetHdmiData(uiPortIndex);
    HV_ASSERT_VALID_PTR_VOID(pstHdmiDataPtr);

    HV_LOG_ERROR(HDMI,"Following is the Hdmi: %d information:", uiPortIndex);
    HV_LOG_ERROR(HDMI,"ePortIndex is the Hdmi: %d :", pstHdmiDataPtr->enPortIndex);
    HV_LOG_ERROR(HDMI,"enCurrentPortState : %s ", GetInputPortState(pstHdmiDataPtr->enCurrentPortState));
    HV_LOG_ERROR(HDMI,"Cable Connect Status is : %s .", pstHdmiDataPtr->bIsCableConnected ? "YES":"NO");
    HV_LOG_ERROR(HDMI,"bHPDStatus is : %s .", pstHdmiDataPtr->bHPDStatus ? "UP" : "DOWN");
#ifdef HDMI_DEBUG_EVENT_TIC
    HV_LOG_ERROR(HDMI,"HDMI have received the Interrupt Counter : %d .", g_usEventStatstcs[uiPortIndex][InputPortEventId_HDMI_IntGen]);
    HV_LOG_ERROR(HDMI,"HDMI have received the CablePlgIn Counter : %d .", g_usEventStatstcs[uiPortIndex][InputPortEventId_HDMI_5VPlugIn]);
    HV_LOG_ERROR(HDMI,"HDMI have received the CablePlgOut Counter : %d .", g_usEventStatstcs[uiPortIndex][InputPortEventId_HDMI_5VPlugOut]);
    HV_LOG_ERROR(HDMI,"HDMI have received the Cable Interrupt Counter : %d .", g_usEventStatstcs[uiPortIndex][InputPortEventId_HDMI_Max]);
#endif
    HV_LOG_ERROR(HDMI,"ucHdmiFRLRate is : %d .", pstHdmiDataPtr->ucHdmiFRLRate);
    HV_LOG_ERROR(HDMI,"bEnterAllm is : %d .", pstHdmiDataPtr->bEnterAllm);
    HV_LOG_ERROR(HDMI,"ucGrearMode is : %d .", pstHdmiDataPtr->ucGrearMode);
    HV_LOG_ERROR(HDMI,"enEdidConfiged is : %d .", pstHdmiDataPtr->enEdidConfiged);
    HV_LOG_ERROR(HDMI,"uiEdidLength is : %d .", pstHdmiDataPtr->uiEdidLength);
    HV_LOG_ERROR(HDMI,"bEnteredVRR is : %s .", pstHdmiDataPtr->bEnteredVRR ? "ON":"OFF");
    HV_LOG_ERROR(HDMI,"ucHdcpEncStatus : %d .", pstHdmiDataPtr->ucHdcpEncStatus);
    HV_LOG_ERROR(HDMI,"ucEqStatus : %d .", pstHdmiDataPtr->ucEqStatus);

    HV_LOG_ERROR(HDMI,"The Timing and HDR information: ");
    PrintHdmiTimingPara(&(pstHdmiDataPtr->stTimingPara));
    PrintHdmiAviColorPara(&(pstHdmiDataPtr->stColorPara));
    
    HV_LOG_ERROR(HDMI,"@@ HDR info: Type %d", pstHdmiDataPtr->stHdrPara.xType);

    HV_LOG_ERROR(HDMI,"@@ info: VRR eVendor is %d", pstHdmiDataPtr->stVrrInfo.eVendor);
    if(pstHdmiDataPtr->stVrrInfo.eVendor == VendorType_AMD)
    {
        HV_LOG_ERROR(HDMI,"*******************HDMI VSI Info Start**********************");
        HV_LOG_ERROR(HDMI,"@@ VSI info: eVendor Type is %d", pstHdmiDataPtr->stVrrInfo.eVendor);
        HV_LOG_ERROR(HDMI,"@@ VSI info: ucVersion is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.ucVersion);
        HV_LOG_ERROR(HDMI,"@@ VSI info: ucFreeSyncMinReFresh is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.ucFreeSyncMinReFresh);
        HV_LOG_ERROR(HDMI,"@@ VSI info: ucFreeSyncMaxReFresh is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.ucFreeSyncMaxReFresh);
        HV_LOG_ERROR(HDMI,"@@ VSI info: ucBrightneesControl is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.ucBrightneesControl);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bFreeSyncSupported is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bFreeSyncSupported);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bFreeSyncEnabled is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bFreeSyncEnabled);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bFreeSyncActive is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bFreeSyncActive);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bBT709EOTFActive is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bBT709EOTFActive);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bGamma22EOTFActive is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bGamma22EOTFActive);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bGamma26EOTFActive is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bGamma26EOTFActive);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bLocalDimmingDisabled is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bLocalDimmingDisabled);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bNativeColorSpaceActive is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bNativeColorSpaceActive);
        HV_LOG_ERROR(HDMI,"@@ VSI info: bSRGBEOTFActive is %d", pstHdmiDataPtr->stVrrInfo.uvsi.stAmdSpdInfPara.bSRGBEOTFActive);
        HV_LOG_ERROR(HDMI,"*******************HDMI VSI Info END***********************");
    }

    HV_LOG_ERROR(HDMI, "Frame Rate for current is: %d", Hv_Mw_HdmiRx_GetCurrentFrameRate(pstHdmiDataPtr->enPortIndex));

    return;
}

void Hv_Shell_Hdmi_Dump(UINT32 uiPortIndex, UINT32 uiDumpOption)
{
    UINT32 uiPortIndexLoop = 0;

    if(uiPortIndex <= HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
    {
        Hv_Shell_Hdmi_DumpPortData(uiPortIndex, uiDumpOption);
    }
    else
    {
        return;
    }

    HV_LOG_ERROR(HDMI,"The Main Channel Index is: %d.", Hv_Mw_InputPort_GetManagerPtr()->enMainPortIndex);
    HV_LOG_ERROR(HDMI,"The Sub Channel Index is: %d.", Hv_Mw_InputPort_GetManagerPtr()->enSubPortIndex);

    HV_LOG_ERROR(HDMI,"Dump HDMI Data : %d Success.", uiPortIndex);

    return;
}

void Hv_Shell_HdmiDebugReset(UINT32 uiPortIndex)
{
    UINT32 uiPortIndexLoop = 0;
    if(uiPortIndex <= HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
    {
        Hv_Cal_HdmiRx_ResetAudioFifo(uiPortIndex);
        Hv_Cal_HdmiRx_Reset(uiPortIndex);
    }
    else
    {
        for(uiPortIndexLoop = 0; uiPortIndexLoop < HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM; uiPortIndexLoop ++)
        {
            Hv_Cal_HdmiRx_ResetAudioFifo(uiPortIndexLoop);
            Hv_Cal_HdmiRx_Reset(uiPortIndexLoop);
        }
    }

    return;
}

void Hv_Shell_Hdmi_SetHPDCtrlSwitch(UINT32 uiPortIndex, BOOL uiSwitch)
{
    UINT32 uiPortIndexLoop = 0;
    HdmiCtrlData* pstHdmiDataPtr = HV_Mw_HdmiRx_GetHdmiData(uiPortIndex);

    HV_ASSERT_VALID_PTR_VOID(pstHdmiDataPtr);

    Hv_Mw_HdmiRx_DDCCIHPDControl(pstHdmiDataPtr->enPortIndex, uiSwitch);

    return;
}

void Hv_Shell_Hdmi_DumpEdidUsed(UINT32 uiPortIndex)
{
    HdmiCtrlData* pstHdmiPtr = NULL;
    HV_LOG_ERROR(HDMI, "Edid of HDMI%d:", uiPortIndex);

    if(uiPortIndex == 0)
    {
        pstHdmiPtr = HV_Mw_HdmiRx_GetHdmiData(0);
    }
    else
    {
        pstHdmiPtr = HV_Mw_HdmiRx_GetHdmiData(1);
    }

    HV_LOG_BUF(HV_LOG_LEVEL_ERROR, "Data", pstHdmiPtr->aucEdidData, pstHdmiPtr->uiEdidLength);
}

void Hv_Mw_Hdmi_UpdateEdidDebug(USHORT16 uiPortIndex, EDIDType eEdidConfigure)
{
    HdmiCtrlData* pstHdmiPtr = NULL;

    if(uiPortIndex <= HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
    {
        pstHdmiPtr = HV_Mw_HdmiRx_GetHdmiData(uiPortIndex);
        if(pstHdmiPtr == NULL)
        {
            HV_LOG_ERROR(HDMI, "Port Index:%d Is Invalid.", uiPortIndex);
            return;
        }

        Hv_Mw_HdmiRx_UpdateEdid(pstHdmiPtr->enPortIndex, eEdidConfigure);
    }
    else
    {
        Hv_Mw_HdmiRx_UpdateEdid(LINK_PORT_INDEX_HDMI_RX0, eEdidConfigure);
        Hv_Mw_HdmiRx_UpdateEdid(LINK_PORT_INDEX_HDMI_RX1, eEdidConfigure);
    }

    return;
}

void Hv_Shell_Hdmi_SetRatioGearMode(UINT32 uiPortIndex, UCHAR8 ucMode)
{
    UINT32 uiReadValue = 0;
    UINT32 uiAddrOffset = (((uiPortIndex) == 0) ? 0 : HV_HDMIRX_ADDR_OFFSET);
    UINT32 uiFrameRateFreq = 0, uiNewFrameRateFreq = 0;
    USHORT16 usHTotal = 0;
    USHORT16 usVTotal = 0, usNewVtotal = 0;
    USHORT16 usVActive = 0;
    USHORT16 usFrameRate = 0;
    HV_R32_DECL_VAR();
    UINT32 uiPixelClock = 0;
    UINT32 uiLoop = 0;
    UINT32 uiDelay = 0;
    UINT32 uiCnt = 0;

    for(uiLoop = 0; uiLoop < 500; uiLoop++)
    {
        uiCnt = 0;
        uiReadValue = HV_R32(RX_HDMI21_RX_POST_0_PROC_00_C4 + uiAddrOffset);
        usVActive = HV_R32_FIELD_EX(RX_HDMI21_RX_POST_0_PROC_00_C0, uiAddrOffset, regr_00_mr_tmds_vact);
        uiNewFrameRateFreq = HV_R32_FIELD_EX(RX_HDMI21_RX_POST_0_PROC_00_A8, uiAddrOffset, regr_00_hd21rx_frame_rate);

        //usHTotal = uiReadValue & 0x7FFF;
        //uiReadValue >>= 15;
        //usVTotal = uiReadValue & 0x7FFF;
        //uiDelay = ((uiFrameRateFreq * usVActive / 27 / usVTotal));
        usHTotal = uiReadValue & 0x7FFF;
        uiReadValue >>= 15;
        usNewVtotal = uiReadValue & 0x7FFF;

        //if(ucMode)
        {
            //Hv_Vos_Delayus(uiDelay);
            //uiReadValue = HV_R32(RX_HDMI21_RX_POST_0_PROC_00_C4 + uiAddrOffset);
            do{
                usVTotal = usNewVtotal;
                uiFrameRateFreq = uiNewFrameRateFreq;
                //uiDelay = (((((UINT64)uiFrameRateFreq * usVActive) / 27) / usVTotal));
                uiDelay = (uiFrameRateFreq / 27);
                Hv_Vos_Delayus(uiDelay);
                uiNewFrameRateFreq = HV_R32_FIELD_EX(RX_HDMI21_RX_POST_0_PROC_00_A8, uiAddrOffset, regr_00_hd21rx_frame_rate);
                uiReadValue = HV_R32(RX_HDMI21_RX_POST_0_PROC_00_C4 + uiAddrOffset);
                usNewVtotal = (uiReadValue >> 15) & 0x7FFF;
                uiCnt ++;
                //HV_LOG_INFO(HDMI, "Freq / Vtotal: %d, %d",uiNewFrameRateFreq / usNewVtotal, uiFrameRateFreq / usVTotal);
            }while((ABS(uiNewFrameRateFreq / usNewVtotal, uiFrameRateFreq / usVTotal) > 0) && (uiCnt < 21));
            usVTotal = usNewVtotal;
            uiFrameRateFreq = uiNewFrameRateFreq;
        }

        if((HDMI_RX_ORG_CLK_FRQ % uiFrameRateFreq) >  (uiFrameRateFreq >> 3))
        {
            usFrameRate = (USHORT16)((HDMI_RX_ORG_CLK_FRQ / uiFrameRateFreq) + 1);
        }
        else
        {
            usFrameRate = (USHORT16)(HDMI_RX_ORG_CLK_FRQ / uiFrameRateFreq);
        }

        uiPixelClock = usHTotal;
        uiPixelClock *= usVTotal;
        uiPixelClock *= usFrameRate;

        HV_LOG_INFO(HDMI, "Timing of the HDMI is H-V-F:%d-%d-%d-%d and PixelClk:%d.", uiNewFrameRateFreq / usNewVtotal, usVTotal, usFrameRate, uiCnt, uiPixelClock);

        //Hv_Vos_MSleep(5);
    }

    return;
}

void Hv_Shell_Hdmi_SetPacketErrorHdcp(UINT32 uiPortIndex, UCHAR8 ucMode)
{
    SystemEvent stSystemEvent = {0};

    HV_VOS_QUEUE_S* xSystembQueue = Hv_Mw_System_GetSystemQueue();
    HV_ASSERT_VALID_PTR_VOID(xSystembQueue);

    stSystemEvent.enEventType = SYSTEM_REV_EVENT_TYPE_INPUTPORT;
    stSystemEvent.usEventId = InputPortEventId_HDMI_TimingChange;
    stSystemEvent.ucPortIndex = 1;

    HV_ASSERT_TRUE_VOID(Hv_Vos_QueueSend(xSystembQueue, (void *)&stSystemEvent));

    return;
}

void Hv_Shell_Hdmi_CheckEdidForcedToDb(UINT32 uiPortIndex, UCHAR8 ucMode)
{
    HdmiEdidDBRegion *pstEdidDb    = Hv_Common_Db_GetHdmiEdidDBRegionPtr();
    HV_LOG_ERROR(HDMI, "HdmiEdidDBRegion Length is %d.", sizeof(HdmiEdidDBRegion));
    HV_LOG_ERROR(HDMI, "Data Content is %d : %d - %d.", ((pstEdidDb->astHdmiEdid)[0]).eEdidType, ((pstEdidDb->astEdid)[0]).eEdidType, ((pstEdidDb->astDpEdid)[0]).eEdidType);
    HV_LOG_ERROR(HDMI, "Data Content is %d : %d - %d.", ((pstEdidDb->astHdmiEdid)[1]).eEdidType, ((pstEdidDb->astEdid)[1]).eEdidType, ((pstEdidDb->astDpEdid)[1]).eEdidType);
    HV_LOG_ERROR(HDMI, "Data Content is %d : %d - %d.", ((pstEdidDb->astHdmiEdid)[2]).eEdidType, ((pstEdidDb->astEdid)[2]).eEdidType, ((pstEdidDb->astDpEdid)[2]).eEdidType);
    HV_LOG_ERROR(HDMI, "EDID Numbers is %d ", (pstEdidDb->ucNumber));
/*
    ((pstEdidDb->astHdmiEdid)[1]).eEdidType = 0x7;
    ((pstEdidDb->astHdmiEdid)[1]).eEdidType = 0x6;
*/
    return;
}

void Hv_Shell_Hdmi_EdidEEPROMTest(UINT32 ucInput)
{
    HdmiCtrlData* pstHdmiPtr = HV_Mw_HdmiRx_GetHdmiData(0);
    UCHAR8 aucEdidExtData[HV_EDID_SEGMENT_DATA_SIZE] = {0,};

    if(ucInput > 256)
    {
        ucInput = 256;
    }
#if (HV_PROJECT_CONFIG_EDID_EXTER_EEPROM == HV_CONFIG_OFF)
    Hv_Cal_HdmiRx_CloseRegisterEdid(0);
#endif
    Hv_Drv_Eeprom_Read(I2CS0, 0, aucEdidExtData, ucInput);

    HV_LOG_BUF_PRINT("Origanl Data On EEPROM:",aucEdidExtData, ucInput);

    if(ucInput >= 256)
    {
        HV_LOG_BUF_PRINT("Write Data:",pstHdmiPtr->aucEdidData,256);
        Hv_Drv_Eeprom_Write(I2CS0, 0, pstHdmiPtr->aucEdidData, 256);
        Hv_Drv_Eeprom_Read(I2CS0, 0, aucEdidExtData, 256);
        HV_LOG_BUF_PRINT("After Write Data On EEPROM:",aucEdidExtData,256);
#if (HV_PROJECT_CONFIG_EDID_EXTER_EEPROM == HV_CONFIG_OFF)
        HV_MEMSET(aucEdidExtData, 0xFF, 256);
        Hv_Drv_Eeprom_Write(I2CS0, 0, aucEdidExtData, 256);
        HV_MEMSET(aucEdidExtData, 0x00, 256);
        Hv_Drv_Eeprom_Read(I2CS0, 0, aucEdidExtData, 256);
        HV_LOG_BUF_PRINT("After 0xFF Data On EEPROM:",aucEdidExtData,256);
#endif
    }

#if (HV_PROJECT_CONFIG_EDID_EXTER_EEPROM == HV_CONFIG_OFF)
    Hv_Cal_HdmiRx_OpenRegisterEdid(0, 1);
#endif

    return;
}

void Hv_Shell_Hdmi_DumpHdmiFac()
{
    UINT32 i = 0;
    HV_LOG_ERROR(HDMI, "HDMI EDID Etc Factory Content.");
    UCHAR8* pucEdidUsed = NULL;
    USHORT16 usEdidUsedLen = 0;
    HdmiEdidDBRegion *pstEdidDb    = Hv_Common_Db_GetHdmiEdidDBRegionPtr();
    HdmiEdidDBRegion *pstEdidDb1   = Hv_Common_Db_GetHdmi1EdidDBRegionPtr();
    FactoryDataDBRegion *pstFactDb = Hv_Common_Db_GetFactoryDataDBRegionPtr();
    UserDataDBRegion *pstUserDb    = Hv_Common_Db_GetUserDataDBRegionPtr();

    HV_LOG_ERROR(HDMI, "HDMI Factory WEEK %x, YEAR: %x and sepHDCP : %d.", pstFactDb->ucFactWeek, pstFactDb->ucFactYear, pstFactDb->ucUseSeperatorHDCPKey);

#if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
    HV_LOG_ERROR(HDMI, "HDMI0 EDID Conf Type: %d .", pstUserDb->ucHdmi0EdidCfg);
#endif

#if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
    HV_LOG_ERROR(HDMI, "HDMI1 EDID Conf Type: %d .", pstUserDb->ucHdmi1EdidCfg);
#endif

    HV_LOG_BUF_PRINT("HDMI Factory PRODUCT SN:", (pstFactDb->acProductSn), PRODUCT_SN_LENTH);
    HV_LOG_BUF_PRINT("HDMI Factory EDID SN:", (pstFactDb->acDescSn), EDID_DESC_SN_LENTH);

#if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
    HV_LOG_ERROR(HDMI, "HDMI0 EDID ucNumber %d, uiMagicNumber: %x .", pstEdidDb->ucNumber, pstEdidDb->uiMagicNumber);

    for(i = 0; i < pstEdidDb->ucNumber && i < HDMI_EDID_MAX_NUMBER; i++)
    {
        HV_LOG_ERROR(HDMI, "HDMI0 EDID%d with eEdidType %d, uiEdidLen: %d .", i, pstEdidDb->astHdmiEdid[i].eEdidType, pstEdidDb->astHdmiEdid[i].uiEdidLen);
        if(pstUserDb->ucHdmi0EdidCfg == pstEdidDb->astHdmiEdid[i].eEdidType)
        {
            pucEdidUsed = pstEdidDb->astHdmiEdid[i].acEdid;
            usEdidUsedLen = pstEdidDb->astHdmiEdid[i].uiEdidLen;
        }
    }

    HV_LOG_BUF(HV_LOG_LEVEL_ERROR, "HDMI0 Used EDID:", pucEdidUsed, usEdidUsedLen);
#endif

#if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
    HV_LOG_ERROR(HDMI, "HDMI1 EDID ucNumber %d, uiMagicNumber: %x .", pstEdidDb1->ucNumber, pstEdidDb1->uiMagicNumber);

    for(i = 0; i < pstEdidDb1->ucNumber && i < HDMI_EDID_MAX_NUMBER; i++)
    {
        HV_LOG_ERROR(HDMI, "HDMI0 EDID%d with eEdidType %d, uiEdidLen: %d .", i, pstEdidDb1->astHdmiEdid[i].eEdidType, pstEdidDb1->astHdmiEdid[i].uiEdidLen);
        if(pstUserDb->ucHdmi1EdidCfg == pstEdidDb1->astHdmiEdid[i].eEdidType)
        {
            pucEdidUsed = pstEdidDb1->astHdmiEdid[i].acEdid;
            usEdidUsedLen = pstEdidDb1->astHdmiEdid[i].uiEdidLen;
        }
    }

    HV_LOG_BUF(HV_LOG_LEVEL_ERROR, "HDMI1 Used EDID:", pucEdidUsed, usEdidUsedLen);
#endif

    return;
}
void Hv_Shell_Hdmi_BlackDebug(UINT32 uiInput)
{
    switch (uiInput)
    {
        case 0:
            HV_LOG_ERROR(HDMI, "Closed the Curser of RX and TX.");
            HV_W32_FIELD(RX_HSRX_CH_00_04, reg_00_hsrx_cursor_en, 0);
            HV_W32_FIELD(DISP_TOP_SUB_LDG_68, reg_black_insert_color_r, 0x00);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_B8, reg_disp_ctrl_post_cursor_en, 0);
            break;
        case 1:
            HV_LOG_ERROR(HDMI, "Open the Curser of RX and TX.");
            HV_W32_FIELD(RX_HSRX_CH_00_04, reg_00_hsrx_cursor_hcnt, 0x100);
            HV_W32_FIELD(RX_HSRX_CH_00_04, reg_00_hsrx_cursor_vcnt, 0x100);
            HV_W32_FIELD(RX_HSRX_CH_00_04, reg_00_hsrx_cursor_color, 0x4);
            HV_W32_FIELD(RX_HSRX_CH_00_04, reg_00_hsrx_cursor_en, 0x1);

            HV_W32_FIELD(DISP_TOP_SUB_LDG_68, reg_black_insert_color_r, 0xFF);

            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_BC, reg_disp_ctrl_post_cursor_hcnt, 0x120);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_BC, reg_disp_ctrl_post_cursor_hstep, 0x1);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_BC, reg_disp_ctrl_post_cursor_hwidth, 0x1);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_C0, reg_disp_ctrl_post_cursor_vcnt, 0x120);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_C0, reg_disp_ctrl_post_cursor_vstep, 0x1);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_C0, reg_disp_ctrl_post_cursor_vwidth, 0x1);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_B8, reg_disp_ctrl_post_cursor_color, 0x7);
            HV_W32_FIELD(TX_DISP_CTRL_TOP_1_B8, reg_disp_ctrl_post_cursor_en, 0x1);
            break;
        default:
            HV_LOG_ERROR(HDMI, "InValid Input: 1: Open, 0: Closed.");
            break;
    }
    return;
}
/*
 * hdmidbeug -i 1 -e 4
 */
int Hv_Shell_HdmiRxDebug(int argc, char* argv[])
{
    int         c = -1;
    char        dump_info[HDMI_DUMP_OPT_MAX_LEN + 1] = {0};
    static USHORT16    usHdmiPortIndex = HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM;
    BOOL        bInputPortIndex = HV_FALSE;
    UCHAR8      ucAutoDetectSwitch = 0, ucHpdSwitch = 0, ucTmp = 0;

    while ((c = Hv_getOpt(argc, argv, "i:g:p:r:d:e:c:s:w:l:a:b:h:f:")) != -1)
    {
        switch(c)
        {
            case 'a':
                Hv_Shell_Hdmi_EdidEEPROMTest(atoi(hv_optarg));
                break;
            case 'b':
                Hv_Shell_Hdmi_BlackDebug(atoi(hv_optarg));
                break;
            case 'e':
                ucTmp = atoi(hv_optarg) & 0xFF;
                Hv_Mw_Hdmi_UpdateEdidDebug(usHdmiPortIndex, ucTmp);
                break;

            case 'l':
                {
                    ucTmp = atoi(hv_optarg) & 0xFF;
                    Hv_Shell_Hdmi_DumpEdidUsed(ucTmp);
                    break;
                }

            case 'd':

                strncpy(dump_info, hv_optarg, HDMI_DUMP_OPT_MAX_LEN);

                if(strcmp(dump_info,"all") == 0)
                {
                    Hv_Shell_Hdmi_Dump(0, 0);
                    Hv_Shell_Hdmi_Dump(1, 0);
                }
                else if (strcmp(dump_info,"fac") == 0)
                {
                    Hv_Shell_Hdmi_DumpHdmiFac();
                }
                else
                {   
                    ucTmp = atoi(dump_info) & 0xFF;
                    if(ucTmp < 2)
                    {
                        Hv_Shell_Hdmi_Dump(ucTmp, 0);
                    }
                    else
                    {
                        Hv_Shell_Hdmi_Dump(0, 0);
                        Hv_Shell_Hdmi_Dump(1, 0);
                    }
                }

                break;

            case 'i':
                usHdmiPortIndex = atoi(hv_optarg) & 0xFF;
                if (usHdmiPortIndex > HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
                {
                    HV_LOG_ERROR(HDMI,"invalid Hdmi port index %d\n", usHdmiPortIndex);
                    Hv_Shell_Hdmi_Usage();
                    return 0;
                }
                bInputPortIndex = HV_TRUE;
                break;

            case 'r':
                ucTmp = atoi(hv_optarg) & 0xFF;
                Hv_Shell_HdmiDebugReset(ucTmp);
                break;

            case 'p':
                ucHpdSwitch = atoi(hv_optarg) & 0xFF;
                if(ucHpdSwitch == 0)
                {
                    Hv_Shell_Hdmi_SetHPDCtrlSwitch(0, HV_FALSE);
                    Hv_Shell_Hdmi_SetHPDCtrlSwitch(1, HV_FALSE);
                }
                else
                {
                    Hv_Shell_Hdmi_SetHPDCtrlSwitch(0, HV_TRUE);
                    Hv_Shell_Hdmi_SetHPDCtrlSwitch(1, HV_TRUE);
                }
                break;

            case 'g':
                {
                    ucTmp = atoi(hv_optarg) & 0xFF;
                    Hv_Shell_Hdmi_SetRatioGearMode(usHdmiPortIndex, ucTmp);
                    break;
                }

            case 'f':
                {
                    ucTmp = atoi(hv_optarg) & 0xFF;
                    Hv_Shell_Hdmi_CheckEdidForcedToDb(usHdmiPortIndex, ucTmp);
                    break;
                }

            case 'c':
                {
                    ucTmp = atoi(hv_optarg) & 0xFF;
                    Hv_Shell_Hdmi_SetPacketErrorHdcp(usHdmiPortIndex, ucTmp);
                    break;
                }

            case 's':
                {
                    ucTmp = atoi(hv_optarg) & 0xFF;
                    if (ucTmp > HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
                    {
                        HV_LOG_ERROR(HDMI,"invalid Hdmi port index %d\n", ucTmp);
                        Hv_Shell_Hdmi_Usage();
                        return 0;
                    }
                    Hv_Shell_Hdmi_DumpPointStaticsCnt(ucTmp, 0);

                    break;
                }

            case 'w':
                {
                    ucTmp = atoi(hv_optarg) & 0xFF;
                    if (ucTmp > HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM)
                    {
                        HV_LOG_ERROR(HDMI,"invalid Hdmi port index %d\n", ucTmp);
                        Hv_Shell_Hdmi_Usage();
                        return 0;
                    }
                    Hv_Shell_Hdmi_DumpEventStaticsCnt(ucTmp, 0);

                    break;
                }

            case 'h':
                Hv_Shell_Hdmi_Usage();
                break;
    
            default:
                HV_LOG_ERROR(HDMI,"Command Error. Please reference the usage:\n", c);
                Hv_Shell_Hdmi_Usage();
                break;
        }
    }

    hv_optind = 1;
    hv_optarg = NULL;

    return 0;
}

//HV_SHELL_EXPORT_CMD(hdmidebug, Hv_Shell_HdmiRxDebug, "hdmidebug command line");

//HV_SHELL_EXPORT_CMD(hdmidebug, Hv_HdmiRxDebug, hdmidebug command line);

#endif

