//<MStar Software>
//******************************************************************************
// MStar Software
// Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
// All software, firmware and related documentation herein ("MStar Software") are
// intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
// law, including, but not limited to, copyright law and international treaties.
// Any use, modification, reproduction, retransmission, or republication of all
// or part of MStar Software is expressly prohibited, unless prior written
// permission has been granted by MStar.
//
// By accessing, browsing and/or using MStar Software, you acknowledge that you
// have read, understood, and agree, to be bound by below terms ("Terms") and to
// comply with all applicable laws and regulations:
//
// 1. MStar shall retain any and all right, ownership and interest to MStar
//    Software and any modification/derivatives thereof.
//    No right, ownership, or interest to MStar Software and any
//    modification/derivatives thereof is transferred to you under Terms.
//
// 2. You understand that MStar Software might include, incorporate or be
//    supplied together with third party`s software and the use of MStar
//    Software may require additional licenses from third parties.
//    Therefore, you hereby agree it is your sole responsibility to separately
//    obtain any and all third party right and license necessary for your use of
//    such third party`s software.
//
// 3. MStar Software and any modification/derivatives thereof shall be deemed as
//    MStar`s confidential information and you agree to keep MStar`s
//    confidential information in strictest confidence and not disclose to any
//    third party.
//
// 4. MStar Software is provided on an "AS IS" basis without warranties of any
//    kind. Any warranties are hereby expressly disclaimed by MStar, including
//    without limitation, any warranties of merchantability, non-infringement of
//    intellectual property rights, fitness for a particular purpose, error free
//    and in conformity with any international standard.  You agree to waive any
//    claim against MStar for any loss, damage, cost or expense that you may
//    incur related to your use of MStar Software.
//    In no event shall MStar be liable for any direct, indirect, incidental or
//    consequential damages, including without limitation, lost of profit or
//    revenues, lost or damage of data, and unauthorized system use.
//    You agree that this Section 4 shall still apply without being affected
//    even if MStar Software has been modified by MStar in accordance with your
//    request or instruction for your use, except otherwise agreed by both
//    parties in writing.
//
// 5. If requested, MStar may from time to time provide technical supports or
//    services in relation with MStar Software to you for your use of
//    MStar Software in conjunction with your or your customer`s product
//    ("Services").
//    You understand and agree that, except otherwise agreed by both parties in
//    writing, Services are provided on an "AS IS" basis and the warranty
//    disclaimer set forth in Section 4 above shall apply.
//
// 6. Nothing contained herein shall be construed as by implication, estoppels
//    or otherwise:
//    (a) conferring any license or right to use MStar name, trademark, service
//        mark, symbol or any other identification;
//    (b) obligating MStar or any of its affiliates to furnish any person,
//        including without limitation, you and your customers, any assistance
//        of any kind whatsoever, or any information; or
//    (c) conferring any license or right under any intellectual property right.
//
// 7. These terms shall be governed by and construed in accordance with the laws
//    of Taiwan, R.O.C., excluding its conflict of law rules.
//    Any and all dispute arising out hereof or related hereto shall be finally
//    settled by arbitration referred to the Chinese Arbitration Association,
//    Taipei in accordance with the ROC Arbitration Law and the Arbitration
//    Rules of the Association by three (3) arbitrators appointed in accordance
//    with the said Rules.
//    The place of arbitration shall be in Taipei, Taiwan and the language shall
//    be English.
//    The arbitration award shall be final and binding to both parties.
//
//******************************************************************************
//<MStar Software>
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008-2009 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// (!MStar Confidential Information!L) by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
////////////////////////////////////////////////////////////////////////////////
//==============================================================================
// [mhal_hdmi.c]
// Date: 20081203
// Descriptions: Add a new layer for HW setting
//==============================================================================
#define  MHAL_HDMI_C

// Common Definition
#include "MsCommon.h"
#include "MsOS.h"
#include "mhal_xc_chip_config.h"
#include "utopia_dapi.h"
#include "xc_Analog_Reg.h"

#include "drvXC_IOPort.h"
#include "xc_hwreg_utility2.h"
#include "hwreg_dvi_atop.h"//alex_tung
#include "hwreg_pm_sleep.h"//alex_tung
#include "apiXC.h"
#include "apiXC_Adc.h"
#include "apiXC_Auto.h"
#include "apiXC_ModeParse.h"
#include "apiXC_PCMonitor.h"
#include "drvXC_HDMI_if.h"
#include "drv_sc_ip.h"
#include "drv_sc_display.h"
#include "drv_sc_isr.h"
#include "mvideo_context.h"
#include "drvXC_HDMI_Internal.h"
#include "drvSYS.h"
#if (LD_ENABLE==1)
#include "mdrv_ld.h"
#include "mdrv_ldalgo.h"
#endif
#include "mdrv_sc_3d.h"
#include "drv_sc_menuload.h"
#include "drvXC_ADC_Internal.h"
#include "mhal_sc.h"
#if FRC_INSIDE
#include "mdrv_frc.h"
#include "mhal_frc.h"
#endif
#include "XC_private.h"
#include "mhal_hdmi.h"
#include "apiHDMIRx_private.h"

#include "hwreg_mhl.h"

#define PM_REG_READ(reg)            PM_R1BYTE(reg, 7:0)
#define PM_REG_WRITE(reg, data)     PM_W1BYTE(reg, data, 7:0)
#define MST_XTAL_CLOCK_HZ           12000000UL

#ifdef MSOS_TYPE_LINUX_KERNEL
#include <linux/string.h>
#else
#include <string.h>
#endif
#define MHAL_HDMI_HDR_DBG(x) //x

#if(defined(CONFIG_MLOG))
#include "ULog.h"

#define MHAL_HDMIRX_MSG_INFO(format, args...)       ULOGI("HDMIRX", format, ##args)
#define MHAL_HDMIRX_MSG_WARNING(format, args...)    ULOGW("HDMIRX", format, ##args)
#define MHAL_HDMIRX_MSG_DEBUG(format, args...)      ULOGD("HDMIRX", format, ##args)
#define MHAL_HDMIRX_MSG_ERROR(format, args...)      ULOGE("HDMIRX", format, ##args)
#define MHAL_HDMIRX_MSG_FATAL(format, args...)      ULOGF("HDMIRX", format, ##args)

#else
#define MHAL_HDMIRX_MSG_INFO(format, args...)       printf(format, ##args)
#define MHAL_HDMIRX_MSG_WARNING(format, args...)    printf(format, ##args)
#define MHAL_HDMIRX_MSG_DEBUG(format, args...)      printf(format, ##args)
#define MHAL_HDMIRX_MSG_ERROR(format, args...)      printf(format, ##args)
#define MHAL_HDMIRX_MSG_FATAL(format, args...)      printf(format, ##args)

#endif

#define HDMI_CHIP_VERIFY_REPEATER           0
#define HDMI_CHIP_VERIFY_POWER_SAVING       0
#define HDMI_CHIP_VERIFY_AUTO_EQ            0

#define HDMI_PHY_OLD_PATCH                  0
#define PGA_PATCH_BY_SW                     0

#define PHY_SW_VERSION 0x0300
//==============================================================================
// For MCU access HDCP key SRAM issue.
// Need to read timer once to cover the period of HDCP busy bit's transition.
#define TIMER_0_CNT_REG             0x3028//BIT0-BIT31, RO
//==============================================================================
// HDMI Black Level
#define HDMI_BLACK_LEVEL_HIGH_YC_OFFSET     0x00F0
#define HDMI_BLACK_LEVEL_HIGH_YC_GAIN       0x403B

#define HDMI_BLACK_LEVEL_LOW_YC_OFFSET      0x00E0
#define HDMI_BLACK_LEVEL_LOW_YC_GAIN        0x4045

//==============================================================================
/******************************************************************************/
/// for Patch Flag
/******************************************************************************/

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetPMSCDCBankOffset()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U32 _Hal_tmds_GetPMSCDCBankOffset(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PMSCDCBankOffset = 0;

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:   // BK 0x102
            u32PMSCDCBankOffset = REG_PM_SCDC_P0_OFFSET;
            break;

        case INPUT_PORT_DVI1:   // BK 0x103
            u32PMSCDCBankOffset = REG_PM_SCDC_P1_OFFSET;
            break;

        case INPUT_PORT_DVI2:   // BK 0x104
            u32PMSCDCBankOffset = REG_PM_SCDC_P2_OFFSET;
            break;

        case INPUT_PORT_DVI3:   // BK 0x105
            u32PMSCDCBankOffset = REG_PM_SCDC_P3_OFFSET;
            break;

        default:
            break;
    };

    return u32PMSCDCBankOffset;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetPHYPMBankOffset()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U32 _Hal_tmds_GetPHYPMBankOffset(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2PMBankOffset = 0;

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:   // BK 0x107
            u32PHY2PMBankOffset = REG_DVI_PHY2P1_PM_P0_OFFSET;
            break;

        case INPUT_PORT_DVI1:   // BK 0x108
            u32PHY2PMBankOffset = REG_DVI_PHY2P1_PM_P1_OFFSET;
            break;

        case INPUT_PORT_DVI2:   // BK 0x109
            u32PHY2PMBankOffset = REG_DVI_PHY2P1_PM_P2_OFFSET;
            break;

        case INPUT_PORT_DVI3:   // BK 0x10A
            u32PHY2PMBankOffset = REG_DVI_PHY2P1_PM_P3_OFFSET;
            break;

        default:
            break;
    };

    return u32PHY2PMBankOffset;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetPHY2P1BankOffset()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U32 _Hal_tmds_GetPHY2P1BankOffset(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = 0;

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:   // BK 0x3510, 0x3511, 0x3512, 0x3513, 0x3514, 0x3515
            u32PHY2P1BankOffset = REG_DVI_PHY2P1_P0_OFFSET;
            break;

        case INPUT_PORT_DVI1:   // BK 0x3520, 0x3521, 0x3522, 0x3523, 0x3524, 0x3525
            u32PHY2P1BankOffset = REG_DVI_PHY2P1_P1_OFFSET;
            break;

        case INPUT_PORT_DVI2:   // BK 0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535
            u32PHY2P1BankOffset = REG_DVI_PHY2P1_P2_OFFSET;
            break;

        case INPUT_PORT_DVI3:   // BK 0x3610, 0x3611, 0x3612, 0x3613, 0x3614, 0x3615
            u32PHY2P1BankOffset = REG_DVI_PHY2P1_P3_OFFSET;
            break;

        default:
            break;
    };

    return u32PHY2P1BankOffset;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetDTOPBankOffset()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U32 _Hal_tmds_GetDTOPBankOffset(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32DTOPBankOffset = 0;

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:   // BK 0x1710, 0x1711, 0x1712, 0x1713
            u32DTOPBankOffset = REG_DVI_DTOP_P0_OFFSET;
            break;

        case INPUT_PORT_DVI1:   // BK 0x1714, 0x1715, 0x1716, 0x1717
            u32DTOPBankOffset = REG_DVI_DTOP_P1_OFFSET;
            break;

        case INPUT_PORT_DVI2:   // BK 0x1718, 0x1719, 0x171A, 9x171B
            u32DTOPBankOffset = REG_DVI_DTOP_P2_OFFSET;
            break;

        case INPUT_PORT_DVI3:   // BK 0x171C, 0x171D, 0x171E, 0x171F
            u32DTOPBankOffset = REG_DVI_DTOP_P3_OFFSET;
            break;

        default:
            break;
    };

    return u32DTOPBankOffset;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetVEBankOffset()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U32 _Hal_tmds_GetVEBankOffset(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32VEBankOffset = 0;

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:   // BK 0x1720
            u32VEBankOffset = REG_HDMIRX_VE_P0_OFFSET;
            break;

        case INPUT_PORT_DVI1:   // BK 0x1721
            u32VEBankOffset = REG_HDMIRX_VE_P1_OFFSET;
            break;

        case INPUT_PORT_DVI2:   // BK 0x1722
            u32VEBankOffset = REG_HDMIRX_VE_P2_OFFSET;
            break;

        case INPUT_PORT_DVI3:   // BK 0x1723
            u32VEBankOffset = REG_HDMIRX_VE_P3_OFFSET;
            break;

        default:
            break;
    };

    return u32VEBankOffset;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetHDMIBankOffset()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U32 _Hal_tmds_GetHDMIBankOffset(MS_U8 u8HDMIInfoSource)
{
    MS_U32 u32HDMIBankOffset = 0;

    switch(u8HDMIInfoSource)
    {
        case HDMI_INFO_SOURCE0:     // Bank 0x1730, 0x1731, 0x1732, 0x1733
        case HDMI_INFO_SOURCE1:
        case HDMI_INFO_SOURCE2:
        case HDMI_INFO_SOURCE3:
            u32HDMIBankOffset = REG_HDMI_DUAL_P0_OFFSET;
            break;

        default:
            break;
    };

    return u32HDMIBankOffset;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_DIGLockCheck()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_DIGLockCheck(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if( (R2BYTE(REG_PHY2P1_4_P0_5E_L + u32PHY2P1BankOffset)&BIT(12))==BIT(12))  //dig lock
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }

}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_Bypass422to444()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_Bypass422to444(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32VEBankOffset = _Hal_tmds_GetVEBankOffset(enInputPortType);

    if(SC_R2BYTEMSK(0, REG_SC_BK79_3F_L, BIT(14))) // verify trim efuse to disable Dolby HDR
    {
        // Disable bypass, 422to444 at HDMI
        W2BYTEMSK(REG_HDMIRX_VE_U0_08_L +u32VEBankOffset, 0, BIT(0)); // hdmirx_ve_08[0]: reg_bypass_422to444
    }
    else
    {
        // bypass, 422to444 at scaler
        W2BYTEMSK(REG_HDMIRX_VE_U0_08_L +u32VEBankOffset, BIT(0), BIT(0)); // hdmirx_ve_08[0]: reg_bypass_422to444
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_EnableDfeTap()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_EnableDfeTap(E_MUX_INPUTPORT enInputPortType, MS_BOOL bEnTap1to4, MS_BOOL bEnTap5to12)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if (bEnTap1to4)
    {
        // release override tap1~tap4
        W2BYTE(REG_PHY2P1_2_P0_07_L +u32PHY2P1BankOffset, 0); // phy2p1_2_07[3:0]: reg_gc_dfe_idac_tap1_l3/2/10_ov_en; [7:4]: reg_gc_dfe_idac_tap2_l3/2/1/0_ov_en; [11:8]: reg_gc_dfe_idac_tap3_l3/2/1/0_ov_en; [15:12]: reg_gc_dfe_idac_tap4_l3/2/1/0_ov_en
    }
    else
    {
        // override dfe tap1~tap4 to 0
        W2BYTE(REG_PHY2P1_2_P0_07_L +u32PHY2P1BankOffset, 0xFFFF); // phy2p1_2_07[3:0]: reg_gc_dfe_idac_tap1_l3/2/10_ov_en; [7:4]: reg_gc_dfe_idac_tap2_l3/2/1/0_ov_en; [11:8]: reg_gc_dfe_idac_tap3_l3/2/1/0_ov_en; [15:12]: reg_gc_dfe_idac_tap4_l3/2/1/0_ov_en
        W2BYTE(REG_PHY2P1_2_P0_08_L +u32PHY2P1BankOffset, 0); // phy2p1_2_08[7:0]: reg_gc_dfe_idac_tap1_l0_ov; [15:8]: reg_gc_dfe_idac_tap1_l1_ov
        W2BYTE(REG_PHY2P1_2_P0_09_L +u32PHY2P1BankOffset, 0); // phy2p1_2_09[7:0]: reg_gc_dfe_idac_tap1_l2_ov; [15:8]: reg_gc_dfe_idac_tap1_l3_ov
        W2BYTE(REG_PHY2P1_2_P0_0A_L +u32PHY2P1BankOffset, 0); // phy2p1_2_0A[7:0]: reg_gc_dfe_idac_tap2_l0_ov; [15:8]: reg_gc_dfe_idac_tap2_l1_ov
        W2BYTE(REG_PHY2P1_2_P0_0B_L +u32PHY2P1BankOffset, 0); // phy2p1_2_0B[7:0]: reg_gc_dfe_idac_tap2_l2_ov; [15:8]: reg_gc_dfe_idac_tap2_l3_ov
        W2BYTE(REG_PHY2P1_2_P0_0C_L +u32PHY2P1BankOffset, 0); // phy2p1_2_0C[7:0]: reg_gc_dfe_idac_tap3_l0_ov; [15:8]: reg_gc_dfe_idac_tap3_l1_ov
        W2BYTE(REG_PHY2P1_2_P0_0D_L +u32PHY2P1BankOffset, 0); // phy2p1_2_0D[7:0]: reg_gc_dfe_idac_tap3_l2_ov; [15:8]: reg_gc_dfe_idac_tap3_l3_ov
        W2BYTE(REG_PHY2P1_2_P0_0E_L +u32PHY2P1BankOffset, 0); // phy2p1_2_0E[7:0]: reg_gc_dfe_idac_tap4_l0_ov; [15:8]: reg_gc_dfe_idac_tap4_l1_ov
        W2BYTE(REG_PHY2P1_2_P0_0F_L +u32PHY2P1BankOffset, 0); // phy2p1_2_0F[7:0]: reg_gc_dfe_idac_tap4_l2_ov; [15:8]: reg_gc_dfe_idac_tap4_l3_ov
    }

    if(bEnTap5to12)
    {
        // release override tap5~tap12
        W2BYTE(REG_PHY2P1_2_P0_30_L +u32PHY2P1BankOffset, 0); // phy2p1_2_30[5:0]: reg_gc_dfe_idac_tap5_l0_ov; [7]: reg_gc_dfe_idac_tap5_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap5_l1_ov; [15]: reg_gc_dfe_idac_tap5_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_31_L +u32PHY2P1BankOffset, 0); // phy2p1_2_31[5:0]: reg_gc_dfe_idac_tap5_l2_ov; [7]: reg_gc_dfe_idac_tap5_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap5_l3_ov; [15]: reg_gc_dfe_idac_tap5_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_32_L +u32PHY2P1BankOffset, 0); // phy2p1_2_32[5:0]: reg_gc_dfe_idac_tap6_l0_ov; [7]: reg_gc_dfe_idac_tap6_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap6_l1_ov; [15]: reg_gc_dfe_idac_tap6_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_33_L +u32PHY2P1BankOffset, 0); // phy2p1_2_33[5:0]: reg_gc_dfe_idac_tap6_l2_ov; [7]: reg_gc_dfe_idac_tap6_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap6_l3_ov; [15]: reg_gc_dfe_idac_tap6_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_34_L +u32PHY2P1BankOffset, 0); // phy2p1_2_34[5:0]: reg_gc_dfe_idac_tap7_l0_ov; [7]: reg_gc_dfe_idac_tap7_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap7_l1_ov; [15]: reg_gc_dfe_idac_tap7_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_35_L +u32PHY2P1BankOffset, 0); // phy2p1_2_35[5:0]: reg_gc_dfe_idac_tap7_l2_ov; [7]: reg_gc_dfe_idac_tap7_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap7_l3_ov; [15]: reg_gc_dfe_idac_tap7_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_36_L +u32PHY2P1BankOffset, 0); // phy2p1_2_36[5:0]: reg_gc_dfe_idac_tap8_l0_ov; [7]: reg_gc_dfe_idac_tap8_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap8_l1_ov; [15]: reg_gc_dfe_idac_tap8_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_37_L +u32PHY2P1BankOffset, 0); // phy2p1_2_37[5:0]: reg_gc_dfe_idac_tap8_l2_ov; [7]: reg_gc_dfe_idac_tap8_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap8_l3_ov; [15]: reg_gc_dfe_idac_tap8_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_38_L +u32PHY2P1BankOffset, 0); // phy2p1_2_38[5:0]: reg_gc_dfe_idac_tapf1_l0_ov; [7]: reg_gc_dfe_idac_tapf1_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf1_l1_ov; [15]: reg_gc_dfe_idac_tapf1_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_39_L +u32PHY2P1BankOffset, 0); // phy2p1_2_39[5:0]: reg_gc_dfe_idac_tapf1_l2_ov; [7]: reg_gc_dfe_idac_tapf1_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf1_l3_ov; [15]: reg_gc_dfe_idac_tapf1_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3A_L +u32PHY2P1BankOffset, 0); // phy2p1_2_3A[5:0]: reg_gc_dfe_idac_tapf2_l0_ov; [7]: reg_gc_dfe_idac_tapf2_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf2_l1_ov; [15]: reg_gc_dfe_idac_tapf2_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3B_L +u32PHY2P1BankOffset, 0); // phy2p1_2_3B[5:0]: reg_gc_dfe_idac_tapf2_l2_ov; [7]: reg_gc_dfe_idac_tapf2_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf2_l3_ov; [15]: reg_gc_dfe_idac_tapf2_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3C_L +u32PHY2P1BankOffset, 0); // phy2p1_2_3C[5:0]: reg_gc_dfe_idac_tapf3_l0_ov; [7]: reg_gc_dfe_idac_tapf3_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf3_l1_ov; [15]: reg_gc_dfe_idac_tapf3_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3D_L +u32PHY2P1BankOffset, 0); // phy2p1_2_3D[5:0]: reg_gc_dfe_idac_tapf3_l2_ov; [7]: reg_gc_dfe_idac_tapf3_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf3_l3_ov; [15]: reg_gc_dfe_idac_tapf3_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3E_L +u32PHY2P1BankOffset, 0); // phy2p1_2_3E[5:0]: reg_gc_dfe_idac_tapf4_l0_ov; [7]: reg_gc_dfe_idac_tapf4_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf4_l1_ov; [15]: reg_gc_dfe_idac_tapf4_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3F_L +u32PHY2P1BankOffset, 0); // phy2p1_2_3F[5:0]: reg_gc_dfe_idac_tapf4_l2_ov; [7]: reg_gc_dfe_idac_tapf4_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf4_l3_ov; [15]: reg_gc_dfe_idac_tapf4_l3_ov_en
    }
    else
    {
        // override dfe tap5~tap12 to 0
        W2BYTE(REG_PHY2P1_2_P0_30_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_30[5:0]: reg_gc_dfe_idac_tap5_l0_ov; [7]: reg_gc_dfe_idac_tap5_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap5_l1_ov; [15]: reg_gc_dfe_idac_tap5_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_31_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_31[5:0]: reg_gc_dfe_idac_tap5_l2_ov; [7]: reg_gc_dfe_idac_tap5_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap5_l3_ov; [15]: reg_gc_dfe_idac_tap5_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_32_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_32[5:0]: reg_gc_dfe_idac_tap6_l0_ov; [7]: reg_gc_dfe_idac_tap6_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap6_l1_ov; [15]: reg_gc_dfe_idac_tap6_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_33_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_33[5:0]: reg_gc_dfe_idac_tap6_l2_ov; [7]: reg_gc_dfe_idac_tap6_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap6_l3_ov; [15]: reg_gc_dfe_idac_tap6_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_34_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_34[5:0]: reg_gc_dfe_idac_tap7_l0_ov; [7]: reg_gc_dfe_idac_tap7_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap7_l1_ov; [15]: reg_gc_dfe_idac_tap7_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_35_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_35[5:0]: reg_gc_dfe_idac_tap7_l2_ov; [7]: reg_gc_dfe_idac_tap7_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap7_l3_ov; [15]: reg_gc_dfe_idac_tap7_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_36_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_36[5:0]: reg_gc_dfe_idac_tap8_l0_ov; [7]: reg_gc_dfe_idac_tap8_l0_ov_en; [13:8]: reg_gc_dfe_idac_tap8_l1_ov; [15]: reg_gc_dfe_idac_tap8_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_37_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_37[5:0]: reg_gc_dfe_idac_tap8_l2_ov; [7]: reg_gc_dfe_idac_tap8_l2_ov_en; [13:8]: reg_gc_dfe_idac_tap8_l3_ov; [15]: reg_gc_dfe_idac_tap8_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_38_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_38[5:0]: reg_gc_dfe_idac_tapf1_l0_ov; [7]: reg_gc_dfe_idac_tapf1_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf1_l1_ov; [15]: reg_gc_dfe_idac_tapf1_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_39_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_39[5:0]: reg_gc_dfe_idac_tapf1_l2_ov; [7]: reg_gc_dfe_idac_tapf1_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf1_l3_ov; [15]: reg_gc_dfe_idac_tapf1_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3A_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_3A[5:0]: reg_gc_dfe_idac_tapf2_l0_ov; [7]: reg_gc_dfe_idac_tapf2_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf2_l1_ov; [15]: reg_gc_dfe_idac_tapf2_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3B_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_3B[5:0]: reg_gc_dfe_idac_tapf2_l2_ov; [7]: reg_gc_dfe_idac_tapf2_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf2_l3_ov; [15]: reg_gc_dfe_idac_tapf2_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3C_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_3C[5:0]: reg_gc_dfe_idac_tapf3_l0_ov; [7]: reg_gc_dfe_idac_tapf3_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf3_l1_ov; [15]: reg_gc_dfe_idac_tapf3_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3D_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_3D[5:0]: reg_gc_dfe_idac_tapf3_l2_ov; [7]: reg_gc_dfe_idac_tapf3_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf3_l3_ov; [15]: reg_gc_dfe_idac_tapf3_l3_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3E_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_3E[5:0]: reg_gc_dfe_idac_tapf4_l0_ov; [7]: reg_gc_dfe_idac_tapf4_l0_ov_en; [13:8]: reg_gc_dfe_idac_tapf4_l1_ov; [15]: reg_gc_dfe_idac_tapf4_l1_ov_en
        W2BYTE(REG_PHY2P1_2_P0_3F_L +u32PHY2P1BankOffset, 0x8080); // phy2p1_2_3F[5:0]: reg_gc_dfe_idac_tapf4_l2_ov; [7]: reg_gc_dfe_idac_tapf4_l2_ov_en; [13:8]: reg_gc_dfe_idac_tapf4_l3_ov; [15]: reg_gc_dfe_idac_tapf4_l3_ov_en
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_InitInternalInfo()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_InitInternalInfo(stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    pstHDMIPollingInfo->u8FRLRate = HDMI_FRL_MODE_LEGACY;
    pstHDMIPollingInfo->bClockStableFlag = FALSE;
    pstHDMIPollingInfo->bVersionChangeFlag = FALSE;
    pstHDMIPollingInfo->bActiveCableFlag = FALSE;
    pstHDMIPollingInfo->bResetDCFifoFlag = FALSE;
    pstHDMIPollingInfo->u8RatioDetect = HDMI_FRL_MODE_LEGACY;
    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_NONE;
    pstHDMIPollingInfo->bPowerControlOn = FALSE;
    pstHDMIPollingInfo->bForcePowerDown = FALSE;
    pstHDMIPollingInfo->u8Colordepth = HDMI_COLOR_DEPTH_NONE;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_PHYInit()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_PHYInit(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U32 u32PHY2P1PMBankOffset = _Hal_tmds_GetPHYPMBankOffset(enInputPortType);

    W2BYTEMSK(REG_PHY2P1_1_P0_57_L + u32PHY2P1BankOffset, 0, BIT(11)); // phy2p1_57[11]: enable of saff cal start hardware mode
    W2BYTE(REG_PHY2P1_3_P0_06_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_3_06[3:0]: reg_hdmi2p1_atop_gate; [7:4]: reg_hdmi2p1_atop_inv

    // autoEQ parameter
    W2BYTE(REG_PHY2P1_1_P0_01_L + u32PHY2P1BankOffset, 0xFFFF);

    W2BYTE(REG_PHY2P1_1_P0_08_L + u32PHY2P1BankOffset, 0x03FF); // phy1_08[15:0] reg_pat_pass2_num_a_l0
    W2BYTE(REG_PHY2P1_1_P0_09_L + u32PHY2P1BankOffset, 0x03FF); // phy1_09[15:0] reg_pat_pass2_num_b_l0
    W2BYTE(REG_PHY2P1_1_P0_0A_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0a[15:0] reg_pat_pass2_num_c_l0
    W2BYTE(REG_PHY2P1_1_P0_0B_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0b[15:0] reg_pat_pass2_num_d_l0
    W2BYTE(REG_PHY2P1_1_P0_0C_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0c[15:0] reg_pat_pass2_num_a_l1
    W2BYTE(REG_PHY2P1_1_P0_0D_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0d[15:0] reg_pat_pass2_num_b_l1
    W2BYTE(REG_PHY2P1_1_P0_0E_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0e[15:0] reg_pat_pass2_num_c_l1
    W2BYTE(REG_PHY2P1_1_P0_0F_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0f[15:0] reg_pat_pass2_num_d_l1
    W2BYTE(REG_PHY2P1_1_P0_10_L + u32PHY2P1BankOffset, 0x03FF); // phy1_10[15:0] reg_pat_pass2_num_a_l2
    W2BYTE(REG_PHY2P1_1_P0_11_L + u32PHY2P1BankOffset, 0x03FF); // phy1_11[15:0] reg_pat_pass2_num_b_l2
    W2BYTE(REG_PHY2P1_1_P0_12_L + u32PHY2P1BankOffset, 0x03FF); // phy1_12[15:0] reg_pat_pass2_num_c_l2
    W2BYTE(REG_PHY2P1_1_P0_13_L + u32PHY2P1BankOffset, 0x03FF); // phy1_13[15:0] reg_pat_pass2_num_d_l2

    W2BYTE(REG_PHY2P1_1_P0_14_L + u32PHY2P1BankOffset, 0x03F0); // phy1_14[9:0] reg_eq_sth_acc_th_a_l0
    W2BYTE(REG_PHY2P1_1_P0_15_L + u32PHY2P1BankOffset, 0x03F0); // phy1_15[9:0] reg_eq_sth_acc_th_b_l0
    W2BYTE(REG_PHY2P1_1_P0_16_L + u32PHY2P1BankOffset, 0x03F0); // phy1_16[9:0] reg_eq_sth_acc_th_c_l0
    W2BYTE(REG_PHY2P1_1_P0_17_L + u32PHY2P1BankOffset, 0x03F0); // phy1_17[9:0] reg_eq_sth_acc_th_d_l0
    W2BYTE(REG_PHY2P1_1_P0_18_L + u32PHY2P1BankOffset, 0x03F0); // phy1_18[9:0] reg_eq_sth_acc_th_a_l1
    W2BYTE(REG_PHY2P1_1_P0_19_L + u32PHY2P1BankOffset, 0x03F0); // phy1_19[9:0] reg_eq_sth_acc_th_b_l1
    W2BYTE(REG_PHY2P1_1_P0_1A_L + u32PHY2P1BankOffset, 0x03F0); // phy1_1a[9:0] reg_eq_sth_acc_th_c_l1
    W2BYTE(REG_PHY2P1_1_P0_1B_L + u32PHY2P1BankOffset, 0x03F0); // phy1_1b[9:0] reg_eq_sth_acc_th_d_l1
    W2BYTE(REG_PHY2P1_1_P0_1C_L + u32PHY2P1BankOffset, 0x03F0); // phy1_1c[9:0] reg_eq_sth_acc_th_a_l2
    W2BYTE(REG_PHY2P1_1_P0_1D_L + u32PHY2P1BankOffset, 0x03F0); // phy1_1d[9:0] reg_eq_sth_acc_th_b_l2
    W2BYTE(REG_PHY2P1_1_P0_1E_L + u32PHY2P1BankOffset, 0x03F0); // phy1_1e[9:0] reg_eq_sth_acc_th_c_l2
    W2BYTE(REG_PHY2P1_1_P0_1F_L + u32PHY2P1BankOffset, 0x03F0); // phy1_1f[9:0] reg_eq_sth_acc_th_d_l2

    W2BYTE(REG_PHY2P1_1_P0_20_L + u32PHY2P1BankOffset, 0x00FF); // phy1_20[9:0] reg_eq_sth_chg_th_a_l0
    W2BYTE(REG_PHY2P1_1_P0_21_L + u32PHY2P1BankOffset, 0x00FF); // phy1_21[9:0] reg_eq_sth_chg_th_b_l0
    W2BYTE(REG_PHY2P1_1_P0_22_L + u32PHY2P1BankOffset, 0x00FF); // phy1_22[9:0] reg_eq_sth_chg_th_c_l0
    W2BYTE(REG_PHY2P1_1_P0_23_L + u32PHY2P1BankOffset, 0x00FF); // phy1_23[9:0] reg_eq_sth_chg_th_d_l0
    W2BYTE(REG_PHY2P1_1_P0_24_L + u32PHY2P1BankOffset, 0x00FF); // phy1_24[9:0] reg_eq_sth_chg_th_a_l1
    W2BYTE(REG_PHY2P1_1_P0_25_L + u32PHY2P1BankOffset, 0x00FF); // phy1_25[9:0] reg_eq_sth_chg_th_b_l1
    W2BYTE(REG_PHY2P1_1_P0_26_L + u32PHY2P1BankOffset, 0x00FF); // phy1_26[9:0] reg_eq_sth_chg_th_c_l1
    W2BYTE(REG_PHY2P1_1_P0_27_L + u32PHY2P1BankOffset, 0x00FF); // phy1_27[9:0] reg_eq_sth_chg_th_d_l1
    W2BYTE(REG_PHY2P1_1_P0_28_L + u32PHY2P1BankOffset, 0x00FF); // phy1_28[9:0] reg_eq_sth_chg_th_a_l2
    W2BYTE(REG_PHY2P1_1_P0_29_L + u32PHY2P1BankOffset, 0x00FF); // phy1_29[9:0] reg_eq_sth_chg_th_b_l2
    W2BYTE(REG_PHY2P1_1_P0_2A_L + u32PHY2P1BankOffset, 0x00FF); // phy1_2a[9:0] reg_eq_sth_chg_th_c_l2
    W2BYTE(REG_PHY2P1_1_P0_2B_L + u32PHY2P1BankOffset, 0x00FF); // phy1_2b[9:0] reg_eq_sth_chg_th_d_l2

    W2BYTE(REG_PHY2P1_1_P0_30_L + u32PHY2P1BankOffset, PHY_SW_VERSION);
    W2BYTEMSK(REG_PHY2P1_0_P0_2C_L + u32PHY2P1BankOffset, 0x0C00, BMASK(15:10)); // phy2p1_0_2C[10]: reg_eq_sth_acc_sel; [11]: reg_eq_mode_add_ov_en; [15:12]: reg_eq_mode_add_ov
    W2BYTEMSK(REG_PHY2P1_3_P0_38_L + u32PHY2P1BankOffset, 0x0009, BIT(3)|BMASK(1:0)); // phy2p1_3_38[3]: reg_agc_mode_select_ov_en; [1:0]: reg_agc_mode_select

    W2BYTEMSK(REG_PHY2P1_1_P0_48_L + u32PHY2P1BankOffset, BIT(9), BIT(9)); // phy2p1_1_48[9]: reg_hdmi_14_20_freq_det_only
    W2BYTEMSK(REG_PHY2P1_1_P0_4A_L + u32PHY2P1BankOffset, 0x40, BMASK(7:4)); // phy2p1_1_4A[7:4]: reg_s3_cmp_c_sel
    W2BYTE(REG_PHY2P1_1_P0_5C_L + u32PHY2P1BankOffset, 0xFFFF); // IRQ mask

    W2BYTEMSK(REG_PHY2P1_3_P0_0A_L + u32PHY2P1BankOffset, 0x0000, BMASK(9:8)|BMASK(1:0)); // phy2p1_3_0A[0]: reg_atop_pd_hw_ctrl_sel; [1]: reg_atop_pd_hw_ctrl_en; [9]: reg_en_clko_link_div20_ov_en
    W2BYTEMSK(REG_PHY2P1_3_P0_07_L + u32PHY2P1BankOffset, BIT(12), BIT(12)); // phy2p1_3_07[12]: reg_en_clko_pix_ov_en
    W2BYTEMSK(REG_PHY2P1_3_P0_20_L + u32PHY2P1BankOffset, 6, BMASK(3:0));

    W2BYTE(REG_PHY2P1_2_P0_02_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_2_02[3:0]: reg_gcr_iedata_load_sync_ov; [7]: reg_gcr_iedata_load_sync_ov_en; phy2_02[9:8] reg_gc_phdac_int_wei; phy2_02[12] reg_en_acdr_mode
    W2BYTE(REG_PHY2P1_2_P0_04_L + u32PHY2P1BankOffset, 0x0007);
    W2BYTE(REG_PHY2P1_2_P0_05_L + u32PHY2P1BankOffset, 0x0883);
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L + u32PHY2P1BankOffset, 0, BIT(4)|BIT(7)); // phy2p1_2_2f[4]: reg_pd_lane_ov_en; [7]:  reg_pd_pll_ov_en
    W2BYTE(REG_PHY2P1_2_P0_2E_L + u32PHY2P1BankOffset, 0x0094); // phy2_2e[3] reg_pd_clkin_ov, phy2_2e[4] reg_en_clko_pix_ov, phy2_2e[7] reg_pd_phdac_i_ov_en, phy2_2e[13] reg_pd_phdac_q_ov_en
    W2BYTE(REG_PHY2P1_2_P0_6E_L + u32PHY2P1BankOffset, 0x0020); // phy2p1_2_6E[2:0]: reg_gc_phdac_slewrate_ov; [3]: reg_gc_phdac_slewrate_ov_en; [4]: reg_en_clko_tmds2x_ov; [5]: reg_en_clko_vcodiv; [6]: reg_pd_ldo

    W2BYTEMSK(REG_PHY2P1_2_P0_6C_L + u32PHY2P1BankOffset, BIT(1), BMASK(1:0)); // phy2p1_2_6C[1]: reg_en_clko_link_datarate_div36_2x_ov_en; [0]: reg_en_clko_link_datarate_div36_2x_ov
    W2BYTEMSK(REG_PHY2P1_PM_P0_40_L + u32PHY2P1PMBankOffset, 0x000C, BMASK(3:0));
    W2BYTE(REG_PHY2P1_PM_P0_41_L + u32PHY2P1PMBankOffset, 0x0000); // phy2p1_pm_41[5:0]: reg_nodie_sq_cal_ov_ov; [7]: reg_nodie_sq_cal_ov_ov_en; [14:12]: reg_nodie_sqh_vth_ov; [15]: reg_nodie_sqh_vth_ov
    W2BYTE(REG_PHY2P1_PM_P0_42_L + u32PHY2P1PMBankOffset, 0x8F20); // phy2p1_pm_42[2]: reg_nodie_en_hdmi2p1_ov; [3]: reg_nodie_en_hdmi2p1_ov_en; [4]: reg_nodie_pd_clkin_ov; [5]: reg_nodie_pd_clkin_ov_en; [7]: reg_nodie_en_pad_short; [11:8]: reg_nodie_pd_rt_ov; [15]: reg_nodie_pd_rt_ov_en
    W2BYTEMSK(REG_PHY2P1_3_P0_75_L + u32PHY2P1BankOffset, 0x0000, BMASK(15:8)); // phy2p1_3_75[8]: reg_acdr_ov_phdac_en
    W2BYTE(REG_PHY2P1_3_P0_60_L + u32PHY2P1BankOffset, 0x00E4); // phy2p1_3_60[7:0]: reg_lane_swap0/1/2/3; [9:8]: reg_ckg_xtal; [11:10]: reg_ckg_mpll; [13:12]: reg_ckg_dvi_raw; [15]: reg_lane_swap_ov_en
    W2BYTE(REG_PHY2P1_3_P0_61_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_3_61[7:0]: reg_ckg_clko_data_l0/1/2/3_1st; [15:8]: reg_ckg_clko_edata_l0/1/2/3_1st
    W2BYTE(REG_PHY2P1_3_P0_62_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_3_62[7:0]: reg_ckg_clko_data_l0/1/2/3_swap; [15:8]: reg_ckg_clko_edata_l0/1/2/3_swap

    W2BYTEMSK(REG_PHY2P1_3_P0_63_L + u32PHY2P1BankOffset, 0x0000, BMASK(3:0)); // phy3_63[1:0] reg_ckg_lckdet_swap; phy3_63[3:2] reg_ckg_pll_fb_swap

    W2BYTE(REG_PHY2P1_3_P0_64_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_3_64[1:0]: reg_ckg_clko_data_af_ls_40; [3:2]: reg_ckg_clko_data_af_ls_36; [6:4]: reg_ckg_tstbus_sel; [7]: reg_phy2mac_ctrl_select; [8]: reg_clk_xtal_div2_en; [10]: reg_select_hdmi20_20b_source (hdmi21 40bit to 20 bit)
    W2BYTEMSK(REG_PHY2P1_3_P0_65_L + u32PHY2P1BankOffset, 0x7C << 8, BMASK(15:8)); // phy2p1_3_65[15:8]: reg_lanesync_fifo_wr_ptr_rst
    W2BYTEMSK(REG_PHY2P1_3_P0_67_L + u32PHY2P1BankOffset, 0, BMASK(14:12)); // phy2p1_3_64[1:0]: reg_ckg_clko_data_af_ls_40; [3:2]: reg_ckg_clko_data_af_ls_36; [6:4]: reg_ckg_tstbus_sel; [7]: reg_phy2mac_ctrl_select; [8]: reg_clk_xtal_div2_en; [10]: reg_select_hdmi20_20b_source (hdmi21 40bit to 20 bit)
    W2BYTE(REG_PHY2P1_3_P0_68_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_3_68[7:0]: reg_ckg_br_det_l0/1/2/3_swap; [9:8]: reg_ckg_tmds_fg; [15:12]: reg_lane_pn_swape

    W2BYTE(REG_PHY2P1_0_P0_1C_L + u32PHY2P1BankOffset, 0x01FF); // phy0_1c[15:0]: reg_i_smbl_lk_conti

    W2BYTE(REG_PHY2P1_0_P0_38_L + u32PHY2P1BankOffset, 0x000F); // phy2p1_0_38[9:0]: reg_dlev_at_agc_eq

    W2BYTEMSK(REG_PHY2P1_0_P0_4E_L + u32PHY2P1BankOffset, 0x0F, BMASK(9:0)); // phy2p1_0_4E[9:0]: reg_dlev_at_eq; [10]: reg_dlev_at_eq_en; [14]: eg_en_idac_tap_clr; [15]: reg_en_idac_tap_set
    W2BYTE(REG_PHY2P1_0_P0_4F_L + u32PHY2P1BankOffset, 0x0202); // phy2p1_0_4F[6:0]: reg_phase_good_thr; [14:8]: reg_phase_enough_thr

    W2BYTEMSK(REG_PHY2P1_3_P0_66_L + u32PHY2P1BankOffset, 0x6000, BMASK(15:8)); // phy2p1_3_66[11:8]: reg_lane_reverse36; [12]: reg_hd20_hd21_sel; [13]: reg_clk_20bit_out; [14]: reg_20bit_out; [15]: reg_36bit_out

    // same as old phy (combo_phy1_10~1F)
    W2BYTE(REG_PHY2P1_3_P0_50_L + u32PHY2P1BankOffset, 0x0008); // phy2p1_3_50[4]: reg_swap_dcdr_updn_polity; [3]: reg_enable_phase_step
    W2BYTE(REG_PHY2P1_3_P0_58_L + u32PHY2P1BankOffset, 0x009A); // phy2p1_3_58[6:0]: reg_csync_interval0; [7]: reg_csync_slow0; [8]: reg_phase_hump0
    W2BYTE(REG_PHY2P1_3_P0_59_L + u32PHY2P1BankOffset, 0x009A); // phy2p1_3_59[6:0]: reg_csync_interval1; [7]: reg_csync_slow1; [8]: reg_phase_hump1
    W2BYTE(REG_PHY2P1_3_P0_5A_L + u32PHY2P1BankOffset, 0x009A); // phy2p1_3_5A[6:0]: reg_csync_interval2; [7]: reg_csync_slow2; [8]: reg_phase_hump2
    W2BYTE(REG_PHY2P1_3_P0_5B_L + u32PHY2P1BankOffset, 0x009A); // phy2p1_3_5B[6:0]: reg_csync_interval3; [7]: reg_csync_slow3; [8]: reg_phase_hump3
    W2BYTE(REG_PHY2P1_3_P0_53_L + u32PHY2P1BankOffset, 0x0100); // phy2p1_3_53[7:0]: reg_dvi_phase_thd; [8]: reg_auto_clr_enz; [10]: reg_delocken

    W2BYTE(REG_PHY2P1_0_P0_06_L + u32PHY2P1BankOffset, 0x0261); // phy0_06[3]: enable link train change FRL rate to reset eq fsm, phy0_06[4]: enable FFE change to reset eq fsm, phy2p1_0_06[9]: time out enable (2048us per state)
    W2BYTE(REG_PHY2P1_0_P0_08_L + u32PHY2P1BankOffset, 0x5555); // phy2p1_0_08[3:0]: reg_tap1_stable_thrd; [7:4]: reg_tap2_stable_thrd; [11:8]: reg_tap3_stable_thrd; [15:12]: reg_tap4_stable_thrd
    W2BYTE(REG_PHY2P1_0_P0_09_L + u32PHY2P1BankOffset, 0x5555); // phy2p1_0_09[3:0]: reg_tap5_stable_thrd; [7:4]: reg_tap6_stable_thrd; [11:8]: reg_tap7_stable_thrd; [15:12]: reg_tap8_stable_thrd
    W2BYTE(REG_PHY2P1_0_P0_0A_L + u32PHY2P1BankOffset, 0x5555); // phy2p1_0_0A[3:0]: reg_tapf1_stable_thrd; [7:4]: reg_tapf2_stable_thrd; [11:8]: reg_tapf3_stable_thrd; [15:12]: reg_tapf4_stable_thrd
    W2BYTE(REG_PHY2P1_0_P0_18_L + u32PHY2P1BankOffset, 0x0518); // phy0_18[3]reg_sweep_bypass, phy0_18[4] reg_dynamic_bypass, phy0_18[10:8] reg_aaba_ext, phy0_18[14] reg_dis_sqh_condi
    W2BYTE(REG_PHY2P1_0_P0_19_L + u32PHY2P1BankOffset, 0);
    // search each aaba timeout
    W2BYTE(REG_PHY2P1_0_P0_1E_L + u32PHY2P1BankOffset, 0xFFFF); // phy2p1_0_1E[15:0]: reg_eq_sth_det_duration
    W2BYTEMSK(REG_PHY2P1_0_P0_20_L + u32PHY2P1BankOffset, 0x0300, BMASK(15:8)); // phy2p1_0_20[15]: reg_eq_coarse_direc; [10:8]:
    // under thershold = 3, upper thershold = 30
    W2BYTEMSK(REG_PHY2P1_0_P0_21_L + u32PHY2P1BankOffset, 0x1E03, BMASK(15:8)| BMASK(5:0)); // phy2p1_0_21[13:8]: reg_eq_up_bond; [5:0]: reg_eq_lw_bond
    W2BYTE(REG_PHY2P1_0_P0_23_L + u32PHY2P1BankOffset, 0x80FF); // phy2p1_0_23[9:0]: reg_eq_sth_chg_th, phy0_23[15] reg_enable_time_out
    W2BYTEMSK(REG_PHY2P1_0_P0_25_L + u32PHY2P1BankOffset, 0x0A00, BMASK(13:8)|BMASK(5:0)); // phy2p1_0_25[5:0]: reg_eq_strength_active_cable; [13:8]: reg_sth_eq_seq_vld;
    W2BYTE(REG_PHY2P1_0_P0_26_L + u32PHY2P1BankOffset, 0x0003); // phy2p1_0_26[15]: reg_enhan_aeq_enable; [12:8]: reg_redo_enhan_aeq; [5:0]: reg_sth_eq_diff_th
    // aaba reference to blanking
    W2BYTE(REG_PHY2P1_0_P0_27_L + u32PHY2P1BankOffset, 0x9100); // phy2p1_0_27[15:0]: reg_eq_top_condi
    W2BYTE(REG_PHY2P1_0_P0_2A_L + u32PHY2P1BankOffset, 0x012F); // phy2p1_0_2A[7:0]: reg_under_over_max_time; [15:8]: reg_err_cnt_th
    W2BYTE(REG_PHY2P1_0_P0_2B_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_0_2B[5:0]: reg_eq_result_offset; [10:8]: reg_redo_aeq
#if (PGA_PATCH_BY_SW)
    W2BYTE(REG_PHY2P1_0_P0_2E_L + u32PHY2P1BankOffset, 0x0A00); // phy0_2e[7:0]reg_agc_min, phy2p1_0_2E[15:8]: reg_agc_max
    W2BYTE(REG_PHY2P1_0_P0_3B_L + u32PHY2P1BankOffset, 0xD7D2); // phy2p1_0_3B
    W2BYTEMSK(REG_PHY2P1_0_P0_5D_L + u32PHY2P1BankOffset, 0x000A, BMASK(7:0)); // phy2p1_0_5D[7:0]: reg_agc_initial; [15:8]: reg_agc_dlev_target
#else
    W2BYTE(REG_PHY2P1_0_P0_2E_L + u32PHY2P1BankOffset, 0x8A80); // phy0_2e[7:0]reg_agc_min, phy2p1_0_2E[15:8]: reg_agc_max
    W2BYTE(REG_PHY2P1_0_P0_3B_L + u32PHY2P1BankOffset, 0x57D2); // phy2p1_0_3B
    W2BYTEMSK(REG_PHY2P1_0_P0_5D_L + u32PHY2P1BankOffset, 0x008A, BMASK(7:0)); // phy2p1_0_5D[7:0]: reg_agc_initial; [15:8]: reg_agc_dlev_target
#endif

    if(MDrv_SYS_Query(E_SYS_QUERY_HDMI_DLEV_TARGET_128MV_SUPPORTED) == TRUE) // FT is passed under the condition of dlev target 128mV
    {
        W2BYTEMSK(REG_PHY2P1_0_P0_5D_L + u32PHY2P1BankOffset, 0x2600, BMASK(15:8));
    }
    else if(MDrv_SYS_Query(E_SYS_QUERY_HDMI_DLEV_TARGET_128MV_SUPPORTED)  == FALSE)
    {
        W2BYTEMSK(REG_PHY2P1_0_P0_5D_L + u32PHY2P1BankOffset, 0x2C00, BMASK(15:8));
    }

    W2BYTEMSK(REG_PHY2P1_0_P0_2F_L + u32PHY2P1BankOffset, 0x0100, BMASK(15:8)); // phy0_2f[9] reg_en_ffe3_to_ffe0_clr_cr_lock

    W2BYTEMSK(REG_PHY2P1_0_P0_34_L + u32PHY2P1BankOffset, 0x0000, BMASK(7:0)); // phy2p1_0_34[1:0]: reg_scan_src_sel; [3:2]: reg_scan_rpt_sel; [5]: reg_scan_timer_sel; [6]: reg_scan_timer_sel; [7]: reg_bps_af_eq_scan
    W2BYTEMSK(REG_PHY2P1_0_P0_35_L + u32PHY2P1BankOffset, 0x0030, BMASK(7:4)); // phy0_35[7:4] reg_autoscan_accum_time
    W2BYTEMSK(REG_PHY2P1_0_P0_3A_L + u32PHY2P1BankOffset, 0x0010, BMASK(7:0)); // phy2p1_0_3A[1]: reg_enable_coarse2done; [2]: reg_enable_coarse2done_bypass_enh_eq

    W2BYTEMSK(REG_PHY2P1_0_P0_50_L + u32PHY2P1BankOffset, 0xC200, BMASK(15:8)); // phy2p1_0_50[11:8]: reg_dlev_settle_iteration; [14]: reg_update_dlev_time_out_enable; [15]: reg_dfe_time_out_en
    W2BYTEMSK(REG_PHY2P1_0_P0_51_L + u32PHY2P1BankOffset, 0x4117, BMASK(14:0)); // phy2p1_0_51[7]: reg_en_pga_max; [10:8]: reg_filter_depth_dlev; [14:12]: reg_filter_depth_tap
    W2BYTEMSK(REG_PHY2P1_0_P0_52_L + u32PHY2P1BankOffset, 0x1000, BMASK(15:8)); // phy2p1_0_52[13:12]: reg_dlev_step
    W2BYTEMSK(REG_PHY2P1_0_P0_53_L + u32PHY2P1BankOffset, 0xFC00, BMASK(15:8)); // phy2p1_0_53[11:10]: reg_dlev_settle_pulse_en
    W2BYTE(REG_PHY2P1_0_P0_54_L + u32PHY2P1BankOffset, 0x0A26); // phy2p1_0_54[15:8]: reg_dlev_stable_thrd; [7:4]: reg_dfe_settle_iteration
    W2BYTEMSK(REG_PHY2P1_0_P0_59_L + u32PHY2P1BankOffset, 0x0000, BMASK(15:8)); // phy2p1_0_59[15:14]: reg_agc_output_sel
    W2BYTEMSK(REG_PHY2P1_0_P0_5A_L + u32PHY2P1BankOffset, 0x3400, BMASK(15:8)); // phy2p1_0_5A[11:10]: reg_eq_output_sel; [15:12]: reg_dfe_agc_freerun
    W2BYTE(REG_PHY2P1_0_P0_5C_L + u32PHY2P1BankOffset, 0x1020); // phy2p1_0_5C[7:0]: reg_dlev_good; [15:8]: reg_dlev_enough
    W2BYTE(REG_PHY2P1_0_P0_5E_L + u32PHY2P1BankOffset, 0x0823); // phy2p1_0_5E[15:8]: reg_dlev_stable_thrd_dfe; [7:4]: reg_agc_settle_iteration
    W2BYTE(REG_PHY2P1_2_P0_10_L + u32PHY2P1BankOffset, 0xCFCF); // phy2p1_2_10[7:0]: reg_pga_gain_l0_ov; [15:8]: reg_pga_gain_l1_ov
    W2BYTE(REG_PHY2P1_2_P0_11_L + u32PHY2P1BankOffset, 0xCFCF); // phy2p1_2_11[7:0]: reg_pga_gain_l2_ov; [15:8]: reg_pga_gain_l3_ov
    W2BYTEMSK(REG_PHY2P1_2_P0_12_L + u32PHY2P1BankOffset, 0x0000, BMASK(3:0)); // phy2p1_2_12[3:0]: reg_pga_gain_l3/2/1/0_ov_en

    W2BYTE(REG_PHY2P1_3_P0_30_L + u32PHY2P1BankOffset, 0x1414); // phy2p1_3_30[6:0]: reg_enhan_aeq_eye_target; [15:8]: reg_dfe_eh_target
    W2BYTE(REG_PHY2P1_3_P0_31_L + u32PHY2P1BankOffset, 0x2094); // phy2p1_3_31[6:0]: reg_sweep_eye_target; [7]: reg_wait_for_agc_dfe_stable; [15:8]: reg_sweep_eye_high_target
    W2BYTEMSK(REG_PHY2P1_3_P0_32_L + u32PHY2P1BankOffset, 0x0000, BMASK(6:4)|BMASK(2:0)); // phy2p1_3_32[2:0]: reg_agc_dlev_eh_sel; [6:4]: reg_agc_dfe_eh_sel
    W2BYTE(REG_PHY2P1_3_P0_33_L + u32PHY2P1BankOffset, 0x4180); // phy2p1_3_33[2:0]: reg_dfe_ew_check_time; [3]: reg_dfe_ew_check_en; [4]: reg_sweep_ew_disable; [5]: reg_sweep_eh_disable; [6]: reg_sweep_mode_direction; [7]: reg_auto_eq_gray_enable; [10:8]: reg_sweep_check_time
    W2BYTE(REG_PHY2P1_3_P0_37_L + u32PHY2P1BankOffset, 0x001F); // phy2p1_3_37[6:0]: reg_active_cable_eye_target
    W2BYTE(REG_PHY2P1_3_P0_3D_L + u32PHY2P1BankOffset, 0x0190); // phy2p1_3_3D[15:0]: reg_data_div40_clk_thr1
    W2BYTEMSK(REG_PHY2P1_3_P0_3F_L + u32PHY2P1BankOffset, 0x00E9, BMASK(11:0)); // phy2p1_3_3F[11:0]: reg_data_div40_clk_thr_tolrnt
    // z-type
    W2BYTE(REG_PHY2P1_3_P0_4D_L + u32PHY2P1BankOffset, 0x0000); // phy2p1_3_4D[2:0][6:4][10:8][14:12]: reg_eq_code_mode_a/b/c/d
    W2BYTE(REG_PHY2P1_4_P0_5A_L + u32PHY2P1BankOffset, 0x6C63); // phy2p1_4_5A[5]: reg_auto_vcorst_en, phy4_5a[15:12] reg_dig_lck_cnt_power
    W2BYTE(REG_PHY2P1_4_P0_5B_L + u32PHY2P1BankOffset, 0x1033); // phy4_5b[3:0] reg_dig_lck_range, phy4_5b[9:4] reg_dig_lose_range
    W2BYTE(REG_PHY2P1_4_P0_5E_L + u32PHY2P1BankOffset, 0x0351); // phy4_5e[3:0] reg_dig_lck_range_power, phy4_5e[7:4] reg_dig_lose_range_power, phy4_5e[8] reg_lck_range_sel, phy4_5e[9] reg_lose_range_sel
    W2BYTE(REG_PHY2P1_4_P0_60_L + u32PHY2P1BankOffset, 0x0000); // phy4_60[11:0] reg_clk_valid_l
    W2BYTE(REG_PHY2P1_4_P0_61_L + u32PHY2P1BankOffset, 0x0FFF); // phy4_61[12:0] reg_clk_valid_u
    if (MDrv_SYS_GetChipRev() == 0)
    {
        W2BYTE(REG_PHY2P1_4_P0_08_L + u32PHY2P1BankOffset, 0x6655); // phy4_08[2:0] reg_hd20_gc_divsel_pll_l0_band_3
        W2BYTEMSK(REG_PHY2P1_4_P0_0C_L +u32PHY2P1BankOffset, 0x1100, BMASK(15:8)); //phy4_0x0c[14:12]= 0x1, h20_dvisel_post_band0
    }
    else
    {
        W2BYTE(REG_PHY2P1_4_P0_08_L + u32PHY2P1BankOffset, 0x6555); // phy4_08[2:0] reg_hd20_gc_divsel_pll_l0_band_3
        W2BYTEMSK(REG_PHY2P1_4_P0_0C_L +u32PHY2P1BankOffset, 0x1000, BMASK(15:8)); //phy4_0x0c[14:12]= 0x1, h20_dvisel_post_band0
    }
    W2BYTEMSK(REG_PHY2P1_4_P0_62_L + u32PHY2P1BankOffset, 0x9A00, BMASK(15:8));
    W2BYTEMSK(REG_PHY2P1_4_P0_1F_L + u32PHY2P1BankOffset, 0x0700, BMASK(15:8));
    W2BYTE(REG_PHY2P1_4_P0_71_L + u32PHY2P1BankOffset, 0); // phy2p1_4_71
    W2BYTE(REG_PHY2P1_4_P0_72_L + u32PHY2P1BankOffset, 0); // phy2p1_4_72

    W2BYTEMSK(REG_PHY2P1_3_P0_15_L + u32PHY2P1BankOffset, BIT(15), BIT(15)); // phy2p1_3_15[15]: reg_en_clk_rx2tx

    // 2.0 port setting >>>>>>>>>
    W2BYTE(REG_PHY2P1_4_P0_40_L + u32PHY2P1BankOffset, 0x0202); // phy2p1_4_40[5:0]: reg_hd20_gc_ictrl_pd_wide_l0_band_3; [13:8]: reg_hd20_gc_ictrl_pd_wide_l0_band_2
    W2BYTE(REG_PHY2P1_4_P0_41_L + u32PHY2P1BankOffset, 0x0202); // phy2p1_4_41[5:0]: reg_hd20_gc_ictrl_pd_wide_l0_band_1; [13:8]: reg_hd20_gc_ictrl_pd_wide_l0_band_0
    W2BYTE(REG_PHY2P1_4_P0_42_L + u32PHY2P1BankOffset, 0x0202); // phy2p1_4_42[5:0]: reg_hd14_gc_ictrl_pd_wide_l0_band_6; [13:8]: reg_hd14_gc_ictrl_pd_wide_l0_band_5
    W2BYTE(REG_PHY2P1_4_P0_43_L + u32PHY2P1BankOffset, 0x0808); // phy2p1_4_43[5:0]: reg_hd14_gc_ictrl_pd_wide_l0_band_4; [13:8]: reg_hd14_gc_ictrl_pd_wide_l0_band_3
    W2BYTE(REG_PHY2P1_4_P0_44_L + u32PHY2P1BankOffset, 0x0808); // phy2p1_4_44[5:0]: reg_hd14_gc_ictrl_pd_wide_l0_band_2; [13:8]: reg_hd14_gc_ictrl_pd_wide_l0_band_1
    W2BYTE(REG_PHY2P1_4_P0_45_L + u32PHY2P1BankOffset, 0x0208); // phy2p1_4_45[5:0]: reg_hd14_gc_ictrl_pd_wide_l0_band_0; [13:8]: reg_hd21_gc_ictrl_pd_wide_l0_12g
    W2BYTE(REG_PHY2P1_4_P0_46_L + u32PHY2P1BankOffset, 0x0202); // phy2p1_4_46[5:0]: reg_hd21_gc_ictrl_pd_wide_l0_10g; [13:8]: reg_hd21_gc_ictrl_pd_wide_l0_8g
    W2BYTE(REG_PHY2P1_4_P0_47_L + u32PHY2P1BankOffset, 0x0202); // phy2p1_4_47[5:0]: reg_hd21_gc_ictrl_pd_wide_l0_6g; [13:8]: reg_hd21_gc_ictrl_pd_wide_l0_3g
    W2BYTE(REG_PHY2P1_4_P0_57_L + u32PHY2P1BankOffset, 0xC65A);

    W2BYTEMSK(REG_PHY2P1_3_P0_50_L + u32PHY2P1BankOffset, 0, BIT(4)); // phy2p1_3_50[4]: reg_swap_dcdr_updn_polity
    W2BYTEMSK(REG_PHY2P1_3_P0_6A_L + u32PHY2P1BankOffset, 0, BIT(0)); // phy2p1_3_6A[0]: reg_en_dvi_clk_div

    W2BYTE(REG_PHY2P1_3_P0_7E_L + u32PHY2P1BankOffset, 0x0081); // phy2p1_3_7E[9:0]: reg_dlev_max_table
    W2BYTEMSK(REG_PHY2P1_3_P0_77_L + u32PHY2P1BankOffset, 0x0002, BIT(1));
    W2BYTEMSK(REG_PHY2P1_3_P0_7D_L + u32PHY2P1BankOffset, 0x0001, BIT(0));

    W2BYTE(REG_PHY2P1_5_P0_52_L + u32PHY2P1BankOffset, 0x1111); // phy5_52[2:0] reg_under_bit_select_l0, phy5_52[6:4] reg_under_bit_select_l1, phy5_52[10:8] reg_under_bit_select_l2, phy5_52[14:12] reg_under_bit_select_l3
    W2BYTE(REG_PHY2P1_5_P0_53_L +u32PHY2P1BankOffset, 0x5d5d); // phy5_53[6:0] reg_aaba_pattern_l0, phy5_53[14:8] reg_aaba_pattern_l1
    W2BYTE(REG_PHY2P1_5_P0_54_L +u32PHY2P1BankOffset, 0x5d5d); // phy5_54[6:0] reg_aaba_pattern_l2, phy5_54[14:8] reg_aaba_pattern_l3

    W2BYTE(REG_PHY2P1_4_P0_58_L +u32PHY2P1BankOffset, 0x04BD);
    W2BYTE(REG_PHY2P1_4_P0_59_L +u32PHY2P1BankOffset, 0x83F5); //phy4_0x59[15:0]= 0x83f5, band0 to band1 clock threshold = 3.80G + 3.125%

    // Enable DFE Taps
    // enable dfe tap1~tap4 & disable dfe tap5~tap12
    _Hal_tmds_EnableDfeTap(enInputPortType, TRUE, FALSE);

    W2BYTEMSK(REG_PHY2P1_2_P0_52_L +u32PHY2P1BankOffset, BMASK(6:5), BMASK(6:5));
    W2BYTEMSK(REG_PHY2P1_2_P0_56_L +u32PHY2P1BankOffset, BMASK(6:5), BMASK(6:5));
    W2BYTEMSK(REG_PHY2P1_2_P0_5A_L +u32PHY2P1BankOffset, BMASK(6:5), BMASK(6:5));
    W2BYTEMSK(REG_PHY2P1_2_P0_5E_L +u32PHY2P1BankOffset, BMASK(6:5), BMASK(6:5));
    // <<<<<<<<<< 2.0 port setting

    W2BYTE(REG_PHY2P1_2_P0_01_L +u32PHY2P1BankOffset, 0xAAAA); // phy2p1_2_01[15:0]: reg_gc_dfe_mode_l3/2/1/0_ov_en; reg_gc_dfe_mode_l3/2/1/0_ov
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_MACInit()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_MACInit(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PMSCDCBankOffset = _Hal_tmds_GetPMSCDCBankOffset(enInputPortType);
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);
    MS_U32 u32VEBankOffset = _Hal_tmds_GetVEBankOffset(enInputPortType);

    // RR_Enable
    W2BYTEMSK(REG_PM_SCDC_P0_05_L +u32PMSCDCBankOffset, 0x6800, BMASK(15:8)); // scdc_05[15:8]: reg_read_request_retry_period
    W2BYTE(REG_PM_SCDC_P0_12_L +u32PMSCDCBankOffset, 0x1600); // scdc_12[15:0]: reg_bus_free_cnt
    W2BYTEMSK(REG_PM_SCDC_P0_20_L +u32PMSCDCBankOffset, BMASK(13:12), BMASK(13:12)); // scdc_20[12]: reg_rr_vld_range_en; [13]: reg_rr_trig_sel
    W2BYTEMSK(REG_PM_SCDC_P0_23_L +u32PMSCDCBankOffset, 0, BIT(2)); // scdc_23[2]: reg_rr_trig_mask - rr_test

    // Enable auto detect scramble
    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_47_L +u32DTOPBankOffset, BIT(8), BMASK(9:8)|BIT(2)); // hdmirx_dtop_47[2]: reg_dis_sscp_only; [8]: reg_wb_scmb_auto; [9]: reg_scmb_en_both

    // Check decode error setting
    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_4D_L +u32DTOPBankOffset, BIT(10),  BIT(10)); // hdmirx_dtop_4D[10]: reg_dvt_ph

    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_62_L +u32DTOPBankOffset, 0,  BIT(2)); // hdmirx_dtop_62[2]: reg_end_c_err_en
    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_66_L +u32DTOPBankOffset, 0,  BIT(0)); // hdmirx_dtop_66[0]: reg_wbdry_glitch

    // BCM HDCP re-auth issue
    W2BYTEMSK(REG_HDCP_DUAL_P0_1F_L +u32DTOPBankOffset, BMASK(15:14), BMASK(15:14)); // hdmirx_hdcp_1F[15:14]: XOR by enc_en

    // Enable write offset
    W2BYTEMSK(REG_HDCP_DUAL_P0_68_L +u32DTOPBankOffset, BIT(15)|TMDS_HDCP2_SOURCE_READ_OFFSET, BIT(15)|BMASK(9:0)); //b'[0..9]offset; b'[15]: enable bit

    W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_00_L +u32DTOPBankOffset, BIT(1)|BIT(0), BIT(1)|BIT(0)); // hdmirx_dtop_pkt_00[0]: reg_en_deep_color; [1]: reg_auto_rst_dc_fifo
    W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_18_L +u32DTOPBankOffset, BIT(0), BIT(0)); // hdmirx_dtop_pkt_18[0]: reg_rcv_gcp_sel

    // Frame repetition manual mode
    W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_21_L +u32DTOPBankOffset, BIT(7), BMASK(7:4)); // hdmirx_dtop_pkt_21[7:4]: reg_frame_rp_mode

    // For xc repetition setting
    // if = 0: repetition times to xc from pkt
    // if = 1: repetition times to xc = 0
    W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_00_L +u32DTOPBankOffset, BIT(14), BIT(14)); // hdmirx_dtop_pkt_00[14]: reg_dc_rep_en

    // For XC AVMUTE_online
    //W2BYTEMSK(REG_HDMIRX_VE_U0_05_L +u32VEBankOffset, BIT(9)|BIT(8)|BIT(6)|BIT(5)|BIT(3)|BIT(1)|BIT(0), BMASK(9:0)); // hdmirx_ve_05[9:0]: reg_vmute_condi (to XC AVMUTE_online)

    W2BYTEMSK(REG_HDMIRX_VE_U0_04_L +u32VEBankOffset, BMASK(1:0), BMASK(1:0)); // hdmirx_ve_04[0]: reg_vmuteblank; [1]: reg_en_avmute
    W2BYTEMSK(REG_HDMIRX_VE_U0_07_L +u32VEBankOffset, 0, BIT(6)); // hdmirx_ve_07[6]: reg_video_blank_sel

    _Hal_tmds_Bypass422to444(enInputPortType);

}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_HDMIInit()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_HDMIInit(MS_U8 u8HDMIInfoSource)
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(u8HDMIInfoSource);

    W2BYTEMSK(REG_HDMI2_DUAL_0_24_L +u32HDMIBankOffset, 0, BIT(10)); // hdmi2_u0_24[10]: reg_pkt_8p_en

    W2BYTEMSK(REG_HDMI3_DUAL_0_71_L +u32HDMIBankOffset, BIT(13), BIT(13)|BIT(12)); // hdmi3_u0_71[12]: reg_aud_mask_en; [13]: reg_aud_mask_ove

    W2BYTEMSK(REG_HDMI_DUAL_0_06_L +u32HDMIBankOffset, BIT(6), BIT(6)); // hdmi_u0_06[6]: reg_en_hbr

    W2BYTEMSK(REG_HDMI_DUAL_0_64_L +u32HDMIBankOffset, BIT(1), BMASK(3:0)); // hdmi_u0_64[1]: Auto detect non-PCM mode; [3]: Auto detect DSD mode

    W2BYTEMSK(REG_HDMI3_DUAL_0_3F_L +u32HDMIBankOffset, 0, BIT(11)); // [11] reg_vsif_ful_shift_en
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_Toggle2XMode()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_Toggle2XMode(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    W2BYTEMSK(REG_PHY2P1_4_P0_0A_L +u32PHY2P1BankOffset, 0x0500, BMASK(10:8)); // reg_hd14_gc_divsel_pll_l0_band_0
    W2BYTEMSK(REG_PHY2P1_4_P0_0E_L +u32PHY2P1BankOffset, 0x0200, BMASK(10:8)); // reg_hd14_gc_divsel_post_l0_band_0

    MsOS_DelayTaskUs_Poll(20);

    W2BYTEMSK(REG_PHY2P1_4_P0_0A_L +u32PHY2P1BankOffset, 0x0600, BMASK(10:8));
    W2BYTEMSK(REG_PHY2P1_4_P0_0E_L +u32PHY2P1BankOffset, 0x0300, BMASK(10:8));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ResetPhyDtop()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ResetPhyDtop(E_MUX_INPUTPORT enInputPortType, MS_U16 u16Reset)
{
    MS_U16 u16temp = 1000;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    W2BYTE(REG_PHY2P1_1_P0_00_L + u32PHY2P1BankOffset, u16Reset); // phy2p1_00[15:0]: reg_dtop_rst_sw

    while(u16temp--); // delay 5us

    W2BYTE(REG_PHY2P1_1_P0_00_L + u32PHY2P1BankOffset, 0); // phy2p1_00[15:0]: reg_dtop_rst_sw
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ResetHDMI20VersionFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ResetHDMI20VersionFlag(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PMSCDCBankOffset = _Hal_tmds_GetPMSCDCBankOffset(enInputPortType);

    W2BYTEMSK(REG_PM_SCDC_P0_0C_L +u32PMSCDCBankOffset, BMASK(3:2), BMASK(3:2)); // scdc_0C[2]: reg_tx_5v_reset_ov; [3]: reg_tx_5v_reset_ov_en
    W2BYTEMSK(REG_PM_SCDC_P0_0C_L +u32PMSCDCBankOffset, 0, BMASK(3:2)); // scdc_0C[2]: reg_tx_5v_reset_ov; [3]: reg_tx_5v_reset_ov_en
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetClockStableFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetClockStableFlag(E_MUX_INPUTPORT enInputPortType)
{
    MS_BOOL bStatusFlag = FALSE;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if(R2BYTE(REG_PHY2P1_4_P0_5F_L +u32PHY2P1BankOffset) & BIT(3)) // phy2p1_4_5F[3]: reg_clk_stable_out
    {
        bStatusFlag = TRUE;
    }

    return bStatusFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetSquelchFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetSquelchFlag(E_MUX_INPUTPORT enInputPortType)
{
    MS_BOOL bStatusFlag = FALSE;
    MS_U32 u32PHY2P1PMBankOffset = _Hal_tmds_GetPHYPMBankOffset(enInputPortType);

    if(R2BYTE(REG_PHY2P1_PM_P0_43_L +u32PHY2P1PMBankOffset) & BIT(15)) // phy2p1_pm_43[15]: reg_data_debounce_out_l
    {
        bStatusFlag = TRUE;
    }

    return bStatusFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_EnCodeGray()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 _Hal_tmds_EnCodeGray(MS_U8 u8BinaryValue)
{
    MS_U8 u8GrayValue = u8BinaryValue ^ (u8BinaryValue >> 1);

    return u8GrayValue;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_DeCodeGray()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 _Hal_tmds_DeCodeGray(MS_U8 u8GrayValue)
{
    MS_U8 u8BinaryValue = 0;

    while(u8GrayValue != 0x00)
    {
        u8BinaryValue = u8BinaryValue ^ u8GrayValue;
        u8GrayValue = u8GrayValue >> 1;
    }

    return u8BinaryValue;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SetNewPHYEQValue()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SetNewPHYEQValue(E_MUX_INPUTPORT enInputPortType, MS_BOOL bOvenFlag, MS_U8 *pu8EQvalue)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if(bOvenFlag)
    {
        if(pu8EQvalue != NULL)
        {
            W2BYTEMSK(REG_PHY2P1_2_P0_24_L +u32PHY2P1BankOffset, BIT(15)|(_Hal_tmds_EnCodeGray(pu8EQvalue[1]) << 8)|BIT(7)|_Hal_tmds_EnCodeGray(pu8EQvalue[0]), BIT(15)|BMASK(13:8)|BIT(7)|BMASK(5:0)); // phy2p1_2_24[5:0]: reg_gc_eq_l0_ov; [7]: reg_gc_eq_l0_ov_en; [13:8]: reg_gc_eq_l1_ov; [15]: reg_gc_eq_l1_ov_en
            W2BYTEMSK(REG_PHY2P1_2_P0_25_L +u32PHY2P1BankOffset, BIT(15)|(_Hal_tmds_EnCodeGray(pu8EQvalue[3]) << 8)|BIT(7)|_Hal_tmds_EnCodeGray(pu8EQvalue[2]), BIT(15)|BMASK(13:8)|BIT(7)|BMASK(5:0)); // phy2p1_2_25[5:0]: reg_gc_eq_l2_ov; [7]: reg_gc_eq_l2_ov_en; [13:8]: reg_gc_eq_l3_ov; [15]: reg_gc_eq_l3_ov_en
        }
    }
    else
    {
        W2BYTEMSK(REG_PHY2P1_2_P0_24_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(7)); // phy2p1_2_24[7]: reg_gc_eq_l0_ov_en; [15]: reg_gc_eq_l1_ov_en
        W2BYTEMSK(REG_PHY2P1_2_P0_25_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(7)); // phy2p1_2_25[7]: reg_gc_eq_l2_ov_en; [15]: reg_gc_eq_l3_ov_en
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SetPGAGainValue()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SetPGAGainValue(E_MUX_INPUTPORT enInputPortType, MS_BOOL bOvenFlag, MS_U8 *pu8PGAvalue)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if(bOvenFlag)
    {
        if(pu8PGAvalue != NULL)
        {
            W2BYTEMSK(REG_PHY2P1_2_P0_12_L +u32PHY2P1BankOffset, BMASK(3:0), BMASK(3:0)); // phy2p1_2_12[0][1][2][3]: reg_pga_gain_l0/1/2/3_ov_en
            W2BYTE(REG_PHY2P1_2_P0_10_L +u32PHY2P1BankOffset, (pu8PGAvalue[1] << 8)|pu8PGAvalue[0]); // phy2p1_2_10[7:0]: reg_pga_gain_l0_ov; [15:8]: reg_pga_gain_l1_ov
            W2BYTE(REG_PHY2P1_2_P0_11_L +u32PHY2P1BankOffset, (pu8PGAvalue[3] << 8)|pu8PGAvalue[2]); // phy2p1_2_11[7:0]: reg_pga_gain_l2_ov; [15:8]: reg_pga_gain_l3_ov
        }
    }
    else
    {
        W2BYTEMSK(REG_PHY2P1_2_P0_12_L +u32PHY2P1BankOffset, 0, BMASK(3:0)); // phy2p1_2_12[0][1][2][3]: reg_pga_gain_l0/1/2/3_ov_en
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetClockRatePort()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U16 _Hal_tmds_GetClockRatePort(E_MUX_INPUTPORT enInputPortType, MS_U8 u8SourceVersion)
{
    MS_U16 u16ClockCount = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    u16ClockCount = R2BYTE(REG_PHY2P1_4_P0_74_L +u32PHY2P1BankOffset); // phy2p1_4_74[15:0]: reg_cr_done_cnt_hold
    u16ClockCount = u16ClockCount * HDMI_XTAL_CLOCK_MHZ / HDMI_XTAL_DIVIDER;

    return u16ClockCount;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetClockChangeFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetClockChangeFlag(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_BOOL bClockBigChangeFlag = FALSE;
    MS_U16 u16ClockCount = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    u16ClockCount = _Hal_tmds_GetClockRatePort(enInputPortType, pstHDMIPollingInfo->ucSourceVersion);

    if(R2BYTE(REG_PHY2P1_4_P0_5F_L +u32PHY2P1BankOffset) & BIT(2)) // phy2p1_4_5F[2]: reg_clk_big_chg_sts
    {
        W2BYTEMSK(REG_PHY2P1_4_P0_5F_L +u32PHY2P1BankOffset, BIT(2), BIT(2)); // phy2p1_4_5F[2]: reg_clk_big_chg_sts

        bClockBigChangeFlag = TRUE;
    }

    if(ABS_MINUS(pstHDMIPollingInfo->usClockCount, u16ClockCount) > HDMI_CLOCK_UNSTABLE_OFFSET)
    {
        pstHDMIPollingInfo->usClockCount = u16ClockCount;

        bClockBigChangeFlag = TRUE;
    }

    return bClockBigChangeFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetYUV420Flag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetYUV420Flag(MS_U8 u8HDMIInfoSource, MS_U32 u32PacketStatus)
{
    MS_BOOL bYUV420Flag = FALSE;

    if(u32PacketStatus & HDMI_STATUS_AVI_PACKET_RECEIVE_FLAG) // AVI packet receive
    {
        if((Hal_HDMI_avi_infoframe_info(u8HDMIInfoSource, _BYTE_1, NULL) & BMASK(7:5)) == 0x60)
        {
            bYUV420Flag = TRUE;
        }
    }

    return bYUV420Flag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_YUV420PHYSetting()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_YUV420PHYSetting(E_MUX_INPUTPORT enInputPortType, MS_BOOL bYUV420Flag, MS_U8 u8SourceVersion, MS_U8 u8Colordepth)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U8 u8GPTOPOffset = 0;

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:
            u8GPTOPOffset = 0;
            break;

        case INPUT_PORT_DVI1:
            u8GPTOPOffset = 0x08 *2;
            break;

        case INPUT_PORT_DVI2:
            u8GPTOPOffset = 0x10 *2;
            break;

        case INPUT_PORT_DVI3:
            u8GPTOPOffset = 0x18 *2;
            break;

        default:
            break;
    }

    if(bYUV420Flag)
    {
        if((u8SourceVersion == HDMI_SOURCE_VERSION_HDMI20) && (u8Colordepth == HDMI_COLOR_DEPTH_16BIT) && (MDrv_SYS_GetChipRev() == 0))
        {
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L + u32PHY2P1BankOffset, BIT(11), BIT(11)|BMASK(9:8)); // PHY2_2c[11]: enable pixcko md overwrite;PHY2_2c[9:8]:pixcko md set to 8bit mode
        }
        else
        {
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L + u32PHY2P1BankOffset, 0, BIT(11)|BMASK(9:8)); //PHY2_2c[11]: disable pixcko md overwrite;PHY2_2c[9:8]:pixcko md set to 8bit mode
        }

        W2BYTEMSK(REG_PHY2P1_3_P0_07_L + u32PHY2P1BankOffset, BMASK(13:12), BMASK(13:12)); // phy2p1_3_07[12]: reg_en_clko_pix_ov_en; [13]: reg_en_clko_pix_2x_ov_en
        W2BYTEMSK(REG_PHY2P1_2_P0_2E_L + u32PHY2P1BankOffset, BMASK(5:4), BMASK(5:4)); // phy2p1_2_2E[4]: reg_en_clko_pix_ov; [5]: reg_en_clko_pix_2x_ov
        W2BYTEMSK(REG_COMBO_GP_TOP_15_L + u8GPTOPOffset, BIT(4), BIT(4)); // combo_gp_top_15[4]: reg_pix_clk_div2_en
    }
    else
    {
        W2BYTEMSK(REG_PHY2P1_2_P0_2C_L + u32PHY2P1BankOffset, 0, BIT(11)|BMASK(9:8)); //PHY2_2c[11]: disable pixcko md overwrite;PHY2_2c[9:8]:pixcko md set to 8bit mode
        W2BYTEMSK(REG_PHY2P1_3_P0_07_L + u32PHY2P1BankOffset, BIT(12), BMASK(13:12)); // phy2p1_3_07[12]: reg_en_clko_pix_ov_en; [13]: reg_en_clko_pix_2x_ov_en
        W2BYTEMSK(REG_PHY2P1_2_P0_2E_L + u32PHY2P1BankOffset, BIT(4), BMASK(5:4)); // phy2p1_2_2E[4]: reg_en_clko_pix_ov; [5]: reg_en_clko_pix_2x_ov
        W2BYTEMSK(REG_COMBO_GP_TOP_15_L + u8GPTOPOffset, 0, BIT(4)); // combo_gp_top_15[4]: reg_pix_clk_div2_en
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetHDMIModeFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetHDMIModeFlag(E_MUX_INPUTPORT enInputPortType)
{
    MS_BOOL bHDMIModeFlag = FALSE;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(R2BYTE(REG_HDCP_DUAL_P0_01_L + u32DTOPBankOffset) & BIT(0)) // hdmirx_hdcp_01[0]: reg_status_hdmi_mode_rpt
    {
        bHDMIModeFlag = TRUE;
    }

    return bHDMIModeFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ClearEDRVaildFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ClearEDRVaildFlag(MS_U8 u8HDMIInfoSource)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +u8HDMIInfoSource));
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(u8HDMIInfoSource);

    // clear interrupt - Dolby EDR Valid
    W2BYTEMSK(REG_HDMI2_DUAL_0_27_L +u32HDMIBankOffset, BIT(11), BIT(11)); // hdmi2_u0_27[11]: reg_hdmi2_irq_clear3
    W2BYTEMSK(REG_HDMI2_DUAL_0_27_L +u32HDMIBankOffset, 0, BIT(11));

    // clear Dolby EDR enable (version 0.9, from VSIF)
    W2BYTEMSK(REG_HDMI3_DUAL_0_2F_L +u32HDMIBankOffset, BIT(15), BIT(15)); // hdmi3_u0_2F[15]:  reg_clr_dolby_edr
    W2BYTEMSK(REG_HDMI3_DUAL_0_2F_L +u32HDMIBankOffset, 0, BIT(15));

    // clear Dolby EDR enable (version 1.1, from AVI)
    W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_20_L +u32DTOPBankOffset, BIT(14), BIT(14)); // hdmirx_dtop_pkt_20[14]: reg_clr_dolby_edr11
    W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_20_L +u32DTOPBankOffset, 0, BIT(14));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetEMPacketInfo()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U16 _Hal_tmds_GetEMPacketInfo(E_MUX_INPUTPORT enInputPortType, MS_U8 u8HDMIInfoSource, MS_U32 u32PacketStatus)
{
    MS_U16 u16EMPacketStatus = 0;
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(u8HDMIInfoSource);

    if(u32PacketStatus & HDMI_STATUS_EM_PACKET_RECEIVE_FLAG) // AVI packet receive
    {
        u16EMPacketStatus = R2BYTE(REG_HDMI_EM_U0_02_L +u32HDMIBankOffset) & BMASK(3:0); //hdmirx_emp_02[3:0]

        if(R2BYTE(REG_HDMI_EM_U0_01_L +u32HDMIBankOffset) & BIT(15)) //hdmirx_emp_01[15]
        {
            u16EMPacketStatus = u16EMPacketStatus | HDMI_EM_PACKET_HDR_ENABLE;
        }
        if(R2BYTE(REG_HDMI_EM_U0_02_L +u32HDMIBankOffset) & BIT(0)) //hdmirx_emp_02[0]
        {
            u16EMPacketStatus = u16EMPacketStatus | HDMI_EM_PACKET_DSC_ENABLE;
        }
        if(R2BYTE(REG_HDMI_EM_U0_02_L +u32HDMIBankOffset) & BIT(1)) //hdmirx_emp_02[1]
        {
            u16EMPacketStatus = u16EMPacketStatus | HDMI_EM_PACKET_VRR_ENABLE;
        }
        if(R2BYTE(REG_HDMI_EM_U0_02_L +u32HDMIBankOffset) & BIT(2)) //hdmirx_emp_02[2]
        {
            u16EMPacketStatus = u16EMPacketStatus | HDMI_EM_PACKET_VENDOR_ENABLE;
        }
        if(R2BYTE(REG_HDMI_EM_U0_02_L +u32HDMIBankOffset) & BIT(3)) //hdmirx_emp_02[3]
        {
            u16EMPacketStatus = u16EMPacketStatus | HDMI_EM_PACKET_FVA_ENABLE;
        }
    }

    return u16EMPacketStatus;
}
//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetFreeSyncInfo()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetFreeSyncInfo(MS_U8 u8HDMIInfoSource, MS_U32 u32PacketStatus, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U8 u8temp = 0;
    MS_U8 u8PacketData = 0;
    MS_U8 u8PacketContent[6] = {0};
    MS_U8 u8FreeSyncInfo = 0;

    if(u32PacketStatus & HDMI_STATUS_SPD_PACKET_RECEIVE_FLAG)
    {
        for(u8temp = 0; u8temp < 6; u8temp++)
        {
            if(Hal_HDMI_get_packet_value(u8HDMIInfoSource, PKT_SPD, u8temp, &u8PacketData, NULL))
            {
                u8PacketContent[u8temp] = u8PacketData;
            }
        }

        if((u8PacketContent[0] == 0x1A) && (u8PacketContent[1] == 0x00) && (u8PacketContent[2] == 0x00))
        {
            if(u8PacketContent[5] & BIT(0))
            {
                u8FreeSyncInfo = u8FreeSyncInfo| HDMI_FREE_SYNC_SUPPORTED;
            }

            if(u8PacketContent[5] & BIT(1))
            {
                u8FreeSyncInfo = u8FreeSyncInfo| HDMI_FREE_SYNC_ENABLED;
            }

            if(u8PacketContent[5] & BIT(2))
            {
                u8FreeSyncInfo = u8FreeSyncInfo| HDMI_FREE_SYNC_ACTIVE;
            }
        }
    }

    return u8FreeSyncInfo;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_CheckTxDcBalanceEn()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_CheckTxDcBalanceEn(E_MUX_INPUTPORT enInputPortType, MS_BOOL bEnable)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(bEnable == TRUE) //turn on check TxDcBalance scheme
    {
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_52_L +u32DTOPBankOffset, 0 , BIT(7)); // hd21_dvi_dtop_dual_52[7]: reg_dis_dc_balance_count
    }
    else
    {
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_52_L +u32DTOPBankOffset, BIT(7) , BIT(7)); // hd21_dvi_dtop_dual_52[7]: reg_dis_dc_balance_count
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SetDEStableFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SetDEStableFlag(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo, MS_U32 u32PacketStatus, MS_BOOL bStable)
{
    MS_BOOL bVRRFlag = FALSE;
    MS_BOOL bFreeSyncFlag = FALSE;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if((u32PacketStatus & HDMI_STATUS_EM_PACKET_RECEIVE_FLAG) && (pstHDMIPollingInfo->u16EMPacketInfo & HDMI_EM_PACKET_VRR_ENABLE))
    {
        bVRRFlag = TRUE;
    }

    if(_Hal_tmds_GetFreeSyncInfo(pstHDMIPollingInfo->ucHDMIInfoSource, u32PacketStatus, NULL) & BIT(2))
    {
        bFreeSyncFlag = TRUE;
    }

    if(bStable && (bVRRFlag || bFreeSyncFlag))
    {
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_31_L +u32DTOPBankOffset, BIT(2), BIT(2)); // hdmirx_dtop_31[2]: reg_dep_fsm_pause

        if(!(R2BYTE(REG_DVI_DTOP_DUAL_P0_30_L + u32DTOPBankOffset) & BIT(5))) // hdmirx_dtop_30[5]: reg_de_stable
        {
            W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_31_L +u32DTOPBankOffset, 0, BIT(2)); // hdmirx_dtop_31[2]: reg_dep_fsm_pause
        }
    }
    else
    {
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_31_L +u32DTOPBankOffset, 0, BIT(2)); // hdmirx_dtop_31[2]: reg_dep_fsm_pause
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_UpdateErrorStatus()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_UpdateErrorStatus(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    // DE change
    if(R2BYTE(REG_HDMIRX_DTOP_PKT_P0_10_L + u32DTOPBankOffset) & BIT(12)) // hdmirx_dtop_pkt_10[12]: reg_depack_dec_irq_status_0 -The number of DE pixel changed
    {
        pstHDMIPollingInfo->bDEChangeFlag = TRUE;

        W2BYTE(REG_HDMIRX_DTOP_PKT_P0_10_L +u32DTOPBankOffset, BIT(12)); // hdmirx_dtop_pkt_10[8]: Checksum Error occurred; packet discarded; [13]: BCH parity Error occurred; packet discarded; [15]: Single bit BCH parity Error occurred and Corrected
    }
    else
    {
        pstHDMIPollingInfo->bDEChangeFlag = FALSE;
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetFRLRate()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 _Hal_tmds_GetFRLRate(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U8 u8FRLRate = R2BYTE(REG_PHY2P1_1_P0_57_L +u32PHY2P1BankOffset) &BMASK(3:0);

    if(u8FRLRate > HDMI_FRL_MODE_NONE)
    {
        u8FRLRate = HDMI_FRL_MODE_NONE;
    }
    else if(u8FRLRate == HDMI_FRL_MODE_LEGACY)
    {
        if(R2BYTE(REG_PHY2P1_1_P0_57_L +u32PHY2P1BankOffset) &BIT(8))
        {
            u8FRLRate = HDMI_FRL_MODE_LEGACY_20;
        }
        else
        {
            u8FRLRate = HDMI_FRL_MODE_LEGACY_14;
        }
    }

    return u8FRLRate;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SACalibration()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SACalibration(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    volatile MS_U16 u16temp = 0;

    // (A). Power down lane to reset previous SA calibration values
    //REG_PD_LANE_OV[3:0] = 0xf
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, BMASK(3:0), BMASK(3:0));
    //REG_PD_LANE_OV_EN = 1'b1
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, BIT(4), BIT(4));
    //REG_PD_CAL_SAFF_Lx=1'b1, set 1 to clear SA calibration
    W2BYTEMSK(REG_PHY2P1_2_P0_1F_L +u32PHY2P1BankOffset, 0x00FF, BMASK(7:0));

    //wait 1us
    u16temp = 300; // 200:1us
    while(u16temp--);

    //REG_PD_LANE_OV[3:0] = 0x0
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, 0, BMASK(3:0));
    //REG_PD_LANE_OV_EN= 1'b0
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, 0, BIT(4));
    //REG_PD_CAL_SAFF_Lx=1'b0
    W2BYTEMSK(REG_PHY2P1_2_P0_1F_L +u32PHY2P1BankOffset, 0x000F, BMASK(7:0));

    // (B). Start SA calibration
    //GC_CAL_START_SAFF_Lx_OV = 1'b1
    //GC_CAL_START_SAFF_Lx_OVE = 1'b1
    W2BYTEMSK(REG_PHY2P1_2_P0_12_L +u32PHY2P1BankOffset, 0xFF00, BMASK(15:8));

    //wait  >10us, SA cal. pulse width >10u
    u16temp = 3000; // 2000:10us
    while(u16temp--);

    //GC_CAL_START_SAFF_Lx_OV = 1'b0
    //GC_CAL_START_SAFF_Lx_OVE = 1'b0
    W2BYTEMSK(REG_PHY2P1_2_P0_12_L +u32PHY2P1BankOffset, 0x0000, BMASK(15:8));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_BandDependSetting()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_BandDependSetting(E_MUX_INPUTPORT enInputPortType)
{
    MS_U16 u16BandInd, i;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    u16BandInd = R2BYTEMSK(REG_PHY2P1_1_P0_37_L +u32PHY2P1BankOffset, BMASK(10:0));
    for(i=0 ; i<HDMI_TMDS_CLOCK_NUMOF_BAND ; i++)
    {
        if((u16BandInd & (0x1<<i)) != 0)
        {
            break;
        }
    }

    switch(i)
    {
        case HDMI_TMDS_CLOCK_H14_BAND0:
            // 45+6.25%~25MHz
            // phy2_1a[3][1:0]=[1'b0][2'h0], phy2_1a[11][10:8]=[1'b0][3'h6], phy2_1a[15][14:12]=[1'b0][3'h3]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0600, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'hc], phy2_27[3][2:0]=[1'b0][3'h7]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x00c7);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b111]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000f, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b111]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0070, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h2], phy2_1[7][5:4]=[1'b0][2'h2], phy2_1[11][9:8]=[1'b0][2'h2], phy2_1[15][13:12]=[1'b0][2'h2]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0xAAAA);
            // phy2_6e[8][7]=[1'b1][1'b0], phy2_6e[3][2:0]=[1'b1][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0109, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h1], phy2_7f[7][6:4]=[1'b1][3'h1], phy2_7f[11][10:8]=[1'b1][3'h1], phy2_7f[15][14:12]=[1'b1][3'h1]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0x9999);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H14_BAND1:
            // 90+6.25%~45MHz
            // phy2_1a[3][1:0]=[1'b0][2'h0], phy2_1a[11][10:8]=[1'b0][3'h5], phy2_1a[15][14:12]=[1'b0][3'h2]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0500, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'h0], phy2_27[3][2:0]=[1'b0][3'h7]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x0007);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b111]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000f, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b111]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0070, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h2], phy2_1[7][5:4]=[1'b0][2'h2], phy2_1[11][9:8]=[1'b0][2'h2], phy2_1[15][13:12]=[1'b0][2'h2]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0xAAAA);
            // phy2_6e[8][7]=[1'b1][1'b0], phy2_6e[3][2:0]=[1'b1][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0109, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h1], phy2_7f[7][6:4]=[1'b1][3'h1], phy2_7f[11][10:8]=[1'b1][3'h1], phy2_7f[15][14:12]=[1'b1][3'h1]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0x9999);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H14_BAND2:
            // 180+6.25%~90MHz
            // phy2_1a[3][1:0]=[1'b0][2'h0], phy2_1a[11][10:8]=[1'b0][3'h4], phy2_1a[15][14:12]=[1'b0][3'h1]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0400, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'h0], phy2_27[3][2:0]=[1'b0][3'h0]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b111]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000f, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b111]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0070, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h2], phy2_1[7][5:4]=[1'b0][2'h2], phy2_1[11][9:8]=[1'b0][2'h2], phy2_1[15][13:12]=[1'b0][2'h2]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0xAAAA);
            // phy2_6e[8][7]=[1'b1][1'b0], phy2_6e[3][2:0]=[1'b1][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0109, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h2], phy2_7f[7][6:4]=[1'b1][3'h2], phy2_7f[11][10:8]=[1'b1][3'h2], phy2_7f[15][14:12]=[1'b1][3'h2]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xAAAA);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H14_BAND3:
            // 300+6.25%~180MHz
            // phy2_1a[3][1:0]=[1'b0][2'h1], phy2_1a[11][10:8]=[1'b0][3'h5], phy2_1a[15][14:12]=[1'b0][3'h1]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0501, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'h0], phy2_27[3][2:0]=[1'b0][3'h7]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x0007);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b101]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000d, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b101]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0050, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h2], phy2_1[7][5:4]=[1'b0][2'h2], phy2_1[11][9:8]=[1'b0][2'h2], phy2_1[15][13:12]=[1'b0][2'h2]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0xAAAA);
            // phy2_6e[8][7]=[1'b0][1'b0], phy2_6e[3][2:0]=[1'b1][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0009, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h2], phy2_7f[7][6:4]=[1'b1][3'h2], phy2_7f[11][10:8]=[1'b1][3'h2], phy2_7f[15][14:12]=[1'b1][3'h2]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xAAAA);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H14_BAND4:
            // 360+6.25%~300MHz
            // phy2_1a[3][1:0]=[1'b0][2'h1], phy2_1a[11][10:8]=[1'b0][3'h5], phy2_1a[15][14:12]=[1'b0][3'h1]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0501, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'h0], phy2_27[3][2:0]=[1'b0][3'h7]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x0007);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b100]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000c, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b100]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0040, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h1->2'h0], phy2_1[7][5:4]=[1'b0][2'h1->2'h0], phy2_1[11][9:8]=[1'b0][2'h1->2'h0], phy2_1[15][13:12]=[1'b0][2'h1->2'h0]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x9999);
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x8888);
            // phy2_6e[8][7]=[1'b0][1'b0], phy2_6e[3][2:0]=[1'b1][2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0008, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h3], phy2_7f[7][6:4]=[1'b1][3'h3], phy2_7f[11][10:8]=[1'b1][3'h3], phy2_7f[15][14:12]=[1'b1][3'h3]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xbbbb);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H14_BAND5:
            // 450+6.25%~360MHz
            // phy2_1a[3][1:0]=[1'b0][2'h2], phy2_1a[11][10:8]=[1'b0][3'h5], phy2_1a[15][14:12]=[1'b0][3'h0]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0502, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'hc], phy2_27[3][2:0]=[1'b0][3'h0]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x00c0);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b100]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000c, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b100]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0040, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h1->2'h0], phy2_1[7][5:4]=[1'b0][2'h1->2'h0], phy2_1[11][9:8]=[1'b0][2'h1->2'h0], phy2_1[15][13:12]=[1'b0][2'h1->2'h0]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x9999);
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x8888);
            // phy2_6e[8][7]=[1'b1][1'b0], phy2_6e[3][2:0]=[1'b1][2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0108, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h3], phy2_7f[7][6:4]=[1'b1][3'h3], phy2_7f[11][10:8]=[1'b1][3'h3], phy2_7f[15][14:12]=[1'b1][3'h3]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xbbbb);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H14_BAND6:
            // 600~450MHz
            // phy2_1a[3][1:0]=[1'b0][2'h2], phy2_1a[11][10:8]=[1'b0][3'h5], phy2_1a[15][14:12]=[1'b0][3'h0]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0502, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'hc], phy2_27[3][2:0]=[1'b0][3'h0]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x00c0);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b011]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000b, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b011]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0030, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h1->2'h0], phy2_1[7][5:4]=[1'b0][2'h1->2'h0], phy2_1[11][9:8]=[1'b0][2'h1->2'h0], phy2_1[15][13:12]=[1'b0][]2'h1->2'h0]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x9999);
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x8888);
            // phy2_6e[8][7]=[1'b1][1'b0], phy2_6e[3][2:0]=[1'b1][2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0108, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[]2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h3], phy2_7f[7][6:4]=[1'b1][3'h3], phy2_7f[11][10:8]=[1'b1][3'h3], phy2_7f[15][14:12]=[1'b1][3'h3]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xbbbb);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H20_BAND0:
            // 90+6.25%~75MHz
            // phy2_1a[3][1:0]=[1'b0][2'h0], phy2_1a[11][10:8]=[1'b0][3'h6], phy2_1a[15][14:12]=[1'b0][3'h1]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0600, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'h3], phy2_27[3][2:0]=[1'b0][3'h7]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x0037);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b100]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000c, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b100]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0040, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h1->2'h0], phy2_1[7][5:4]=[1'b0][2'h1->2'h0], phy2_1[11][9:8]=[1'b0][2'h1->2'h0], phy2_1[15][13:12]=[1'b0][2'h1->2'h0]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0xAAAA);
            // phy2_6e[8][7]=[1'b0][1'b0], phy2_6e[3][2:0]=[1'b1][2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0088, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h3], phy2_7f[7][6:4]=[1'b1][3'h3], phy2_7f[11][10:8]=[1'b1][3'h3], phy2_7f[15][14:12]=[1'b1][3'h3]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xbbbb);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H20_BAND1: // 112.5+6.25%~90MHz
        case HDMI_TMDS_CLOCK_H20_BAND2: // 152.5+3.125%~112.5MHz
            // phy2_1a[3][1:0]=[1'b0][2'h0], phy2_1a[11][10:8]=[1'b0][3'h5], phy2_1a[15][14:12]=[1'b0][3'h0]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0500, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'hc], phy2_27[3][2:0]=[1'b0][3'h0]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x00c0);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b011]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000b, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b011]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0030, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h1->2'h0], phy2_1[7][5:4]=[1'b0][2'h1->2'h0], phy2_1[11][9:8]=[1'b0][2'h1->2'h0], phy2_1[15][13:12]=[1'b0][2'h1->2'h0]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x9999);
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x8888);
            // phy2_6e[8][7]=[1'b1][1'b0], phy2_6e[3][2:0]=[1'b1][2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0088, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h3], phy2_7f[7][6:4]=[1'b1][3'h3], phy2_7f[11][10:8]=[1'b1][3'h3], phy2_7f[15][14:12]=[1'b1][3'h3]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xbbbb);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        case HDMI_TMDS_CLOCK_H20_BAND3:
            // 170~152.5MHz
            // phy2_1a[3][1:0]=[1'b0][2'h0], phy2_1a[11][10:8]=[1'b0][3'h5], phy2_1a[15][14:12]=[1'b0][3'h0]
            W2BYTEMSK(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset, 0x0500, 0x0F0B);
            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                // phy2_28[7][4:0]=[1'b0][5'h0]
                W2BYTE(REG_PHY2P1_2_P0_28_L + u32PHY2P1BankOffset, 0x0000);
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_72_L +u32PHY2P1BankOffset, 0x4000, BIT(14)); // phy2_72[14]= 1'b1, switch to big current mode
                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0084, BIT(7)|BMASK(4:0));
            }
            // phy2_27[11][8:4]=[1'b0][5'h0], phy2_27[3][2:0]=[1'b0][3'h7]
            W2BYTE(REG_PHY2P1_2_P0_27_L + u32PHY2P1BankOffset, 0x0007);
            // phy2_2c[6][5:4]=[1'b0][2'b01]
            W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0010, BMASK(6:4));
            // phy2_6[3][2:0]=[1'b1][3'b010]
            W2BYTEMSK(REG_PHY2P1_2_P0_06_L +u32PHY2P1BankOffset, 0x000a, BMASK(3:0));
            // phy2_26[7][6:4]=[1'b0][3'b010]
            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0x0020, BMASK(7:4));
            // phy2_0[3][2:0]=[1'b0][3'b0], phy2_0[7][6:4]=[1'b0][3'b0], phy2_0[11][10:8]=[1'b0][3'b0], phy2_0[15][14:12]=[1'b0][3'b0]
            W2BYTE(REG_PHY2P1_2_P0_00_L + u32PHY2P1BankOffset, 0x0000);
            // phy2_1[3][1:0]=[1'b0][2'h1->2'h0], phy2_1[7][5:4]=[1'b0][2'h1->2'h0], phy2_1[11][9:8]=[1'b0][2'h1->2'h0], phy2_1[15][13:12]=[1'b0][2'h1->2'h0]
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x9999);
            W2BYTE(REG_PHY2P1_2_P0_01_L + u32PHY2P1BankOffset, 0x8888);
            // phy2_6e[8][7]=[1'b1][1'b0], phy2_6e[3][2:0]=[1'b1][2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, 0x0088, BMASK(8:7)|BMASK(3:0));
            // phy2_2[9:8]=[]2'b00]
            W2BYTEMSK(REG_PHY2P1_2_P0_02_L +u32PHY2P1BankOffset, 0x0000, BMASK(9:8));
            // phy2_7f[3][2:0]=[1'b1][3'h3], phy2_7f[7][6:4]=[1'b1][3'h3], phy2_7f[11][10:8]=[1'b1][3'h3], phy2_7f[15][14:12]=[1'b1][3'h3]
            W2BYTE(REG_PHY2P1_2_P0_7F_L + u32PHY2P1BankOffset, 0xbbbb);
            // phy2_7e[3][2:0]=[1'b1][3'h5], phy2_7e[7][6:4]=[1'b1][3'h5], phy2_7e[11][10:8]=[1'b1][3'h5], phy2_7e[15][14:12]=[1'b1][3'h5]
            W2BYTE(REG_PHY2P1_2_P0_7E_L + u32PHY2P1BankOffset, 0xdddd);
            break;

        default:
            break;
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetRatioDetect()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 _Hal_tmds_GetRatioDetect(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U8 u8RatioDetect = HDMI_FRL_MODE_NONE;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U32 ulClockCount = _Hal_tmds_GetClockRatePort(enInputPortType, pstHDMIPollingInfo->ucSourceVersion);

    if((ulClockCount > 150) || (ulClockCount < 85))
    {
        u8RatioDetect = HDMI_FRL_MODE_LEGACY_14;
    }
    else if(R2BYTE(REG_PHY2P1_1_P0_4A_L +u32PHY2P1BankOffset) &BIT(12))
    {
        u8RatioDetect = HDMI_FRL_MODE_LEGACY_20;
    }

    return u8RatioDetect;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_NewPHYSwitch()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_NewPHYSwitch(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U8 u8PGAValue[4] = {0xCF, 0xCF, 0xCF, 0xCF}; // eg_pga_gain_lx_ov[7:6] = 2'b11 for H20 patch
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    _Hal_tmds_CheckTxDcBalanceEn(enInputPortType, FALSE);

    // release DFE overwrite
    W2BYTE(REG_PHY2P1_2_P0_01_L +u32PHY2P1BankOffset, 0); // phy2p1_2_01[15:0]: reg_gc_dfe_mode_l3/2/1/0_ov_en; reg_gc_dfe_mode_l3/2/1/0_ov

    _Hal_tmds_SetPGAGainValue(enInputPortType, FALSE, NULL);

    _Hal_tmds_BandDependSetting(enInputPortType);

    // Release VDAC
    W2BYTEMSK(REG_PHY2P1_2_P0_14_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_15_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_16_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_17_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));

    // Release FSM
    W2BYTE(REG_PHY2P1_0_P0_10_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_11_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_12_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_13_L +u32PHY2P1BankOffset, 0);

    W2BYTEMSK(REG_PHY2P1_0_P0_51_L +u32PHY2P1BankOffset, 0x0100, BMASK(10:8)|BIT(3)); // phy0_51[3]: reg_en_dlev_sw_mode; [10:8]: reg_filter_depth_dlev

    W2BYTEMSK(REG_PHY2P1_2_P0_2C_L +u32PHY2P1BankOffset, 0x0000, BIT(11)); // PHY2_2c[11]=1'h0 -> disable pixcko md overwrite

    switch(pstHDMIPollingInfo->ucSourceVersion)
    {
        case HDMI_SOURCE_VERSION_HDMI14:
            // disable dfe tap1~tap4 & disable dfe tap5~tap12
            _Hal_tmds_EnableDfeTap(enInputPortType, FALSE, FALSE);
            W2BYTEMSK(REG_PHY2P1_0_P0_57_L +u32PHY2P1BankOffset, 0x0000, BMASK(11:0));

            W2BYTE(REG_PHY2P1_2_P0_1B_L +u32PHY2P1BankOffset, 0x0000);
            W2BYTE(REG_PHY2P1_2_P0_1C_L +u32PHY2P1BankOffset, 0x0000);
            W2BYTE(REG_PHY2P1_2_P0_1D_L +u32PHY2P1BankOffset, 0x0000);
            W2BYTE(REG_PHY2P1_2_P0_1E_L +u32PHY2P1BankOffset, 0x0000);

            W2BYTEMSK(REG_PHY2P1_0_P0_5A_L +u32PHY2P1BankOffset, 0x0000, BMASK(15:12));

            // [mt5871] restore - increase main current
            W2BYTE(REG_PHY2P1_2_P0_60_L +u32PHY2P1BankOffset, 0x0000);
            W2BYTEMSK(REG_PHY2P1_2_P0_62_L +u32PHY2P1BankOffset, 0x0000, BMASK(7:0));
            W2BYTE(REG_PHY2P1_2_P0_63_L +u32PHY2P1BankOffset, 0x0000);
            W2BYTEMSK(REG_PHY2P1_2_P0_65_L +u32PHY2P1BankOffset, 0x0000, BMASK(7:0));
            W2BYTE(REG_PHY2P1_2_P0_66_L +u32PHY2P1BankOffset, 0x0000);
            W2BYTEMSK(REG_PHY2P1_2_P0_68_L +u32PHY2P1BankOffset, 0x0000, BMASK(7:0));
            W2BYTEMSK(REG_PHY2P1_2_P0_4C_L +u32PHY2P1BankOffset, 0x0000, BIT(11));
            W2BYTEMSK(REG_PHY2P1_2_P0_4D_L +u32PHY2P1BankOffset, 0x0000, BIT(11));
            W2BYTEMSK(REG_PHY2P1_2_P0_4E_L +u32PHY2P1BankOffset, 0x0000, BIT(11));

            // restore - increase DFE main current
            W2BYTEMSK(REG_PHY2P1_2_P0_50_L +u32PHY2P1BankOffset, 0x0000, BIT(15));
            W2BYTEMSK(REG_PHY2P1_2_P0_51_L +u32PHY2P1BankOffset, 0x0000, 0xE00F);
            W2BYTEMSK(REG_PHY2P1_2_P0_54_L +u32PHY2P1BankOffset, 0x0000, BIT(15));
            W2BYTEMSK(REG_PHY2P1_2_P0_55_L +u32PHY2P1BankOffset, 0x0000, 0xE00F);
            W2BYTEMSK(REG_PHY2P1_2_P0_58_L +u32PHY2P1BankOffset, 0x0000, BIT(15));
            W2BYTEMSK(REG_PHY2P1_2_P0_59_L +u32PHY2P1BankOffset, 0x0000, 0xE00F);

            // restore - decrease DFE step
            W2BYTEMSK(REG_PHY2P1_0_P0_53_L + u32PHY2P1BankOffset, 0x8000, BIT(15));

            // set EQ code to N-type EQ
            W2BYTE(REG_PHY2P1_2_P0_49_L +u32PHY2P1BankOffset, 0x9999);

            // power down EQ calibration for MIK
            W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, 0x1800, BMASK(12:11));
            W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, 0x1800, BMASK(12:11));
            W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, 0x1800, BMASK(12:11));

            // [mt5871] restore - reduce PGA-RL
            W2BYTEMSK(REG_PHY2P1_2_P0_05_L + u32PHY2P1BankOffset, 0x0000, BMASK(15:12));
            W2BYTEMSK(REG_PHY2P1_2_P0_13_L + u32PHY2P1BankOffset, 0x0000, BMASK(11:0));

            W2BYTEMSK(REG_PHY2P1_2_P0_73_L + u32PHY2P1BankOffset, 0x0000, BIT(5)); // -> restore - increase vring cmp threshold

            // under threshold = 0x1/0x3FFF
            W2BYTEMSK(REG_PHY2P1_0_P0_23_L +u32PHY2P1BankOffset, 0x1, BMASK(9:0)); // phy2p1_0_23[9:0]: reg_eq_sth_chg_th
            W2BYTE(REG_PHY2P1_0_P0_24_L +u32PHY2P1BankOffset, 0x3FFF); // phy2p1_0_24[15:0]: reg_pat_pass2_num

            // short EQ-RS override disable, EQ-RS1 override disable
            W2BYTEMSK(REG_PHY2P1_3_P0_0C_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0C[3]: short EQ-RS_L0 OVE; [8]: EQ-RS1_L0 OVE; [15]: reg_gc_eqrs_l0_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0D_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0D[3]: short EQ-RS_L1 OVE; [8]: EQ-RS1_L1 OVE; [15]: reg_gc_eqrs_l1_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0E_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0E[3]: short EQ-RS_L2 OVE; [8]: EQ-RS1_L2 OVE; [15]: reg_gc_eqrs_l2_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0F_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0F[3]: short EQ-RS_L3 OVE; [8]: EQ-RS1_L3 OVE; [15]: reg_gc_eqrs_l3_ov_en

            // search each aaba timeout
            W2BYTE(REG_PHY2P1_0_P0_1E_L +u32PHY2P1BankOffset, 0xFFFF); // phy2p1_0_1E[15:0]: reg_eq_sth_det_duration

            W2BYTE(REG_PHY2P1_0_P0_1D_L +u32PHY2P1BankOffset, 0x0028); // phy0_1d[15:0] reg_eq_chg_sattle_time

            //decrease EQ/PGA INEGC (short cable setting)
#if 1 // R3 fine EQ
            W2BYTEMSK(REG_PHY2P1_5_P0_51_L +u32PHY2P1BankOffset, 0x0100, BMASK(15:8)); // phy5_51[9:8] reg_aaba_parse_num_l0=1(R3+), phy5_51[11:10] reg_aaba_parse_num_l1=0, phy5_51[13:12] reg_aaba_parse_num_l2=0, phy5_51[15:14] reg_aaba_parse_num_l3=0
            W2BYTE(REG_PHY2P1_5_P0_4F_L +u32PHY2P1BankOffset, 0x0A1E);// phy5_4f[5:0] reg_coa_eq_up_bond, phy5_4f[13:8] reg_coa_eq_lw_bond

            W2BYTEMSK(REG_PHY2P1_1_P0_20_L + u32PHY2P1BankOffset, 15, BMASK(9:0)); // phy1_20[9:0] reg_eq_sth_chg_th_a_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_21_L + u32PHY2P1BankOffset, 15, BMASK(9:0)); // phy1_21[9:0] reg_eq_sth_chg_th_b_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_22_L + u32PHY2P1BankOffset, 15, BMASK(9:0)); // phy1_22[9:0] reg_eq_sth_chg_th_c_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_23_L + u32PHY2P1BankOffset, 15, BMASK(9:0)); // phy1_23[9:0] reg_eq_sth_chg_th_d_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_24_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_24[9:0] reg_eq_sth_chg_th_a_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_25_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_25[9:0] reg_eq_sth_chg_th_b_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_26_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_26[9:0] reg_eq_sth_chg_th_c_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_27_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_27[9:0] reg_eq_sth_chg_th_d_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_28_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_28[9:0] reg_eq_sth_chg_th_a_l2
            W2BYTEMSK(REG_PHY2P1_1_P0_29_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_29[9:0] reg_eq_sth_chg_th_b_l2
            W2BYTEMSK(REG_PHY2P1_1_P0_2A_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_2a[9:0] reg_eq_sth_chg_th_c_l2
            W2BYTEMSK(REG_PHY2P1_1_P0_2B_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_2b[9:0] reg_eq_sth_chg_th_d_l2

            W2BYTE(REG_PHY2P1_1_P0_08_L + u32PHY2P1BankOffset, 300); // phy1_08[15:0] reg_pat_pass2_num_a_l0
            W2BYTE(REG_PHY2P1_1_P0_09_L + u32PHY2P1BankOffset, 300); // phy1_09[15:0] reg_pat_pass2_num_b_l0
            W2BYTE(REG_PHY2P1_1_P0_0A_L + u32PHY2P1BankOffset, 300); // phy1_0a[15:0] reg_pat_pass2_num_c_l0
            W2BYTE(REG_PHY2P1_1_P0_0B_L + u32PHY2P1BankOffset, 300); // phy1_0b[15:0] reg_pat_pass2_num_d_l0
            W2BYTE(REG_PHY2P1_1_P0_0C_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0c[15:0] reg_pat_pass2_num_a_l1
            W2BYTE(REG_PHY2P1_1_P0_0D_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0d[15:0] reg_pat_pass2_num_b_l1
            W2BYTE(REG_PHY2P1_1_P0_0E_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0e[15:0] reg_pat_pass2_num_c_l1
            W2BYTE(REG_PHY2P1_1_P0_0F_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0f[15:0] reg_pat_pass2_num_d_l1
            W2BYTE(REG_PHY2P1_1_P0_10_L + u32PHY2P1BankOffset, 0x03FF); // phy1_10[15:0] reg_pat_pass2_num_a_l2
            W2BYTE(REG_PHY2P1_1_P0_11_L + u32PHY2P1BankOffset, 0x03FF); // phy1_11[15:0] reg_pat_pass2_num_b_l2
            W2BYTE(REG_PHY2P1_1_P0_12_L + u32PHY2P1BankOffset, 0x03FF); // phy1_12[15:0] reg_pat_pass2_num_c_l2
            W2BYTE(REG_PHY2P1_1_P0_13_L + u32PHY2P1BankOffset, 0x03FF); // phy1_13[15:0] reg_pat_pass2_num_d_l2

            W2BYTEMSK(REG_PHY2P1_0_P0_25_L +u32PHY2P1BankOffset, 0x1000, BMASK(13:8)); // phy0_25[13:8] reg_sth_eq_seq_vld

            W2BYTEMSK(REG_PHY2P1_0_P0_2A_L + u32PHY2P1BankOffset, 0x003F, BMASK(7:0)); // phy0_2a[7:0] reg_under_over_max_time
            W2BYTEMSK(REG_PHY2P1_0_P0_26_L + u32PHY2P1BankOffset, 0x0002, BMASK(5:0)); // phy0_26[5:0] reg_sth_eq_diff_th

            W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, BIT(0), BIT(0)); // L0 Ineg ove
            W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, BIT(0), BIT(0)); // L1 Ineg ove
            W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, BIT(0), BIT(0)); // L2 Ineg ove
            W2BYTEMSK(REG_PHY2P1_2_P0_6A_L +u32PHY2P1BankOffset, BIT(0), BIT(0)); // L3 Ineg ove
#endif

            // under thershold = 3, upper thershold = 30
            W2BYTEMSK(REG_PHY2P1_0_P0_21_L +u32PHY2P1BankOffset, 0x1E03, BMASK(15:8)| BMASK(5:0)); // phy2p1_0_21[13:8]: reg_eq_up_bond; [5:0]: reg_eq_lw_bond

            // aaba reference to blanking
            W2BYTE(REG_PHY2P1_0_P0_27_L +u32PHY2P1BankOffset, 0x9300); // phy0_27[9:8]=3 -> both blanking and video, default=1

            // EQ fine tune symbol continue time value in hdmi1.4 mode
            W2BYTE(REG_PHY2P1_3_P0_7C_L +u32PHY2P1BankOffset, 0x500);

            // select eq output type: average
            W2BYTEMSK(REG_PHY2P1_0_P0_5A_L +u32PHY2P1BankOffset, BIT(10), BMASK(11:10)); // phy2p1_0_5A[11:10]: reg_eq_output_sel

            _Hal_tmds_SetPGAGainValue(enInputPortType, TRUE, u8PGAValue);

            _Hal_tmds_SACalibration(enInputPortType);

            break;

        case HDMI_SOURCE_VERSION_HDMI20:
            _Hal_tmds_EnableDfeTap(enInputPortType, TRUE, TRUE);

            if ((R2BYTE(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset) & 0x7000) == 0x0000) // half rate
            {
                W2BYTEMSK(REG_PHY2P1_0_P0_57_L +u32PHY2P1BankOffset, 0x0FFF, BMASK(11:0));
                W2BYTE(REG_PHY2P1_2_P0_1B_L +u32PHY2P1BankOffset, 0x1FFF);
                W2BYTE(REG_PHY2P1_2_P0_1C_L +u32PHY2P1BankOffset, 0x1FFF);
                W2BYTE(REG_PHY2P1_2_P0_1D_L +u32PHY2P1BankOffset, 0x1FFF);
                W2BYTE(REG_PHY2P1_2_P0_1E_L +u32PHY2P1BankOffset, 0x1FFF);
                W2BYTEMSK(REG_PHY2P1_0_P0_5A_L +u32PHY2P1BankOffset, 0x3000, BMASK(15:12));
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_0_P0_57_L +u32PHY2P1BankOffset, 0x0000, BMASK(11:0));
                W2BYTE(REG_PHY2P1_2_P0_1B_L +u32PHY2P1BankOffset, 0x0000);
                W2BYTE(REG_PHY2P1_2_P0_1C_L +u32PHY2P1BankOffset, 0x0000);
                W2BYTE(REG_PHY2P1_2_P0_1D_L +u32PHY2P1BankOffset, 0x0000);
                W2BYTE(REG_PHY2P1_2_P0_1E_L +u32PHY2P1BankOffset, 0x0000);
                W2BYTEMSK(REG_PHY2P1_0_P0_5A_L +u32PHY2P1BankOffset, 0x0000, BMASK(15:12));
            }

            // [mt5871] increase EQ-Imain
            W2BYTE(REG_PHY2P1_2_P0_60_L +u32PHY2P1BankOffset, 0x069C);
            W2BYTEMSK(REG_PHY2P1_2_P0_62_L +u32PHY2P1BankOffset, 0x0030, BMASK(7:0));
            W2BYTE(REG_PHY2P1_2_P0_63_L +u32PHY2P1BankOffset, 0x069C);
            W2BYTEMSK(REG_PHY2P1_2_P0_65_L +u32PHY2P1BankOffset, 0x0030, BMASK(7:0));
            W2BYTE(REG_PHY2P1_2_P0_66_L +u32PHY2P1BankOffset, 0x069C);
            W2BYTEMSK(REG_PHY2P1_2_P0_68_L +u32PHY2P1BankOffset, 0x0030, BMASK(7:0));
            W2BYTEMSK(REG_PHY2P1_2_P0_4C_L +u32PHY2P1BankOffset, 0x0800, BIT(11));
            W2BYTEMSK(REG_PHY2P1_2_P0_4D_L +u32PHY2P1BankOffset, 0x0800, BIT(11));
            W2BYTEMSK(REG_PHY2P1_2_P0_4E_L +u32PHY2P1BankOffset, 0x0800, BIT(11));

            // increase DFE main current
            W2BYTEMSK(REG_PHY2P1_2_P0_50_L +u32PHY2P1BankOffset, 0x8000, BIT(15));
            W2BYTEMSK(REG_PHY2P1_2_P0_51_L +u32PHY2P1BankOffset, 0xE00F, 0xE00F);
            W2BYTEMSK(REG_PHY2P1_2_P0_54_L +u32PHY2P1BankOffset, 0x8000, BIT(15));
            W2BYTEMSK(REG_PHY2P1_2_P0_55_L +u32PHY2P1BankOffset, 0xE00F, 0xE00F);
            W2BYTEMSK(REG_PHY2P1_2_P0_58_L +u32PHY2P1BankOffset, 0x8000, BIT(15));
            W2BYTEMSK(REG_PHY2P1_2_P0_59_L +u32PHY2P1BankOffset, 0xE00F, 0xE00F);

            // decrease DFE step
            W2BYTEMSK(REG_PHY2P1_0_P0_53_L + u32PHY2P1BankOffset, 0x0000, BIT(15));

            // restore - set EQ code to N-type EQ
            W2BYTE(REG_PHY2P1_2_P0_49_L +u32PHY2P1BankOffset, 0x0000);

            // restore - power down EQ calibration for MIK
            W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, 0x0000, BMASK(12:11));
            W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, 0x0000, BMASK(12:11));
            W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, 0x0000, BMASK(12:11));

            // [mt5871] reduce PGA-RL
            W2BYTEMSK(REG_PHY2P1_2_P0_05_L + u32PHY2P1BankOffset, 0xF000, BMASK(15:12));
            W2BYTEMSK(REG_PHY2P1_2_P0_13_L + u32PHY2P1BankOffset, 0x0DDD, BMASK(11:0));

            if (MDrv_SYS_GetChipRev() == 0)
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_73_L + u32PHY2P1BankOffset, 0x0020, BIT(5)); // -> increase vring cmp threshold
            }
            else
            {
                W2BYTEMSK(REG_PHY2P1_2_P0_73_L + u32PHY2P1BankOffset, 0x0000, BIT(5)); // keep default vring cmp threshold
            }

            // under threshold = 0xFF/0x3FF
            W2BYTEMSK(REG_PHY2P1_0_P0_23_L +u32PHY2P1BankOffset, 0xFF, BMASK(9:0)); // phy2p1_0_23[9:0]: reg_eq_sth_chg_th
            W2BYTE(REG_PHY2P1_0_P0_24_L +u32PHY2P1BankOffset, 0x03FF); // phy2p1_0_24[15:0]: reg_pat_pass2_num

            // short EQ-RS override disable, EQ-RS1 override disable
            W2BYTEMSK(REG_PHY2P1_3_P0_0C_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0C[3]: short EQ-RS_L0 OVE; [8]: EQ-RS1_L0 OVE; [15]: reg_gc_eqrs_l0_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0D_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0D[3]: short EQ-RS_L1 OVE; [8]: EQ-RS1_L1 OVE; [15]: reg_gc_eqrs_l1_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0E_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0E[3]: short EQ-RS_L2 OVE; [8]: EQ-RS1_L2 OVE; [15]: reg_gc_eqrs_l2_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0F_L +u32PHY2P1BankOffset, 0, BIT(15)|BIT(8)|BMASK(7:4)|BIT(3)|BMASK(2:0)); // phy2p1_3_0F[3]: short EQ-RS_L3 OVE; [8]: EQ-RS1_L3 OVE; [15]: reg_gc_eqrs_l3_ov_en

            // search each aaba timeout
            W2BYTE(REG_PHY2P1_0_P0_1E_L +u32PHY2P1BankOffset, 0xA); // phy2p1_0_1E[15:0]: reg_eq_sth_det_duration

            W2BYTE(REG_PHY2P1_0_P0_1D_L +u32PHY2P1BankOffset, 0x0008); // phy0_1d[15:0] reg_eq_chg_sattle_time

            W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, 0, BIT(0)); // L0 Ineg ove
            W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, 0, BIT(0)); // L1 Ineg ove
            W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, 0, BIT(0)); // L2 Ineg ove
            W2BYTEMSK(REG_PHY2P1_2_P0_6A_L +u32PHY2P1BankOffset, 0, BIT(0)); // L3 Ineg ove

            // under thershold = 5, upper thershold = 36
            W2BYTEMSK(REG_PHY2P1_0_P0_21_L +u32PHY2P1BankOffset, 0x2405, BMASK(15:8)| BMASK(5:0)); // phy2p1_0_21[13:8]: reg_eq_up_bond; [5:0]: reg_eq_lw_bond

            // aaba reference to full screen
            W2BYTE(REG_PHY2P1_0_P0_27_L +u32PHY2P1BankOffset, 0x9300); // phy2p1_0_27[15:0]: reg_eq_top_condi

            // EQ fine tune symbol continue time value in hdmi1.4 mode
            W2BYTE(REG_PHY2P1_3_P0_7C_L +u32PHY2P1BankOffset, 0x350);

            // select eq output type: average
            W2BYTEMSK(REG_PHY2P1_0_P0_5A_L +u32PHY2P1BankOffset, BIT(10), BMASK(11:10)); // phy2p1_0_5A[11:10]: reg_eq_output_sel

#if PGA_PATCH_BY_SW
            _Hal_tmds_SetPGAGainValue(enInputPortType, TRUE, u8PGAValue); // H20 force PGA also for reg_pga_gain_lx_ov[7:6] patch
#else
            _Hal_tmds_SetPGAGainValue(enInputPortType, FALSE, NULL);
#endif

            _Hal_tmds_SACalibration(enInputPortType);

            W2BYTEMSK(REG_PHY2P1_5_P0_51_L +u32PHY2P1BankOffset, 0x0000, BMASK(15:8));  // phy5_51[9:8] reg_aaba_parse_num_l0=0, phy5_51[11:10] reg_aaba_parse_num_l1=0, phy5_51[13:12] reg_aaba_parse_num_l2=0, phy5_51[15:14] reg_aaba_parse_num_l3=0
            W2BYTE(REG_PHY2P1_5_P0_4F_L +u32PHY2P1BankOffset, 0x0024);// phy5_4f[5:0] reg_coa_eq_up_bond, phy5_4f[13:8] reg_coa_eq_lw_bond

            W2BYTEMSK(REG_PHY2P1_1_P0_20_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_20[9:0] reg_eq_sth_chg_th_a_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_21_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_21[9:0] reg_eq_sth_chg_th_b_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_22_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_22[9:0] reg_eq_sth_chg_th_c_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_23_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_23[9:0] reg_eq_sth_chg_th_d_l0
            W2BYTEMSK(REG_PHY2P1_1_P0_24_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_24[9:0] reg_eq_sth_chg_th_a_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_25_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_25[9:0] reg_eq_sth_chg_th_b_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_26_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_26[9:0] reg_eq_sth_chg_th_c_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_27_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_27[9:0] reg_eq_sth_chg_th_d_l1
            W2BYTEMSK(REG_PHY2P1_1_P0_28_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_28[9:0] reg_eq_sth_chg_th_a_l2
            W2BYTEMSK(REG_PHY2P1_1_P0_29_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_29[9:0] reg_eq_sth_chg_th_b_l2
            W2BYTEMSK(REG_PHY2P1_1_P0_2A_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_2a[9:0] reg_eq_sth_chg_th_c_l2
            W2BYTEMSK(REG_PHY2P1_1_P0_2B_L + u32PHY2P1BankOffset, 0x00FF, BMASK(9:0)); // phy1_2b[9:0] reg_eq_sth_chg_th_d_l2

            W2BYTE(REG_PHY2P1_1_P0_08_L + u32PHY2P1BankOffset, 0x03FF); // phy1_08[15:0] reg_pat_pass2_num_a_l0
            W2BYTE(REG_PHY2P1_1_P0_09_L + u32PHY2P1BankOffset, 0x03FF); // phy1_09[15:0] reg_pat_pass2_num_b_l0
            W2BYTE(REG_PHY2P1_1_P0_0A_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0a[15:0] reg_pat_pass2_num_c_l0
            W2BYTE(REG_PHY2P1_1_P0_0B_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0b[15:0] reg_pat_pass2_num_d_l0
            W2BYTE(REG_PHY2P1_1_P0_0C_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0c[15:0] reg_pat_pass2_num_a_l1
            W2BYTE(REG_PHY2P1_1_P0_0D_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0d[15:0] reg_pat_pass2_num_b_l1
            W2BYTE(REG_PHY2P1_1_P0_0E_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0e[15:0] reg_pat_pass2_num_c_l1
            W2BYTE(REG_PHY2P1_1_P0_0F_L + u32PHY2P1BankOffset, 0x03FF); // phy1_0f[15:0] reg_pat_pass2_num_d_l1
            W2BYTE(REG_PHY2P1_1_P0_10_L + u32PHY2P1BankOffset, 0x03FF); // phy1_10[15:0] reg_pat_pass2_num_a_l2
            W2BYTE(REG_PHY2P1_1_P0_11_L + u32PHY2P1BankOffset, 0x03FF); // phy1_11[15:0] reg_pat_pass2_num_b_l2
            W2BYTE(REG_PHY2P1_1_P0_12_L + u32PHY2P1BankOffset, 0x03FF); // phy1_12[15:0] reg_pat_pass2_num_c_l2
            W2BYTE(REG_PHY2P1_1_P0_13_L + u32PHY2P1BankOffset, 0x03FF); // phy1_13[15:0] reg_pat_pass2_num_d_l2

            W2BYTEMSK(REG_PHY2P1_0_P0_25_L +u32PHY2P1BankOffset, 0x0A00, BMASK(13:8)); // phy0_25[13:8] reg_sth_eq_seq_vld

            W2BYTEMSK(REG_PHY2P1_0_P0_2A_L + u32PHY2P1BankOffset, 0x002F, BMASK(7:0)); // phy0_2a[7:0] reg_under_over_max_time
            W2BYTEMSK(REG_PHY2P1_0_P0_26_L + u32PHY2P1BankOffset, 0x0003, BMASK(5:0)); // phy0_26[5:0] reg_sth_eq_diff_th

            break;

        default:

            break;
    };

    _Hal_tmds_SetNewPHYEQValue(enInputPortType, FALSE, NULL);
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SetMacPowerDown()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SetMacPowerDown(E_MUX_INPUTPORT enInputPortType, MS_BOOL bPowerDown)
{

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:   // 1739_10
            W2BYTE(REG_COMBO_GP_TOP_10_L, bPowerDown? BMASK(15:1) : 0); // combo_gp_top_10[15:0]: reg_dtop_clk_pd_p0
            W2BYTE(REG_COMBO_GP_TOP_11_L, bPowerDown? BMASK(15:0) : 0); // combo_gp_top_11[15:0]: reg_dtop_clk_pd_p0
            W2BYTEMSK(REG_COMBO_GP_TOP_13_L, bPowerDown? BMASK(7:0) : 0, BMASK(7:0)); // combo_gp_top_13[7:0]: reg_ve_clk_pd_p0
            break;

        case INPUT_PORT_DVI1:   // 1739_18
            W2BYTE(REG_COMBO_GP_TOP_18_L, bPowerDown? BMASK(15:1) : 0); // combo_gp_top_18[15:0]: reg_dtop_clk_pd_p1
            W2BYTE(REG_COMBO_GP_TOP_19_L, bPowerDown? BMASK(15:0) : 0); // combo_gp_top_19[15:0]: reg_dtop_clk_pd_p1
            W2BYTEMSK(REG_COMBO_GP_TOP_1B_L, bPowerDown? BMASK(7:0) : 0, BMASK(7:0)); // combo_gp_top_1B[7:0]: reg_ve_clk_pd_p1
            break;

        case INPUT_PORT_DVI2:   // 1739_20
            W2BYTE(REG_COMBO_GP_TOP_20_L, bPowerDown? BMASK(15:1) : 0); // combo_gp_top_20[15:0]: reg_dtop_clk_pd_p2
            W2BYTE(REG_COMBO_GP_TOP_21_L, bPowerDown? BMASK(15:0) : 0); // combo_gp_top_21[15:0]: reg_dtop_clk_pd_p2
            W2BYTEMSK(REG_COMBO_GP_TOP_23_L, bPowerDown? BMASK(7:0) : 0, BMASK(7:0)); // combo_gp_top_23[7:0]: reg_ve_clk_pd_p2
            break;

        case INPUT_PORT_DVI3:   // 1739_28
            W2BYTE(REG_COMBO_GP_TOP_28_L, bPowerDown? BMASK(15:1) : 0); // combo_gp_top_28[15:0]: reg_dtop_clk_pd_p3
            W2BYTE(REG_COMBO_GP_TOP_29_L, bPowerDown? BMASK(15:0) : 0); // combo_gp_top_29[15:0]: reg_dtop_clk_pd_p3
            W2BYTEMSK(REG_COMBO_GP_TOP_2B_L, bPowerDown? BMASK(7:0) : 0, BMASK(7:0)); // combo_gp_top_2B[7:0]: reg_ve_clk_pd_p3
            break;

        default:
            break;
    }
    MHAL_HDMIRX_MSG_INFO("** HDMI SetMacPower, port: %d, bPowerDown: %d %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType), bPowerDown);
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SetPowerDown()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SetPowerDown(E_MUX_INPUTPORT enInputPortType, MS_BOOL bPowerDown)
{
    volatile MS_U16 u16temp = 400;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U32 u32PHY2P1PMBankOffset = _Hal_tmds_GetPHYPMBankOffset(enInputPortType);

    // REG_PD_BG
    W2BYTEMSK(REG_PHY2P1_3_P0_0A_L +u32PHY2P1BankOffset, 0x0000, BIT(1)); // phy3_0a[1] reg_atop_pd_hw_ctrl_en
    W2BYTEMSK(REG_PHY2P1_2_P0_2E_L +u32PHY2P1BankOffset, bPowerDown? 0x4000: 0x0000, BIT(14)); // phy2_2e[14] reg_pd_bg=1'b1

    // REG_PD_LDO
    W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, bPowerDown? 0x0040: 0x0000, BIT(6)); // phy2_6e[6] reg_pd_ldo

    // REG_PD_PLL
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, bPowerDown? 0x00C0: 0x0080, BMASK(7:6)); // phy2_2f[6] reg_pd_pll_ov, phy2_2f[7] reg_pd_pll_ov_en

    while(u16temp--); // 200count : 1us

    // REG_PD_CAL_CAL_SAFF_L0, REG_PD_CAL_CAL_SAFF_L1, REG_PD_CAL_CAL_SAFF_L2, REG_PD_CAL_CAL_SAFF_L3
    W2BYTEMSK(REG_PHY2P1_2_P0_1F_L +u32PHY2P1BankOffset, bPowerDown? 0x00FF: 0x000F, BMASK(7:0)); // phy2_1f[3:0] reg_pd_cal_saff_l0-3_ov_en, phy2_1f[7:4] reg_pd_cal_saff_l0-3_ov

    // REG_PD_CLKIN
    W2BYTEMSK(REG_PHY2P1_2_P0_2E_L +u32PHY2P1BankOffset, bPowerDown? 0x000C: 0x0004, BMASK(3:2)); // phy2_2e[2] reg_pd_clkin_ov_en, phy2_2e[3] reg_pd_clkin_ov

    // REG_PD_PHD_CAL_L0, REG_PD_PHD_CAL_L1, REG_PD_PHD_CAL_L2, REG_PD_PHD_CAL_L3
    W2BYTEMSK(REG_PHY2P1_2_P0_1F_L +u32PHY2P1BankOffset, bPowerDown? 0xFF00: 0x0F00, BMASK(15:8)); // phy2_1f[11:8] reg_pd_phd_cal_l0-3_ov_en, phy2_1f[15:12] reg_pd_phd_cal_l0-3_ov

    // REG_PD_UPDN_DMX
    W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, bPowerDown? 0x0180: 0x0080, BMASK(8:7)); // phy2_6e[7] reg_pd_updn_dmx_ov_en, phy2_6e[8] reg_pd_updn_dmx_ov

    // REG_PD_LANE
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, bPowerDown? 0x001F: 0x0010, BMASK(4:0)); // phy2_2f[4] reg_pd_lane_ov_en, phy2_2f[3:0] reg_pd_lane_ov

    // REG_PD_DLPF
    W2BYTEMSK(REG_PHY2P1_2_P0_05_L +u32PHY2P1BankOffset, bPowerDown? 0x00F1: 0x0081, BMASK(7:4)|BIT(0)); // phy2_05[0] reg_pd_dlpf_ov_en, phy2_05[7:4] reg_pd_dlpf_ov

    // REG_PD_PHDAC_I
    W2BYTEMSK(REG_PHY2P1_2_P0_2E_L +u32PHY2P1BankOffset, 0x0080, BIT(7)); // phy2_2e[7] reg_pd_phdac_i_ov_en
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, bPowerDown? 0x0F00: 0x0000, BMASK(11:8)); // phy2_2f[11:8] reg_pd_phdac_i_ov

    // REG_PD_PHDAC_Q
    W2BYTEMSK(REG_PHY2P1_2_P0_2E_L +u32PHY2P1BankOffset, 0x2000, BIT(13)); // phy2_2e[13] reg_pd_phdac_q_ov_en
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, bPowerDown? 0xF000: 0x0000, BMASK(15:12)); // phy2_2f[15:12] reg_pd_phdac_q_ov

    // NODIE_PD_RT
    W2BYTEMSK(REG_PHY2P1_PM_P0_42_L + u32PHY2P1PMBankOffset, bPowerDown? 0x8F00: 0x8000, BIT(15)|BMASK(11:8)); // phy2p1_pm_42[11:8] reg_nodie_pd_rt_ov, phy2p1_pm_42[15] reg_nodie_pd_rt_ov_en

    // NODIE_EN_SQH
    W2BYTEMSK(REG_PHY2P1_PM_P0_40_L + u32PHY2P1PMBankOffset, bPowerDown? 0x0008: 0x000C, BMASK(3:2)); // phy2p1_pm_40[3] reg_nodie_en_sqh_ov_en, phy2p1_pm_40[2] reg_nodie_en_sqh_ov

    // NODIE_PD_CLKIN
    W2BYTEMSK(REG_PHY2P1_PM_P0_42_L + u32PHY2P1PMBankOffset, bPowerDown? 0x0030: 0x0020, BMASK(5:4)); // phy2p1_42[4] reg_nodie_pd_clkin_ov, phy2p1_42[5] reg_nodie_pd_clkin_ov_en

    /*
    phy2_04[7:4] reg_pd_dfe_ov
    phy2_04[11:8] reg_pd_dfe_vdac_ov
    phy2_04[15:12] reg_pd_dlev_saff_ov
    */
    W2BYTEMSK(REG_PHY2P1_2_P0_04_L + u32PHY2P1BankOffset, bPowerDown? 0xFFF0: 0x0000, BMASK(15:4));

    // phy2_05[11:8] reg_pd_phd_dec_ov
    W2BYTEMSK(REG_PHY2P1_2_P0_05_L +u32PHY2P1BankOffset, bPowerDown? 0x0700: 0x0000, BMASK(10:8));

    // phy2_2e[4] reg_en_clko_pix_ov
    W2BYTEMSK(REG_PHY2P1_2_P0_2E_L +u32PHY2P1BankOffset, bPowerDown? 0x0000: 0x0010, BIT(4));

    // phy2_6e[5] reg_en_clko_vcodiv
    W2BYTEMSK(REG_PHY2P1_2_P0_6E_L +u32PHY2P1BankOffset, bPowerDown? 0x0000: 0x0020, BIT(5));

    /*
    phy3_60[9:8] reg_ckg_xtal
    phy3_60[11:10] reg_ckg_mpll
    phy3_60[13:12] reg_ckg_dvi_raw
    */
    W2BYTEMSK(REG_PHY2P1_3_P0_60_L + u32PHY2P1BankOffset, bPowerDown? 0x1400: 0x0000, BMASK(13:10));

    /*
    phy3_61[1:0] reg_ckg_clko_data_l0_1st
    phy3_61[3:2] reg_ckg_clko_data_l1_1st
    phy3_61[5:4] reg_ckg_clko_data_l2_1st
    phy3_61[7:6] reg_ckg_clko_data_l3_1st
    phy3_61[9:8] reg_ckg_clko_edata_l0_1st
    phy3_61[11:10] reg_ckg_clko_edata_l1_1st
    phy3_61[13:12] reg_ckg_clko_edata_l2_1st
    phy3_61[15:14] reg_ckg_clko_edata_l3_1st
    */
    W2BYTE(REG_PHY2P1_3_P0_61_L +u32PHY2P1BankOffset, bPowerDown? 0x5555: 0x0000);

    /*
    phy3_62[1:0] reg_ckg_clko_data_l0_swap
    phy3_62[3:2] reg_ckg_clko_data_l1_swap
    phy3_62[5:4] reg_ckg_clko_data_l2_swap
    phy3_62[7:6] reg_ckg_clko_data_l3_swap
    phy3_62[9:8] reg_ckg_clko_edata_l0_swap
    phy3_62[11:10] reg_ckg_clko_edata_l1_swap
    phy3_62[13:12] reg_ckg_clko_edata_l2_swap
    phy3_62[15:14] reg_ckg_clko_edata_l3_swap
    */
    W2BYTE(REG_PHY2P1_3_P0_62_L +u32PHY2P1BankOffset, bPowerDown? 0x5555: 0x0000);

    /*
    phy3_63[1:0] reg_ckg_lckdet_swap
    phy3_63[3:2] reg_ckg_pll_fb_swap
    */
    W2BYTEMSK(REG_PHY2P1_3_P0_63_L +u32PHY2P1BankOffset, bPowerDown? 0x0005: 0x0000, BMASK(3:0));

    /*
    phy3_64[1:0] reg_ckg_clko_data_af_ls_40
    phy3_64[3:2] reg_ckg_clko_data_af_ls_36
    phy3_64[15:14] reg_ckg_clk_af_ls_phy_hd20
    */
    W2BYTEMSK(REG_PHY2P1_3_P0_64_L +u32PHY2P1BankOffset, bPowerDown? 0x4005: 0x0000, 0xC00F);

    /*
    phy3_68[1:0] reg_ckg_br_det_l0_swap
    phy3_68[3:2] reg_ckg_br_det_l1_swap
    phy3_68[5:4] reg_ckg_br_det_l2_swap
    phy3_68[7:6] reg_ckg_br_det_l3_swap
    phy3_68[9:8] reg_ckg_tmds_fg
    */
    W2BYTEMSK(REG_PHY2P1_3_P0_68_L +u32PHY2P1BankOffset, bPowerDown? 0x0155: 0x0000, BMASK(9:0));

    //--------------HDMI MAC------------
    _Hal_tmds_SetMacPowerDown(enInputPortType, bPowerDown);

}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetHDCP22IntStatus()
//  [Description]
//                  Get HDCP2.2 interrupt status
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U16 _Hal_tmds_GetHDCP22IntStatus(E_MUX_INPUTPORT enInputPortType)
{
    MS_U16 u16HDCP22Status = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    u16HDCP22Status = R2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset);

    if(u16HDCP22Status & BIT(1))
    {
        W2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset, BIT(1));
    }

    return u16HDCP22Status;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_BusyPolling()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_BusyPolling(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U8 u8SourceVersion = HDMI_SOURCE_VERSION_NOT_SURE;
    MS_U8 u8FRLRate = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U32 u32PHY2P1PMBankOffset = _Hal_tmds_GetPHYPMBankOffset(enInputPortType);

    if(!pstHDMIPollingInfo->bPowerOnLane)
    {
        _Hal_tmds_InitInternalInfo(pstHDMIPollingInfo);
        _Hal_tmds_SetPowerDown(enInputPortType, TRUE); // power down once when AC on
        pstHDMIPollingInfo->bPowerOnLane = TRUE;
    }

    u8FRLRate =  _Hal_tmds_GetFRLRate(enInputPortType);

    if(pstHDMIPollingInfo->u8FRLRate != u8FRLRate)
    {
        pstHDMIPollingInfo->u8FRLRate = u8FRLRate;
    }
    else if(pstHDMIPollingInfo->u8FRLRate < HDMI_FRL_MODE_NONE)
    {
        MHAL_HDMIRX_MSG_ERROR("** HDMI FRL detect error: %d port %d\r\n", pstHDMIPollingInfo->u8FRLRate, HDMI_GET_PORT_SELECT(enInputPortType));
    }
    else if(_Hal_tmds_GetClockStableFlag(enInputPortType))
    {
        pstHDMIPollingInfo->u8RatioDetect = _Hal_tmds_GetRatioDetect(enInputPortType, pstHDMIPollingInfo);

        if(pstHDMIPollingInfo->u8RatioDetect == HDMI_FRL_MODE_LEGACY_14)
        {
            u8SourceVersion = HDMI_SOURCE_VERSION_HDMI14;
        }
        else if(pstHDMIPollingInfo->u8FRLRate == HDMI_FRL_MODE_LEGACY_14)
        {
            u8SourceVersion = HDMI_SOURCE_VERSION_HDMI14;
        }
        else if(pstHDMIPollingInfo->u8FRLRate == HDMI_FRL_MODE_LEGACY_20)
        {
            u8SourceVersion = HDMI_SOURCE_VERSION_HDMI20;
        }

        pstHDMIPollingInfo->bClockStableFlag = TRUE;
    }
    else if(pstHDMIPollingInfo->bClockStableFlag)
    {
        pstHDMIPollingInfo->bClockStableFlag = FALSE;

        if(pstHDMIPollingInfo->ucSourceVersion != HDMI_SOURCE_VERSION_NOT_SURE)
        {
            pstHDMIPollingInfo->ucSourceVersion = HDMI_SOURCE_VERSION_NOT_SURE;
        }

        // Release FSM when clock unstable for CTS issue
        W2BYTE(REG_PHY2P1_0_P0_10_L +u32PHY2P1BankOffset, 0);
        W2BYTE(REG_PHY2P1_0_P0_11_L +u32PHY2P1BankOffset, 0);
        W2BYTE(REG_PHY2P1_0_P0_12_L +u32PHY2P1BankOffset, 0);
        W2BYTE(REG_PHY2P1_0_P0_13_L +u32PHY2P1BankOffset, 0);
    }

    if (pstHDMIPollingInfo->bPowerControlOn)
    {
        if (!Hal_HDMI_GetSCDCCableDetectFlag(enInputPortType))
        {
            _Hal_tmds_SetPowerDown(enInputPortType, TRUE);
            pstHDMIPollingInfo->bPowerControlOn = FALSE;
        }
    }
    else
    {
        if (Hal_HDMI_GetSCDCCableDetectFlag(enInputPortType)&& !(pstHDMIPollingInfo->bForcePowerDown))
        {
            _Hal_tmds_SetPowerDown(enInputPortType, FALSE);
            pstHDMIPollingInfo->bPowerControlOn = TRUE;
        }
        else
        {
            if (R2BYTEMSK(REG_PHY2P1_PM_P0_42_L +u32PHY2P1PMBankOffset, 0x0F10) != 0x0F10)
            {
                W2BYTEMSK(REG_PHY2P1_PM_P0_42_L +u32PHY2P1PMBankOffset, 0x0F10, 0x0F10);
            }
        }
    }

    if(pstHDMIPollingInfo->ucSourceVersion != u8SourceVersion)
    {
        pstHDMIPollingInfo->ucSourceVersion = u8SourceVersion;
        pstHDMIPollingInfo->bVersionChangeFlag = TRUE;

        if(pstHDMIPollingInfo->ucSourceVersion != HDMI_SOURCE_VERSION_NOT_SURE)
        {
            if((pstHDMIPollingInfo->u8FRLRate == HDMI_FRL_MODE_LEGACY_14) || (pstHDMIPollingInfo->u8FRLRate == HDMI_FRL_MODE_LEGACY_20))
            {
                MHAL_HDMIRX_MSG_INFO("** HDMI FRL Rate = 0, port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
            }
            else
            {
                MHAL_HDMIRX_MSG_INFO("** HDMI FRL Rate = %d, port %d\r\n", pstHDMIPollingInfo->u8FRLRate, HDMI_GET_PORT_SELECT(enInputPortType));
            }

            _Hal_tmds_NewPHYSwitch(enInputPortType, pstHDMIPollingInfo);
        }
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetimingDetectPath()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_GetimingDetectPath(E_MUX_INPUTPORT enInputPortType, EN_HDMI_TIMING_DETECT_PATH enTimingPath)
{
    MS_U32 u32VEBankOffset = _Hal_tmds_GetVEBankOffset(enInputPortType);

    switch(enTimingPath)
    {
        case HDMI_TIMING_DETECT_4_0: // (4) - 0, for legacy
            W2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, 0, BIT(10)); // hdmirx_ve_10[10]: reg_timing_det_status_sel
            W2BYTEMSK(REG_HDMIRX_VE_U0_10_L +u32VEBankOffset, 0, BMASK(6:4)|BMASK(2:0)); // hdmirx_ve_10[2:0]: reg_src_det_sel; [6:4]: reg_src_det_pix_per_cycle
            break;

        case HDMI_TIMING_DETECT_4_1: // (4) - 1, for legacy
            W2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, 0, BIT(10)); // hdmirx_ve_10[10]: reg_timing_det_status_sel
            W2BYTEMSK(REG_HDMIRX_VE_U0_10_L +u32VEBankOffset, 1, BMASK(6:4)|BMASK(2:0)); // hdmirx_ve_10[2:0]: reg_src_det_sel; [6:4]: reg_src_det_pix_per_cycle
            break;

        case HDMI_TIMING_DETECT_4_2: // (4) - 2, for FRL
            W2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, 0, BIT(10)); // hdmirx_ve_10[10]: reg_timing_det_status_sel
            W2BYTEMSK(REG_HDMIRX_VE_U0_10_L +u32VEBankOffset, (7 << 4) | 2, BMASK(6:4)|BMASK(2:0)); // hdmirx_ve_10[2:0]: reg_src_det_sel; [6:4]: reg_src_det_pix_per_cycle
            break;

        case HDMI_TIMING_DETECT_4_3: // (4) - 3, for FRL
            W2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, 0, BIT(10)); // hdmirx_ve_10[10]: reg_timing_det_status_sel
            W2BYTEMSK(REG_HDMIRX_VE_U0_10_L +u32VEBankOffset, (7 << 4) | 3, BMASK(6:4)|BMASK(2:0)); // hdmirx_ve_10[2:0]: reg_src_det_sel; [6:4]: reg_src_det_pix_per_cycle
            break;

        case HDMI_TIMING_DETECT_5_0: // (5) - 0
            W2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, BIT(10), BIT(10)); // hdmirx_ve_10[10]: reg_timing_det_status_sel
            W2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, 0, BMASK(6:4)|BMASK(3:2)); // hdmirx_ve_11[3:2]: reg_sc_det_sel; [6:4]: reg_sc_det_pix_per_cycle
            break;

        default:

            break;
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SignalDetectProc()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SignalDetectProc(E_MUX_INPUTPORT enInputPortType, MS_U32 u32PacketStatus, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_BOOL bNextStateFlag = FALSE;
    MS_U8 u8SignalDetectState = HDMI_SIGNAL_DETECT_SQUELCH;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U8 u8Colordepth;

    do
    {
        switch(u8SignalDetectState)
        {
            case HDMI_SIGNAL_DETECT_SQUELCH:
                if(pstHDMIPollingInfo->bClockStableFlag && (!pstHDMIPollingInfo->bVersionChangeFlag))
                {
                    if(pstHDMIPollingInfo->bNoInputFlag)
                    {
                        pstHDMIPollingInfo->bNoInputFlag = FALSE;
                        pstHDMIPollingInfo->bTimingStableFlag = FALSE;
                        pstHDMIPollingInfo->bActiveCableFlag = FALSE;
                        pstHDMIPollingInfo->bResetDCFifoFlag = FALSE;
                        pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_START;

                        MHAL_HDMIRX_MSG_INFO("** HDMI clock stable port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                        if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20)
                        {
                            MHAL_HDMIRX_MSG_INFO("** HDMI get version 2.0 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                            pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_ACTIVE_CABLE;
                            pstHDMIPollingInfo->u8RetriggerCount20 = 0;
                            pstHDMIPollingInfo->bHDMI20Flag = TRUE;
                            W2BYTE(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0002);

                            _Hal_tmds_GetimingDetectPath(enInputPortType, HDMI_TIMING_DETECT_4_0);
                        }
                        else if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
                        {
                            MHAL_HDMIRX_MSG_INFO("** HDMI get version 1.4 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                            pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_AUTO_EQ;
                            pstHDMIPollingInfo->u8TryNegativeC = 0;
                            pstHDMIPollingInfo->bHDMI20Flag = FALSE;
                            W2BYTE(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0001);

                            _Hal_tmds_GetimingDetectPath(enInputPortType, HDMI_TIMING_DETECT_4_0);
                        }

                        if(_Hal_tmds_GetClockChangeFlag(enInputPortType, pstHDMIPollingInfo))
                        {
                            // clear clock big change
                        }
                    }

                    bNextStateFlag = TRUE;
                }
                else
                {
                    if(!pstHDMIPollingInfo->bNoInputFlag)
                    {
                        pstHDMIPollingInfo->bNoInputFlag = TRUE;
                        pstHDMIPollingInfo->bDEChangeFlag = TRUE;
                        W2BYTE(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0000);

                        _Hal_tmds_ClearEDRVaildFlag(pstHDMIPollingInfo->ucHDMIInfoSource);

                        // hdmirx_dtop_35[15] = 1 reg_dep_de_det_vsync_en (default setting, fix)
                        //_Hal_tmds_SetDEStableFlag(enInputPortType, pstHDMIPollingInfo, u32PacketStatus, FALSE);

                        Hal_HDCP_GetAuthVersion(enInputPortType, FALSE); // Clear HDCP22 interrupt status
                        Hal_DVI_Software_Reset(enInputPortType, HDMI_SW_RESET_HDMI|HDMI_SW_RESET_HDCP); // reset packet status

                        MHAL_HDMIRX_MSG_INFO("** HDMI clock unstable port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }

                    if(pstHDMIPollingInfo->bVersionChangeFlag)
                    {
                        pstHDMIPollingInfo->bVersionChangeFlag = FALSE;
                    }

                    if(pstHDMIPollingInfo->u8FastTrainingState != HDMI_FAST_TRAINING_STOP)
                    {
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_STOP;
                    }

                    bNextStateFlag = FALSE;
                }
                break;

            case HDMI_SIGNAL_DETECT_CLOCK_STABLE:
                if(_Hal_tmds_GetClockChangeFlag(enInputPortType, pstHDMIPollingInfo))
                {
                    pstHDMIPollingInfo->bNoInputFlag = TRUE;
                    pstHDMIPollingInfo->bDEChangeFlag = TRUE;

                    // hdmirx_dtop_35[15] = 1 reg_dep_de_det_vsync_en (default setting, fix)
                    //_Hal_tmds_SetDEStableFlag(enInputPortType, pstHDMIPollingInfo, u32PacketStatus, FALSE);

                    MHAL_HDMIRX_MSG_INFO("** HDMI clock changed, switch to no input port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_START;
                    MHAL_HDMIRX_MSG_INFO("** HDMI clock change trigger FT port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                    bNextStateFlag = FALSE;
                }
                else
                {
                    bNextStateFlag = TRUE;
                }

                break;

            case HDMI_SIGNAL_DETECT_DATA_ENABLE:
                if(Hal_DVI_GetDEStableStatus(enInputPortType))
                {
                    if(!pstHDMIPollingInfo->bResetDCFifoFlag)
                    {
                        Hal_HDMI_pkt_reset(enInputPortType, HDMI_GET_PORT_SELECT(enInputPortType), REST_DEEP_COLOR_FIFO, pstHDMIPollingInfo);
                        pstHDMIPollingInfo->bResetDCFifoFlag = TRUE;
                    }
                    // hdmirx_dtop_35[15] = 1 reg_dep_de_det_vsync_en (default setting, fix)
#if 0
                    if(!pstHDMIPollingInfo->bDEChangeFlag)
                    {
                        _Hal_tmds_SetDEStableFlag(enInputPortType, pstHDMIPollingInfo, u32PacketStatus, TRUE);
                    }
                    else
                    {
                        _Hal_tmds_SetDEStableFlag(enInputPortType, pstHDMIPollingInfo, u32PacketStatus, FALSE);
                    }
#endif

                    if(!pstHDMIPollingInfo->bTimingStableFlag)
                    {
                        pstHDMIPollingInfo->bTimingStableFlag = TRUE;
                    }

                    _Hal_tmds_UpdateErrorStatus(enInputPortType, pstHDMIPollingInfo);

                    bNextStateFlag = TRUE;
                }
                else // DE unstable
                {
                    // hdmirx_dtop_35[15] = 1 reg_dep_de_det_vsync_en (default setting, fix)
                    //_Hal_tmds_SetDEStableFlag(enInputPortType, pstHDMIPollingInfo, u32PacketStatus, FALSE);

                    if(pstHDMIPollingInfo->bYUV420Flag)
                    {
                        pstHDMIPollingInfo->bYUV420Flag = FALSE;

                        _Hal_tmds_YUV420PHYSetting(enInputPortType, pstHDMIPollingInfo->bYUV420Flag, pstHDMIPollingInfo->ucSourceVersion, pstHDMIPollingInfo->u8Colordepth);

                        MHAL_HDMIRX_MSG_INFO("** HDMI back to HDMI 2.0 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }

                    bNextStateFlag = FALSE;
                }
                break;

            case HDMI_SIGNAL_DETECT_HDMI_MODE:
                if(_Hal_tmds_GetHDMIModeFlag(enInputPortType))
                {
                    if(!pstHDMIPollingInfo->bHDMIModeFlag)
                    {
                        pstHDMIPollingInfo->bHDMIModeFlag = TRUE;

                        MHAL_HDMIRX_MSG_INFO("** HDMI detect HDMI mode, port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                }
                else if(pstHDMIPollingInfo->bHDMIModeFlag)
                {
                    pstHDMIPollingInfo->bHDMIModeFlag = FALSE;
                    Hal_HDMI_pkt_reset(enInputPortType, HDMI_GET_PORT_SELECT(enInputPortType), REST_HDMI_STATUS, pstHDMIPollingInfo);

                    MHAL_HDMIRX_MSG_INFO("** HDMI detect DVI mode, port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                }

                bNextStateFlag = TRUE;

                break;

            case HDMI_SIGNAL_DETECT_HDCP_STATUS:
                if(Hal_HDCP_getstatus(enInputPortType) & BIT(8)) // AKSV interrupt status: HDCP1.4
                {
                    Hal_HDCP_ClearStatus(enInputPortType, BIT(0));

                    if(pstHDMIPollingInfo->ucHDCPState != HDMI_HDCP_1_4)
                    {
                        pstHDMIPollingInfo->ucHDCPState = HDMI_HDCP_1_4;

                        MHAL_HDMIRX_MSG_INFO("** HDMI HDCP state 1.4, port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                }
                else if(_Hal_tmds_GetHDCP22IntStatus(enInputPortType) & BIT(1)) // AKE_Init interrupt status: HDCP2.2
                {
                    if(pstHDMIPollingInfo->ucHDCPState != HDMI_HDCP_2_2)
                    {
                        pstHDMIPollingInfo->ucHDCPState = HDMI_HDCP_2_2;

                        MHAL_HDMIRX_MSG_INFO("** HDMI HDCP state 2.2, port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                }

                bNextStateFlag = TRUE;

                break;

            case HDMI_SIGNAL_DETECT_AUDIO_MUTE_EVENT:
                Hal_HDMI_Audio_Status_Clear(NULL);

                bNextStateFlag = TRUE;

                break;

            case HDMI_SIGNAL_DETECT_YUV420:
                if(_Hal_tmds_GetYUV420Flag(pstHDMIPollingInfo->ucHDMIInfoSource, u32PacketStatus))
                {
                    u8Colordepth = Hal_HDMI_GetGCPColorDepth(enInputPortType, u32PacketStatus);
                    if((pstHDMIPollingInfo->u8Colordepth != u8Colordepth) || (!pstHDMIPollingInfo->bYUV420Flag))
                    {
                        pstHDMIPollingInfo->bYUV420Flag = TRUE;
                        pstHDMIPollingInfo->u8Colordepth = u8Colordepth;
                        _Hal_tmds_YUV420PHYSetting(enInputPortType, pstHDMIPollingInfo->bYUV420Flag, pstHDMIPollingInfo->ucSourceVersion, pstHDMIPollingInfo->u8Colordepth);
                        MHAL_HDMIRX_MSG_INFO("** HDMI get YUV420 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                }
                else if(pstHDMIPollingInfo->bYUV420Flag)
                {
                    pstHDMIPollingInfo->bYUV420Flag = FALSE;

                    _Hal_tmds_YUV420PHYSetting(enInputPortType, pstHDMIPollingInfo->bYUV420Flag, pstHDMIPollingInfo->ucSourceVersion, pstHDMIPollingInfo->u8Colordepth);

                    MHAL_HDMIRX_MSG_INFO("** HDMI disable YUV420 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                }

                bNextStateFlag = TRUE;

                break;

            case HDMI_SIGNAL_DETECT_EMP:
                pstHDMIPollingInfo->u16EMPacketInfo = _Hal_tmds_GetEMPacketInfo(enInputPortType, pstHDMIPollingInfo->ucHDMIInfoSource, u32PacketStatus);

                bNextStateFlag = FALSE;

                break;

            default:
                bNextStateFlag = FALSE;
                break;
        };

        u8SignalDetectState++;
    }while(bNextStateFlag);
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_SetRatioDetectValue()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_SetRatioDetectValue(E_MUX_INPUTPORT enInputPortType, MS_U8 u8RatioValue)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    W2BYTEMSK(REG_PHY2P1_1_P0_4A_L + u32PHY2P1BankOffset, (u8RatioValue << 4), BMASK(7:4));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_NewPHYAutoEQTrigger()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_NewPHYAutoEQTrigger(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo, MS_U16 LanSel)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    W2BYTEMSK(REG_PHY2P1_0_P0_20_L +u32PHY2P1BankOffset, 0x14, BMASK(5:0)); // phy2p1_0_20[5:0]: reg_eq_strength_ini

    // trigger autoEQ
    W2BYTEMSK(REG_PHY2P1_0_P0_05_L +u32PHY2P1BankOffset, LanSel, BMASK(11:8));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ActiveCablePatch()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ActiveCablePatch(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U8 u8EQValue[4] = {2, 2, 2, 2};
    MS_U8 u8PGAValue[4] = {0x0F, 0x0F, 0x0F, 0x0F}; // eg_pga_gain_lx_ov[7:6] = 2'b11 for H20 patch
    MS_U16 u16temp = 1000;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, 0, BIT(7));

    _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue); // Set EQ = 2

    _Hal_tmds_SetPGAGainValue(enInputPortType, TRUE, u8PGAValue); // Set PGA gain = 0xF

    // Clear auto scan done flag
    W2BYTE(REG_PHY2P1_0_P0_3E_L +u32PHY2P1BankOffset, BIT(2));
    W2BYTE(REG_PHY2P1_0_P0_42_L +u32PHY2P1BankOffset, BIT(2));
    W2BYTE(REG_PHY2P1_0_P0_46_L +u32PHY2P1BankOffset, BIT(2));

    // Overwrite IDAC = 0 (disable dfe tap1~tap4 & disable dfe tap5~tap12)
    _Hal_tmds_EnableDfeTap(enInputPortType, FALSE, FALSE);

    // Release VDAC
    W2BYTEMSK(REG_PHY2P1_2_P0_14_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_15_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_16_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_17_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));

    if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
    {
        W2BYTEMSK(REG_PHY2P1_0_P0_51_L +u32PHY2P1BankOffset, BIT(9)|BIT(3), BMASK(10:8)|BIT(3)); // phy0_51[3]: reg_en_dlev_sw_mode; [10:8]: reg_filter_depth_dlev

        while(u16temp--);
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetRatioDetectFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetRatioDetectFlag(E_MUX_INPUTPORT enInputPortType)
{
    MS_BOOL bRatioFlag = FALSE;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if(R2BYTE(REG_PHY2P1_1_P0_4A_L +u32PHY2P1BankOffset) & BIT(12)) // phy2p1_1_4A[12:8]: reg_hdmi_case_readback
    {
        bRatioFlag = TRUE;
    }

    return bRatioFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ResetPHYFSM()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ResetPHYFSM(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    W2BYTE(REG_PHY2P1_0_P0_10_L + u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_11_L + u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_12_L + u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_13_L + u32PHY2P1BankOffset, 0);
    W2BYTEMSK(REG_PHY2P1_0_P0_14_L + u32PHY2P1BankOffset, 0, BMASK(7:0));
    W2BYTEMSK(REG_PHY2P1_0_P0_15_L + u32PHY2P1BankOffset, 0, BMASK(7:0));
    W2BYTEMSK(REG_PHY2P1_0_P0_16_L + u32PHY2P1BankOffset, 0, BMASK(7:0));
    W2BYTEMSK(REG_PHY2P1_0_P0_17_L + u32PHY2P1BankOffset, 0, BMASK(7:0));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetFastTrainingResult()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 _Hal_tmds_GetFastTrainingResult(E_MUX_INPUTPORT enInputPortType)
{
    MS_U8 u8FastTrainingResult = HDMI_FAST_TRAINING_RESULT_NONE;
    MS_U16 u16RegisterValue = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    u16RegisterValue = R2BYTE(REG_PHY_TRAIN_P0_31_L +u32PHY2P1BankOffset);

    if(u16RegisterValue &BIT(3)) // Fast train flow done
    {
        u8FastTrainingResult = u16RegisterValue &BMASK(2:0);
    }

    return u8FastTrainingResult;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetFRLTrainingState()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 _Hal_tmds_GetFRLTrainingState(E_MUX_INPUTPORT enInputPortType)
{
    MS_U8 u8FRLTrainingStatue = HDMI_FRL_TRAINING_STATE_NONE;
    MS_U16 u16RegisterValue = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    u16RegisterValue = (R2BYTE(REG_PHY_TRAIN_P0_28_L +u32PHY2P1BankOffset) &BMASK(10:8)) >> 8;

    if(u16RegisterValue < u8FRLTrainingStatue)
    {
        u8FRLTrainingStatue = u16RegisterValue;
    }

    return u8FRLTrainingStatue;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetErrorCountStatus()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetErrorCountStatus(E_MUX_INPUTPORT enInputPortType, MS_BOOL bHDMI20Flag, stHDMI_ERROR_STATUS *pstErrorStatus)
{
    MS_BOOL bWordBoundaryUnlock = FALSE;
    MS_BOOL bDecodeError = FALSE;
    MS_U16 u16DecodeErrorThr = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(R2BYTE(REG_DVI_DTOP_DUAL_P0_4F_L +u32DTOPBankOffset) & BIT(3)) // hdmirx_dtop_4F[15:0]: reg_dbg_rpt - ch0
    {
        bWordBoundaryUnlock = TRUE;
        pstErrorStatus->bWordBoundaryErrorL0 = TRUE;
    }
    if(R2BYTE(REG_DVI_DTOP_DUAL_P0_4F_L +u32DTOPBankOffset) & BIT(7)) // hdmirx_dtop_4F[15:0]: reg_dbg_rpt - ch1
    {
        bWordBoundaryUnlock = TRUE;
        pstErrorStatus->bWordBoundaryErrorL1 = TRUE;
    }
    if(R2BYTE(REG_DVI_DTOP_DUAL_P0_4F_L +u32DTOPBankOffset) & BIT(11)) // hdmirx_dtop_4F[15:0]: reg_dbg_rpt - ch2
    {
        bWordBoundaryUnlock = TRUE;
        pstErrorStatus->bWordBoundaryErrorL2 = TRUE;
    }

    if(bWordBoundaryUnlock)
    {
        // clear WB unlock: hdmirx_dtop_4F[3][7][11]
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_4D_L + u32DTOPBankOffset, BIT(0), BIT(0)); // hdmirx_dtop_4D[0]: reg_clr_err_chk
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_4D_L + u32DTOPBankOffset, 0, BIT(0)); // hdmirx_dtop_4D[0]: reg_clr_err_chk
    }

    u16DecodeErrorThr = bHDMI20Flag ? HDMI_DECODE_ERROR_THRESHOLD20 : HDMI_DECODE_ERROR_THRESHOLD14;

    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_58_L +u32DTOPBankOffset, 0xFE00, BMASK(15:8)); // hdmirx_dtop_58[15:8]: reg_dec20_tst_bus_sel - ch0

    pstErrorStatus->u16DecodeErrorL0 = R2BYTE(REG_DVI_DTOP_DUAL_P0_59_L +u32DTOPBankOffset); // hdmirx_dtop_59[15:0]: reg_tst_bus_rpt0

    if(pstErrorStatus->u16DecodeErrorL0 > u16DecodeErrorThr)
    {
        bDecodeError = TRUE;
    }

    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_58_L +u32DTOPBankOffset, 0xFD00, BMASK(15:8)); // hdmirx_dtop_58[15:8]: reg_dec20_tst_bus_sel - ch1

    pstErrorStatus->u16DecodeErrorL1 = R2BYTE(REG_DVI_DTOP_DUAL_P0_59_L +u32DTOPBankOffset); // hdmirx_dtop_59[15:0]: reg_tst_bus_rpt0

    if(pstErrorStatus->u16DecodeErrorL1 > u16DecodeErrorThr)
    {
        bDecodeError = TRUE;
    }

    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_58_L +u32DTOPBankOffset, 0xFC00, BMASK(15:8)); // hdmirx_dtop_58[15:8]: reg_dec20_tst_bus_sel - ch2

    pstErrorStatus->u16DecodeErrorL2 = R2BYTE(REG_DVI_DTOP_DUAL_P0_59_L +u32DTOPBankOffset); // hdmirx_dtop_59[15:0]: reg_tst_bus_rpt0

    if(pstErrorStatus->u16DecodeErrorL2 > u16DecodeErrorThr)
    {
        bDecodeError = TRUE;
    }

    if(bDecodeError)
    {
        // clear decode error: hdmirx_dtop_59[15:0]
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_40_L + u32DTOPBankOffset, BIT(15), BIT(15)); // hdmirx_dtop_40[15]: reg_sw_clr_err_cnt
        W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_40_L + u32DTOPBankOffset, 0, BIT(15)); // hdmirx_dtop_40[15]: reg_sw_clr_err_cnt
    }

    return (bWordBoundaryUnlock || bDecodeError);
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ResetDLPF()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ResetDLPF(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    volatile MS_U16 dly;

    W2BYTEMSK(REG_PHY2P1_2_P0_05_L +u32PHY2P1BankOffset, 0x00F1, BMASK(7:4)|BIT(0)); // pd_dlpf
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, 0x0F00, BMASK(11:8)); // pd_phdac_i
    for (dly=0 ; dly<200 ; dly++); // 1us delay
    W2BYTEMSK(REG_PHY2P1_2_P0_05_L +u32PHY2P1BankOffset, 0x0001, BMASK(7:4)|BIT(0));
    W2BYTEMSK(REG_PHY2P1_2_P0_2F_L +u32PHY2P1BankOffset, 0x0000, BMASK(11:8));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetH14AutoEQEnable()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
EN_HDMI_14_TMDS_CLOCK_RANGE _Hal_tmds_GetH14AutoEQEnable(E_MUX_INPUTPORT enInputPortType, MS_U32 ulClockRate)
{
    EN_HDMI_14_TMDS_CLOCK_RANGE enClockRange = HDMI_14_TMDS_CLOCK_NONE;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if(ulClockRate < 75)
    {
        MS_U8 u8EQValue[4] = {10, 10, 10, 10};

        // aaba reference to full screen
        W2BYTE(REG_PHY2P1_0_P0_27_L +u32PHY2P1BankOffset, 0x9300); // phy2p1_0_27[15:0]: reg_eq_top_condi

        _Hal_tmds_ResetDLPF(enInputPortType);
        _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

        enClockRange = HDMI_14_TMDS_CLOCK_UNDER_75M;
    }
    else if(ulClockRate < 135)
    {
        MS_U8 u8EQValue[4] = {15, 15, 15, 15};

        // aaba reference to full screen
        W2BYTE(REG_PHY2P1_0_P0_27_L +u32PHY2P1BankOffset, 0x9300); // phy2p1_0_27[15:0]: reg_eq_top_condi

        _Hal_tmds_ResetDLPF(enInputPortType);
        _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

        enClockRange = HDMI_14_TMDS_CLOCK_75M_TO_135M;
    }
    else // Auto EQ
    {
        enClockRange = HDMI_14_TMDS_CLOCK_OVER_135M;
    }

    return enClockRange;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ActiveCableCheckDLEV()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_ActiveCableCheckDLEV(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_BOOL bDLEVFlag = FALSE;
    MS_U8 u8DLEVCnt = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
    {
        u8DLEVCnt = HDMI_VDAC_DLEV_COUNT_PORT20;
    }
    else
    {
        u8DLEVCnt = HDMI_VDAC_DLEV_COUNT_H20;
    }

    if(_Hal_tmds_DIGLockCheck(enInputPortType))
    {
        if(R2BYTE(REG_PHY2P1_0_P0_64_L +u32PHY2P1BankOffset) > u8DLEVCnt) // phy0_64[9:0]: reg_vdac_in_dlev_bin_0
        {
            if(R2BYTE(REG_PHY2P1_0_P0_65_L +u32PHY2P1BankOffset) > u8DLEVCnt) // phy0_65[9:0]: reg_vdac_in_dlev_bin_1
            {
                if(R2BYTE(REG_PHY2P1_0_P0_66_L +u32PHY2P1BankOffset) > u8DLEVCnt) // phy0_66[9:0]: reg_vdac_in_dlev_bin_2
                {
                    bDLEVFlag = TRUE;
                }
            }
        }
    }

    return bDLEVFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ActiveCableCheckPhase()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_ActiveCableCheckPhase(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_BOOL bActiveCableFlag = FALSE;
    MS_U8 u8temp = 0;
    MS_U8 u8PhaseCount[3] = {0};
    volatile MS_U16 u16temp = 1000;
    MS_U16 u16RegValue = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
    {
        W2BYTEMSK(REG_PHY2P1_0_P0_51_L +u32PHY2P1BankOffset, 0x0100, BMASK(10:8)|BIT(3)); // phy0_51[3]: reg_en_dlev_sw_mode; [10:8]: reg_filter_depth_dlev
    }


    // Overwrite VDAC code = 0
    W2BYTEMSK(REG_PHY2P1_2_P0_14_L +u32PHY2P1BankOffset, 0x8000, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_15_L +u32PHY2P1BankOffset, 0x8000, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_16_L +u32PHY2P1BankOffset, 0x8000, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_17_L +u32PHY2P1BankOffset, 0x8000, BIT(15)|BMASK(8:0));

    // Overwrite FSM
    W2BYTE(REG_PHY2P1_0_P0_10_L +u32PHY2P1BankOffset, 0x0080);
    W2BYTE(REG_PHY2P1_0_P0_11_L +u32PHY2P1BankOffset, 0x0080);
    W2BYTE(REG_PHY2P1_0_P0_12_L +u32PHY2P1BankOffset, 0x0080);
    W2BYTE(REG_PHY2P1_0_P0_13_L +u32PHY2P1BankOffset, 0x0080);

    while(u16temp--);

    W2BYTE(REG_PHY2P1_0_P0_3E_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_42_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_46_L +u32PHY2P1BankOffset, 0);

    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_0B_L +u32DTOPBankOffset, 0x0100, BMASK(15:8));

    // Re-trigger auto scan
    W2BYTEMSK(REG_PHY2P1_0_P0_34_L +u32PHY2P1BankOffset, 0xF000, 0xF00C);

    // Re-trigger auto EQ
    //_Hal_tmds_NewPHYAutoEQTrigger(enInputPortType);

    u16temp = 60000;

    while(u16temp > 0)
    {
        // Wait scan phase done
        if(R2BYTE(REG_PHY2P1_0_P0_3F_L +u32PHY2P1BankOffset) &BIT(2))
        {
            if(R2BYTE(REG_PHY2P1_0_P0_43_L +u32PHY2P1BankOffset) &BIT(2))
            {
                if(R2BYTE(REG_PHY2P1_0_P0_47_L +u32PHY2P1BankOffset) &BIT(2))
                {
                    //MHAL_HDMIRX_MSG_INFO("** HDMI auto scan done %d\r\n", u16temp);

                    break;
                }
            }
        }

        u16temp--;
    }

    if(u16temp > 0)
    {
        // Count phase count
        for(u8temp = 0; u8temp < 3; u8temp++)
        {
            W2BYTEMSK(REG_PHY2P1_0_P0_2D_L +u32PHY2P1BankOffset, (u8temp << 10), BMASK(11:10));

            u16RegValue = R2BYTE(REG_PHY2P1_0_P0_31_L +u32PHY2P1BankOffset);
            u8PhaseCount[u8temp] = (u16RegValue >> 8) & 0x7F;
        }

        MHAL_HDMIRX_MSG_INFO("** HDMI active cable phase scan done value %d, %d, %d \r\n", u8PhaseCount[0], u8PhaseCount[1], u8PhaseCount[2]);

        if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
        {
            bActiveCableFlag = (u8PhaseCount[0] > HDMI_SCAN_PHASE_THRESHOLD_14) & (u8PhaseCount[1] > HDMI_SCAN_PHASE_THRESHOLD_14) & (u8PhaseCount[2] > HDMI_SCAN_PHASE_THRESHOLD_14);
        }

        if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20)
        {
            bActiveCableFlag = (u8PhaseCount[0] > HDMI_SCAN_PHASE_THRESHOLD_20) & (u8PhaseCount[1] > HDMI_SCAN_PHASE_THRESHOLD_20) & (u8PhaseCount[2] > HDMI_SCAN_PHASE_THRESHOLD_20);
        }
    }
    else
    {
        MHAL_HDMIRX_MSG_INFO("** HDMI auto scan not done \r\n");
    }

    return bActiveCableFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ReleaseActiveCablePatch()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ReleaseActiveCablePatch(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U8 u8PGAValue[4] = {0xCF, 0xCF, 0xCF, 0xCF}; // eg_pga_gain_lx_ov[7:6] = 2'b11 for H20 patch

    // Normal cable
    _Hal_tmds_SetNewPHYEQValue(enInputPortType, FALSE, NULL);  // Auto EQ

    if((pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20) && ((R2BYTE(REG_PHY2P1_2_P0_1A_L +u32PHY2P1BankOffset) & 0x7000) == 0x0000))
    {
        // Release IDAC (Enable DFE Taps)
        _Hal_tmds_EnableDfeTap(enInputPortType, TRUE, TRUE);

#if !(PGA_PATCH_BY_SW)
        _Hal_tmds_SetPGAGainValue(enInputPortType, FALSE, NULL); // PGA gain not enable
#endif
    }
    else
    {
        _Hal_tmds_SetPGAGainValue(enInputPortType, TRUE, u8PGAValue); // Set PGA gain = 0xF
    }

    // Release VDAC
    W2BYTEMSK(REG_PHY2P1_2_P0_14_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_15_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_16_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));
    W2BYTEMSK(REG_PHY2P1_2_P0_17_L +u32PHY2P1BankOffset, 0, BIT(15)|BMASK(8:0));

    // Release FSM
    W2BYTE(REG_PHY2P1_0_P0_10_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_11_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_12_L +u32PHY2P1BankOffset, 0);
    W2BYTE(REG_PHY2P1_0_P0_13_L +u32PHY2P1BankOffset, 0);

    MHAL_HDMIRX_MSG_INFO("** HDMI change to normal cable \r\n");
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ForcePGAPatchProc()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_ForcePGAPatchProc(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U8 u8PGAValue[4] = {0xCF, 0xCF, 0xCF, 0xCF};
    MS_U8 u8PGACheckList[11] = {0xCF, 0xCD, 0xCC, 0xC4, 0xC5, 0xC7, 0xC6, 0xC2, 0xC3, 0xC1, 0xC0};
    MS_U8 u8CheckDone, i;
    volatile MS_U16 dly;
    MS_U16 u16PGACheckLevel[4] = {0};
    MS_U32 t1, t2;
    MS_U8 u8DlevTarget = R2BYTEMSK(REG_PHY2P1_0_P0_5D_L +u32PHY2P1BankOffset, BMASK(15:8)) >> 8; // phy0_5d[15:8]: reg_agc_dlev_target

    t1 = MsOS_GetSystemTime();

    for (i=1,u8CheckDone=0 ; i<sizeof(u8PGACheckList) ; i++)
    {
        for (dly=0 ; dly<2000 ; dly++); // 10us delay

        if ((u8CheckDone & 0x1) == 0)
        {
            u16PGACheckLevel[0] = R2BYTEMSK(REG_PHY2P1_0_P0_64_L +u32PHY2P1BankOffset, BMASK(9:0)); // phy0_64[9:0] reg_vdac_in_dlev_bin_0
            if(u16PGACheckLevel[0] > (u8DlevTarget + 3))
            {
                u8PGAValue[0] = u8PGACheckList[i];
            }
            else
            {
                u8CheckDone |= 0x1;
            }
        }

        if ((u8CheckDone & 0x2) == 0)
        {
            u16PGACheckLevel[1] = R2BYTEMSK(REG_PHY2P1_0_P0_65_L +u32PHY2P1BankOffset, BMASK(9:0)); // phy0_65[9:0] reg_vdac_in_dlev_bin_1
            if(u16PGACheckLevel[1] > (u8DlevTarget + 3))
            {
                u8PGAValue[1] = u8PGACheckList[i];
            }
            else
            {
                u8CheckDone |= 0x2;
            }
        }

        if ((u8CheckDone & 0x4) == 0)
        {
            u16PGACheckLevel[2] = R2BYTEMSK(REG_PHY2P1_0_P0_66_L +u32PHY2P1BankOffset, BMASK(9:0)); // phy0_66[9:0] reg_vdac_in_dlev_bin_2
            if(u16PGACheckLevel[2] > (u8DlevTarget + 3))
            {
                u8PGAValue[2] = u8PGACheckList[i];
            }
            else
            {
                u8CheckDone |= 0x4;
            }
        }

        if (u8CheckDone == 0x7)
        {
            break;
        }

        _Hal_tmds_SetPGAGainValue(enInputPortType, TRUE, u8PGAValue);

        // REG_PD_DLPF
        W2BYTEMSK(REG_PHY2P1_2_P0_05_L +u32PHY2P1BankOffset, 0x0071, BMASK(6:4)|BIT(0)); // phy2_05[0] reg_pd_dlpf_ov_en, phy2_05[7:4] reg_pd_dlpf_ov
        for (dly=0 ; dly<200 ; dly++); // 1us delay
        W2BYTEMSK(REG_PHY2P1_2_P0_05_L +u32PHY2P1BankOffset, 0x0001, BMASK(6:4)|BIT(0)); // phy2_05[0] reg_pd_dlpf_ov_en, phy2_05[7:4] reg_pd_dlpf_ov
    }

    t2 = MsOS_GetSystemTime();

    MHAL_HDMIRX_MSG_INFO("** HDMI force PGA patch finish: L0/L1/L2 Binary = 0x%x/0x%x/0x%x, 0x%x/0x%x/0x%x, spend %dms\r\n",
        u8PGAValue[0], u8PGAValue[1], u8PGAValue[2],
        u16PGACheckLevel[0], u16PGACheckLevel[1], u16PGACheckLevel[2],
        (int)(t2-t1));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_CheckActiveCableProc()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_CheckActiveCableProc(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_BOOL bCheckDoneFlag = FALSE;
    MS_BOOL bNextStateFlag = FALSE;
    MS_U16 u16temp = 2000;
    stHDMI_ERROR_STATUS stErrorStatus = {0};
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    do
    {
        switch(pstHDMIPollingInfo->u8ActiveCableState)
        {
            case HDMI_ACTIVE_CABLE_START:
                _Hal_tmds_ActiveCablePatch(enInputPortType, pstHDMIPollingInfo);

                if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
                {
                    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_CHECK_DLEV;
                    bNextStateFlag = TRUE;
                }
                else if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20)
                {
                    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_CHECK_DLEV;
                    bNextStateFlag = TRUE;
                }
                else
                {
                    bNextStateFlag = FALSE;
                }

                break;

            case HDMI_ACTIVE_CABLE_CHECK_DLEV:
                if(_Hal_tmds_ActiveCableCheckDLEV(enInputPortType, pstHDMIPollingInfo))
                {
                    //since the SQUELCH will not disable when signal re-enter
                    //do the PDLF reset
                    _Hal_tmds_ResetDLPF(enInputPortType);

                    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_CHECK_PHASE;
                    bNextStateFlag = TRUE;
                }
                else
                {
                    bNextStateFlag = FALSE;
                }

                break;

            case HDMI_ACTIVE_CABLE_CHECK_PHASE:
                if(_Hal_tmds_ActiveCableCheckPhase(enInputPortType, pstHDMIPollingInfo))
                {
                    if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
                    {
                        pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_EQ_FLOW_H14;
                    }
                    else if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20)
                    {
                        pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_EQ_FLOW_H20;
                    }

                    pstHDMIPollingInfo->u16ActiveCableCheckErrorCount = 0;
                    pstHDMIPollingInfo->u8ActiveCableClearErrorStatusCount = 0;
                    bNextStateFlag = FALSE;
                }
                else
                {
                    pstHDMIPollingInfo->bActiveCableFlag = FALSE;
                    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_FINISH;
                    bNextStateFlag = TRUE;
                }
                break;

            case HDMI_ACTIVE_CABLE_EQ_FLOW_H14:
                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                MHAL_HDMIRX_MSG_INFO("** HDMI 14 Active cable clear error status port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_CHECK_STABLE_H14;
                bNextStateFlag = TRUE;

                break;

            case HDMI_ACTIVE_CABLE_CHECK_STABLE_H14:
                if(Hal_DVI_GetDEStableStatus(enInputPortType) &&
                    (!_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus)))
                {
                    if(pstHDMIPollingInfo->u16ActiveCableCheckErrorCount < TMDS_14_CHECK_ERROR_TIMES)
                    {
                        pstHDMIPollingInfo->u16ActiveCableCheckErrorCount++;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_FINISH;
                        pstHDMIPollingInfo->bActiveCableFlag = TRUE;
                        bNextStateFlag = TRUE;
                    }
                }
                else // DE unstable or BCH error
                {
                    MHAL_HDMIRX_MSG_INFO("** HDMI 14 Active cable error happened, decode error: 0x%x, 0x%x, 0x%x port %d\r\n", stErrorStatus.u16DecodeErrorL0, stErrorStatus.u16DecodeErrorL1, stErrorStatus.u16DecodeErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    MHAL_HDMIRX_MSG_INFO("** HDMI 14 Active cable error happened, WB error: %d, %d, %d port %d\r\n", stErrorStatus.bWordBoundaryErrorL0, stErrorStatus.bWordBoundaryErrorL1, stErrorStatus.bWordBoundaryErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_FINISH;
                    pstHDMIPollingInfo->bActiveCableFlag = FALSE;
                    bNextStateFlag = TRUE;
                }
                break;

            case HDMI_ACTIVE_CABLE_EQ_FLOW_H20:
                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, TRUE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                if(pstHDMIPollingInfo->u8ActiveCableClearErrorStatusCount < TMDS_CLEAR_ERROR_STATUS_COUNT)
                {
                    pstHDMIPollingInfo->u8ActiveCableClearErrorStatusCount++;
                    bNextStateFlag = FALSE;
                }
                else
                {
                    MHAL_HDMIRX_MSG_INFO("** HDMI 20 Active cable clear error status port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_CHECK_STABLE_H20;
                    bNextStateFlag = TRUE;
                }
                break;

            case HDMI_ACTIVE_CABLE_CHECK_STABLE_H20:
                if(Hal_DVI_GetDEStableStatus(enInputPortType) &&
                    (!_Hal_tmds_GetErrorCountStatus(enInputPortType, TRUE, &stErrorStatus)))
                {
                    if(pstHDMIPollingInfo->u16ActiveCableCheckErrorCount < TMDS_20_CHECK_ERROR_TIMES)
                    {
                        pstHDMIPollingInfo->u16ActiveCableCheckErrorCount++;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_FINISH;
                        pstHDMIPollingInfo->bActiveCableFlag = TRUE;
                        bNextStateFlag = TRUE;
                    }
                }
                else // DE unstable or BCH error
                {
                    MHAL_HDMIRX_MSG_INFO("** HDMI 20 Active cable error happened, decode error: 0x%x, 0x%x, 0x%x port %d\r\n", stErrorStatus.u16DecodeErrorL0, stErrorStatus.u16DecodeErrorL1, stErrorStatus.u16DecodeErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    MHAL_HDMIRX_MSG_INFO("** HDMI 20 Active cable error happened, WB error: %d, %d, %d port %d\r\n", stErrorStatus.bWordBoundaryErrorL0, stErrorStatus.bWordBoundaryErrorL1, stErrorStatus.bWordBoundaryErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_FINISH;
                    pstHDMIPollingInfo->bActiveCableFlag = FALSE;
                    bNextStateFlag = TRUE;
                }
                break;

            case HDMI_ACTIVE_CABLE_FINISH:
                pstHDMIPollingInfo->u8ActiveCableState = HDMI_ACTIVE_CABLE_NONE;
                W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0008, BIT(3));

                if(!pstHDMIPollingInfo->bActiveCableFlag)
                {
                    _Hal_tmds_ReleaseActiveCablePatch(enInputPortType, pstHDMIPollingInfo);
                }
                else
                {
                    W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0004, BIT(2));
                }

                bNextStateFlag = TRUE;
                break;

            default:
                bNextStateFlag = FALSE;
                bCheckDoneFlag = TRUE;
                break;

        }
    }while(bNextStateFlag);

    return bCheckDoneFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetEQFlowDoneFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_GetEQFlowDoneFlag(E_MUX_INPUTPORT enInputPortType, MS_U8 opt)
{
    MS_U8 bEQFlowDoneFlag = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if(R2BYTE(REG_PHY2P1_0_P0_10_L +u32PHY2P1BankOffset) &BIT(7))
        bEQFlowDoneFlag |= 0x01;

    if(R2BYTE(REG_PHY2P1_0_P0_11_L +u32PHY2P1BankOffset) &BIT(7))
        bEQFlowDoneFlag |= 0x02;

    if(R2BYTE(REG_PHY2P1_0_P0_12_L +u32PHY2P1BankOffset) &BIT(7))
        bEQFlowDoneFlag |= 0x04;

    if(R2BYTE(REG_PHY2P1_0_P0_13_L +u32PHY2P1BankOffset) &BIT(7))
        bEQFlowDoneFlag |= 0x08;

    bEQFlowDoneFlag &= opt;
    return (bEQFlowDoneFlag == opt);
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_GetNewPHYEQValue()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_GetNewPHYEQValue(E_MUX_INPUTPORT enInputPortType, MS_U8 *pu8EQValue)
{
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    // gray code
    pu8EQValue[0] = R2BYTE(REG_PHY2P1_2_P0_24_L +u32PHY2P1BankOffset);
    pu8EQValue[1] = R2BYTE(REG_PHY2P1_2_P0_24_L +u32PHY2P1BankOffset) >> 8;
    pu8EQValue[2] = R2BYTE(REG_PHY2P1_2_P0_25_L +u32PHY2P1BankOffset);
    pu8EQValue[3] = R2BYTE(REG_PHY2P1_2_P0_25_L +u32PHY2P1BankOffset) >> 8;

    // binary code
    pu8EQValue[4] = _Hal_tmds_DeCodeGray(pu8EQValue[0] & BMASK(6:0));
    pu8EQValue[5] = _Hal_tmds_DeCodeGray(pu8EQValue[1] & BMASK(6:0));
    pu8EQValue[6] = _Hal_tmds_DeCodeGray(pu8EQValue[2] & BMASK(6:0));
    pu8EQValue[7] = _Hal_tmds_DeCodeGray(pu8EQValue[3] & BMASK(6:0));
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_ChangePHYCase()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL _Hal_tmds_ChangePHYCase(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_BOOL bFinishFlag = FALSE;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);

    if (pstHDMIPollingInfo->u8ChangePHYCase != HDMI_CHANGE_PHY_FINISH)
    {
        _Hal_tmds_ResetDLPF(enInputPortType);
    }

    switch(pstHDMIPollingInfo->u8ChangePHYCase)
    {
        case HDMI_CHANGE_PHY_H14_CASE0:
            {
                MS_U8 u8EQValue[4] = {33, 33, 33, 33};

                MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H14 case0 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H14_CASE1;

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_6A_L +u32PHY2P1BankOffset, 0, BIT(0));
            }
            break;

        case HDMI_CHANGE_PHY_H14_CASE1:
            {
                MS_U8 u8EQValue[4] = {8, 8, 8, 8};

                MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H14 case1 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H14_CASE2;

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_6A_L +u32PHY2P1BankOffset, 0, BIT(0));
            }
            break;

        case HDMI_CHANGE_PHY_H14_CASE2:
            {
                MS_U8 u8EQValue[4] = {16, 16, 16, 16};

                MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H14 case2 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_FINISH;

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, 0, BIT(0));
                W2BYTEMSK(REG_PHY2P1_2_P0_6A_L +u32PHY2P1BankOffset, 0, BIT(0));
            }
            break;

        case HDMI_CHANGE_PHY_H14_75M_TO_135M_CASE0:
            {
                MS_U8 u8EQValue[4] = {15, 15, 15, 15};

                MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H14 75M_TO_135M case0 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H14_75M_TO_135M_CASE1;

                W2BYTEMSK(REG_PHY2P1_2_P0_60_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_60[3:0]: EQ_RL override value - L0; [4]: EQ/PGA-RL override enable - L0
                W2BYTEMSK(REG_PHY2P1_2_P0_63_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_63[3:0]: EQ_RL override value - L1; [4]: EQ/PGA-RL override enable - L1
                W2BYTEMSK(REG_PHY2P1_2_P0_66_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_66[3:0]: EQ_RL override value - L2; [4]: EQ/PGA-RL override enable - L2
                W2BYTEMSK(REG_PHY2P1_2_P0_69_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_69[3:0]: EQ_RL override value - L3; [4]: EQ/PGA-RL override enable - L3

                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0081, BIT(7)|BMASK(4:0)); // phy2_28[4:0] reg_gc_ictrl_pfd_ov, phy2_28[7] reg_gc_ictrl_pfd_ov_en

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);
            }
            break;

        case HDMI_CHANGE_PHY_H14_75M_TO_135M_CASE1:
            {
                MS_U8 u8EQValue[4] = {25, 25, 25, 25};

                MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H14 75M_TO_135M case1 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_FINISH;

                W2BYTEMSK(REG_PHY2P1_2_P0_60_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_60[3:0]: EQ_RL override value - L0; [4]: EQ/PGA-RL override enable - L0
                W2BYTEMSK(REG_PHY2P1_2_P0_63_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_63[3:0]: EQ_RL override value - L1; [4]: EQ/PGA-RL override enable - L1
                W2BYTEMSK(REG_PHY2P1_2_P0_66_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_66[3:0]: EQ_RL override value - L2; [4]: EQ/PGA-RL override enable - L2
                W2BYTEMSK(REG_PHY2P1_2_P0_69_L +u32PHY2P1BankOffset, BIT(4)| BMASK(3:0), BIT(4)| BMASK(3:0)); // phy2p1_2_69[3:0]: EQ_RL override value - L3; [4]: EQ/PGA-RL override enable - L3

                W2BYTEMSK(REG_PHY2P1_2_P0_28_L +u32PHY2P1BankOffset, 0x0081, BIT(7)|BMASK(4:0)); // phy2_28[4:0] reg_gc_ictrl_pfd_ov, phy2_28[7] reg_gc_ictrl_pfd_ov_en

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);
            }
            break;

        case HDMI_CHANGE_PHY_H14_75M_TO_135M_CASE2:
            {
                MS_U8 u8EQValue[4] = {15, 15, 15, 15};

                MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H14 75M_TO_135M case2 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H14_75M_TO_135M_CASE0;

                W2BYTEMSK(REG_PHY2P1_2_P0_60_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_60[3:0]: EQ_RL override value - L0; [4]: EQ/PGA-RL override enable - L0
                W2BYTEMSK(REG_PHY2P1_2_P0_63_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_63[3:0]: EQ_RL override value - L1; [4]: EQ/PGA-RL override enable - L1
                W2BYTEMSK(REG_PHY2P1_2_P0_66_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_66[3:0]: EQ_RL override value - L2; [4]: EQ/PGA-RL override enable - L2
                W2BYTEMSK(REG_PHY2P1_2_P0_69_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_69[3:0]: EQ_RL override value - L3; [4]: EQ/PGA-RL override enable - L3

                W2BYTE(REG_PHY2P1_3_P0_18_L +u32PHY2P1BankOffset, 0x6666); // phy2p1_3_18[15:12][11:8][7:4][3:0] reg_gc_pga_rl_l0,l1,l2,l3

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);
            }
            break;

        case HDMI_CHANGE_PHY_H20_CASE0:
            MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H20 case0 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
            pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H20_CASE1;

            W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, BIT(7)| BIT(5), BIT(7)| BMASK(6:4));

            // case0 EQ setting
            W2BYTEMSK(REG_PHY2P1_2_P0_60_L +u32PHY2P1BankOffset, BIT(4)| 0x5, BIT(4)| BMASK(3:0)); // phy2p1_2_60[3:0]: EQ_RL override value - L0; [4]: EQ/PGA-RL override enable - L0
            W2BYTEMSK(REG_PHY2P1_2_P0_63_L +u32PHY2P1BankOffset, BIT(4)| 0x5, BIT(4)| BMASK(3:0)); // phy2p1_2_63[3:0]: EQ_RL override value - L1; [4]: EQ/PGA-RL override enable - L1
            W2BYTEMSK(REG_PHY2P1_2_P0_66_L +u32PHY2P1BankOffset, BIT(4)| 0x5, BIT(4)| BMASK(3:0)); // phy2p1_2_66[3:0]: EQ_RL override value - L2; [4]: EQ/PGA-RL override enable - L2
            W2BYTEMSK(REG_PHY2P1_2_P0_69_L +u32PHY2P1BankOffset, BIT(4)| 0x5, BIT(4)| BMASK(3:0)); // phy2p1_2_69[3:0]: EQ_RL override value - L3; [4]: EQ/PGA-RL override enable - L3

            W2BYTEMSK(REG_PHY2P1_3_P0_0C_L +u32PHY2P1BankOffset, BIT(15)| BIT(8), BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0C[0:2]: short EQ-RS_L0 OV; [3]: short EQ-RS_L0 OVE; [4:7]: EQ-RS1_L0 OV; [8]: EQ-RS1_L0 OVE; [15]: reg_gc_eqrs_l0_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0D_L +u32PHY2P1BankOffset, BIT(15)| BIT(8), BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0D[0:2]: short EQ-RS_L1 OV; [3]: short EQ-RS_L1 OVE; [4:7]: EQ-RS1_L1 OV; [8]: EQ-RS1_L1 OVE; [15]: reg_gc_eqrs_l1_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0E_L +u32PHY2P1BankOffset, BIT(15)| BIT(8), BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0E[0:2]: short EQ-RS_L2 OV; [3]: short EQ-RS_L2 OVE; [4:7]: EQ-RS1_L2 OV; [8]: EQ-RS1_L2 OVE; [15]: reg_gc_eqrs_l2_ov_en
            W2BYTEMSK(REG_PHY2P1_3_P0_0F_L +u32PHY2P1BankOffset, BIT(15)| BIT(8), BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0F[0:2]: short EQ-RS_L3 OV; [3]: short EQ-RS_L3 OVE; [4:7]: EQ-RS1_L3 OV; [8]: EQ-RS1_L3 OVE; [15]: reg_gc_eqrs_l3_ov_en

            break;

        case HDMI_CHANGE_PHY_H20_CASE1:
            {
                MS_U8 u8EQValue[4] = {8, 8, 8, 8};

                MHAL_HDMIRX_MSG_INFO("** HDMI change PHY H20 case1 port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_FINISH;

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                W2BYTEMSK(REG_PHY2P1_2_P0_26_L +u32PHY2P1BankOffset, BMASK(5:4), BIT(7)| BMASK(6:4));

                // disable case0 EQ setting
                W2BYTEMSK(REG_PHY2P1_2_P0_60_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_60[3:0]: EQ_RL override value - L0; [4]: EQ/PGA-RL override enable - L0
                W2BYTEMSK(REG_PHY2P1_2_P0_63_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_63[3:0]: EQ_RL override value - L1; [4]: EQ/PGA-RL override enable - L1
                W2BYTEMSK(REG_PHY2P1_2_P0_66_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_66[3:0]: EQ_RL override value - L2; [4]: EQ/PGA-RL override enable - L2
                W2BYTEMSK(REG_PHY2P1_2_P0_69_L +u32PHY2P1BankOffset, 0, BIT(4)| BMASK(3:0)); // phy2p1_2_69[3:0]: EQ_RL override value - L3; [4]: EQ/PGA-RL override enable - L3

                W2BYTEMSK(REG_PHY2P1_3_P0_0C_L +u32PHY2P1BankOffset, 0, BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0C[0:2]: short EQ-RS_L0 OV; [3]: short EQ-RS_L0 OVE; [4:7]: EQ-RS1_L0 OV; [8]: EQ-RS1_L0 OVE; [15]: reg_gc_eqrs_l0_ov_en
                W2BYTEMSK(REG_PHY2P1_3_P0_0D_L +u32PHY2P1BankOffset, 0, BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0D[0:2]: short EQ-RS_L0 OV; [3]: short EQ-RS_L0 OVE; [4:7]: EQ-RS1_L0 OV; [8]: EQ-RS1_L0 OVE; [15]: reg_gc_eqrs_l0_ov_en
                W2BYTEMSK(REG_PHY2P1_3_P0_0E_L +u32PHY2P1BankOffset, 0, BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0E[0:2]: short EQ-RS_L0 OV; [3]: short EQ-RS_L0 OVE; [4:7]: EQ-RS1_L0 OV; [8]: EQ-RS1_L0 OVE; [15]: reg_gc_eqrs_l0_ov_en
                W2BYTEMSK(REG_PHY2P1_3_P0_0F_L +u32PHY2P1BankOffset, 0, BIT(15)| BIT(8)| BMASK(7:4)); // phy2p1_3_0F[0:2]: short EQ-RS_L0 OV; [3]: short EQ-RS_L0 OVE; [4:7]: EQ-RS1_L0 OV; [8]: EQ-RS1_L0 OVE; [15]: reg_gc_eqrs_l0_ov_en
            }
            break;

        case HDMI_CHANGE_PHY_FINISH:
            pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_FINISH;
            bFinishFlag = TRUE;
            break;

        default:
            break;
    };

    return bFinishFlag;
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_FastTrainingProc()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_FastTrainingProc(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_BOOL bNextStateFlag = FALSE;
    MS_U16 u16temp = 2000;
    MS_U8 u8EQValue[8] = {0};
    stHDMI_ERROR_STATUS stErrorStatus = {0};
    MS_U8 u8Lane = 0;
    MS_U32 u32PHY2P1BankOffset = _Hal_tmds_GetPHY2P1BankOffset(enInputPortType);
    MS_U16 de_status, max_err, min_err;

    do
    {
        switch(pstHDMIPollingInfo->u8FastTrainingState)
        {
            case HDMI_FAST_TRAINING_START:
                pstHDMIPollingInfo->ucSourceVersion = HDMI_SOURCE_VERSION_NOT_SURE;
                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;

                bNextStateFlag = FALSE;
                break;

            case HDMI_FAST_TRAINING_SQUELCH: // HW detect
                if(_Hal_tmds_GetSquelchFlag(enInputPortType))
                {
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;

                    MHAL_HDMIRX_MSG_INFO("** HDMI get squelch port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                }

                bNextStateFlag = FALSE;
                break;

            case HDMI_FAST_TRAINING_CHECK_AUTO_EQ:
                {
                    MS_U8 u8ClockRange = _Hal_tmds_GetH14AutoEQEnable(enInputPortType, _Hal_tmds_GetClockRatePort(enInputPortType, pstHDMIPollingInfo->ucSourceVersion));

                    if(u8ClockRange == HDMI_14_TMDS_CLOCK_OVER_135M)
                    {
                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 OVER_135M enable auto EQ port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_ACTIVE_CABLE;
                    }
                    else if(u8ClockRange == HDMI_14_TMDS_CLOCK_75M_TO_135M)
                    {
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CLEAR_ERROR_H14_75M_TO_135M;
                        pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H14_75M_TO_135M_CASE0;
                        pstHDMIPollingInfo->u16CheckErrorCount = 0;

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 75M_TO_135M disable auto EQ port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else if (u8ClockRange == HDMI_14_TMDS_CLOCK_UNDER_75M)
                    {
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CLEAR_ERROR_H14_UNDER_75M;
                        pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_FINISH;
                        pstHDMIPollingInfo->u8RetriggerH14Under75M = 0;

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 UNDER_75M disable auto EQ port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }

                    bNextStateFlag = TRUE;
                }

                break;

            case HDMI_FAST_TRAINING_CHECK_ACTIVE_CABLE:
                if(_Hal_tmds_CheckActiveCableProc(enInputPortType, pstHDMIPollingInfo))
                {
                    if(!pstHDMIPollingInfo->bActiveCableFlag)
                    {
                        if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
                        {
                            pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_WAIT_EQ_FLOW_DONE_H14;
                            pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H14_CASE0;

                            for(u8Lane = 0; u8Lane < 4; u8Lane++)
                            {
                                pstHDMIPollingInfo->bEQError0[u8Lane] = FALSE;
                                pstHDMIPollingInfo->bEQError1[u8Lane] = FALSE;
                                pstHDMIPollingInfo->bEQError2[u8Lane] = FALSE;
                            }
                        }
                        else if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20)
                        {
                            pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_WAIT_EQ_FLOW_DONE_H20;
                            pstHDMIPollingInfo->u8ChangePHYCase = HDMI_CHANGE_PHY_H20_CASE0;
                        }

                        pstHDMIPollingInfo->u16CheckErrorCount = 0;
                        bNextStateFlag = FALSE;
                        if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
                        {
                            _Hal_tmds_ResetDLPF(enInputPortType); // reset DLPF before auto EQ re-triger

                            // Overwrite FSM
                            W2BYTE(REG_PHY2P1_0_P0_11_L +u32PHY2P1BankOffset, 0x0080);
                            W2BYTE(REG_PHY2P1_0_P0_12_L +u32PHY2P1BankOffset, 0x0080);
                            W2BYTE(REG_PHY2P1_0_P0_13_L +u32PHY2P1BankOffset, 0x0080);

                            W2BYTEMSK(REG_PHY2P1_0_P0_1B_L +u32PHY2P1BankOffset, 0x100, BMASK(11:8)); // reg_eq_trg_sw_0
                        }
                        else
                        {
                            _Hal_tmds_ResetDLPF(enInputPortType); // reset DLPF before auto EQ re-triger
                            _Hal_tmds_NewPHYAutoEQTrigger(enInputPortType, pstHDMIPollingInfo, BMASK(11:8));
                        }
                        W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0010, BMASK(7:4));

                        MHAL_HDMIRX_MSG_INFO("** HDMI not active cable port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else
                    {
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                        bNextStateFlag = TRUE;

                        MHAL_HDMIRX_MSG_INFO("** HDMI active cable port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                }
                else
                {
                    bNextStateFlag = FALSE;
                }

                break;

            case HDMI_FAST_TRAINING_WAIT_EQ_FLOW_DONE_H14:

#if 1 // trigger EQ only
                if((R2BYTE(REG_PHY2P1_0_P0_14_L +u32PHY2P1BankOffset) & 0xFF) == 0x80)
#else
                if(_Hal_tmds_GetEQFlowDoneFlag(enInputPortType, 0x1))
#endif
                {
                    _Hal_tmds_GetNewPHYEQValue(enInputPortType, u8EQValue);

                    MHAL_HDMIRX_MSG_INFO("** HDMI 14 EQ done value: L0/L1/L2/L3 Gray(Binary) = 0x%x(%d)/0x%x(%d)/0x%x(%d)/0x%x(%d), port %d\r\n", u8EQValue[0], u8EQValue[4], u8EQValue[1], u8EQValue[5], u8EQValue[2], u8EQValue[6], u8EQValue[3], u8EQValue[7], HDMI_GET_PORT_SELECT(enInputPortType));

                    pstHDMIPollingInfo->u8EQValue0[0] = u8EQValue[4];
                    pstHDMIPollingInfo->u8EQValue0[1] = u8EQValue[4];
                    pstHDMIPollingInfo->u8EQValue0[2] = u8EQValue[4];
                    pstHDMIPollingInfo->u8EQValue0[3] = u8EQValue[4];

                    pstHDMIPollingInfo->u8EQValue1[0] = ((pstHDMIPollingInfo->u8EQValue0[0] + 5) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[0] + 5);
                    pstHDMIPollingInfo->u8EQValue1[1] = ((pstHDMIPollingInfo->u8EQValue0[1] + 5) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[1] + 5);
                    pstHDMIPollingInfo->u8EQValue1[2] = ((pstHDMIPollingInfo->u8EQValue0[2] + 5) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[2] + 5);
                    pstHDMIPollingInfo->u8EQValue1[3] = ((pstHDMIPollingInfo->u8EQValue0[3] + 5) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[3] + 5);

                    pstHDMIPollingInfo->u8EQValue2[0] = ((pstHDMIPollingInfo->u8EQValue0[0] + 10) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[0] + 10);
                    pstHDMIPollingInfo->u8EQValue2[1] = ((pstHDMIPollingInfo->u8EQValue0[1] + 10) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[1] + 10);
                    pstHDMIPollingInfo->u8EQValue2[2] = ((pstHDMIPollingInfo->u8EQValue0[2] + 10) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[2] + 10);
                    pstHDMIPollingInfo->u8EQValue2[3] = ((pstHDMIPollingInfo->u8EQValue0[3] + 10) > 30)? 30: (pstHDMIPollingInfo->u8EQValue0[3] + 10);

                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CLEAR_ERROR_H14;
                    bNextStateFlag = TRUE;
                }
                else
                {
                    bNextStateFlag = FALSE;
                }
                break;

            case HDMI_FAST_TRAINING_CLEAR_ERROR_H14:
                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                MHAL_HDMIRX_MSG_INFO("** HDMI 14 clear EQ0 error status. EQ0(Binary) = %d/%d/%d/%d port %d\r\n", pstHDMIPollingInfo->u8EQValue0[0], pstHDMIPollingInfo->u8EQValue0[1], pstHDMIPollingInfo->u8EQValue0[2], pstHDMIPollingInfo->u8EQValue0[3], HDMI_GET_PORT_SELECT(enInputPortType));

                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_EQ0_H14;
                bNextStateFlag = FALSE;

                break;

            case HDMI_FAST_TRAINING_CHECK_EQ0_H14:
                if(!Hal_DVI_GetDEStableStatus(enInputPortType))
                {
                    pstHDMIPollingInfo->bEQError0[0] = TRUE;
                    pstHDMIPollingInfo->bEQError0[1] = TRUE;
                    pstHDMIPollingInfo->bEQError0[2] = TRUE;
                }
                else if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    if((stErrorStatus.u16DecodeErrorL0 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL0)
                    {
                        pstHDMIPollingInfo->bEQError0[0] = TRUE;
                    }
                    if((stErrorStatus.u16DecodeErrorL1 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL1)
                    {
                        pstHDMIPollingInfo->bEQError0[1] = TRUE;
                    }
                    if((stErrorStatus.u16DecodeErrorL2 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL2)
                    {
                        pstHDMIPollingInfo->bEQError0[2] = TRUE;
                    }
                }

#if(!HDMI_PHY_OLD_PATCH)
                for(u8Lane = 0; u8Lane < 4; u8Lane++)
                {
                    // set EQ0 (autoEQ value)
                    u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue0[u8Lane];
                }

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                pstHDMIPollingInfo->u8ClearErrorStatusCount = 1;

                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_STABLE_H14;
#else
                // set EQ1
                for(u8Lane = 0; u8Lane < 4; u8Lane++)
                {
                    u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue1[u8Lane];
                }

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }
                MHAL_HDMIRX_MSG_INFO("** HDMI 14 clear EQ1 error status. EQ1(Binary) = %d/%d/%d/%d port %d\r\n", pstHDMIPollingInfo->u8EQValue1[0], pstHDMIPollingInfo->u8EQValue1[1], pstHDMIPollingInfo->u8EQValue1[2], pstHDMIPollingInfo->u8EQValue1[3], HDMI_GET_PORT_SELECT(enInputPortType));

                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_EQ1_H14;
#endif
                bNextStateFlag = FALSE;

                break;

            case HDMI_FAST_TRAINING_CHECK_EQ1_H14:
                if(!Hal_DVI_GetDEStableStatus(enInputPortType))
                {
                    pstHDMIPollingInfo->bEQError1[0] = TRUE;
                    pstHDMIPollingInfo->bEQError1[1] = TRUE;
                    pstHDMIPollingInfo->bEQError1[2] = TRUE;
                }
                else if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    if((stErrorStatus.u16DecodeErrorL0 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL0)
                    {
                        pstHDMIPollingInfo->bEQError1[0] = TRUE;
                    }
                    if((stErrorStatus.u16DecodeErrorL1 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL1)
                    {
                        pstHDMIPollingInfo->bEQError1[1] = TRUE;
                    }
                    if((stErrorStatus.u16DecodeErrorL2 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL2)
                    {
                        pstHDMIPollingInfo->bEQError1[2] = TRUE;
                    }
                }

                // set EQ2
                for(u8Lane = 0; u8Lane < 4; u8Lane++)
                {
                    u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue2[u8Lane];
                }

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                MHAL_HDMIRX_MSG_INFO("** HDMI 14 clear EQ2 error status. EQ2(Binary) = %d/%d/%d/%d port %d\r\n", pstHDMIPollingInfo->u8EQValue2[0], pstHDMIPollingInfo->u8EQValue2[1], pstHDMIPollingInfo->u8EQValue2[2], pstHDMIPollingInfo->u8EQValue2[3], HDMI_GET_PORT_SELECT(enInputPortType));

                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_EQ2_H14;
                bNextStateFlag = FALSE;

                break;

            case HDMI_FAST_TRAINING_CHECK_EQ2_H14:
                if(!Hal_DVI_GetDEStableStatus(enInputPortType))
                {
                    pstHDMIPollingInfo->bEQError2[0] = TRUE;
                    pstHDMIPollingInfo->bEQError2[1] = TRUE;
                    pstHDMIPollingInfo->bEQError2[2] = TRUE;
                }
                else if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    if((stErrorStatus.u16DecodeErrorL0 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL0)
                    {
                        pstHDMIPollingInfo->bEQError2[0] = TRUE;
                    }
                    if((stErrorStatus.u16DecodeErrorL1 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL1)
                    {
                        pstHDMIPollingInfo->bEQError2[1] = TRUE;
                    }
                    if((stErrorStatus.u16DecodeErrorL2 > HDMI_DECODE_ERROR_THRESHOLD14) || stErrorStatus.bWordBoundaryErrorL2)
                    {
                        pstHDMIPollingInfo->bEQError2[2] = TRUE;
                    }
                }
                for(u8Lane = 0; u8Lane < 4; u8Lane++)
                {
                    if((!pstHDMIPollingInfo->bEQError0[u8Lane]) && (!pstHDMIPollingInfo->bEQError1[u8Lane]) && (!pstHDMIPollingInfo->bEQError2[u8Lane]))
                    {
                        // set EQ1 = EQ0 (autoEQ value) + 5
                        u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue1[u8Lane];

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d EQ0/1/2 no error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else if((!pstHDMIPollingInfo->bEQError0[u8Lane]) && (!pstHDMIPollingInfo->bEQError1[u8Lane]) && (pstHDMIPollingInfo->bEQError2[u8Lane]))
                    {
                        // set (EQ0 (autoEQ value) + EQ1) / 2
                        u8EQValue[u8Lane] = (pstHDMIPollingInfo->u8EQValue0[u8Lane] + pstHDMIPollingInfo->u8EQValue1[u8Lane]) / 2;

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d EQ0/1 no error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));

                    }
                    else if((pstHDMIPollingInfo->bEQError0[u8Lane]) && (!pstHDMIPollingInfo->bEQError1[u8Lane]) && (!pstHDMIPollingInfo->bEQError2[u8Lane]))
                    {
                        // set (EQ1 + EQ2) / 2
                        u8EQValue[u8Lane] = (pstHDMIPollingInfo->u8EQValue1[u8Lane] + pstHDMIPollingInfo->u8EQValue2[u8Lane]) / 2;

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d EQ1/2 no error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else if((!pstHDMIPollingInfo->bEQError0[u8Lane]) && (pstHDMIPollingInfo->bEQError1[u8Lane]) && (!pstHDMIPollingInfo->bEQError2[u8Lane]))
                    {
                        // set EQ0 (autoEQ value)
                        u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue0[u8Lane];

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d EQ0/2 no error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else if((!pstHDMIPollingInfo->bEQError0[u8Lane]) && (pstHDMIPollingInfo->bEQError1[u8Lane]) && (pstHDMIPollingInfo->bEQError2[u8Lane]))
                    {
                        // set EQ0 (autoEQ value)
                        u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue0[u8Lane];

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d EQ0 no error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else if((pstHDMIPollingInfo->bEQError0[u8Lane]) && (!pstHDMIPollingInfo->bEQError1[u8Lane]) && (pstHDMIPollingInfo->bEQError2[u8Lane]))
                    {
                        // set EQ1
                        u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue1[u8Lane];

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d EQ1 no error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else if((pstHDMIPollingInfo->bEQError0[u8Lane]) && (pstHDMIPollingInfo->bEQError1[u8Lane]) && (!pstHDMIPollingInfo->bEQError2[u8Lane]))
                    {
                        // set EQ2
                        u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue2[u8Lane];

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d EQ2 no error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                    else
                    {
                        // set EQ0 (autoEQ value)
                        u8EQValue[u8Lane] = pstHDMIPollingInfo->u8EQValue0[u8Lane];

                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 Lane%d error, select EQ(Binary) = %d port %d\r\n", u8Lane, u8EQValue[u8Lane], HDMI_GET_PORT_SELECT(enInputPortType));
                    }
                }

                _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8EQValue);

                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_STABLE_H14;
                bNextStateFlag = FALSE;

                break;

            case HDMI_FAST_TRAINING_CHECK_STABLE_H14:
                if(pstHDMIPollingInfo->u8ClearErrorStatusCount > 0)
                {
                    if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                    {
                        while(u16temp--);
                    }
                    pstHDMIPollingInfo->u8ClearErrorStatusCount--;
                    bNextStateFlag = FALSE;
                    break;
                }

                de_status = Hal_DVI_GetDEStableStatus(enInputPortType);
                if(de_status && !_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    if(pstHDMIPollingInfo->u16CheckErrorCount < TMDS_14_CHECK_ERROR_TIMES)
                    {
                        pstHDMIPollingInfo->u16CheckErrorCount++;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                        bNextStateFlag = TRUE;
                    }
                }
                else // DE unstable or BCH error
                {
                    MHAL_HDMIRX_MSG_INFO("** HDMI 14 error happened, DE status: %d, decode error: 0x%x, 0x%x, 0x%x port %d\r\n", de_status, stErrorStatus.u16DecodeErrorL0, stErrorStatus.u16DecodeErrorL1, stErrorStatus.u16DecodeErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    MHAL_HDMIRX_MSG_INFO("** HDMI 14 error happened, WB error: %d, %d, %d port %d\r\n", stErrorStatus.bWordBoundaryErrorL0, stErrorStatus.bWordBoundaryErrorL1, stErrorStatus.bWordBoundaryErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x4000, BIT(14));

                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_TRY_NEGATIVE_C_H14;
                    bNextStateFlag = TRUE;
                }
                break;

            case HDMI_FAST_TRAINING_TRY_NEGATIVE_C_H14:
                if (pstHDMIPollingInfo->u8TryNegativeC == 0)
                {
                    pstHDMIPollingInfo->u8TryNegativeC++;
                    W2BYTEMSK(REG_PHY2P1_2_P0_61_L +u32PHY2P1BankOffset, 0, BIT(0));
                    W2BYTEMSK(REG_PHY2P1_2_P0_64_L +u32PHY2P1BankOffset, 0, BIT(0));
                    W2BYTEMSK(REG_PHY2P1_2_P0_67_L +u32PHY2P1BankOffset, 0, BIT(0));
                    W2BYTEMSK(REG_PHY2P1_2_P0_6A_L +u32PHY2P1BankOffset, 0, BIT(0));

                    bNextStateFlag = FALSE; // wait 10ms
                }
                else if (pstHDMIPollingInfo->u8TryNegativeC == 1)
                {
                    pstHDMIPollingInfo->u8TryNegativeC++;
                    _Hal_tmds_SetNewPHYEQValue(enInputPortType, FALSE, NULL);

                    for(u8Lane = 0; u8Lane < 4; u8Lane++)
                    {
                        pstHDMIPollingInfo->bEQError0[u8Lane] = FALSE;
                        pstHDMIPollingInfo->bEQError1[u8Lane] = FALSE;
                        pstHDMIPollingInfo->bEQError2[u8Lane] = FALSE;
                    }

                    pstHDMIPollingInfo->u16CheckErrorCount = 0;

                    _Hal_tmds_ResetDLPF(enInputPortType); // reset DLPF before auto EQ re-triger

                    // Overwrite FSM
                    W2BYTE(REG_PHY2P1_0_P0_11_L +u32PHY2P1BankOffset, 0x0080);
                    W2BYTE(REG_PHY2P1_0_P0_12_L +u32PHY2P1BankOffset, 0x0080);
                    W2BYTE(REG_PHY2P1_0_P0_13_L +u32PHY2P1BankOffset, 0x0080);

                    W2BYTEMSK(REG_PHY2P1_0_P0_1B_L +u32PHY2P1BankOffset, 0x100, BMASK(11:8)); // reg_eq_trg_sw_0
                    W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0020, BMASK(7:4));

                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_WAIT_EQ_FLOW_DONE_H14;
                    bNextStateFlag = FALSE;
                }
                else
                { // Try Negative C still fail
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHANGE_PHY_H14;
                    bNextStateFlag = TRUE;
                }
                break;

            case HDMI_FAST_TRAINING_CHANGE_PHY_H14:
                if(_Hal_tmds_ChangePHYCase(enInputPortType, pstHDMIPollingInfo))
                {
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                    bNextStateFlag = TRUE;
                }
                else
                {
                    if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                    {
                        while(u16temp--);
                    }

                    pstHDMIPollingInfo->u16CheckErrorCount = 0;
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_STABLE_H14;

                    bNextStateFlag = FALSE;
                }

                break;

            case HDMI_FAST_TRAINING_CLEAR_ERROR_H14_75M_TO_135M:
                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                MHAL_HDMIRX_MSG_INFO("** HDMI 14 75M_TO_135M clear error status port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_STABLE_H14_75M_TO_135M;
                bNextStateFlag = FALSE;

                break;

            case HDMI_FAST_TRAINING_CHECK_STABLE_H14_75M_TO_135M:
                if(Hal_DVI_GetDEStableStatus(enInputPortType) &&
                    (!_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus)))
                {
                    if(pstHDMIPollingInfo->u16CheckErrorCount < TMDS_14_CHECK_ERROR_TIMES)
                    {
                        pstHDMIPollingInfo->u16CheckErrorCount++;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                        bNextStateFlag = TRUE;
                    }
                }
                else // DE unstable or BCH error
                {
                    MHAL_HDMIRX_MSG_INFO("** HDMI 14 75M_TO_135M error happened, decode error: 0x%x, 0x%x, 0x%x port %d\r\n", stErrorStatus.u16DecodeErrorL0, stErrorStatus.u16DecodeErrorL1, stErrorStatus.u16DecodeErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    MHAL_HDMIRX_MSG_INFO("** HDMI 14 75M_TO_135M error happened, WB error: %d, %d, %d port %d\r\n", stErrorStatus.bWordBoundaryErrorL0, stErrorStatus.bWordBoundaryErrorL1, stErrorStatus.bWordBoundaryErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x4000, BIT(14));

#if(!HDMI_PHY_OLD_PATCH)
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
#else
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHANGE_PHY_H14_75M_TO_135M;
#endif
                    bNextStateFlag = TRUE;
                }

                break;

            case HDMI_FAST_TRAINING_CHANGE_PHY_H14_75M_TO_135M:
                if(_Hal_tmds_ChangePHYCase(enInputPortType, pstHDMIPollingInfo))
                {
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                    bNextStateFlag = TRUE;
                }
                else
                {
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CLEAR_ERROR_H14_75M_TO_135M;

                    bNextStateFlag = FALSE;
                }

                break;

            case HDMI_FAST_TRAINING_CLEAR_ERROR_H14_UNDER_75M:
                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_STABLE_H14_UNDER_75M;
                pstHDMIPollingInfo->u16CheckErrorCount = 0;
                bNextStateFlag = FALSE;

                break;

            case HDMI_FAST_TRAINING_CHECK_STABLE_H14_UNDER_75M:
                de_status = Hal_DVI_GetDEStableStatus(enInputPortType);
                if(de_status && !_Hal_tmds_GetErrorCountStatus(enInputPortType, FALSE, &stErrorStatus))
                {
                    if(pstHDMIPollingInfo->u16CheckErrorCount < TMDS_14_CHECK_ERROR_TIMES)
                    {
                        pstHDMIPollingInfo->u16CheckErrorCount++;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 UNDER_75M check finish. retrigger %d, port %d\r\n", pstHDMIPollingInfo->u8RetriggerH14Under75M, HDMI_GET_PORT_SELECT(enInputPortType));
                        W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                        bNextStateFlag = TRUE;
                    }
                }
                else // DE unstable or BCH error
                {
                    W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x4000, BIT(14));

                    if (stErrorStatus.u16DecodeErrorL0 > stErrorStatus.u16DecodeErrorL1)
                    {
                        max_err = stErrorStatus.u16DecodeErrorL0;
                        min_err = stErrorStatus.u16DecodeErrorL1;
                    }
                    else
                    {
                        max_err = stErrorStatus.u16DecodeErrorL1;
                        min_err = stErrorStatus.u16DecodeErrorL0;
                    }
                    if (max_err > stErrorStatus.u16DecodeErrorL2)
                    {
                        if (stErrorStatus.u16DecodeErrorL2 < min_err)
                        {
                            min_err = stErrorStatus.u16DecodeErrorL2;
                        }
                    }
                    else
                    {
                        max_err = stErrorStatus.u16DecodeErrorL2;
                    }

                    if ((pstHDMIPollingInfo->u8RetriggerH14Under75M < TMDS_14_RETRIG_UNDER_75M_TIMES) && ((max_err - min_err) < 50))
                    {
                        pstHDMIPollingInfo->u8RetriggerH14Under75M++;
                        _Hal_tmds_Toggle2XMode(enInputPortType);
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CLEAR_ERROR_H14_UNDER_75M;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        MHAL_HDMIRX_MSG_INFO("** HDMI 14 UNDER_75M retrigger stop %d. 0x%x, 0x%x, 0x%x port %d\r\n", pstHDMIPollingInfo->u8RetriggerH14Under75M, stErrorStatus.u16DecodeErrorL0, stErrorStatus.u16DecodeErrorL1, stErrorStatus.u16DecodeErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                        bNextStateFlag = TRUE;
                    }
                }

                break;

            case HDMI_FAST_TRAINING_WAIT_EQ_FLOW_DONE_H20:
                if(_Hal_tmds_GetEQFlowDoneFlag(enInputPortType, 0x7))
                {
                    _Hal_tmds_GetNewPHYEQValue(enInputPortType, u8EQValue);
                    MHAL_HDMIRX_MSG_INFO("** HDMI 20 EQ done value: L0/L1/L2/L3 Gray(Binary) = 0x%x(%d)/0x%x(%d)/0x%x(%d)/0x%x(%d), port %d\r\n", u8EQValue[0], u8EQValue[4], u8EQValue[1], u8EQValue[5], u8EQValue[2], u8EQValue[6], u8EQValue[3], u8EQValue[7], HDMI_GET_PORT_SELECT(enInputPortType));

#if (PGA_PATCH_BY_SW)
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FORCE_PGA_PATCH_H20;
#else
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CLEAR_ERROR_H20;
                    pstHDMIPollingInfo->u8ClearErrorStatusCount = 0;
#endif
                    bNextStateFlag = TRUE;
                }
                else
                {
                    bNextStateFlag = FALSE;
                }
                break;

            case HDMI_FAST_TRAINING_FORCE_PGA_PATCH_H20:
                _Hal_tmds_ForcePGAPatchProc(enInputPortType);
                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CLEAR_ERROR_H20;
                pstHDMIPollingInfo->u8ClearErrorStatusCount = 0;
                bNextStateFlag = TRUE;
                break;

            case HDMI_FAST_TRAINING_CLEAR_ERROR_H20:
                if(_Hal_tmds_GetErrorCountStatus(enInputPortType, TRUE, &stErrorStatus))
                {
                    while(u16temp--);
                }

                if(pstHDMIPollingInfo->u8ClearErrorStatusCount < TMDS_CLEAR_ERROR_STATUS_COUNT)
                {
                    pstHDMIPollingInfo->u8ClearErrorStatusCount++;
                    bNextStateFlag = FALSE;
                }
                else
                {
                    MHAL_HDMIRX_MSG_INFO("** HDMI 20 clear error status port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));

                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHECK_STABLE_H20;
                    bNextStateFlag = TRUE;
                }
                break;

            case HDMI_FAST_TRAINING_CHECK_STABLE_H20:
                de_status = Hal_DVI_GetDEStableStatus(enInputPortType);
                if(de_status && !_Hal_tmds_GetErrorCountStatus(enInputPortType, TRUE, &stErrorStatus))
                {
                    if(pstHDMIPollingInfo->u16CheckErrorCount < TMDS_20_CHECK_ERROR_TIMES)
                    {
                        pstHDMIPollingInfo->u16CheckErrorCount++;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                        W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x0000, BIT(14));
                        bNextStateFlag = TRUE;
                    }
                }
                else // DE unstable or BCH error
                {
                    MHAL_HDMIRX_MSG_INFO("** HDMI 20 error happened, DE: %d, decode error: 0x%x, 0x%x, 0x%x port %d\r\n", de_status, stErrorStatus.u16DecodeErrorL0, stErrorStatus.u16DecodeErrorL1, stErrorStatus.u16DecodeErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    MHAL_HDMIRX_MSG_INFO("** HDMI 20 error happened, WB error: %d, %d, %d port %d\r\n", stErrorStatus.bWordBoundaryErrorL0, stErrorStatus.bWordBoundaryErrorL1, stErrorStatus.bWordBoundaryErrorL2, HDMI_GET_PORT_SELECT(enInputPortType));
                    W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x4000, BIT(14));

#if(!HDMI_PHY_OLD_PATCH)
                    if(pstHDMIPollingInfo->u8RetriggerCount20 < TMDS_20_RETRIGGER_TIMES)
                    {
                        pstHDMIPollingInfo->u8RetriggerCount20++;

                        _Hal_tmds_ResetDLPF(enInputPortType); // reset DLPF before auto EQ re-triger
                        _Hal_tmds_NewPHYAutoEQTrigger(enInputPortType, pstHDMIPollingInfo, BMASK(11:8));
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_WAIT_EQ_FLOW_DONE_H20;
                        pstHDMIPollingInfo->u16CheckErrorCount = 0;
                        bNextStateFlag = FALSE;
                    }
                    else
                    {
                        pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_FINISH;
                        bNextStateFlag = TRUE;
                    }
#else
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_CHANGE_PHY_H20;
                    bNextStateFlag = TRUE;
#endif
                }
                break;

            case HDMI_FAST_TRAINING_CHANGE_PHY_H20:
                if(_Hal_tmds_ChangePHYCase(enInputPortType, pstHDMIPollingInfo))
                {
                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_NONE;
                    bNextStateFlag = FALSE;
                }
                else
                {
                    _Hal_tmds_NewPHYAutoEQTrigger(enInputPortType, pstHDMIPollingInfo, BMASK(11:8));

                    pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_WAIT_EQ_FLOW_DONE_H20;
                    bNextStateFlag = FALSE;
                }

                break;

            case HDMI_FAST_TRAINING_FINISH:
                _Hal_tmds_GetNewPHYEQValue(enInputPortType, u8EQValue);
                MHAL_HDMIRX_MSG_INFO("** HDMI SW patch finish. EQ value: L0/L1/L2/L3 Gray(Binary) = 0x%x(%d)/0x%x(%d)/0x%x(%d)/0x%x(%d), port %d\r\n", u8EQValue[0], u8EQValue[4], u8EQValue[1], u8EQValue[5], u8EQValue[2], u8EQValue[6], u8EQValue[3], u8EQValue[7], HDMI_GET_PORT_SELECT(enInputPortType));
                W2BYTEMSK(REG_PHY2P1_1_P0_35_L +u32PHY2P1BankOffset, 0x8000, BIT(15));

                _Hal_tmds_CheckTxDcBalanceEn(enInputPortType, TRUE);
                pstHDMIPollingInfo->u8FastTrainingState = HDMI_FAST_TRAINING_STOP;
                bNextStateFlag = FALSE;

                break;

            case HDMI_FAST_TRAINING_NONE:
                bNextStateFlag = FALSE;

                break;

            default:
                bNextStateFlag = FALSE;
                break;
        }
    }while(bNextStateFlag);
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_HDCP22_SetReAuthBit()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_HDCP22_SetReAuthBit(MS_U8 ucPortIdx, MS_BOOL bEnReAuth)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    if (bEnReAuth == TRUE)
    {
        W2BYTEMSK(REG_HDCP_DUAL_P0_65_L + u32DTOPBankOffset, BIT(10), BIT(10)); // hdmirx_hdcp_65[10]: reg_reauth_ov_en
        W2BYTEMSK(REG_HDCP_DUAL_P0_65_L + u32DTOPBankOffset, BIT(11), BIT(11)); // hdmirx_hdcp_65[11]: reg_reauth_ov_value
        W2BYTEMSK(REG_HDCP_DUAL_P0_65_L + u32DTOPBankOffset, 0x00, BIT(10)); // hdmirx_hdcp_65[10]: reg_reauth_ov_en
    }
    else
    {
        W2BYTEMSK(REG_HDCP_DUAL_P0_65_L + u32DTOPBankOffset, BIT(12), BIT(12)); // hdmirx_hdcp_65[12]: reg_reauth_clr
    }
}
MS_U8 _Hal_HDMI_GetPacketHdmiPortSelect(void)
{
//return select-port number 0~3
//XC Register "reg_xc2hd_port_sel" : 0x33df_18[3:2]

return (MS_U8)((R2BYTE(0x33df30)&(BIT(3)|BIT(2))) >>2);
}


#if(HDMI_CHIP_VERIFY_REPEATER)
//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_HDCPWriteX74()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_HDCPWriteX74(E_MUX_INPUTPORT enInputPortType, MS_U8 ucAddress, MS_U8 ucLength, MS_U8 *ucData)
{
    MS_U8 uctemp = 0;
    MS_U16 delay = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(ucData != NULL)
    {
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, BIT(10), BIT(10)); // [10]: HDCP enable for DDC
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(15), BIT(15)|BIT(14)); // [15]: CPU write enable, [14]: 0: 74 RAM, 1 :HDCP RAM

        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, ucAddress, BMASK(9:0)); // address
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(5), BIT(5)); // trigger latch address

        for(uctemp = 0; uctemp < ucLength; uctemp++)
        {
            HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_18_L +u32DTOPBankOffset, ucData[uctemp], BMASK(7:0)); // data
            HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(4), BIT(4)); // trigger latch data

            delay = PM_R2BYTE(TIMER_0_CNT_REG, BMASK(15:0));
            while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(7)); // wait write ready
        }

        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, 0, BIT(15)|BIT(14)); // [15]: CPU write disable, [14]: 0: 74 RAM, 1 :HDCP RAM
    }
}

//**************************************************************************
//  [Function Name]:
//                  _Hal_tmds_HDCPVerifyProc()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void _Hal_tmds_HDCPVerifyProc(void)
{
    MS_U8 uctemp = 0;
    MS_U8 ucBuffer[30] = {0};
    E_MUX_INPUTPORT enPortIndex = INPUT_PORT_DVI0;

    // Test V prime 0x20~0x33
    for(uctemp = 0; uctemp < 19; uctemp++)
    {
        ucBuffer[uctemp] = (uctemp *uctemp) %100 +1;
    }

    for(enPortIndex = INPUT_PORT_DVI0; enPortIndex <= INPUT_PORT_DVI_END; enPortIndex++)
    {
        _Hal_tmds_HDCPWriteX74(enPortIndex, 0x20, 19, ucBuffer);
    }

    // Test Bcaps/Bstatus
    ucBuffer[0] = 0xC0;
    ucBuffer[1] = 0xFF;
    ucBuffer[2] = 0xFF;

    for(enPortIndex = INPUT_PORT_DVI0; enPortIndex <= INPUT_PORT_DVI_END; enPortIndex++)
    {
        _Hal_tmds_HDCPWriteX74(enPortIndex, 0x40, 3, ucBuffer);
    }

    // Test Ksv FIFO
    for(uctemp = 0; uctemp < 19; uctemp++)
    {
        ucBuffer[uctemp] = 100 -(uctemp *uctemp) %100;
    }

    for(enPortIndex = INPUT_PORT_DVI0; enPortIndex <= INPUT_PORT_DVI_END; enPortIndex++)
    {
        Hal_HDCP_WriteKSVList(enPortIndex, ucBuffer, 19);
    }

    MHAL_HDMIRX_MSG_INFO("[%s][%d]End!\n", __FUNCTION__, __LINE__);
}

#endif

//****************************************************************
// Initial HDCP22 relative register, structure...etc
//****************************************************************

void Hal_HDCP22_SetReadyBit(MS_U8 ucPortIdx, MS_BOOL bIsReady)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    W2BYTEMSK(REG_HDCP_DUAL_P0_62_L +u32DTOPBankOffset, (bIsReady ? BIT(7) : BIT(6)), BIT(7)|BIT(6)); // hdmirx_hdcp_62[6]: reg_hdcp_v22_clr; [7]: reg_hdcp_v22_ready
}

void Hal_HDCP22_PortInit(MS_U8 ucPortIdx)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    MHAL_HDMIRX_MSG_INFO("[HDCP22] PortInit(), port idx = %d\r\n", ucPortIdx);

    W2BYTEMSK(REG_COMBO_GP_TOP_40_L, 0x05, 0x07); // [2]: Enable CPU write; [1]: disable SRAM read; [0]: enable xiu2hdcpkey

    //wirte 74Ram for HDCP22 version
    W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, BIT(10), BIT(10)); //HDCP enalbe for DDC
    W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(15), BMASK(15:14)); //write enable

    W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, 0x50, BMASK(9:0)); //CPU r/w address
    W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(5), BIT(5)); //HDCP load address pulse

    W2BYTEMSK(REG_HDCP_DUAL_P0_18_L +u32DTOPBankOffset, 0x04, BMASK(7:0)); //bit2: HDCP22 version
    W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(4), BIT(4)); //HDCP data write port pulse generate

    //clear RxStatus
    W2BYTEMSK(REG_HDCP_DUAL_P0_63_L +u32DTOPBankOffset, 0x00, BMASK(9:0));
    W2BYTEMSK(REG_HDCP_DUAL_P0_64_L +u32DTOPBankOffset, BIT(15), BIT(15));

    //clear hdcp_enable cipher bit
    //W2BYTEMSK(REG_HDCP_DUAL_P0_4E_L +u32DTOPBankOffset, 0, BIT(0));

    //clear xiu status
    W2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset, 0x7D);
    W2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset, 0x00);

    //Enable write offset
    W2BYTEMSK(REG_HDCP_DUAL_P0_68_L +u32DTOPBankOffset, BIT(15)| TMDS_HDCP2_SOURCE_READ_OFFSET, BIT(15)| BMASK(9:0)); //b'[0..9]offset; b'[15]: enable bit
}

//****************************************************************
// Check If there is R0 read;
// @param ucPortIdx    [IN] HDMI port index
//****************************************************************
MS_BOOL Hal_HDCP14_PollingR0ReadDone(MS_U8 ucPortIdx)
{
    MS_BOOL bR0ReadDoneFlag = FALSE;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    if(R2BYTE(REG_HDCP_DUAL_P0_01_L + u32DTOPBankOffset) & BIT(12)) //check R0 done
    {
        //clear status
        W2BYTE(REG_HDCP_DUAL_P0_01_L + u32DTOPBankOffset,BIT(12)); //clear write done, write start
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3C_L + u32DTOPBankOffset, BIT(14));
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3C_L + u32DTOPBankOffset, 0);

        bR0ReadDoneFlag = TRUE;
    }

    return bR0ReadDoneFlag;
}

//****************************************************************
// Check If there is any message received;
// @param ucPortIdx    [IN] HDMI port index
//****************************************************************
MS_BOOL Hal_HDCP22_PollingWriteDone(MS_U8 ucPortIdx)
{
    MS_BOOL bWriteDoneFlag = FALSE;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    if(R2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset) & BIT(2)) // hdmirx_hdcp_66[2]: reg_hdcp_v22_interrupt_status - ack_message_write_done
    {
        // clear write done, write start
        W2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset, BIT(4)| BIT(2)); // hdmirx_hdcp_66[2]: ack_message_write_done; [4]: ack_message_write_start  (write 1 clear)
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3C_L +u32DTOPBankOffset, BIT(14)); // hdmirx_dtop_3C[14]: reg_adcdvi_irq_clr_6
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3C_L +u32DTOPBankOffset, 0);

        bWriteDoneFlag = TRUE;
    }

    return bWriteDoneFlag;
}

//****************************************************************
// Check If Tx already finish its read process
// @param ucPortIdx    [IN] HDMI port index
//****************************************************************
MS_BOOL Hal_HDCP22_PollingReadDone(MS_U8 ucPortIdx)
{
    MS_BOOL bReadDoneFlag = FALSE;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    if(R2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset) & BIT(3)) // hdmirx_hdcp_66[3]: reg_hdcp_v22_interrupt_status - ack_message_read_done
    {
        // clear read done
        W2BYTE(REG_HDCP_DUAL_P0_66_L +u32DTOPBankOffset, BIT(3)); // hdmirx_hdcp_66[3]: reg_hdcp_v22_interrupt_status - ack_message_read_done
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3C_L +u32DTOPBankOffset, BIT(14)); // hdmirx_dtop_3C[14]: reg_adcdvi_irq_clr_6
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3C_L +u32DTOPBankOffset, 0);

        bReadDoneFlag = TRUE;
    }

    return bReadDoneFlag;
}

//****************************************************************
// Enable or Disable Cipher process
// @param ucPortType    [IN] HDCP type, ex: HDMI or Miracast
// @param ucPortIdx    [IN] HDMI port index
// @param bIsEnable    [IN] Enable/Disable Cipher
//****************************************************************
void Hal_HDCP22_EnableCipher(MS_U8 UNUSED_PARA(ucPortType), MS_U8 UNUSED_PARA(ucPortIdx), MS_BOOL bIsEnable)
{
    //MS_U32 dwBKOffset = 0;

    MHAL_HDMIRX_MSG_INFO("[HDCP22] EnableCipher(), isEnable = %d\r\n", bIsEnable);

    //dwBKOffset = (ucPortIdx * 0x300);

    //W2BYTEMSK(REG_HDCP_DUAL_P0_4E_L + dwBKOffset, bIsEnable? BIT(0): 0, BIT(0));
}

//****************************************************************
// Fetch message content
// @param ucPortIdx    [IN] HDMI port index
// @param pucRiv    [IN] Data pointer of riv
// @param pucSessionKey    [IN] Data pointer of ks^LC128
//****************************************************************
void Hal_HDCP22_FillCipherKey(MS_U8 ucPortIdx, MS_U8 *pucSessionKey, MS_U8 *pucRiv)
{
#define EN_DBG_CIPHER_KEY 0
    MS_U8 uctemp = 0;
    MS_U8 ucRegOffset = 0;
    //MS_U32 dwBKOffset = 0;

    MHAL_HDMIRX_MSG_INFO("[HDCP22] FillCipherKey\r\n");

    if(ucPortIdx < 10) //to avoid overflow a byte size after multiple with 0x0C
    {
        ucRegOffset = ucPortIdx * 0x18;
        //dwBKOffset = ucPortIdx * 0x300;

        //fill riv: size 8 bytes
#if (EN_DBG_CIPHER_KEY == 1)
        MHAL_HDMIRX_MSG_DEBUG("\r\n[HDCP22]Riv\r\n");
#endif

        for(uctemp = 0; uctemp < 8; uctemp++)
        {
            W2BYTEMSK(REG_SECURE_TZPC_38_L + ucRegOffset + 8 - uctemp - 1, *(MS_U8*)(pucRiv + uctemp), BMASK(7:0));

#if (EN_DBG_CIPHER_KEY == 1)
            MHAL_HDMIRX_MSG_DEBUG("0x%02X : ", *(MS_U8*)(pucRiv + uctemp));
            MHAL_HDMIRX_MSG_DEBUG("(0x%x)0x%02X\r\n", REG_SECURE_TZPC_38_L + ucRegOffset + 8 - uctemp - 1, MDrv_ReadByte(REG_SECURE_TZPC_38_L + ucRegOffset + 8 - uctemp - 1));
#endif
        }

        //fill ks^LC128: size 16 bytes
#if (EN_DBG_CIPHER_KEY == 1)
        MHAL_HDMIRX_MSG_DEBUG("\r\n[HDCP22]SessionKey\r\n");
#endif

        for(uctemp = 0; uctemp < 16; uctemp++)
        {
            W2BYTEMSK(REG_SECURE_TZPC_30_L + ucRegOffset + 16 - uctemp - 1, *(MS_U8*)(pucSessionKey + uctemp), BMASK(7:0));

#if (EN_DBG_CIPHER_KEY == 1)
            MHAL_HDMIRX_MSG_DEBUG("0x%02X : ", *(MS_U8*)(pucSessionKey + uctemp));
            MHAL_HDMIRX_MSG_DEBUG("(0x%x)0x%02X\r\n", REG_SECURE_TZPC_30_L + ucRegOffset + 16 - uctemp - 1, MDrv_ReadByte(REG_SECURE_TZPC_30_L + ucRegOffset + 16 - uctemp - 1));
#endif
        }

        //enable cipher
        MHAL_HDMIRX_MSG_INFO("\r\n[HDCP22]Enable Cipher\r\n");

        //W2BYTEMSK(REG_HDCP_DUAL_P0_4E_L + dwBKOffset, BIT(0), BIT(0));
    }
    else
    {
        MHAL_HDMIRX_MSG_INFO("[HDCP22]Hal_HDCP22_FillCipherKey:: Invalid Port Index!!\r\n");
    }

#undef EN_DBG_CIPHER_KEY
}

//****************************************************************
// Fetch message content
// @param ucPortIdx    [IN] HDMI port index
// @param pucData    [IN] Data pointer to store received message
// @param dwDataLen    [IN] message length
//****************************************************************
void Hal_HDCP22_FetchMsg(MS_U8 ucPortIdx, MS_U8* pucData, MS_U32 dwDataLen)
{
    MS_U8 ucRegOffset = ( ucPortIdx * 4 );
    MS_U32 ultemp = 0;

    W2BYTEMSK(REG_COMBO_GP_TOP_40_L, BIT(0), BMASK(2:0)); //enable XIU read
    W2BYTEMSK(REG_HDCPKEY_04_L + ucRegOffset, 0x00, BMASK(9:0)); //start addr

    for(ultemp = 0; ultemp < dwDataLen; ultemp++)
    {
        *(pucData + ultemp) = (R2BYTE(REG_HDCPKEY_0E_L + 2*(ucRegOffset/0x04)) & BMASK(7:0));
    }
}

//****************************************************************
// Receive message and transmitt message to TEE
// @param ucPortIdx    [IN] HDMI port index
//****************************************************************
MS_BOOL Hal_HDCP22_RecvMsg(MS_U8 ucPortIdx, MS_U8 *ucMsgData)
{
    MS_BOOL bReceiveFlag = FALSE;
    MS_U16 ustemp = 0;
    MS_U32 dwMsgLen = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    if(Hal_HDCP22_PollingReadDone(ucPortIdx))
    {
        // Do nothing
    }

    //fetch msg length
    dwMsgLen = R2BYTE(REG_HDCP_DUAL_P0_64_L +u32DTOPBankOffset) & BMASK(9:0);

    if(dwMsgLen != 0x00)
    {
        //clear length
        W2BYTEMSK(REG_HDCP_DUAL_P0_63_L +u32DTOPBankOffset, 0x00, 0x7FF); // write length
        W2BYTEMSK(REG_HDCP_DUAL_P0_64_L +u32DTOPBankOffset, BIT(15), BIT(15)); // address pulse

        //allocate and init buffer
        for(ustemp = 0; ustemp < HDMI_HDCP22_MESSAGE_LENGTH; ustemp++)
        {
            ucMsgData[ustemp] = 0x00;
        }

        ucMsgData[HDMI_HDCP22_MESSAGE_LENGTH] = dwMsgLen;

        //fetch msg
        Hal_HDCP22_FetchMsg(ucPortIdx, ucMsgData, dwMsgLen);

        //MHAL_HDMIRX_MSG_INFO("[HDCP22] PrtIdx = %d, msgID = 0x%x, len= %td\r\n", ucPortIdx, ucMsgData[0],(ptrdiff_t) dwMsgLen);

        bReceiveFlag = TRUE;
    }

    return bReceiveFlag;
}

//****************************************************************
// Sending message back to TX
// @param ucPortType    [IN] HDCP type, ex: HDMI or Miracast
// @param ucPortIdx    [IN] HDMI port index
// @param pucData    [IN] received message from HDMI port
// @param dwDataLen    [IN] message lenght
// @param pDummy    [IN] dummy pointer for API layer structure
//****************************************************************
void Hal_HDCP22_SendMsg(MS_U8 ucPortType, MS_U8 ucPortIdx, MS_U8* pucData, MS_U32 dwDataLen, void* pDummy, MS_U8* ubRecIDListSetDone)
{
    MS_U8 ucRegOffset = 0;
    MS_U32 ultemp = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucPortIdx));

    //MHAL_HDMIRX_MSG_INFO("[HDCP22] Send, PrtIdx = %d\r\n", ucPortIdx);
    ucRegOffset = ucPortIdx * 0x04;

    if( (*(pucData) == 0x0C) || (*(pucData) == 0x07) )
    {
        //W2BYTE(REG_HDCP_DUAL_P0_66_L + dwBKOffset, BIT(3)); //clear read done
        if(Hal_HDCP22_PollingReadDone(ucPortIdx))
        {
            // Do nothing
        }
    }

    if (*(MS_U8*)(pucData) == 0x15)
    {
        //set rxstatus
        if (dwDataLen >= 0x03) //avoid invalid memory address access
        {
            Hal_HDCP22_SetReadyBit(ucPortIdx, (*(pucData + 1) == 0x01) ? TRUE : FALSE); // 1st byte: READY bit
            _Hal_HDCP22_SetReAuthBit(ucPortIdx, (*(pucData + 2) == 0x01) ? TRUE : FALSE); // 2nd byte: re-auth bit
        }
    }
    else
    {
        if (*(MS_U8*)(pucData) == 0xC) //RepeaterAuth_Send_ReceiverID_List
        {
            *ubRecIDListSetDone = TRUE;
        }

        W2BYTEMSK(REG_COMBO_GP_TOP_40_L, BIT(2)| BIT(0), BMASK(2:0)); //enable XIU write

        for(ultemp = 0; ultemp < dwDataLen; ultemp++)
        {
            W2BYTEMSK(REG_HDCPKEY_04_L + ucRegOffset, ultemp +TMDS_HDCP2_SOURCE_READ_OFFSET, 0x7FF); //set address
            W2BYTEMSK(REG_HDCPKEY_05_L + ucRegOffset, *(pucData + ultemp), BMASK(7:0));
            W2BYTEMSK(REG_HDCPKEY_04_L + ucRegOffset, ultemp +TMDS_HDCP2_SOURCE_READ_OFFSET, 0x7FF); //set address

            while((R2BYTE(REG_HDCPKEY_0E_L + ucPortIdx * 0x02) &BMASK(7:0)) != *(pucData + ultemp))
            {
                //Wilson: retry, software patch for XIU write fail issue;
                W2BYTEMSK(REG_HDCPKEY_04_L + ucRegOffset, ultemp +TMDS_HDCP2_SOURCE_READ_OFFSET, 0x7FF); //set address
                W2BYTEMSK(REG_HDCPKEY_05_L + ucRegOffset, *(pucData + ultemp), BMASK(7:0));
                W2BYTEMSK(REG_HDCPKEY_04_L + ucRegOffset, ultemp +TMDS_HDCP2_SOURCE_READ_OFFSET, 0x7FF); //set address
            }
        }

        W2BYTEMSK(REG_HDCP_DUAL_P0_63_L +u32DTOPBankOffset, dwDataLen, 0x7FF); // write length

        //patch for CTS
        if(*(pucData) == 0x03) //AKE_Send_Cert
        {
            //MHAL_HDMIRX_MSG_INFO("[HDCP22] check DDC free!!\r\n");

            while((R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(10))); //polling DDC free
        }

        W2BYTEMSK(REG_HDCP_DUAL_P0_64_L +u32DTOPBankOffset, BIT(15), BIT(15)); // address pulse
    }
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_GetAuthVersion()
//  [Description]
//                  Get HDCP authentication version
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
E_HDMI_HDCP_STATE Hal_HDCP_GetAuthVersion(E_MUX_INPUTPORT enInputPortType, MS_BOOL bSetFlag)
{
    MS_BOOL bFlag = FALSE;
    MS_U8 ucAuthVersion = E_HDCP_NO_ENCRYPTION;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(!bSetFlag)
    {
        bFlag = TRUE;
    }
    else if(R2BYTE(REG_HDCP_DUAL_P0_66_L + u32DTOPBankOffset) & BIT(6)) // reg_hdcp_v22_interrupt_status[6]: HDCP2.2 version interrupt
    {
        ucAuthVersion= E_HDCP_2_2;
        bFlag = TRUE;
    }

    if(bFlag)
    {
        W2BYTEMSK(REG_HDCP_DUAL_P0_66_L + u32DTOPBankOffset, BIT(6), BIT(6)); // reg_hdcp_v22_interrupt_status[6]: HDCP2.2 version interrupt
    }

    return (E_HDMI_HDCP_STATE)ucAuthVersion;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_GetEncryptionFlag()
//  [Description]
//                  Get input is encryption or not
//  [Arguments]:
//
//  [Return]:
//                 TRUE: encryption, FALSE: no encryption
//**************************************************************************
MS_BOOL Hal_HDCP_GetEncryptionFlag(E_MUX_INPUTPORT enInputPortType)
{
    MS_BOOL bEncryptionFlag = FALSE;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(R2BYTE(REG_HDCP_DUAL_P0_1B_L +u32DTOPBankOffset) & BIT(9)) // hdmirx_hdcp_1B[9]: reg_enc_en_status
    {
        bEncryptionFlag = TRUE;

        W2BYTE(REG_HDCP_DUAL_P0_1B_L +u32DTOPBankOffset, BIT(9)); // hdmirx_hdcp_1B[9]: reg_enc_en_status (write 1 clear)
    }

    return bEncryptionFlag;
}

//=========================================================//
// Function : Hal_HDMI_Func_Caps
// Description: report which patch function hdmi needs
//=========================================================//
MS_U16 Hal_HDMI_Func_Caps(void)
{
    return 0;
}

/******************************************************************************/
/// for HDCP
/******************************************************************************/
//=========================================================//
// Function : Hal_HDCP_clearflag
// Description: clear hdcp status, must during hpd low
//=========================================================//
void Hal_HDCP_clearflag(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    W2BYTE(REG_HDCP_DUAL_P0_01_L +u32DTOPBankOffset, 0xFF00); // hdmirx_hdcp_01
}

//=========================================================//
// Function : Hal_HDCP_getstatus
// Description: get HDCP status
//=========================================================//
MS_U16 Hal_HDCP_getstatus(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    return R2BYTE(REG_HDCP_DUAL_P0_01_L +u32DTOPBankOffset); // hdmirx_hdcp_01
}

/******************************************************************************/
/// for HDMI
/******************************************************************************/
//=========================================================//
// Function : Hal_HDMI_pullhpd
// Description: Pull DVI Hot-Plug-Detection pin
//=========================================================//
void Hal_HDMI_pullhpd(MS_BOOL bHighLow, E_MUX_INPUTPORT enInputPortType, MS_BOOL bInverse, MS_U8 ucMHLSupportPath)
{
    if(!bInverse)
    {
        switch(enInputPortType)
        {
            case INPUT_PORT_DVI0:
                PM_W2BYTE(REG_PM_SCDC_P0_0C_L, BIT(5), BIT(5)|BIT(4)); // scdc_0C[4]: reg_tx_5v_reset_i; [5]: reg_tx_5v_reset_oen
                PM_W2BYTE(REG_PM_SLEEP_36_L, bHighLow ? BIT(12) : 0, BIT(12)); // pm_sleep_36[12]: reg_pad_pu1k (PAD_HOTPLUGA)
                break;

            case INPUT_PORT_DVI1:
                PM_W2BYTE(REG_PM_SCDC_P1_0C_L, BIT(5), BIT(5)|BIT(4)); // scdc_0C[4]: reg_tx_5v_reset_i; [5]: reg_tx_5v_reset_oen
                PM_W2BYTE(REG_PM_SLEEP_36_L, bHighLow ? BIT(13) : 0, BIT(13)); // pm_sleep_36[13]: reg_pad_pu1k (PAD_HOTPLUGB)
                break;

            case INPUT_PORT_DVI2:
                PM_W2BYTE(REG_PM_SCDC_P2_0C_L, BIT(5), BIT(5)|BIT(4)); // scdc_0C[4]: reg_tx_5v_reset_i; [5]: reg_tx_5v_reset_oen
                PM_W2BYTE(REG_PM_SLEEP_36_L, bHighLow ? BIT(14) : 0, BIT(14)); // pm_sleep_36[14]: reg_pad_pu1k (PAD_HOTPLUGC)
                break;

            case INPUT_PORT_DVI3:
                PM_W2BYTE(REG_PM_SCDC_P3_0C_L, BIT(5), BIT(5)|BIT(4)); // scdc_0C[4]: reg_tx_5v_reset_i; [5]: reg_tx_5v_reset_oen
                PM_W2BYTE(REG_PM_SLEEP_36_L, bHighLow ? BIT(15) : 0, BIT(15)); // pm_sleep_36[15]: reg_pad_pu1k (PAD_HOTPLUGD)
                break;

            default:
                break;
        }
    }
    else
    {
        // not support

        MHAL_HDMIRX_MSG_INFO("** HDMI HPD not support invert case port %d\r\n", HDMI_GET_PORT_SELECT(enInputPortType));
    }

    if(!bHighLow)
    {
        _Hal_tmds_ResetHDMI20VersionFlag(enInputPortType);
    }
}

//=========================================================//
// Function : Hal_HDCP_initproductionkey
// Description:
//=========================================================//
// Aaron comment:  HDCP OESS mode in U3
void Hal_HDCP_initproductionkey( MS_U8 * pu8HdcpKeyData )
{
    MS_U16 i;
    MS_U8 * pu8HdcpKeyData_bk;
    MS_U32 u32DTOPBankOffset = 0;
    E_MUX_INPUTPORT port_index = INPUT_PORT_DVI0;

    pu8HdcpKeyData_bk = pu8HdcpKeyData;
    MHAL_HDMIRX_MSG_INFO("[%s][%d]Start!\n", __FUNCTION__, __LINE__);

    // write BKSV/Bcaps into 4 HDCP engines
    for(port_index = INPUT_PORT_DVI0; port_index <= INPUT_PORT_DVI_END; port_index++)
    {
        u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(port_index);

        pu8HdcpKeyData = pu8HdcpKeyData_bk;
        // Bksv
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, BIT(10), BIT(10)); // [10]: HDCP enable for DDC
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(15), BIT(15)|BIT(14)); // [15]: CPU write enable, [14]: 0: 74 RAM, 1 :HDCP RAM

        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, 0x00, BMASK(9:0)); // address
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(5), BIT(5)); // trigger latch address

        for ( i = 0; i < 5; i++ )
        {
            HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_18_L +u32DTOPBankOffset, *pu8HdcpKeyData, BMASK(7:0)); // data
            HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(4), BIT(4)); // trigger latch data

            pu8HdcpKeyData += 1;
            while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(7)); // wait write ready
            while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(7)); // wait write ready
        }

        // Bcaps = 0x80
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, 0x40, BMASK(9:0)); // address
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(5), BIT(5)); // trigger latch address

        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_18_L +u32DTOPBankOffset, 0x80, BMASK(7:0)); // data
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(4), BIT(4)); // trigger latch data

        while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(7)); // wait write ready
        while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(7)); // wait write ready

        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, 0, BIT(15)|BIT(14)); // [15]: CPU write disable, [14]: 0: 74 RAM, 1 :HDCP RAM

        // [10:8]: 3'b111 determine Encrp_En during Vblank in DVI mode; [5]:HDCP enable; [0]: EESS mode deglitch Vsync mode
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_00_L +u32DTOPBankOffset, (BIT(10)|BIT(9)|BIT(8)|BIT(5)|BIT(0)), (BIT(10)|BIT(9)|BIT(8)|BIT(5)|BIT(0)));
    }
#if 0  // this is old version, it can work now, but prefer using new version, so we can use new sersion after einstion 2.0 code stable
    // HDCP key
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L, BIT(15)|BIT(14), BIT(15)|BIT(14)); // [15]: CPU write enable, [14]: 0: 74 RAM, 1 :HDCP RAM
    // burst write from address 0x00
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L, 0x00, BMASK(9:0)); // address
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L, BIT(5), BIT(5)); // trigger latch address

    for ( i = 0; i < 284; i++ )
    {
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_18_L, *pu8HdcpKeyData, BMASK(7:0)); // data
        HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L, BIT(4), BIT(4)); // trigger latch data
        delay=PM_R2BYTE(TIMER_0_CNT_REG,BMASK(15:0));
        pu8HdcpKeyData += 1;
        while(R2BYTE(REG_HDCP_DUAL_P0_19_L) & BIT(7)); // wait write ready
    }

    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L, 0, BIT(15)|BIT(14)); // [15]: CPU write disable, [14]: 0: 74 RAM, 1 :HDCP RAM
#endif
  // this is new version, please use this after einstein 2.0 code stable

    HDCP_W2BYTEMSK(REG_HDCPKEY_02_L, BIT(8), BIT(8));

    // HDCP key
    HDCP_W2BYTEMSK(REG_COMBO_GP_TOP_40_L, BIT(3)|BIT(2)|BIT(0), BIT(3)|BIT(2)|BIT(0)); // [2]: CPU write enable, [3]: 0: 74 RAM, 1 :HDCP RAM
    // burst write from address 0x05
    HDCP_W2BYTEMSK(REG_HDCPKEY_00_L, 0x05, BMASK(9:0)); // address

    for( i = 0; i < 284; i++ )
    {
        HDCP_W2BYTEMSK(REG_HDCPKEY_01_L, *pu8HdcpKeyData, BMASK(7:0)); // data
        pu8HdcpKeyData += 1;
    }
    HDCP_W2BYTEMSK(REG_COMBO_GP_TOP_40_L, 0, BIT(3)|BIT(2)|BIT(0)); // [2]: CPU write enable, [3]: 0: 74 RAM, 1 :HDCP RAM

    // to resolve the coverity issue
    MHAL_HDMIRX_MSG_INFO("[%s][%d]End!\n", __FUNCTION__, __LINE__);

#if(HDMI_CHIP_VERIFY_REPEATER)
    _Hal_tmds_HDCPVerifyProc();
#endif
}

//=========================================================//
// Function : Hal_HDCP_ddc_en
// Description:
//=========================================================//
void Hal_HDCP_ddc_en(E_MUX_INPUTPORT enInputPortType, MS_BOOL bEnable)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, (bEnable ? BIT(10) : 0), BIT(10)); // hdmirx_hdcp_17[10]: reg_ddc_hdcp_en
}

//=========================================================//
// Function : Hal_HDCP_Vsync_end_en
// Description:
//=========================================================//
// Aaron comment: doesn't need in U3
void Hal_HDCP_Vsync_end_en(MS_BOOL bEnalbe __attribute__ ((unused)))
{
     //do nothing in U3
}

//=========================================================//
// Function : Hal_HDMI_hw_reset
// Description: reset the HDMI packet status
//=========================================================//
void Hal_HDMI_pkt_reset(E_MUX_INPUTPORT enInputPortType, MS_U8 u8HDMIInfoSource, HDMI_REST_t enResetType, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__((unused)))
{
    MS_U16 u16ResetValue = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(u8HDMIInfoSource);

    if(enResetType & REST_DEEP_COLOR_FIFO)
    {
        W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_00_L +u32DTOPBankOffset, BIT(13), BIT(13)); // hdmirx_dtop_pkt_00[13]: reg_reset_dc_fifo
        MsOS_DelayTask(1);
        W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_00_L +u32DTOPBankOffset, 0, BIT(13)); // hdmirx_dtop_pkt_00[13]: reg_reset_dc_fifo
    }

    if(enResetType & REST_HDMI_STATUS)
    {
        // reset AVI/GCP/SPD/RSV register status
        W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_16_L +u32DTOPBankOffset, BIT(15), BIT(15)); // hdmirx_dtop_pkt_16[15:8]: reg_pkt_rst
        MsOS_DelayTask(1);
        W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_16_L +u32DTOPBankOffset, 0, BIT(15)); // hdmirx_dtop_pkt_16[15:8]: reg_pkt_rst

        // reset ACP/AUDIO info/audio cs/GMP/HDR/ISRC/MEPG/VBI/VSIF/VSP register status
        W2BYTEMSK(REG_HDMI_DUAL_0_5F_L +u32HDMIBankOffset, BIT(15), BIT(15)); // hdmi_u0_5F[15]: reg_pkt_rst
        MsOS_DelayTask(1);
        W2BYTEMSK(REG_HDMI_DUAL_0_5F_L +u32HDMIBankOffset, 0, BIT(15)); // hdmi_u0_5F[15]: reg_pkt_rst
    }

    if(enResetType & (REST_AVMUTE|REST_Y_COLOR|REST_PIXEL_REPETITION|REST_FRAME_REPETITION|REST_GCP_PKT))
    {
        u16ResetValue = enResetType & (REST_AVMUTE|REST_Y_COLOR|REST_PIXEL_REPETITION|REST_FRAME_REPETITION|REST_GCP_PKT);

        W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_16_L +u32DTOPBankOffset, u16ResetValue, BMASK(14:8)); // hdmirx_dtop_pkt_16[15:8]: reg_pkt_rst
        MsOS_DelayTask(1);
        W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_16_L +u32DTOPBankOffset, 0, BMASK(14:8)); // hdmirx_dtop_pkt_16[15:8]: reg_pkt_rst
    }
}

void Hal_HDMI_exit(E_MUX_INPUTPORT enInputPortType)
{
    // Disable all DDC
    W2BYTEMSK(REG_DDC_4A_L, 0 , 0x80);
    W2BYTEMSK(REG_DDC_4B_L, 0 , 0x8080);
    W2BYTEMSK(REG_DDC_4C_L, 0 , 0x80);

    // Disable audio
    Hal_HDMI_audio_output(DISABLE);

    // HPD low
    Hal_HDMI_hpd_en(DISABLE);

    // Disable HDCP
    Hal_HDCP_ddc_en(enInputPortType, DISABLE);

}

//=========================================================//
// Function : Hal_HDMI_init
// Description:
//=========================================================//
void Hal_HDMI_init(MS_BOOL bImmeswitchSupport, MS_U8 ucMHLSupportPath)
{
    MS_U8 u8HDMIInfoSource = 0;
    E_MUX_INPUTPORT enPortIndex = INPUT_PORT_DVI0;

    // DVI setting
    MHAL_HDMIRX_MSG_INFO(">>[%s][%d]HDMI Immeswitch support flag = %x\n", __FUNCTION__, __LINE__, bImmeswitchSupport);

    W2BYTE(REG_COMBO_GP_TOP_02_L, 0); //  combo_gp_top_02[15:0]: reg_misc_clk_pd
    W2BYTEMSK(REG_COMBO_GP_TOP_03_L, 0, BMASK(7:0)); //  combo_gp_top_03[7:0]: reg_misc_clk_pd

    W2BYTE(REG_COMBO_GP_TOP_10_L, 0); // combo_gp_top_10[15:0]: reg_dtop_clk_pd_p0
    W2BYTE(REG_COMBO_GP_TOP_11_L, 0); // combo_gp_top_11[15:0]: reg_dtop_clk_pd_p0
    W2BYTEMSK(REG_COMBO_GP_TOP_13_L, 0, BMASK(7:0)); // combo_gp_top_13[7:0]: reg_ve_clk_pd_p0
    W2BYTE(REG_COMBO_GP_TOP_18_L, 0); // combo_gp_top_18[15:0]: reg_dtop_clk_pd_p1
    W2BYTE(REG_COMBO_GP_TOP_19_L, 0); // combo_gp_top_19[15:0]: reg_dtop_clk_pd_p1
    W2BYTEMSK(REG_COMBO_GP_TOP_1B_L, 0, BMASK(7:0)); // combo_gp_top_1B[7:0]: reg_ve_clk_pd_p1
    W2BYTE(REG_COMBO_GP_TOP_20_L, 0); // combo_gp_top_20[15:0]: reg_dtop_clk_pd_p2
    W2BYTE(REG_COMBO_GP_TOP_21_L, 0); // combo_gp_top_21[15:0]: reg_dtop_clk_pd_p2
    W2BYTEMSK(REG_COMBO_GP_TOP_23_L, 0, BMASK(7:0)); // combo_gp_top_23[7:0]: reg_ve_clk_pd_p2
    W2BYTE(REG_COMBO_GP_TOP_28_L, 0); // combo_gp_top_28[15:0]: reg_dtop_clk_pd_p3
    W2BYTE(REG_COMBO_GP_TOP_29_L, 0); // combo_gp_top_29[15:0]: reg_dtop_clk_pd_p3
    W2BYTEMSK(REG_COMBO_GP_TOP_2B_L, 0, BMASK(7:0)); // combo_gp_top_2B[7:0]: reg_ve_clk_pd_p3

    W2BYTEMSK(REG_COMBO_GP_TOP_54_L, 0x0A00, BMASK(11:8)); // combo_gp_top_54[9:8]: reg_aud_fifo_empty_diff; [11:10]: reg_aud_fifo_full_diff

    W2BYTEMSK(REG_COMBO_GP_TOP_49_L, 0, BIT(6)); // combo_gp_top_49[6]: reg_aud_8p_en

    W2BYTEMSK(REG_COMBO_GP_TOP_49_L, BIT(12), BIT(12)); // combo_gp_top_49[12]: reg_afifo_rst
    W2BYTEMSK(REG_COMBO_GP_TOP_49_L, 0, BIT(12)); // combo_gp_top_49[12]: reg_afifo_rst

    // 48[14] = 1 audio fifo underflow don't do HW reset; 48[15] = 1 audio fifo overflow don't do HW reset
    W2BYTEMSK(REG_COMBO_GP_TOP_48_L, BMASK(15:14), BMASK(15:14)); // combo_gp_top_48[14]: audio fifo underflow don't do hw reset; [15]: audio fifo overflow don't do hw reset
    W2BYTEMSK(REG_COMBO_GP_TOP_4B_L, BMASK(5:4), BMASK(5:4)); // combo_gp_top_4B[4]: reg_af_rctrl_rstz_roll_back; [5]: reg_read_rdy_dis

    W2BYTEMSK(REG_COMBO_GP_TOP_44_L, BIT(7)|BIT(0), BIT(7)|BIT(0)); // combo_gp_top_44[0]: reg_synth_sel_cts_ref; [7]: reg_en_cts_n_synth
    W2BYTEMSK(REG_COMBO_GP_TOP_38_L, BIT(0), BIT(0)); // combo_gp_top_38[0] : hdmi_hdcp dtop module disable mask

    // de-repetition
    W2BYTEMSK(REG_COMBO_GP_TOP_15_L, BIT(13), BIT(13)); // combo_gp_top_15[13]:reg_pixel_rep_en_p0
    W2BYTEMSK(REG_COMBO_GP_TOP_1D_L, BIT(13), BIT(13)); // combo_gp_top_1D[13]:reg_pixel_rep_en_p1
    W2BYTEMSK(REG_COMBO_GP_TOP_25_L, BIT(13), BIT(13)); // combo_gp_top_25[13]:reg_pixel_rep_en_p2
    W2BYTEMSK(REG_COMBO_GP_TOP_2D_L, BIT(13), BIT(13)); // combo_gp_top_2D[13]:reg_pixel_rep_en_p3

    for(enPortIndex = INPUT_PORT_DVI0; enPortIndex <= INPUT_PORT_DVI_END; enPortIndex++)
    {
        _Hal_tmds_PHYInit(enPortIndex);
        _Hal_tmds_MACInit(enPortIndex);
    }

    for(u8HDMIInfoSource = HDMI_INFO_SOURCE0; u8HDMIInfoSource < HDMI_INFO_SOURCE_MAX; u8HDMIInfoSource++)
    {
        _Hal_tmds_HDMIInit(u8HDMIInfoSource);
    }

    Hal_HDMI_Audio_MUTE_Enable(HDMI_AVMUTE, HDMI_AVMUTE);
    W2BYTEMSK(REG_COMBO_GP_TOP_4D_L, 0, BIT(6)); // combo_gp_top_4D[6]: reg_hdmi_audio_status_en:audio fifo overflow/underflow for QD980 cts 8-21/23 audio cutting

    W2BYTEMSK(REG_COMBO_GP_TOP_01_L, BIT(6), BIT(6)); // combo_gp_top_01[6]: DVI2MIU enable
    W2BYTEMSK(REG_COMBO_GP_TOP_01_L, 0x3000, BMASK(15:12)); // combo_gp_top_01[15:12]:0x3 Enable DVI2MIU select Clock source CLKO_TMDS
}

//-------------------------------------------------------------------------------------------------
/// Get the HDMI DE
/// @return @ref MS_U16
//-------------------------------------------------------------------------------------------------
MS_U16 Hal_HDMI_GetHDEInfo(MS_U8 ucHDMIInfoSource)
{
    return Hal_HDMI_GetDataInfo(E_HDMI_GET_HDE, ucHDMIInfoSource, NULL);
}

//-------------------------------------------------------------------------------------------------
/// Get the HDMI HDE, VDE, HTT, VTT
/// @return @ref MS_U16
//-------------------------------------------------------------------------------------------------
MS_U16 Hal_HDMI_GetDataInfo(E_HDMI_GET_DATA_INFO enInfo, MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U16 u16HDMIDataInfo = 0;
    MS_U32 u32VEBankOffset = _Hal_tmds_GetVEBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    switch(enInfo)
    {
        case E_HDMI_GET_HDE:
            u16HDMIDataInfo = R2BYTEMSK(REG_HDMIRX_VE_U0_14_L +u32VEBankOffset, 0x3FFF); // hdmirx_ve_14[15:0]: reg_timing_det_hde
            break;

        case E_HDMI_GET_VDE:
            u16HDMIDataInfo = R2BYTEMSK(REG_HDMIRX_VE_U0_15_L +u32VEBankOffset, 0x3FFF); // hdmirx_ve_15[15:0]: reg_timing_det_vde
            break;

        case E_HDMI_GET_HTT:
            u16HDMIDataInfo = R2BYTEMSK(REG_HDMIRX_VE_U0_12_L +u32VEBankOffset, 0x3FFF); // hdmirx_ve_12[15:0]: reg_timing_det_htt
            break;

        case E_HDMI_GET_VTT:
            u16HDMIDataInfo = R2BYTEMSK(REG_HDMIRX_VE_U0_13_L +u32VEBankOffset, 0x3FFF); // hdmirx_ve_13[15:0]: reg_timing_det_vtt
            break;

        case E_HDMI_GET_SUPPORT_EDID_SIZE:
            u16HDMIDataInfo = HDMI_EDID_SUPPORT_SIZE;
            break;

        case E_HDMI_GET_MULTIVS_COUNT:
            u16HDMIDataInfo = R2BYTEMSK(REG_HDMI3_DUAL_0_2F_L +u32HDMIBankOffset, BMASK(3:0)); // hdmi3_u0_2F[3:0]: reg_vsif_cnt
            break;

        case E_HDMI_GET_H_POLARITY:
            u16HDMIDataInfo = (R2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, BIT(13)) & BIT(13)) >> 13; // hdmirx_ve_11[13]: reg_hs_pol
            break;

        case E_HDMI_GET_V_POLARITY:
            u16HDMIDataInfo = (R2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, BIT(12)) & BIT(12)) >> 12; // hdmirx_ve_11[12]: reg_vs_pol
            break;

        case E_HDMI_GET_INTERLACE:
            u16HDMIDataInfo = (R2BYTEMSK(REG_HDMIRX_VE_U0_11_L +u32VEBankOffset, BIT(15)) & BIT(15)) >> 15; // hdmirx_ve_11[15]: reg_src_det_i_md_en
            break;

        case E_HDMI_GET_CHIP_HDCP_CAPABILITY:
            u16HDMIDataInfo = HDMI_HDCP_2_2;
            break;

        case E_HDMI_GET_EMP_ENABLE_STATUS:
            u16HDMIDataInfo = pstHDMIPollingInfo->u16EMPacketInfo;
            MHAL_HDMIRX_MSG_INFO("** HDMI port %d, EMP Enable status:0x%x \r\n", ucHDMIInfoSource, u16HDMIDataInfo);
            break;

        default:
            MHAL_HDMIRX_MSG_INFO("** HDMI port %d, GetDataInfo cmd not found. \r\n", ucHDMIInfoSource);
            break;
    };

    return u16HDMIDataInfo;
}

//=========================================================//
// Function : Hal_HDMI_set_EQ
// Description:
//=========================================================//
void Hal_HDMI_Set_EQ(E_MUX_INPUTPORT enInputPortType, MS_HDMI_EQ enEq, MS_U8 u8EQValue)
{
    MS_U8 u8SetEQValue[4] = {u8EQValue, u8EQValue, u8EQValue, u8EQValue};

    switch (enEq)
    {
        case MS_HDMI_EQ_2M:
            break;
        case MS_HDMI_EQ_10M:
            break;
        case MS_HDMI_EQ_15M:
            break;
        case MS_HDMI_EQ_MAX:
            break;
        case MS_HDMI_EQ_USER_DEFINE:
            _Hal_tmds_SetNewPHYEQValue(enInputPortType, TRUE, u8SetEQValue);
            break;
        default:
            break;
    }
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetGCPColorDepth()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_HDMI_GetGCPColorDepth(E_MUX_INPUTPORT enInputPortType, MS_U32 u32PacketStatus)
{
    MS_U8 u8ReValue = HDMI_COLOR_DEPTH_8BIT;
    MS_U16 u16ColorDepth = 0;

    if(u32PacketStatus & HDMI_STATUS_GCP_PACKET_RECEIVE_FLAG) // GCP packet received
    {
        u16ColorDepth = Hal_HDMI_gcontrol_info(G_Ctrl_CD_VAL, HDMI_GET_PORT_SELECT(enInputPortType));

        switch(u16ColorDepth) // Color depth
        {
            case 0x500:
                u8ReValue = HDMI_COLOR_DEPTH_10BIT;
                break;

            case 0x600:
                u8ReValue = HDMI_COLOR_DEPTH_12BIT;
                break;

            case 0x700:
                u8ReValue = HDMI_COLOR_DEPTH_16BIT;
                break;

            default:
                break;
        };
    }

    return u8ReValue;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_ForcePowerDownPort()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDMI_ForcePowerDownPort(E_MUX_INPUTPORT enInputPortType, stHDMI_POLLING_INFO *pstHDMIPollingInfo, MS_BOOL bPowerDown)
{
    if (bPowerDown)
    {
        _Hal_tmds_SetPowerDown(enInputPortType, TRUE);
        pstHDMIPollingInfo->bPowerControlOn = FALSE;
        pstHDMIPollingInfo->bForcePowerDown = TRUE;
    }
    else
    {
        pstHDMIPollingInfo->bForcePowerDown = FALSE;
    }
}

//=========================================================//
// Function : Hal_HDMI_Audio_MUTE_Enable
// Description:
//=========================================================//
void Hal_HDMI_Audio_MUTE_Enable(MS_U16 u16MuteEvent, MS_U16 u16MuteMask)
{
    W2BYTEMSK(REG_COMBO_GP_TOP_4A_L, u16MuteEvent, u16MuteMask); // combo_gp_top_4A[7:0]: audio mute event to vivaldi
}

//=========================================================//
// Function : Hal_HDMI_Audio_Status_Clear
// Description:
//=========================================================//
void Hal_HDMI_Audio_Status_Clear(stHDMI_POLLING_INFO *stHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U8 u8HDMIInfoSource = HDMI_INFO_SOURCE0;
    MS_U8 ucMuteEvent = R2BYTE(REG_COMBO_GP_TOP_4A_L) & BMASK(7:0);
    MS_U8 ucAudioMux = R2BYTE(REG_COMBO_GP_TOP_4B_L) & BMASK(1:0);
    MS_U32 u32HDMIBankOffset = 0;

    switch(ucAudioMux)
    {
        case HDMI_AUDIO_PATH0:
            u8HDMIInfoSource = HDMI_INFO_SOURCE0;
            break;

        case HDMI_AUDIO_PATH1:
            u8HDMIInfoSource = HDMI_INFO_SOURCE1;
            break;

        case HDMI_AUDIO_PATH2:
            u8HDMIInfoSource = HDMI_INFO_SOURCE2;
            break;

        case HDMI_AUDIO_PATH3:
            u8HDMIInfoSource = HDMI_INFO_SOURCE3;
            break;

        default:
            break;
    };

    u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(u8HDMIInfoSource);

    if(ucMuteEvent & HDMI_CTSN_OVERRANGE)
    {
        if(R2BYTE(REG_HDMI_DUAL_0_02_L +u32HDMIBankOffset) & BIT(6)) // hdmi_u0_02[6]: reg_ctsn_ov_range
        {
            //load current CTS/N value first
            W2BYTE(REG_HDMI_DUAL_0_12_L +u32HDMIBankOffset, 0xFFFF); // hdmi_u0_12[15:0]: CTS[15:0] from ACR packet
            W2BYTE(REG_HDMI_DUAL_0_13_L +u32HDMIBankOffset, 0xFFFF); // hdmi_u0_13[15:0]: N[15:0] from ACR packet
            W2BYTEMSK(REG_HDMI_DUAL_0_14_L +u32HDMIBankOffset, 0xFF, 0xFF); // hdmi_u0_14[7:4]: N[19:16]; [3:0]: CTS[19:16] from ACR packet

            //update CTS value
            W2BYTE(REG_HDMI_DUAL_0_0A_L +u32HDMIBankOffset, R2BYTE(REG_HDMI_DUAL_0_12_L +u32HDMIBankOffset)); // hdmi_u0_0A[15:0]: Limited CTS[15:0]
            W2BYTEMSK(REG_HDMI_DUAL_0_09_L +u32HDMIBankOffset, (R2BYTE(REG_HDMI_DUAL_0_14_L +u32HDMIBankOffset) & 0x0F) << 8, 0x0F00); // hdmi_u0_09[11:8]: Limited CTS[19:16]

            //update N value
            W2BYTE(REG_HDMI_DUAL_0_0B_L +u32HDMIBankOffset, R2BYTE(REG_HDMI_DUAL_0_13_L +u32HDMIBankOffset)); // hdmi_u0_0B[15:0]: Limited N[15:0]
            W2BYTEMSK(REG_HDMI_DUAL_0_09_L +u32HDMIBankOffset, (R2BYTE(REG_HDMI_DUAL_0_14_L +u32HDMIBankOffset) & 0xF0) << 8, 0xF000); // hdmi_u0_09[15:12]: Limited N[19:16]

            //setup CTS/N range
            W2BYTE(REG_HDMI_DUAL_0_0C_L +u32HDMIBankOffset, 0xFFFF); // hdmi_u0_0C[15:8]: N range; [7:0]: CTS range

            //upload new CTS/N value
            W2BYTEMSK(REG_HDMI_DUAL_0_07_L +u32HDMIBankOffset, BIT(15), BIT(15)); // hdmi_u0_07[15]: reg_update_lmt_ctsn

            //clear received CTS/N over range status
            W2BYTEMSK(REG_HDMI_DUAL_0_02_L +u32HDMIBankOffset, BIT(6), BIT(6)); // hdmi_u0_02[6]: reg_ctsn_ov_range (write 1 clear)
        }
    }

    if(ucMuteEvent & HDMI_CLOCK_BIG_CHANGE)
    {
        if(R2BYTE(REG_HDMI_DUAL_0_02_L +u32HDMIBankOffset) & BIT(7)) // hdmi_u0_02[7]: reg_vclk_big_chg
        {
            //clear HDMI video clock freqency big change
            W2BYTEMSK(REG_HDMI_DUAL_0_02_L +u32HDMIBankOffset, BIT(7), BIT(7)); // hdmi_u0_02[7]: reg_vclk_big_chg (write 1 clear)
        }
    }

    if(ucMuteEvent & HDMI_AVMUTE)
    {

    }

    if(ucMuteEvent & HDMI_NO_INPUT_CLOCK)
    {

    }

    if(ucMuteEvent & HDMI_AUDIO_SAMPLE_FLAT_BIT)
    {
        if(R2BYTE(REG_COMBO_GP_TOP_49_L) & BIT(4)) // combo_gp_top_49[4]: reg_flat_asmp_rcvd
        {
            //clear flat audio sample
            W2BYTEMSK(REG_COMBO_GP_TOP_49_L, BIT(4), BIT(4)); // combo_gp_top_49[4]: reg_flat_asmp_rcvd (write 1 clear)
        }
    }

    if(ucMuteEvent &  HDMI_AUDIO_PRESENT_BIT_ERROR)
    {
        if(R2BYTE(REG_HDMI_DUAL_0_04_L +u32HDMIBankOffset) & BIT(10)) // hdmi_u0_04[10]: reg_asp_prsnt_bit_err
        {
            //clear audio sample packet present bit error
            W2BYTEMSK(REG_HDMI_DUAL_0_04_L +u32HDMIBankOffset, BIT(10), BIT(10)); // hdmi_u0_04[10]: reg_asp_prsnt_bit_err (write 1 clear)
        }
    }

    if(ucMuteEvent & HDMI_AUDIO_FIFO_OVERFLOW_UNDERFLOW)
    {
        if(R2BYTE(REG_COMBO_GP_TOP_49_L) & (BIT(9)|BIT(8))) // combo_gp_top_49[9]: reg_afifo12_over; [8]: reg_afifo12_under
        {
            //clear audio fifo overflow/underflow
            W2BYTEMSK(REG_COMBO_GP_TOP_49_L, BIT(9)|BIT(8), BIT(9)|BIT(8)); // combo_gp_top_49[9]: reg_afifo12_over; [8]: reg_afifo12_under (write 1 clear)
        }
    }

    if(ucMuteEvent & HDMI_AUDIO_SAMPLE_PARITY_ERROR)
    {
        if(R2BYTE(REG_HDMI_DUAL_0_04_L +u32HDMIBankOffset) & (BIT(5)|BIT(4))) // hdmi_dual_04[5]: reg_as_pbit_err; [4]: Audio Sample packet receive Error occurred; sample repeated
        {
            //clear audio sample parity error
            W2BYTEMSK(REG_HDMI_DUAL_0_04_L +u32HDMIBankOffset, BIT(5)|BIT(4), BIT(5)|BIT(4)); // hdmi_dual_04[5]: reg_as_pbit_err; [4]: Audio Sample packet receive Error occurred; sample repeated (write 1 clear)
        }
    }
}

//=========================================================//
// Function : Hal_HDMI_gcontrol_info
// Description:
//#[15:12]: PP_VAL[3:0]
//#[11:8]: CD_VAL[3:0]
//#[7:5]: PRE_LPP[2:0]
//#[4:2]: LAST_PP[2:0]
//#[1]: Default_Phase
//#[0]: AVMUTE
//=========================================================//
MS_U16 Hal_HDMI_gcontrol_info(HDMI_GControl_INFO_t gcontrol, MS_U8 ucHDMIInfoSource)
{
    MS_U16 u16regvalue;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));

    u16regvalue = R2BYTE(REG_HDMIRX_DTOP_PKT_P0_19_L +u32DTOPBankOffset); // hdmirx_dtop_pkt_19[15:0]: reg_gcontrol

    switch(gcontrol)
    {
        default:
        case G_CTRL_AVMUTE://#[0]: AVMUTE
            u16regvalue &= BIT(0);
            break;
        case G_Ctrl_DEFAULT_PHASE://#[1]: Default_Phase
            u16regvalue &= BIT(1);
            break;
        case G_Ctrl_LAST_PP://#[4:2]: LAST_PP[2:0]
            u16regvalue &= (BIT(4)|BIT(3)|BIT(2));
            break;
        case G_Ctrl_PRE_LPP://#[7:5]: PRE_LPP[2:0]
            u16regvalue &= (BIT(7)|BIT(6)|BIT(5));
            break;
        case G_Ctrl_CD_VAL://#[11:8]: CD_VAL[3:0]
            u16regvalue &= (BIT(11)|BIT(10)|BIT(9)|BIT(8));
            break;
        case G_Ctrl_PP_VAL://#[15:12]: PP_VAL[3:0]
            u16regvalue &= (BIT(15)|BIT(14)|BIT(13)|BIT(12));
            break;
        case G_Ctrl_ALL:
            u16regvalue &=(LBMASK|HBMASK);
            break;
    }

    return u16regvalue;
}

// T3 doesn't have HPLL
//=========================================================//
// Function : Hal_HDMI_pll_ctrl1/2
// Description:
// bread = 1-> read or write
//=========================================================//
MS_U16 Hal_HDMI_pll_ctrl1(HDMI_PLL_CTRL_t pllctrl __attribute__ ((unused)), MS_BOOL bread __attribute__ ((unused)), MS_U16 u16value __attribute__ ((unused)))
{
    MS_U16 u16regvalue = 0;

    return u16regvalue;
}

MS_U16 Hal_HDMI_pll_ctrl2(HDMI_PLL_CTRL2_t pllctrl __attribute__ ((unused)), MS_BOOL bread __attribute__ ((unused)), MS_U16 u16value __attribute__ ((unused)))
{
    MS_U16 u16regvalue = 0;

    return u16regvalue;
}


void Hal_HDMI_hpd_en(MS_BOOL benable)
{
    MS_U16 u16value;

    if(benable) // 0 is output enable
        u16value= 0x0000;
    else
        u16value= 0xFFFF;

    //PM_W2BYTE(REG_PM_SLEEP_27_L, u16value & BMASK(7:4), BMASK(7:4));
    PM_W2BYTE(REG_PM_SLEEP_27_L, u16value, 0x00FF);
}

//=========================================================//
// Function : Hal_HDMI_packet_info
// Description:
//=========================================================//
MS_U32 Hal_HDMI_packet_info(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_BOOL bCFDPlusFlag = FALSE;
    MS_U16 usPacketStatus = 0;
    MS_U32 ulPacketStatus = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    // Dummy reg for CFD+
    usPacketStatus = R2BYTE(REG_HDMIRX_DTOP_PKT_P0_0B_L +u32DTOPBankOffset); // hdmirx_dtop_pkt_0B[15:0]: reg_pkt_reserved_0

    if(usPacketStatus > 0)
    {
        if(usPacketStatus & BIT(0))
        {
            ulPacketStatus = ulPacketStatus | HDMI_STATUS_AVI_PACKET_RECEIVE_FLAG;
        }

        W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_0B_L +u32DTOPBankOffset, 0, BIT(0)); // hdmirx_dtop_pkt_0B[15:0]: reg_pkt_reserved_0

        if(ucHDMIInfoSource == _Hal_HDMI_GetPacketHdmiPortSelect()) // check HDMI source is same as reg_xc2hd_port_sel
        {
            if(usPacketStatus & BIT(1))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_HDR_PACKET_RECEIVE_FLAG;
            }

            if(usPacketStatus & BIT(2))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_VS_PACKET_RECEIVE_FLAG;
            }

            W2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_0B_L +u32DTOPBankOffset, 0, BMASK(2:1)); // hdmirx_dtop_pkt_0B[15:0]: reg_pkt_reserved_0
        }

        if(usPacketStatus & BIT(15))
        {
            bCFDPlusFlag = TRUE;
        }

    }

    usPacketStatus = R2BYTE(REG_HDMIRX_DTOP_PKT_P0_10_L +u32DTOPBankOffset); // hdmirx_dtop_pkt_10[3]: GCP; [4]: AVI; [5]: SPD; [6]: RSV packet received

    if(usPacketStatus & BIT(3))
    {
        ulPacketStatus = ulPacketStatus | HDMI_STATUS_GCP_PACKET_RECEIVE_FLAG;
    }
    if(usPacketStatus & BIT(4))
    {
        ulPacketStatus = ulPacketStatus | HDMI_STATUS_AVI_PACKET_RECEIVE_FLAG;
    }
    if(usPacketStatus & BIT(5))
    {
        ulPacketStatus = ulPacketStatus | HDMI_STATUS_SPD_PACKET_RECEIVE_FLAG;
    }
    if(usPacketStatus & BIT(6))
    {
        ulPacketStatus = ulPacketStatus | HDMI_STATUS_RESERVED_PACKET_RECEIVE_FLAG;
    }

    if((usPacketStatus & BMASK(6:3)) > 0)
    {
        if(bCFDPlusFlag)
        {
            usPacketStatus = usPacketStatus& (~(BIT(4))); // HDMI_STATUS_AVI_PACKET_RECEIVE_FLAG
        }

        // Clear status
        W2BYTE(REG_HDMIRX_DTOP_PKT_P0_10_L +u32DTOPBankOffset, usPacketStatus); // hdmirx_dtop_pkt_10[3]: GCP; [4]: AVI; [5]: SPD; [6]: RSV packet received
    }

    if(ucHDMIInfoSource == _Hal_HDMI_GetPacketHdmiPortSelect())//check HDMI source is same as reg_xc2hd_port_sel
    {
        usPacketStatus = R2BYTE(REG_HDMI_DUAL_0_01_L +u32HDMIBankOffset);

        if(usPacketStatus > 0)
        {
            ulPacketStatus |= usPacketStatus;

            if(bCFDPlusFlag)
            {
                usPacketStatus = usPacketStatus& (~HDMI_STATUS_VS_PACKET_RECEIVE_FLAG);
            }

            Hal_HDMI_packet_ctrl(ucHDMIInfoSource, usPacketStatus, NULL);
        }

        usPacketStatus = R2BYTE(REG_HDMI_DUAL_0_02_L +u32HDMIBankOffset) & BMASK(15:14);

        if(usPacketStatus > 0)
        {
            if(usPacketStatus &BIT(14))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_HDR_PACKET_RECEIVE_FLAG;
            }

            if(bCFDPlusFlag)
            {
                usPacketStatus = 0;
            }

            // Clear status
            W2BYTE(REG_HDMI_DUAL_0_02_L +u32HDMIBankOffset, usPacketStatus);
        }

        usPacketStatus = R2BYTE(REG_HDMI2_DUAL_0_26_L +u32HDMIBankOffset) &BIT(3);

        if(usPacketStatus &BIT(3))
        {
            ulPacketStatus = ulPacketStatus | HDMI_STATUS_EDR_VALID_FLAG;

            // Clear status
            //_Hal_tmds_ClearEDRVaildFlag(ucHDMIInfoSource);
        }

        usPacketStatus = R2BYTE(REG_HDMI_DUAL_0_03_L +u32HDMIBankOffset) & BMASK(6:0);

        if(usPacketStatus > 0)
        {
            if(usPacketStatus &BIT(0))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_AUDIO_DST_RECEIVE_FLAG;
            }

            if(usPacketStatus &BIT(1))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_AUDIO_3D_ASP_RECEIVE_FLAG;
                ulPacketStatus = ulPacketStatus & (~HDMI_STATUS_AUDIO_SAMPLE_PACKET_RECEIVE_FLAG);
            }

            if(usPacketStatus &BIT(2))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_AUDIO_3D_DSD_RECEIVE_FLAG;
                ulPacketStatus = ulPacketStatus & (~HDMI_STATUS_DSD_PACKET_RECEIVE_FLAG);
            }

            if(usPacketStatus &BIT(4))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_AUDIO_MULTI_ASP_RECEIVE_FLAG;
                ulPacketStatus = ulPacketStatus & (~HDMI_STATUS_AUDIO_SAMPLE_PACKET_RECEIVE_FLAG);
            }

            if(usPacketStatus &BIT(5))
            {
                ulPacketStatus = ulPacketStatus | HDMI_STATUS_AUDIO_MULTI_DSD_RECEIVE_FLAG;
                ulPacketStatus = ulPacketStatus & (~HDMI_STATUS_DSD_PACKET_RECEIVE_FLAG);
            }

            // Clear status
            W2BYTE(REG_HDMI_DUAL_0_03_L +u32HDMIBankOffset, usPacketStatus);
        }

        if(R2BYTE(REG_HDMI_EM_U0_07_L +u32HDMIBankOffset) & BIT(3))
        {
            ulPacketStatus = ulPacketStatus| HDMI_STATUS_EM_PACKET_RECEIVE_FLAG;

            W2BYTE(REG_HDMI_EM_U0_0D_L +u32HDMIBankOffset, BIT(3));
        }
    }

    return ulPacketStatus;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetPacketReceiveCount()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_HDMI_GetPacketReceiveCount(MS_U8 u8HDMIInfoSource, MS_U8 u8PrePacketReceiveCount, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U8 u8PacketReceiveCount = HDMI_PACKET_RECEIVE_COUNT;
    MS_U16 u16HTTValue = Hal_HDMI_GetDataInfo(E_HDMI_GET_HTT, u8HDMIInfoSource, NULL);
    MS_U16 u16VTTValue = Hal_HDMI_GetDataInfo(E_HDMI_GET_VTT, u8HDMIInfoSource, NULL);

    MS_U16 u16ColorDepth = 0;
    MS_U32 u32VFrequency = 0;

    if((!pstHDMIPollingInfo[u8HDMIInfoSource].bNoInputFlag) && (Hal_DVI_GetDEStableStatus((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +u8HDMIInfoSource)) == TRUE))
    {
        u32VFrequency = pstHDMIPollingInfo[u8HDMIInfoSource].usClockCount;

        if((u32VFrequency > 0) && (u16HTTValue > 0))
        {
            // HDMI 2.0
            if(pstHDMIPollingInfo[u8HDMIInfoSource].ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20)
            {
                u32VFrequency = u32VFrequency << 2;
            }

            u16ColorDepth = Hal_HDMI_gcontrol_info(G_Ctrl_CD_VAL, u8HDMIInfoSource);

            // Color depth
            switch(u16ColorDepth)
            {
                case 0x500:
                    u32VFrequency = u32VFrequency *8 /10;
                    break;

                case 0x600:
                    u32VFrequency = u32VFrequency *8 /12;
                    break;

                case 0x700:
                    u32VFrequency = u32VFrequency *8 /16;
                    break;

                default:
                    break;
            };

            u32VFrequency = (MS_U32)u32VFrequency * 1000000 / u16HTTValue;

            if(u16VTTValue > 0)
            {
                u32VFrequency = u32VFrequency / u16VTTValue;

                if(u32VFrequency > 0)
                {
                    u8PacketReceiveCount = ((1000 /u32VFrequency) +HDMI_POLLING_INTERVAL +HDMI_FRAME_RATE_OFFSET) /HDMI_POLLING_INTERVAL;
                }

                if(u8PacketReceiveCount > HDMI_PACKET_RECEIVE_COUNT)
                {
                    u8PacketReceiveCount = HDMI_PACKET_RECEIVE_COUNT;
                }

                //MHAL_HDMIRX_MSG_INFO("** HDMI V freq %d count %d source %d\r\n", u32VFrequency, u8PacketReceiveCount, u8HDMIInfoSource);
            }
        }
        if(u8PrePacketReceiveCount != u8PacketReceiveCount)
        {
            MHAL_HDMIRX_MSG_INFO("** HDMI packet receive count change from %d to %d source %d\r\n", u8PrePacketReceiveCount, u8PacketReceiveCount, u8HDMIInfoSource);
        }
    }
    return u8PacketReceiveCount;
}

//=========================================================//
// Function : Hal_HDMI_packet_ctrl
// Description:
// HDMI_PACKET_INFO_t
//=========================================================//
void Hal_HDMI_packet_ctrl(MS_U8 ucHDMIInfoSource, MS_U16 u16pkt, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    W2BYTE(REG_HDMI_DUAL_0_01_L +u32HDMIBankOffset, u16pkt); // hdmi_u0_01[15:0]
}

//=========================================================//
// Function : Hal_HDMI_avi_infoframe_info_ver
// Description: avi info frame version
//=========================================================//
EN_AVI_INFOFRAME_VERSION Hal_HDMI_avi_infoframe_info_ver(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U16 u16RegValue;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));
    EN_AVI_INFOFRAME_VERSION enPktVersion = E_AVI_INFOFRAME_VERSION_NON;

    u16RegValue = R2BYTEMSK(REG_HDMIRX_DTOP_PKT_P0_22_L +u32DTOPBankOffset, BMASK(9:8)) >> 8; // hdmirx_dtop_pkt_22[15:8]: reg_avi_version

    enPktVersion = (EN_AVI_INFOFRAME_VERSION)u16RegValue;

    return enPktVersion;
}

//=========================================================//
// Function : Hal_HDMI_avi_infoframe_info
// Description: avi info frame byte 1~14
//=========================================================//
MS_U8 Hal_HDMI_avi_infoframe_info(MS_U8 ucHDMIInfoSource, MS_U8 u8byte, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U8 u8ReturnValue = 0;
    MS_U16 u16Reg = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));

    if(u8byte > 0)
    {
        u16Reg = R2BYTE(REG_HDMIRX_DTOP_PKT_P0_23_L +u32DTOPBankOffset +((u8byte - 1)/2)*2); // hdmirx_dtop_pkt_23[7:0]: reg_avi_if1; 29[15:8]: reg_avi_if14;
        u8ReturnValue = (MS_U8)(((u8byte-1)&0x01) ? (u16Reg>>8) : (u16Reg&0xFF));
    }

    return u8ReturnValue;
}

//=========================================================//
// Function : Hal_HDMI_get_packet_value
// Description:
//=========================================================//
MS_BOOL Hal_HDMI_get_packet_value(MS_U8 ucHDMIInfoSource, MS_HDMI_PACKET_STATE_t u8state, MS_U8 u8byte_idx, MS_U8 *pu8Value, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32Base_add = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    switch(u8state)
    {
        case PKT_MPEG:
            // 1~5
            if(u8byte_idx > 5)
                return FALSE;

            u32Base_add = REG_HDMI_DUAL_0_57_L +u32HDMIBankOffset; // hdmi_u0_57[7:0]: reg_mpeg_if1; 59[7:0]: reg_mpeg_if5
            break;

        case PKT_AUI:
            // 1~10
            if(u8byte_idx > 10)
                return FALSE;
            u32Base_add = REG_HDMI3_DUAL_0_52_L +u32HDMIBankOffset; // hdmi3_u0_52[7:0]: reg_audio_if01; hdmi3_u0_56[15:8]: reg_audio_if10
            break;

        case PKT_SPD:
            // 1~25
            if(u8byte_idx > 25)
                return FALSE;

            u32Base_add = REG_HDMIRX_DTOP_PKT_P0_30_L +u32DTOPBankOffset; // hdmirx_dtop_pkt_30[7:0]: reg_spd_if1; 3C[7:0]: reg_spd_if25
            break;

        case PKT_AVI:
            // 1~14
            if(u8byte_idx > 13)
                return FALSE;

            u32Base_add = REG_HDMIRX_DTOP_PKT_P0_23_L +u32DTOPBankOffset; // hdmirx_dtop_pkt_23[7:0]: reg_avi_if1; 29[15:8]: reg_avi_if14
            break;

        case PKT_GC:
            // 2
            if(u8byte_idx > 2)
                return FALSE;

            u32Base_add = REG_HDMIRX_DTOP_PKT_P0_19_L +u32DTOPBankOffset; // hdmirx_dtop_pkt_19[15:0]: reg_gcontrol
            break;

        case PKT_ASAMPLE:
            break;

        case PKT_ACR:
            break;

        case PKT_VS:
            // 0~2:header, 4~31:payload
            if(u8byte_idx > 31)
                return FALSE;

            u32Base_add = REG_HDMI_DUAL_0_30_L +u32HDMIBankOffset; // hdmi_u0_30[7:0]: reg_vs_hdr0; 31[7:0]: reg_vs_hdr2; 32[7:0]: reg_vs_if1; 3F[15:8]: reg_vs_if28
            break;

        case PKT_NULL:
            break;

        case PKT_ISRC1:
            // 0~15
            u8byte_idx ++;
            if(u8byte_idx > 16)
                return FALSE;

            W2BYTEMSK(REG_HDMI_DUAL_0_07_L, 0, BIT(13)); // hdmi_u0_07[13]: Orignial ISRC packet
            u32Base_add = REG_HDMI_DUAL_0_20_L +u32HDMIBankOffset; // hdmi_u0_20[7:0]: reg_isrc_pb0; 27[15:8]: reg_isrc_pb15
            break;

        case PKT_ISRC2:
            // 0~15
            u8byte_idx ++;
            if(u8byte_idx > 16)
                return FALSE;

            u32Base_add = REG_HDMI_DUAL_0_28_L +u32HDMIBankOffset; // hdmi_u0_28[7:0]: reg_isrc_pb16; 2F[15:8]: reg_isrc_pb31
            break;

        case PKT_ACP:
            // 0~15
            u8byte_idx ++;
            if(u8byte_idx > 16)
                return FALSE;

            u32Base_add = REG_HDMI_DUAL_0_17_L +u32HDMIBankOffset; // hdmi_u0_17[7:0]: reg_acp_pb0; 1E[15:8]: reg_acp_pb15
            break;

        case PKT_ONEBIT_AUD:
            break;

        case PKT_HDR:
            // 0~1: header, 2~29: payload
            if(u8byte_idx > 29)
                return FALSE;

            u32Base_add = REG_HDMI2_DUAL_0_60_L +u32HDMIBankOffset; // hdmi2_u0_60[7:0]: reg_hdr_hdr2; [15:8]: reg_hdr_hdr1; 61[7:0]: reg_hdr_pb01; [15:8]: reg_hdr_pb00; 6E[7:0]: reg_hdr_pb27
            break;

        case PKT_MULTI_VS:
            if(u8byte_idx < 120)
            {
                if(u8byte_idx < 30)
                {
                    u32Base_add = REG_HDMI3_DUAL_0_00_L +u32HDMIBankOffset; // hdmi3_u0_00[7:0]: reg_vsif_hdr2_0; [15:8]: reg_vsif_hdr1_0; 01[7:0]: reg_vsif_pb01_0; [15:8]: reg_vsif_pb00_0; 0E[7:0]: reg_vsif_pb27_0
                }
                else if((u8byte_idx >= 30) && (u8byte_idx < 60))
                {
                    u32Base_add = REG_HDMI3_DUAL_0_10_L +u32HDMIBankOffset; // hdmi3_u0_10[7:0]: reg_vsif_hdr2_1; [15:8]: reg_vsif_hdr1_1; 11[7:0]: reg_vsif_pb01_1; [15:8]: reg_vsif_pb00_1; 1E[7:0]: reg_vsif_pb27_1
                    u8byte_idx = u8byte_idx - 30;
                }
                else if((u8byte_idx >= 60) && (u8byte_idx < 90))
                {
                    u32Base_add = REG_HDMI3_DUAL_0_20_L +u32HDMIBankOffset; // hdmi3_u0_20[7:0]: reg_vsif_hdr2_2; [15:8]: reg_vsif_hdr1_2; 21[7:0]: reg_vsif_pb01_2; [15:8]: reg_vsif_pb00_2; 2E[7:0]: reg_vsif_pb27_2
                    u8byte_idx = u8byte_idx - 60;
                }
                else if((u8byte_idx >= 90) && (u8byte_idx < 120))
                {
                    u32Base_add = REG_HDMI3_DUAL_0_30_L +u32HDMIBankOffset; // hdmi3_u0_30[7:0]: reg_vsif_hdr2_3; [15:8]: reg_vsif_hdr1_3; 31[7:0]: reg_vsif_pb01_3; [15:8]: reg_vsif_pb00_3; 3E[7:0]: reg_vsif_pb27_3
                    u8byte_idx = u8byte_idx - 90;
                }
            }
            break;

        default:
            break;
    }

    *pu8Value = MDrv_ReadByte(u32Base_add +u8byte_idx);

    return TRUE;
}

//=========================================================//
// Function : Hal_HDMI_acp_info
// Description: ACP_HDR1[7:0]
//=========================================================//
MS_U8 Hal_HDMI_audio_content_protection_info(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    return R2BYTEMSK(REG_HDMI_DUAL_0_16_L +u32HDMIBankOffset, LBMASK); // hdmi_u0_16[7:0]: reg_acp_hdr1
}

//=========================================================//
// Function : Hal_HDMI_audio_payload_info
// Description: ACP packet payload byte 0~15
//=========================================================//
MS_U8 Hal_HDMI_audio_payload_info(MS_U8 ucHDMIInfoSource, MS_U8 u8byte, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    if(u8byte%2)
    {
        return ((R2BYTEMSK(REG_HDMI_DUAL_0_17_L +u32HDMIBankOffset +(u8byte/2)*2, HBMASK)) >> 8); // hdmi_u0_17[7:0]: reg_acp_pb0
    }
    else
    {
        return R2BYTEMSK(REG_HDMI_DUAL_0_17_L +u32HDMIBankOffset +(u8byte/2)*2, LBMASK); // hdmi_u0_17[7:0]: reg_acp_pb0
    }
}

//=========================================================//
// Function : Hal_HDMI_err_status_update
// Description:
//=========================================================//
MS_U8 Hal_HDMI_err_status_update(MS_U8 ucHDMIInfoSource, MS_U8 u8value, MS_BOOL bread, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U8 u8ErrorStatus = 0;
    MS_U16 u16RegValue = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));

    if(bread)
    {
        u16RegValue = R2BYTE(REG_HDMIRX_DTOP_PKT_P0_10_L +u32DTOPBankOffset); // hdmirx_dtop_pkt_10[8]: Checksum Error occurred; packet discarded; [13]: BCH parity Error occurred; packet discarded; [15]: Single bit BCH parity Error occurred and Corrected

        if(u16RegValue & BIT(15))
        {
            u8ErrorStatus = u8ErrorStatus | HDMI_BCH_ERROR_CORRECTED;
        }
        if(u16RegValue & BIT(13))
        {
            u8ErrorStatus = u8ErrorStatus | HDMI_BCH_ERROR;
        }
        if(u16RegValue & BIT(8))
        {
            u8ErrorStatus = u8ErrorStatus | HDMI_CHECKSUM_ERROR;
        }
    }
    else
    {
        if(u8value & HDMI_BCH_ERROR_CORRECTED)
        {
            u16RegValue = u16RegValue | BIT(15);
        }
        if(u8value & HDMI_BCH_ERROR)
        {
            u16RegValue = u16RegValue | BIT(13);
        }
        if(u8value & HDMI_CHECKSUM_ERROR)
        {
            u16RegValue = u16RegValue | BIT(8);
        }

        W2BYTE(REG_HDMIRX_DTOP_PKT_P0_10_L +u32DTOPBankOffset, u16RegValue); // hdmirx_dtop_pkt_10[8]: Checksum Error occurred; packet discarded; [13]: BCH parity Error occurred; packet discarded; [15]: Single bit BCH parity Error occurred and Corrected
    }

    return u8ErrorStatus;
}
/******************************************************************************/
/// for HDMI AUDIO
/******************************************************************************/
//=========================================================//
// Function : Hal_HDMI_audio_output
// Description:
//=========================================================//
void Hal_HDMI_audio_output( MS_BOOL bEnable __attribute__ ((unused)))
{

}

//=========================================================//
// Function : Hal_HDMI_audio_channel_status
// Description: channel status byte 0~4
//=========================================================//
MS_U8 Hal_HDMI_audio_channel_status(MS_U8 ucHDMIInfoSource, MS_U8 u8byte, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    // 192 bit
    if(u8byte%2)
    {
        return ((R2BYTEMSK(REG_HDMI_DUAL_0_70_L +u32HDMIBankOffset +(u8byte/2)*2, HBMASK)) >> 8); // hdmi_70[7:0]: reg_hdmi_cs
    }
    else
    {
        return R2BYTEMSK(REG_HDMI_DUAL_0_70_L +u32HDMIBankOffset +(u8byte/2)*2, LBMASK); // hdmi_70[7:0]: reg_hdmi_cs
    }
}

/******************************************************************************/
/// for DVI
/******************************************************************************/
// Aaron comment: doesn't need in U3 because IC already has auto mode
//=========================================================//
// Function : Hal_DVI_clk_lessthan70mhz_usingportc
// Description:
//=========================================================//
MS_BOOL Hal_DVI_clk_lessthan70mhz_usingportc(MS_BOOL bIsPortC __attribute__ ((unused)) )
{
    // do nothing

    return FALSE;
}

//=========================================================//
// Function : Hal_DVI_clk_stable_usingportc
// Description:
//=========================================================//
MS_BOOL Hal_DVI_clk_stable_usingportc(MS_BOOL bIsPortC __attribute__ ((unused)))
{
    // do nothinig

    return FALSE;
}

//-------------------------------------------------------------------------------------------------
/// Returne Phase status
/// @param  bClockLessThan70MHz                \b IN: u8Channel
//-------------------------------------------------------------------------------------------------
MS_U16 Hal_DVI_ChannelPhaseStatus(MS_U8 u8Channel __attribute__ ((unused)))
{
    // do nothing

    return 0;
}

//=========================================================//
// Function : Hal_DVI_Accumulator_Monitor
// Description:
//=========================================================//
void Hal_DVI_Accumulator_Monitor( void )
{
    // do nothing
}


//=========================================================//
// Function : Hal_DVI_HF_adjust
// Description:
//=========================================================//
void Hal_DVI_HF_adjust( void )
{
    // do nothing
}

//=========================================================//
// Function : Hal_DVI_adc_adjust
// Description:
//=========================================================//
void Hal_DVI_adc_adjust(MS_BOOL bClockLessThan70MHz __attribute__ ((unused)))
{
    // do nothing
}

//=========================================================//
// Function : Hal_DVI_clklose_det
// Description:
//=========================================================//
MS_BOOL Hal_DVI_clklose_det(E_MUX_INPUTPORT enInputPortType) // 4M clock
{
    MS_BOOL bClockStable = FALSE;

    if(_Hal_tmds_GetClockStableFlag(enInputPortType))
    {
        bClockStable = TRUE;
    }

    return (!bClockStable);
}

void Hal_DVI_IMMESWITCH_PS_SW_Path(void)
{
    // do nothing
}

/******************************************************************************/
///DVI soft reset
/******************************************************************************/
void Hal_DVI_sw_reset(MS_U16 u16Reset __attribute__ ((unused)))
{
    // do nothing
}

//=========================================================//
// Function : Hal_DVI_irq_info
// Description:
//=========================================================//
MS_U16 Hal_DVI_irq_info(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), MS_U16 irqbit __attribute__ ((unused)))
{
    // do nothing

    return 0;
}

//=========================================================//
// Function : Hal_DVI_irq_clear
// Description:
//=========================================================//
void Hal_DVI_irq_mask(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), MS_U16 irqbit __attribute__ ((unused)))
{
    // do nothing
}

//=========================================================//
// Function : Hal_DVI_irq_forcemode
// Description:
//=========================================================//
void Hal_DVI_irq_forcemode(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), MS_U16 irqbit __attribute__ ((unused)))
{
    // do nothing
}

//=========================================================//
// Function : Hal_DVI_irq_clear
// Description:
//=========================================================//
void Hal_DVI_irq_clear(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), MS_U16 irqbit __attribute__ ((unused)))
{
    // do nothing
}

//=========================================================//
// Function : Hal_DVI_ClkPullLow
// Description:
//=========================================================//
void Hal_DVI_ClkPullLow(MS_BOOL bPullLow, E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32PHY2P1PMBankOffset = _Hal_tmds_GetPHYPMBankOffset(enInputPortType);

    W2BYTEMSK(REG_PHY2P1_PM_P0_42_L +u32PHY2P1PMBankOffset, bPullLow ? 0x0110 : 0, 0x0110); // phy2p1_pm_42[11:8]: reg_nodie_pd_rt_ov, phy2p1_pm_42[4]: reg_nodie_pd_clkin_ov
}

//=========================================================//
// Function : Hal_DVI_SwitchSrc
// Description:
//=========================================================//
void Hal_DVI_SwitchSrc(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), MS_U8 ucHDMIInfoSource __attribute__ ((unused)))
{
    // do nothing
}

void HAL_HDMI_DDCRam_SelectPort(E_XC_DDCRAM_PROG_TYPE eDDCRamType)
{
    switch(eDDCRamType)
    {
        case E_XC_PROG_DVI0_EDID:
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(14:14,DDC_RAM_SRAM_DVI),BMASK(14:14));
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(12:11,DDC_RAM_SRAM_DVI0),REG_DDC_SRAM_SEL_MASK);
            DDC_WRITE_MASK(REG_DDC_D0_SRAM_BASEADDR,BITS(4:0,DDC_OFFSET_SRAM_DVI0),REG_DDC_D0_BASEADDR_MASK);
            break;
        case E_XC_PROG_DVI1_EDID:
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(14:14,DDC_RAM_SRAM_DVI),BMASK(14:14));
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(12:11,DDC_RAM_SRAM_DVI1),REG_DDC_SRAM_SEL_MASK);
            DDC_WRITE_MASK(REG_DDC_D1_SRAM_BASEADDR,BITS(12:8,DDC_OFFSET_SRAM_DVI1),REG_DDC_D1_BASEADDR_MASK);
            break;
        case E_XC_PROG_DVI2_EDID:
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(14:14,DDC_RAM_SRAM_DVI),BMASK(14:14));
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(12:11,DDC_RAM_SRAM_DVI2),REG_DDC_SRAM_SEL_MASK);
            DDC_WRITE_MASK(REG_DDC_D2_SRAM_BASEADDR,BITS(4:0,DDC_OFFSET_SRAM_DVI2),REG_DDC_D2_BASEADDR_MASK);
            break;
        case E_XC_PROG_DVI3_EDID:
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(14:14,DDC_RAM_SRAM_DVI),BMASK(14:14));
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(12:11,DDC_RAM_SRAM_DVI3),REG_DDC_SRAM_SEL_MASK);
            DDC_WRITE_MASK(REG_DDC_D3_SRAM_BASEADDR,BITS(12:8,DDC_OFFSET_SRAM_DVI3),REG_DDC_D3_BASEADDR_MASK);
            break;
        case E_XC_PROG_VGA_EDID:
            DDC_WRITE_MASK(REG_DDC_SRAM_SEL,BITS(14:14,DDC_RAM_SRAM_ADC),BMASK(14:14));
            DDC_WRITE_MASK(REG_DDC_A_SRAM_BASEADDR,BITS(12:8,DDC_OFFSET_SRAM_ADC),REG_DDC_A_BASEADDR_MASK);
            break;
        default:
            //ASSERT("Not support!\n");
            break;
    }
}

void HAL_HDMI_DDCRAM_SetPhyAddr(XC_DDCRAM_PROG_INFO *pstDDCRam_Info __attribute__ ((unused)))
{
    // do nothing
}

//**************************************************************************
//  [Function Name]:
//                  HAL_HDMI_LoadEDIDNewMode()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void HAL_HDMI_LoadEDIDNewMode(E_XC_DDCRAM_PROG_TYPE eDDCRamType, MS_U16 u16EDIDSize, MS_U8 *pu8EDIDTable)
{
    MS_U8 u8temp = 0;
    MS_U8 u8EDIDBlock = 0;
    MS_U8 u8EDIDBlockSize = 0;
    MS_U8 u8SRAMBaseOffset = 0;
    MS_U16 u16EDIDTableIndex = 0;

    switch(u16EDIDSize)
    {
        case HDMI_EDID_SUPPORT_128:
            u8EDIDBlockSize = 1;
            break;

        case HDMI_EDID_SUPPORT_256:
            u8EDIDBlockSize = 2;
            break;

        case HDMI_EDID_SUPPORT_384:
            u8EDIDBlockSize = 3;
            break;

        case HDMI_EDID_SUPPORT_512:
            u8EDIDBlockSize = 4;
            break;

        default:
            break;
    };

    W2BYTEMSK(REG_DDC_76_L, BIT(15), BIT(15));

    switch(eDDCRamType)
    {
        case E_XC_PROG_DVI0_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI0;
            break;
        case E_XC_PROG_DVI1_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI1;
            break;
        case E_XC_PROG_DVI2_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI2;
            break;
        case E_XC_PROG_DVI3_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI3;
            break;
        case E_XC_PROG_VGA_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_ADC;
            break;
        default:
            //ASSERT("Not support!\n");
            break;
    }

    for(u8EDIDBlock = 0; u8EDIDBlock < u8EDIDBlockSize; u8EDIDBlock++)
    {
        W2BYTEMSK(REG_DDC_75_L, u8SRAMBaseOffset +u8EDIDBlock, BMASK(4:0));

        for(u8temp = 0; u8temp < 128; u8temp++)
        {
            DDC_WRITE_MASK(REG_DDC_D_ACCESS,REG_DDC_D_ACCESS_BITS(0), REG_DDC_D_ACCESS_MASK);
            DDC_WRITE_MASK(REG_DDC_D_WRITEADDR,REG_DDC_D_WRITEADDR_BITS(u8temp), REG_DDC_D_WRITEADDR_MASK);
            DDC_WRITE_MASK(REG_DDC_D_WRITEDATA,REG_DDC_D_WRITEDATA_BITS(*(pu8EDIDTable +u16EDIDTableIndex +u8temp)), REG_DDC_D_WRITEDATA_MASK);
            DDC_WRITE_MASK(REG_DDC_D_WRITEPULSE,REG_DDC_D_WRITEPULSE_BITS(1), REG_DDC_D_WRITEPULSE_MASK);

            MsOS_DelayTaskUs(1);
        }

        u16EDIDTableIndex = u16EDIDTableIndex +128;
    }
}

//**************************************************************************
//  [Function Name]:
//                  HAL_HDMI_ReadEDIDNewMode()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void HAL_HDMI_ReadEDIDNewMode(E_XC_DDCRAM_PROG_TYPE eDDCRamType, MS_U16 u16EDIDSize, MS_U8 *pu8EDIDTable)
{
    MS_U8 u8temp = 0;
    MS_U8 u8EDIDBlock = 0;
    MS_U8 u8EDIDBlockSize = 0;
    MS_U8 u8SRAMBaseOffset = 0;
    MS_U16 u16EDIDTableIndex = 0;

    switch(u16EDIDSize)
    {
        case HDMI_EDID_SUPPORT_128:
            u8EDIDBlockSize = 1;
            break;

        case HDMI_EDID_SUPPORT_256:
            u8EDIDBlockSize = 2;
            break;

        case HDMI_EDID_SUPPORT_384:
            u8EDIDBlockSize = 3;
            break;

        case HDMI_EDID_SUPPORT_512:
            u8EDIDBlockSize = 4;
            break;

        default:
            break;
    };

    W2BYTEMSK(REG_DDC_76_L, BIT(15), BIT(15));

    switch(eDDCRamType)
    {
        case E_XC_PROG_DVI0_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI0;
            break;
        case E_XC_PROG_DVI1_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI1;
            break;
        case E_XC_PROG_DVI2_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI2;
            break;
        case E_XC_PROG_DVI3_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_DVI3;
            break;
        case E_XC_PROG_VGA_EDID:
            u8SRAMBaseOffset = DDC_OFFSET_SRAM_ADC;
            break;
        default:
            //ASSERT("Not support!\n");
            break;
    }

    for(u8EDIDBlock = 0; u8EDIDBlock < u8EDIDBlockSize; u8EDIDBlock++)
    {
        W2BYTEMSK(REG_DDC_75_L, u8SRAMBaseOffset +u8EDIDBlock, BMASK(4:0));

        for(u8temp = 0; u8temp < 128; u8temp++)
        {
            DDC_WRITE_MASK(REG_DDC_A_ACCESS,REG_DDC_A_ACCESS_BITS(1),REG_DDC_A_ACCESS_MASK);
            DDC_WRITE_MASK(REG_DDC_A_WRITEADDR,REG_DDC_A_WRITEADDR_BITS(u8temp),REG_DDC_A_WRITEADDR_MASK);
            DDC_WRITE_MASK(REG_DDC_A_READPULSE,REG_DDC_A_READPULSE_BITS(1),REG_DDC_A_READPULSE_MASK);

            while(R2BYTE(REG_DDC_3D_L) & BIT(12)); // ADC_0 cpu rd busy status (rd for ADC sram)

            *(pu8EDIDTable + u8temp +u16EDIDTableIndex) = (MS_U8)(DDC_READ_MASK(REG_DDC_A_READDATA, REG_DDC_A_READDATA_MASK)>>8);
        }

        u16EDIDTableIndex = u16EDIDTableIndex +128;

        if(u8EDIDBlock < HDMI_EDID_1BLOCK)
        {
            u8EDIDBlockSize = *(pu8EDIDTable + HDMI_EDID_EXTENSION_FLAG_ADDRESS) +1;

            if(u8EDIDBlockSize > HDMI_EDID_4BLOCK) // check max block support size
            {
                u8EDIDBlockSize = HDMI_EDID_4BLOCK;
            }
        }
    }
}

//=========================================================//
// Function : Hal_DVI_GetPowerSavingStatus
// Description: Get power saving mode status
// return:  TRUE: stable, FALSE: unstable
//=========================================================//
MS_BOOL Hal_DVI_GetPowerSavingStatus(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)))
{
    return FALSE;
}

//=========================================================//
// Function : Hal_DVI_GetDEStableStatus
// Description: Get DE stable status for Immeswitch power saving mode
// return:  TRUE: stable, FALSE: unstable
//=========================================================//
MS_BOOL Hal_DVI_GetDEStableStatus(E_MUX_INPUTPORT enInputPortType)
{
    MS_BOOL bDEStableFlag = FALSE;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(R2BYTE(REG_DVI_DTOP_DUAL_P0_30_L + u32DTOPBankOffset) & BIT(5)) // hdmirx_dtop_30[5]: reg_de_stable
    {
        bDEStableFlag = TRUE;
    }

    return bDEStableFlag;
}

//=========================================================//
// Function : Hal_DVI_EnhanceImmeswitch
// Description: Enable / Disable Immeswitch enhancement
//=========================================================//
void Hal_DVI_EnhanceImmeswitch(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), MS_BOOL bflag __attribute__ ((unused)))
{
    // do nothing
}

//=========================================================//
// Function : Hal_DVI_ForceAllPortsEnterPS
// Description: Force all DVI ports enter power saving mode
//=========================================================//
void Hal_DVI_ForceAllPortsEnterPS(void)
{
    // do nothing
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//                                HDMI 1.4 new feature:
//                                1. 3D format
//                                2. 4K x 2K format
//                                3. ARC
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// HDMI_Video_Format: Vendor Specifc Info-frame, PB4[7:5]
//   000: No additional HDMI video format is presented in this packet
//   001: Extended resolution format (e.g. 4Kx2K video) present
//   010: 3D format indication present
//   011~111: Reserved
E_HDMI_ADDITIONAL_VIDEO_FORMAT Hal_HDMI_Check_Additional_Format(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);
    E_HDMI_ADDITIONAL_VIDEO_FORMAT val = E_HDMI_RESERVED;

    if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(7:5)) == 0)
    {
        val = E_HDMI_NO_ADDITIONAL_FORMAT;
    }
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(7:5)) == BIT(5))
    {
        val = E_HDMI_4Kx2K_FORMAT;
    }
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(7:5)) == BIT(6))
    {
        val = E_HDMI_3D_FORMAT;
    }
    else
    {
        // Do nothing for XC code review
    }

    return val;
}

// 3D_Structure: Vendor Specifc Info-frame, PB5[7:4]
//   0000: Frame packing
//   0001: Field alternative
//   0010: Line alternative
//   0011: Side-by-Side(Full)
//   0100: L+depth
//   0101: L+depth+graphics+graphics-depth
//   0110: Top-and-Bottom
//   0111: Reserved
//   1000: Side-by-Side(Half)
//   1001 ~ 1111: Reserved
E_XC_3D_INPUT_MODE Hal_HDMI_Get_3D_Structure(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);
    E_XC_3D_INPUT_MODE val = E_XC_3D_INPUT_MODE_NONE;

    if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == 0)
        val = E_XC_3D_INPUT_FRAME_PACKING;
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == BIT(12))
        val = E_XC_3D_INPUT_FIELD_ALTERNATIVE;
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == BIT(13))
        val = E_XC_3D_INPUT_LINE_ALTERNATIVE;
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == (BIT(13)|BIT(12)))
        val = E_XC_3D_INPUT_SIDE_BY_SIDE_FULL;
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == BIT(14))
        val = E_XC_3D_INPUT_L_DEPTH;
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == (BIT(14)|BIT(12)))
        val = E_XC_3D_INPUT_L_DEPTH_GRAPHICS_GRAPHICS_DEPTH;
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == (BIT(14)|BIT(13)))
        val = E_XC_3D_INPUT_TOP_BOTTOM;
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:12)) == BIT(15))
        val = E_XC_3D_INPUT_SIDE_BY_SIDE_HALF;
    else
        val = E_XC_3D_INPUT_MODE_NONE;

    return val;
}

// 3D_Ext_Data: Vendor Specifc Info-frame, PB6[7:4]
//   0000 ~ 0011 : Horizontal sub-sampling
//   0100: Quincunx matrix - Odd/Left  picture, Odd/Right  picture
//   0101: Quincunx matrix - Odd/Left  picture, Even/Right picture
//   0110: Quincunx matrix - Even/Left picture, Odd/Right  picture
//   0111: Quincunx matrix - Even/Left picture, Even/Right picture
//   1000 ~ 1111: Reserved
E_HDMI_3D_EXT_DATA_T Hal_HDMI_Get_3D_Ext_Data(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U16 u16temp = 0;
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);
    E_HDMI_3D_EXT_DATA_T e_3d_extdata = E_3D_EXT_DATA_MODE_MAX;

    u16temp = R2BYTEMSK(REG_HDMI_DUAL_0_35_L +u32HDMIBankOffset, BMASK(7:4));

    switch(u16temp)
    {
        case 0x0000:
            e_3d_extdata = E_3D_EXT_DATA_HOR_SUB_SAMPL_0;
            break;
        case 0x0010:
            e_3d_extdata = E_3D_EXT_DATA_HOR_SUB_SAMPL_1;
            break;
        case 0x0020:
            e_3d_extdata = E_3D_EXT_DATA_HOR_SUB_SAMPL_2;
            break;
        case 0x0030:
            e_3d_extdata = E_3D_EXT_DATA_HOR_SUB_SAMPL_3;
            break;
        case 0x0040:
            e_3d_extdata = E_3D_EXT_DATA_QUINCUNX_MATRIX_0;
            break;
        case 0x0050:
            e_3d_extdata = E_3D_EXT_DATA_QUINCUNX_MATRIX_1;
            break;
        case 0x0060:
            e_3d_extdata = E_3D_EXT_DATA_QUINCUNX_MATRIX_2;
            break;
        case 0x0070:
            e_3d_extdata = E_3D_EXT_DATA_QUINCUNX_MATRIX_3;
            break;
        default:
            e_3d_extdata = E_3D_EXT_DATA_MODE_MAX;
            break;
    };

    return e_3d_extdata;
}

// 3D_Meta_Field: Vendor Specifc Info-frame, PB5[3], PB7 ~ PB7+N
//   - 3D_Meta_Present: PB5[3]
//   - 3D_Metadata_Type: PB7[7:5]
//       000: parallax information defined in ISO23002-3
//       001 ~ 111: reserved
//   - 3D_Metadata_Length(N, N <= 31-8 = 23): PB7[4:0]
//   - 3D_Metadata[] : PB8 ~ PB7+N
void Hal_HDMI_Get_3D_Meta_Field(MS_U8 ucHDMIInfoSource, sHDMI_3D_META_FIELD *pdata, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U16 u16temp = 0;
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    pdata->b3D_Meta_Present = R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BIT(11)) > 0 ? TRUE : FALSE;
    u16temp = R2BYTEMSK(REG_HDMI_DUAL_0_35_L +u32HDMIBankOffset, BMASK(15:13));

    switch(u16temp)
    {
        case 0x0000:
            pdata->t3D_Metadata_Type = E_3D_META_DATA_PARALLAX_ISO23002_3;
            break;
        case 0x2000:
        case 0x3000:
        case 0x4000:
        case 0x5000:
        case 0x6000:
        case 0x7000:
            pdata->t3D_Metadata_Type = E_3D_META_DATA_RESERVE;
            break;
        default:
            pdata->t3D_Metadata_Type = E_3D_META_DATA_MAX;
            break;
    }

    pdata->u83D_Metadata_Length = (MS_U8)(R2BYTEMSK(REG_HDMI_DUAL_0_35_L +u32HDMIBankOffset, BMASK(12:8)) >> 8);

    for(u16temp = 0; u16temp < pdata->u83D_Metadata_Length; u16temp++)
    {
        pdata->u83D_Metadata[u16temp] = R2BYTEMSK(REG_HDMI_DUAL_0_36_L +u32HDMIBankOffset +u16temp, BMASK(7:0));
    }
}

// VIC_CODE: Auxiliary Video Information Info-frame, PB4[6:0]
MS_U8 Hal_HDMI_Get_VIC_Code(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U8 val = 0;

    val = (Hal_HDMI_avi_infoframe_info(ucHDMIInfoSource, _BYTE_4, NULL));

    return val;
}

// 4Kx2K VIC code: Vendor Specifc Info-frame, PB5[7:0]
//   0x01: 1920(x2)x1080(x2) @ 29.97/30Hz
//   0x02: 1920(x2)x1080(x2) @ 25Hz
//   0x03: 1920(x2)x1080(x2) @ 23.976/24Hz
//   0x04: 2048(x2)x1080(x2) @ 24Hz
//   0x00, 0x05 ~ 0xFF: Reserved
E_HDMI_VIC_4Kx2K_CODE Hal_HDMI_Get_4Kx2K_VIC_Code(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);
    E_HDMI_VIC_4Kx2K_CODE val = E_VIC_RESERVED;

    if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:8)) >> 8 == 0x01)
    {
        val = E_VIC_4Kx2K_30Hz;
    }
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:8)) >> 8 == 0x02)
    {
        val = E_VIC_4Kx2K_25Hz;
    }
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:8)) >> 8 == 0x03)
    {
        val = E_VIC_4Kx2K_24Hz;
    }
    else if (R2BYTEMSK(REG_HDMI_DUAL_0_34_L +u32HDMIBankOffset, BMASK(15:8)) >> 8 == 0x04)
    {
        val = E_VIC_4Kx2K_24Hz_SMPTE;
    }
    else
    {
        // Do nothing for XC code review
    }

    return val;
}

// It must set to non-bypass(0) when input source is detected as HDMI 3D format
// 0: no bypass, 1: bypass
void Hal_HDMI_Set_YUV422to444_Bypass(MS_BOOL btrue __attribute__ ((unused)))
{
    // do nothing
}

// Check whether input pixel rate is large 166MHz or not.
MS_BOOL Hal_HDMI_Is_Input_Large_166MHz(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_BOOL bflag = FALSE;
    MS_U16 reg_val = 0;
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    reg_val = R2BYTEMSK(REG_HDMI2_DUAL_0_36_L +u32HDMIBankOffset, BMASK(12:0));

    if ((reg_val/128)*12 >= 166)
        bflag = TRUE;

    return bflag;
}

// If input format is 3D or 4Kx2K and pixel rate large than 166MHz, it need to do the horizontal scaling down.
void Hal_HDMI_AVG_ScaleringDown(MS_U8 ucHDMIInfoSource __attribute__ ((unused)), MS_BOOL btrue __attribute__ ((unused)))
{
    // do nothing
}

// HDMI ARC pin control
//     - enInputPortType: INPUT_PORT_DVI0 / INPUT_PORT_DVI1 / INPUT_PORT_DVI2 / INPUT_PORT_DVI3
//     - bEnable: ARC enable or disable
//     - bDrivingHigh: ARC driving current high or low
void Hal_HDMI_ARC_PINControl(E_MUX_INPUTPORT enInputPortType, MS_BOOL bEnable , MS_BOOL bDrivingHigh __attribute__ ((unused)))
{
//	 TO  mt5870 can not access EARC bank

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0: // A
        case INPUT_PORT_DVI1: // B
        case INPUT_PORT_DVI2: // C
        case INPUT_PORT_DVI3: // D
            W2BYTEMSK(REG_CHIPTOP_GPIO_FUNC_MUX_3E_L, bEnable ? BIT(0) : 0, BIT(0)); // PAD_ARC MODE Function
            break;
        default:
            break;
    }
    //Driving level decided by efuse trim value.0000 trim pad voltage should be ~0.52V, using trim 1000 it should be ~0.58V
    //W2BYTEMSK(REG_CHIPTOP_GPIO_AUDIO_78_L, bDrivingHigh ? BIT(7) : 0, BMASK(7:4));//322e_0x78[7:4],reg_gpio_arc_drv0/1/2/3_00

}

/******************************************************************************/
///DVI soft reset
/******************************************************************************/
//[6]: soft-reset hdmi
//[5]: soft-reset hdcp
//[4]: soft-reset dvi
void Hal_DVI_Software_Reset(E_MUX_INPUTPORT enInputPortType, MS_U16 u16Reset)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    if(u16Reset &HDMI_SW_RESET_DVI) // Bit4
    {
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3E_L +u32DTOPBankOffset, BIT(0)); // hdmirx_dtop_3E[0]: dvi sw reset
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3E_L +u32DTOPBankOffset, 0);
    }

    if(u16Reset &HDMI_SW_RESET_HDCP) // Bit5
    {
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3E_L +u32DTOPBankOffset, BIT(2)); // hdmirx_dtop_3E[2]: hdcp sw reset
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3E_L +u32DTOPBankOffset, 0);
    }

    if(u16Reset &HDMI_SW_RESET_HDMI) // Bit6
    {
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3E_L +u32DTOPBankOffset, BIT(3)); // hdmirx_dtop_3E[3]: hdmi sw reset
        W2BYTE(REG_DVI_DTOP_DUAL_P0_3E_L +u32DTOPBankOffset, 0);
    }

    if(u16Reset &HDMI_SW_RESET_DVI2MIU) // Bit10
    {
        W2BYTE(REG_COMBO_GP_TOP_34_L, BIT(1)); // combo_gp_top_34[1]: reset dvi2miu
        W2BYTE(REG_COMBO_GP_TOP_34_L, 0);
    }

    if(u16Reset &HDMI_SW_RESET_AUDIO_FIFO) // Bit15
    {
        W2BYTEMSK(REG_COMBO_GP_TOP_49_L, BIT(12), BIT(12)); // combo_gp_top_49[12]: reg_afifo_rst
        W2BYTEMSK(REG_COMBO_GP_TOP_49_L, 0, BIT(12));
    }
}

MS_U16 Hal_HDMI_GetTMDSFreq(void)
{
    return 0;
}

// Hal_HDMI_CheckHDMI20_Setting
//     - enInputPortType: INPUT_PORT_DVI0 / INPUT_PORT_DVI1 / INPUT_PORT_DVI2 / INPUT_PORT_DVI3
//     - Check input is over/under 3.4G and color format, and do the related setting
MS_BOOL Hal_HDMI_CheckHDMI20_Setting(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)))
{
    return FALSE; // Always report 1P mode
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_StablePolling()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDMI_StablePolling(MS_U8 ucMHLSupportPath __attribute__ ((unused)), MS_U32 *ulPacketStatus, stHDMI_POLLING_INFO *stHDMIPollingInfo, HDCP14_AccessWriteProtectedReg_CBF fpHdcp14_AccessWriteProtectedReg __attribute__ ((unused)))
{
    E_MUX_INPUTPORT enPortIndex = INPUT_PORT_DVI0;

    for(enPortIndex = INPUT_PORT_DVI0; enPortIndex <= INPUT_PORT_DVI_END; enPortIndex++)
    {
        _Hal_tmds_BusyPolling(enPortIndex, &stHDMIPollingInfo[HDMI_GET_PORT_SELECT(enPortIndex)]);

        _Hal_tmds_SignalDetectProc(enPortIndex, ulPacketStatus[stHDMIPollingInfo[HDMI_GET_PORT_SELECT(enPortIndex)].ucHDMIInfoSource], &stHDMIPollingInfo[HDMI_GET_PORT_SELECT(enPortIndex)]);

        _Hal_tmds_FastTrainingProc(enPortIndex, &stHDMIPollingInfo[HDMI_GET_PORT_SELECT(enPortIndex)]);
    }
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_Set5VDetectGPIOSelect()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDMI_Set5VDetectGPIOSelect(MS_U32 ul5VDetectGPIOIndex __attribute__ ((unused)))
{
    // do nothing
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_SwitchVSDBtoHDRPacket()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDMI_SwitchVSDBtoHDRPacket(MS_BOOL bEnableHDR __attribute__ ((unused)))
{
    // do nothing
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_Get_InfoFrame()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_HDMI_Get_InfoFrame(MS_U8 ucHDMIInfoSource, MS_HDMI_PACKET_STATE_t u8state, void *pData, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_BOOL bRet = FALSE;
    MS_U8 uctemp = 0;
    MS_U16 usPacketContent = 0;
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    switch(u8state)
    {
        case PKT_HDR:
            {
                MS_U16 *pInfFrame = (MS_U16*)pData;

                for(uctemp = 0; uctemp < HDMI_HDR_PACKET_SIZE; uctemp++)
                {
                    usPacketContent = R2BYTE(REG_HDMI2_DUAL_0_61_L +u32HDMIBankOffset +uctemp *2); // hdmi2_u0_61[7:0]: reg_hdr_pb01

                    pInfFrame[uctemp] = (usPacketContent << 8) | (usPacketContent >> 8);
                }

                bRet = TRUE;
            }
            break;

        default:
            break;
    };

    return bRet;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_DataRtermControl()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDMI_DataRtermControl(E_MUX_INPUTPORT enInputPortType, MS_BOOL bDataRtermEnable)
{
    MS_U32 u32PHY2P1PMBankOffset = _Hal_tmds_GetPHYPMBankOffset(enInputPortType);

    W2BYTEMSK(REG_PHY2P1_PM_P0_42_L +u32PHY2P1PMBankOffset, bDataRtermEnable ? 0 : BMASK(11:9), BMASK(11:9)); // phy2p1_pm_42[11:8]: reg_nodie_pd_rt_ov
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetSCDCValue()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_HDMI_GetSCDCValue(E_MUX_INPUTPORT enInputPortType, MS_U8 u8Offset)
{
    MS_U8 u8XA8Data = 0;
    MS_U32 u32PMSCDCBankOffset = _Hal_tmds_GetPMSCDCBankOffset(enInputPortType);

    W2BYTEMSK(REG_PM_SCDC_P0_02_L +u32PMSCDCBankOffset, 0, BIT(13)); // scdc_02[13]: Enable CPU write (not enable)

    W2BYTEMSK(REG_PM_SCDC_P0_02_L +u32PMSCDCBankOffset, u8Offset, BMASK(9:0)); // scdc_02[9:0]: SCDC CPU r/w address
    W2BYTEMSK(REG_PM_SCDC_P0_02_L +u32PMSCDCBankOffset, BIT(10), BIT(10)); // scdc_02[10]: SCDC address load pulse generate

    // wait read ready
    while(R2BYTE(REG_PM_SCDC_P0_04_L +u32PMSCDCBankOffset) & BIT(9)); // scdc_04[9]: CPU read busy status

    u8XA8Data = R2BYTE(REG_PM_SCDC_P0_04_L +u32PMSCDCBankOffset) & BMASK(7:0); // scdc_04[7:0]: CPU read data port (for scdc)

    return u8XA8Data;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetSCDCCableDetectFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_HDMI_GetSCDCCableDetectFlag(E_MUX_INPUTPORT enInputPortType)
{
    MS_BOOL bCableDetectFlag = FALSE;
    MS_U32 u32PMSCDCBankOffset = _Hal_tmds_GetPMSCDCBankOffset(enInputPortType);

    bCableDetectFlag = ((R2BYTE(REG_PM_SCDC_P0_0C_L +u32PMSCDCBankOffset) & BIT(6)) ?TRUE: FALSE); // scdc_0C[6]: reg_tx_5v_reset_c

    return bCableDetectFlag;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetSourceSelect()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_HDMI_GetSourceSelect(E_MUX_INPUTPORT enInputPortType)
{
    MS_U8 ucHDMIInfoSource; // For coverity unused value

    ucHDMIInfoSource = HDMI_GET_PORT_SELECT(enInputPortType);

    if(ucHDMIInfoSource == HDMI_INFO_SOURCE_MAX)
    {
        ucHDMIInfoSource = HDMI_INFO_SOURCE_NONE;
    }

    return ucHDMIInfoSource;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetPortToSourceMapping()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_HDMI_GetPortToSourceMapping(E_MUX_INPUTPORT enInputPortType)
{
    MS_U8 ucHDMIInfoSource = HDMI_INFO_SOURCE_NONE;

    switch(enInputPortType)
    {
        case INPUT_PORT_DVI0:
            ucHDMIInfoSource = HDMI_INFO_SOURCE0;
            break;

        case INPUT_PORT_DVI1:
            ucHDMIInfoSource = HDMI_INFO_SOURCE1;
            break;

        case INPUT_PORT_DVI2:
            ucHDMIInfoSource = HDMI_INFO_SOURCE2;
            break;

        case INPUT_PORT_DVI3:
            ucHDMIInfoSource = HDMI_INFO_SOURCE3;
            break;

        default:
            break;
    };

    return ucHDMIInfoSource;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetAverageModeFlag()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_HDMI_GetAverageModeFlag(E_MUX_INPUTPORT UNUSED_PARA(enInputPortType))
{
    return FALSE;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetISRC1HeaderInfo()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_HDMI_GetISRC1HeaderInfo(MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    return R2BYTEMSK(REG_HDMI_DUAL_0_1F_L +u32HDMIBankOffset, LBMASK); // hdmi_u0_1F[7:0]: reg_isrc1_hdr1
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_Get_AudioInfo()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDMI_Get_AudioInfo(stHDMI_AUDIO_INFO *pstAudioInfo, MS_U8 ucHDMIInfoSource, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U8 u8FRLRate = _Hal_tmds_GetFRLRate((E_MUX_INPUTPORT)(INPUT_PORT_DVI0 +ucHDMIInfoSource));
    MS_U32 u32HDMIBankOffset = _Hal_tmds_GetHDMIBankOffset(ucHDMIInfoSource);

    if((pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI14)
        || (pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI20))
    {
        W2BYTE(REG_HDMI_DUAL_0_12_L +u32HDMIBankOffset, 0xFFFF); // hdmi_u0_12[15:0]: CTS[15:0] from ACR packet
        W2BYTE(REG_HDMI_DUAL_0_13_L +u32HDMIBankOffset, 0xFFFF); // hdmi_u0_13[15:0]: N[15:0] from ACR packet
        W2BYTEMSK(REG_HDMI_DUAL_0_14_L +u32HDMIBankOffset, 0xFF, 0xFF); // hdmi_u0_14[7:4]: N[19:16]; [3:0]: CTS[19:16] from ACR packet

        pstAudioInfo->u32AudioInfo_CTS = (R2BYTEMSK(REG_HDMI_DUAL_0_14_L +u32HDMIBankOffset,BMASK(3:0)) << 16) + R2BYTE(REG_HDMI_DUAL_0_12_L +u32HDMIBankOffset);
        pstAudioInfo->u32AudioInfo_N = (R2BYTEMSK(REG_HDMI_DUAL_0_14_L +u32HDMIBankOffset,BMASK(7:4)) << 12) + R2BYTE(REG_HDMI_DUAL_0_13_L +u32HDMIBankOffset);

        if(!pstHDMIPollingInfo->bNoInputFlag)
        {
            pstAudioInfo->u32ClockRates = 1000 * pstHDMIPollingInfo->usClockCount;
        }

        if(pstAudioInfo->u32AudioInfo_CTS != 0)
        {
            // fs = ftmds_clk * N / (CTS * 128)
            //u32AudioInfo_FS = u32ClockRates * u32AudioInfo_N / (u32AudioInfo_CTS * HDMI_XTAL_DIVIDER);
            pstAudioInfo->u32AudioInfo_FS = pstAudioInfo->u32ClockRates * pstAudioInfo->u32AudioInfo_N / (pstAudioInfo->u32AudioInfo_CTS * HDMI_XTAL_DIVIDER);
        }

        pstAudioInfo->u8AudioMux = R2BYTEMSK(REG_COMBO_GP_TOP_4B_L +u32HDMIBankOffset, BMASK(1:0));
        pstAudioInfo->u8AudioStatusEnable = R2BYTEMSK(REG_COMBO_GP_TOP_4D_L +u32HDMIBankOffset, BMASK(7:0));
        pstAudioInfo->u8AudioMuteEnable = R2BYTEMSK(REG_COMBO_GP_TOP_4A_L +u32HDMIBankOffset, BMASK(7:0));
    }
    else if(pstHDMIPollingInfo->ucSourceVersion == HDMI_SOURCE_VERSION_HDMI21)
    {
    }
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_WriteX74()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_HDCP_WriteX74(E_MUX_INPUTPORT enInputPortType, MS_U8 ubOffset, MS_U8 ubData)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, BIT(10), BIT(10)); // [10]: HDCP enable for DDC
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(15), BIT(15)|BIT(14)); // [15]: CPU write enable, [14]: 0: 74 RAM, 1 :HDCP RAM

    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, ubOffset, BMASK(9:0)); // address
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(5), BIT(5)); // trigger latch address

    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_18_L +u32DTOPBankOffset, ubData, BMASK(7:0)); // data
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(4), BIT(4)); // trigger latch data

    while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(7)); // wait write ready
    while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(7)); // wait write ready

    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, 0, BIT(15)|BIT(14)); // [15]: CPU write disable, [14]: 0: 74 RAM, 1 :HDCP RAM

    return TRUE;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_ReadX74()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_HDCP_ReadX74(E_MUX_INPUTPORT enInputPortType, MS_U8 ubOffset)
{
    MS_U16 usRData = 0xFFFF;
    MS_U8 ucX74Data; // For coverity unused value
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, BIT(10), BIT(10)); // [10]: HDCP enable for DDC
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, 0, BIT(15)|BIT(14)); // [15]: CPU write enable, [14]: 0: 74 RAM, 1 :HDCP RAM

    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_17_L +u32DTOPBankOffset, ubOffset, BMASK(9:0)); // address
    HDCP_W2BYTEMSK(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset, BIT(5), BIT(5)); // trigger latch address

    while(R2BYTE(REG_HDCP_DUAL_P0_19_L +u32DTOPBankOffset) & BIT(6)); // wait read ready

    usRData = HDCP_R2BYTEMSK(REG_HDCP_DUAL_P0_18_L +u32DTOPBankOffset, BMASK(15:0)); // read data
    ucX74Data = (MS_U8) ((usRData & 0xFF00) >> 8);

    return ucX74Data;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_SetReady()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDCP_SetReady(E_MUX_INPUTPORT enInputPortType, MS_BOOL bIsReady)
{
    MS_U8 ucBcaps = 0x00;

    ucBcaps = Hal_HDCP_ReadX74(enInputPortType, 0x40);//Read Bcaps

    if(bIsReady)
    {
        ucBcaps = ucBcaps | 0x20;
    }
    else
    {
        ucBcaps = ucBcaps & 0xDF;
    }

    Hal_HDCP_WriteX74(enInputPortType, 0x40, ucBcaps);
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_WriteKSVList()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDCP_WriteKSVList(E_MUX_INPUTPORT enInputPortType, MS_U8* pucData, MS_U32 ulDataLen)
{
    MS_U8 ucPortIdx = 0;
    MS_U8 ucRegOffset = 0;
    MS_U32 ultemp = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    ucPortIdx = (MS_U8)(enInputPortType - INPUT_PORT_DVI0);

    ucRegOffset = ucPortIdx * 0x04;

    W2BYTEMSK(REG_COMBO_GP_TOP_40_L, BIT(2)| BIT(0), BMASK(2:0)); //enable XIU write
    W2BYTEMSK(REG_HDCPKEY_04_L +ucRegOffset, TMDS_HDCP2_SOURCE_READ_OFFSET, 0x7FF); //set address

    for(ultemp = 0; ultemp < ulDataLen; ultemp++)
    {
        W2BYTEMSK(REG_HDCPKEY_05_L +ucRegOffset, *(pucData + ultemp), BMASK(7:0));
    }

    W2BYTEMSK(REG_HDCP_DUAL_P0_63_L +u32DTOPBankOffset, ulDataLen, 0x7FF); // write length

    W2BYTEMSK(REG_HDCP_DUAL_P0_64_L +u32DTOPBankOffset, BIT(15), BIT(15)); // address pulse
    W2BYTEMSK(REG_HDCP_DUAL_P0_65_L +u32DTOPBankOffset, BIT(15)|BIT(14), BIT(15)|BIT(14));

    W2BYTEMSK(REG_COMBO_GP_TOP_40_L, 0, BMASK(2:0)); //disable XIU write
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_ClearStatus()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDCP_ClearStatus(E_MUX_INPUTPORT enInputPortType, MS_U16 usInt)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    HDCP_W2BYTE(REG_HDCP_DUAL_P0_01_L +u32DTOPBankOffset, usInt << 8); // hdmirx_hdcp_01[15:8]
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_WriteDoneInterruptEnable()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDCP_WriteDoneInterruptEnable(E_MUX_INPUTPORT enInputPortType, MS_BOOL bEnableIRQ)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_3B_L +u32DTOPBankOffset, bEnableIRQ? 0: BIT(14), BIT(14)); // hdmirx_dtop_3B[14]: reg_adcdvi_irq_mask
    W2BYTEMSK(REG_HDCP_DUAL_P0_15_L +u32DTOPBankOffset, bEnableIRQ? 0: BIT(15), BIT(15)); // hdmirx_hdcp_15[15]: reg_mask_irq_level
    W2BYTEMSK(REG_HDCP_DUAL_P0_67_L +u32DTOPBankOffset, bEnableIRQ? 0: BIT(3)|BIT(2), BIT(3)|BIT(2)); // hdmirx_hdcp_67[2]: reg_hdcp_v22_interrupt_mask - ack_message_write_done; [3]: ack_message_read_done
}

E_HDMI_PIPELINE_MODE Hal_HDMI_GetPipeLineMode(void)
{
    E_HDMI_PIPELINE_MODE eReturn;
    //1.4 chip is 1p mode
    eReturn = MS_HDMI_PIPELINE_2P;
    return eReturn;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_ReadR0InterruptEnable()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDCP_ReadR0InterruptEnable(E_MUX_INPUTPORT enInputPortType, MS_BOOL bEnableIRQ)
{
    MS_U32 ulMACBankOffset = 0;
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);
    //printf("HDCP Read R0 Enable : port %d\r\n", enInputPortType);

    W2BYTEMSK(REG_DVI_DTOP_DUAL_P0_3B_L +u32DTOPBankOffset, bEnableIRQ? 0: BIT(14), BIT(14));
    W2BYTEMSK(REG_HDCP_DUAL_P0_15_L +u32DTOPBankOffset, bEnableIRQ? 0: BIT(15), BIT(15));
    W2BYTEMSK(REG_HDCP_DUAL_P0_15_L +u32DTOPBankOffset, bEnableIRQ? 0: BIT(12), BIT(12)); // R0 IRQ Mask
}

//-------------------------------------------------------------------------------------------------
//  EARC TX Functions
//-------------------------------------------------------------------------------------------------

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_InitialSetting()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_EARC_TX_InitialSetting(void)
{
    //do nothing
}

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_SetLatencyInfo()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_EARC_TX_SetLatencyInfo(stHDMI_EARCTX_COMMON_MODE_POLLING_INFO *pstCommonModePollingInfo __attribute__ ((unused)), MS_U8 u8LatencyValue __attribute__ ((unused)))
{
    //do nothing
}

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_SetATOPSetting_AUPLL()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_EARC_TX_SetATOPSetting_AUPLL(MS_U8 u8AUPLLModeSelect __attribute__ ((unused)), EN_EARC_AUDIO_FREQUENCY_TYPE enAudioFrequency __attribute__ ((unused)), EN_EARC_AUDIO_CHANNEL_LAYOUT_TYPE enAudioChannelLayout __attribute__ ((unused)))
{
    MS_BOOL bReValue = FALSE;

    return bReValue;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_SetAudioOutputStream()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_EARC_TX_SetAudioOutputStream(MS_BOOL bEnableFlag __attribute__ ((unused)))
{
    //do nothing
}

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_SetSupportMode()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_EARC_TX_SetSupportMode(EN_EARC_SUPPORT_MODE enSupportMode __attribute__ ((unused)))
{
    MS_BOOL ReValue = FALSE;

    return ReValue;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_GetChipCapability()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U8 Hal_EARC_TX_GetChipCapability(void)
{
    MS_U8 u8ChipCapability = SUPPORT_ARC;

    MHAL_HDMIRX_MSG_INFO("** EARC Chip Capability is SUPPORT_ARC\r\n");

    return u8ChipCapability;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_OutputPortSelect()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_EARC_TX_OutputPortSelect(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), MS_BOOL bEnable5VDetectInvert __attribute__ ((unused)), MS_BOOL bEnableHPDInvert __attribute__ ((unused)))
{
    //do nothing
}

//**************************************************************************
//  [Function Name]:
//                  Hal_EARC_TX_PollingHandler()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_EARC_TX_PollingHandler(HDMI_EARCTX_RESOURCE_PRIVATE *pHDMIEARCTxResourcePrivate __attribute__ ((unused)))
{
    //do nothing
}

//=========================================================//
// Function : Hal_HDMI_Get_Audio_Mux
// Description:
//=========================================================//
MS_U8 Hal_HDMI_Get_Audio_Mux(void)
{
    MS_U8 ucAudioMux = R2BYTE(REG_COMBO_GP_TOP_4B_L) & BMASK(1:0);
    return ucAudioMux;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_SCDCIsr()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
void Hal_HDMI_SCDCIsr(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    // do nothing
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetCRCValue()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_HDMI_GetCRCValue(E_MUX_INPUTPORT enInputPortType, MS_DVI_CHANNEL_TYPE u8Channel ,MS_U16 *pu16CRCVal, stHDMI_POLLING_INFO *pstHDMIPollingInfo)
{
    MS_U32 u32VEBankOffset = _Hal_tmds_GetVEBankOffset(enInputPortType);
    MS_BOOL bRet =TRUE;

    if((pstHDMIPollingInfo->bNoInputFlag) || (Hal_DVI_GetDEStableStatus(enInputPortType) == FALSE))//if DE unstable return CRC value 0
    {
        bRet = FALSE;
    }

    switch(u8Channel)
    {
        case MS_DVI_CHANNEL_G:
            *pu16CRCVal = R2BYTE(REG_HDMIRX_VE_U0_24_L +u32VEBankOffset); // hdmirx_ve_24[15:0]: reg_crc_out_g
            break;

        case MS_DVI_CHANNEL_B:
            *pu16CRCVal = R2BYTE(REG_HDMIRX_VE_U0_25_L +u32VEBankOffset); // hdmirx_ve_25[15:0]: reg_crc_out_b
            break;

        case MS_DVI_CHANNEL_R:
            *pu16CRCVal = R2BYTE(REG_HDMIRX_VE_U0_26_L +u32VEBankOffset); // hdmirx_ve_26[15:0]: reg_crc_out_r
            break;

        default:
            break;
    };

    return bRet;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDCP_Read22HwControl()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U16 Hal_HDCP_Read22HwControl(E_MUX_INPUTPORT enInputPortType)
{
    MS_U32 u32DTOPBankOffset = _Hal_tmds_GetDTOPBankOffset(enInputPortType);

    return R2BYTE(REG_HDCP_DUAL_P0_4E_L +u32DTOPBankOffset); // hdmirx_hdcp_01
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_GetPHYDone()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_BOOL Hal_HDMI_GetPHYDone(E_MUX_INPUTPORT enInputPortType __attribute__ ((unused)), stHDMI_POLLING_INFO *pstHDMIPollingInfo __attribute__ ((unused)))
{
    MS_BOOL bPhyDone = TRUE;

    return bPhyDone;
}

//**************************************************************************
//  [Function Name]:
//                  Hal_HDMI_Get_HW_Ability()
//  [Description]
//
//  [Arguments]:
//
//  [Return]:
//
//**************************************************************************
MS_U32 Hal_HDMI_Get_HW_Ability(E_MUX_INPUTPORT enInputPortType, E_HDMI_GET_WHICH_HW_ABILITY enWhichAbility)
{
    MS_U32 u32Result = 0;

    switch(enWhichAbility)
    {
        case E_HDMI_FRL_ABILITY:
            u32Result = 0;
            MHAL_HDMIRX_MSG_INFO("[%s] ** HDMI Not Support the Ability:%d \n", __FUNCTION__, enWhichAbility);
            break;
        default:
            MHAL_HDMIRX_MSG_INFO("[%s] ** HDMI Unknown enWhichAbility:%d \n", __FUNCTION__, enWhichAbility);
            break;
    };

    return u32Result;
}

