/**
 * @file hv_cal_EdpTxTraining.c
 * @brief EdpTxTraining module driver
 * @details This module provide interfaces for Hiview-Madia-Ware.
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 20221111
 * @copyright Copyright(c),2022-11, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author                         <th>Date             <th>Details
 * <tr><td>HiView SoC Software Team   <td>20221111       <td>Create and first Version.
 * </table>
 **/

#include "hv_cal_EdpTxTraining.h"
#include "PanelConfig.h"
#include "hv_vos_Comm.h"
#include "HV_REGS_HT7315.h"
#include "hv_comm_Log.h"

#define HV_EDP_TX_AUX_DELAY    3
#define EDP_TX_ADDR_OFFSET(a) (((a) == 0) ? 0 : HV_EDP_TX_ADDR_OFFSET)

#define EDPTX_AUX_TRANS_RETRY_COUNT            4
#define HV_EDP_TX_ADDR_OFFSET                  0x1800
#define EDPTX_AUX_TRANS_WRITE_REGR_DONE_COUNT  (50)   /*等待aux只读寄存器翻转*/
UINT32 Hv_Cal_EdpTX_GetAuxDelay(VOID)
{
    return HV_EDP_TX_AUX_DELAY;
}

/*xfli add*/
UCHAR8 Hv_Cal_EdpTx_AuxNativeMasterWrite(HvEdpTxAuxTransInfo *pstEdpTxAuxTransInfo)
{
    UCHAR8 ucRetryCnt = 0;
    USHORT16 usWtainAuxTransDone = 0;
    EdpAuxPortIndex enPortIndex = pstEdpTxAuxTransInfo->enEdpAuxPortIndex;
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);

    HV_LOG_DEBUG(PANEL, "Hv_Cal_EdpTx_AuxNativeMasterWrite addr:%x ", pstEdpTxAuxTransInfo->uiAuxAddr);

    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_A4, uiAddrOffset, reg_00_aux_trans_type, pstEdpTxAuxTransInfo->ucAuxCmd);

    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C0, uiAddrOffset, reg_00_aux_trans_wdata0, pstEdpTxAuxTransInfo->aucData[0]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C0, uiAddrOffset, reg_00_aux_trans_wdata1, pstEdpTxAuxTransInfo->aucData[1]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C0, uiAddrOffset, reg_00_aux_trans_wdata2, pstEdpTxAuxTransInfo->aucData[2]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C0, uiAddrOffset, reg_00_aux_trans_wdata3, pstEdpTxAuxTransInfo->aucData[3]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C4, uiAddrOffset, reg_00_aux_trans_wdata4, pstEdpTxAuxTransInfo->aucData[4]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C4, uiAddrOffset, reg_00_aux_trans_wdata5, pstEdpTxAuxTransInfo->aucData[5]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C4, uiAddrOffset, reg_00_aux_trans_wdata6, pstEdpTxAuxTransInfo->aucData[6]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C4, uiAddrOffset, reg_00_aux_trans_wdata7, pstEdpTxAuxTransInfo->aucData[7]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C8, uiAddrOffset, reg_00_aux_trans_wdata8, pstEdpTxAuxTransInfo->aucData[8]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C8, uiAddrOffset, reg_00_aux_trans_wdata9, pstEdpTxAuxTransInfo->aucData[9]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C8, uiAddrOffset, reg_00_aux_trans_wdata10, pstEdpTxAuxTransInfo->aucData[10]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_C8, uiAddrOffset, reg_00_aux_trans_wdata11, pstEdpTxAuxTransInfo->aucData[11]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_CC, uiAddrOffset, reg_00_aux_trans_wdata12, pstEdpTxAuxTransInfo->aucData[12]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_CC, uiAddrOffset, reg_00_aux_trans_wdata13, pstEdpTxAuxTransInfo->aucData[13]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_CC, uiAddrOffset, reg_00_aux_trans_wdata14, pstEdpTxAuxTransInfo->aucData[14]);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_CC, uiAddrOffset, reg_00_aux_trans_wdata15, pstEdpTxAuxTransInfo->aucData[15]);

    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_B8, uiAddrOffset, reg_00_aux_trans_addr, pstEdpTxAuxTransInfo->uiAuxAddr);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_B8, uiAddrOffset, reg_00_aux_trans_len, pstEdpTxAuxTransInfo->ucDataLen);

    /* 100us */
    Hv_Vos_Delayus(100);

    for (ucRetryCnt = 0; ucRetryCnt < EDPTX_AUX_TRANS_RETRY_COUNT; ucRetryCnt++)
    {
        Hv_Cal_EdpTx_AuxTransStart(enPortIndex, HV_FALSE);

        Hv_Cal_EdpTx_ClearAuxTransStaus(enPortIndex);

        Hv_Vos_Delayus(100);

        Hv_Cal_EdpTx_AuxTransStart(enPortIndex, HV_TRUE);
        usWtainAuxTransDone = 0;
        while (Hv_Cal_EdpTx_GetAuxTransDone(enPortIndex) == HV_FALSE)
        {
            HV_LOG_DEBUG(PANEL, "AuxNativeMasterWrite waite trans done");
            usWtainAuxTransDone++;
            if (usWtainAuxTransDone < EDPTX_AUX_TRANS_WRITE_REGR_DONE_COUNT)
            {
                Hv_Vos_Delayus(100);
            }
            else
            {
                break;
            }
        }

        usWtainAuxTransDone = 0;
        while (Hv_Cal_EdpTx_GetAuxTransTimeOut(enPortIndex) == HV_TRUE)
        {
            usWtainAuxTransDone++;
            if (usWtainAuxTransDone < EDPTX_AUX_TRANS_WRITE_REGR_DONE_COUNT)
            {
                Hv_Vos_Delayus(100);
            }
            else
            {
                HV_LOG_ERROR(PANEL, "AuxNativeMasterWrite timeout!  retry: %d", ucRetryCnt);
                break;
            }
        }
        if (Hv_Cal_EdpTx_GetAuxTransRsp(enPortIndex, pstEdpTxAuxTransInfo->ucAuxCmd) != 0)
        {
            HV_LOG_ERROR(PANEL, "AuxNativeMasterWrite NACK or DEFER! retry: %d", ucRetryCnt);
            //Hv_Vos_Delayus(1);

            Hv_Cal_EdpTx_AuxTransStart(enPortIndex, HV_FALSE);
            continue;
        }
        else
        {
            //HV_LOG_INFO(PANEL, "AuxNativeMasterWrite ok");
            return HV_SUCCESS;
        }
    }
    return HV_FAILURE;
}

UCHAR8 Hv_Cal_EdpTx_AuxNativeMasterRead(HvEdpTxAuxTransInfo *pstEdpTxAuxTransInfo)
{
    UCHAR8 ucRetryCnt = 0;
    USHORT16 usWtainAuxTransDone = 0;
    EdpAuxPortIndex enPortIndex = pstEdpTxAuxTransInfo->enEdpAuxPortIndex;
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);

    HV_LOG_DEBUG(PANEL, "Hv_Cal_EdpTx_AuxNativeMasterRead... addr: %x ", pstEdpTxAuxTransInfo->uiAuxAddr);
    HV_LOG_DEBUG(PANEL, "Hv_Cal_EdpTx_AuxNativeMasterRead... len: %d ", pstEdpTxAuxTransInfo->ucDataLen);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_A4, uiAddrOffset, reg_00_aux_trans_type, pstEdpTxAuxTransInfo->ucAuxCmd);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_B8, uiAddrOffset, reg_00_aux_trans_addr, pstEdpTxAuxTransInfo->uiAuxAddr);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_B8, uiAddrOffset, reg_00_aux_trans_len, pstEdpTxAuxTransInfo->ucDataLen);

    for (ucRetryCnt = 0; ucRetryCnt < EDPTX_AUX_TRANS_RETRY_COUNT; ucRetryCnt++)
    {
        Hv_Cal_EdpTx_AuxTransStart(enPortIndex, HV_FALSE);

        Hv_Cal_EdpTx_ClearAuxTransStaus(enPortIndex);

        /* 100us */
        Hv_Vos_Delayus(100);

        Hv_Cal_EdpTx_AuxTransStart(enPortIndex, HV_TRUE);
        usWtainAuxTransDone = 0;
        while (Hv_Cal_EdpTx_GetAuxTransDone(enPortIndex) == HV_FALSE)
        {
            HV_LOG_DEBUG(PANEL, "Hv_Cal_EdpTx_AuxNativeMasterRead waite trans done usWtainAuxTransDone %u", usWtainAuxTransDone);
            usWtainAuxTransDone++;
            if (usWtainAuxTransDone < EDPTX_AUX_TRANS_WRITE_REGR_DONE_COUNT)
            {
                Hv_Vos_Delayus(100);
            }
            else
            {
                break;
            }
        }

        usWtainAuxTransDone = 0;
        while (Hv_Cal_EdpTx_GetAuxTransTimeOut(enPortIndex) == HV_TRUE)
        {
            usWtainAuxTransDone++;
            if (usWtainAuxTransDone < EDPTX_AUX_TRANS_WRITE_REGR_DONE_COUNT)
            {
                Hv_Vos_Delayus(100);
            }
            else
            {
                HV_LOG_ERROR(PANEL, "AuxNativeMasterWrite timeout!  retry: %d", ucRetryCnt);
                break;
            }
        }

        if (Hv_Cal_EdpTx_GetAuxTransTimeOut(enPortIndex) == HV_TRUE)
        {
            HV_LOG_ERROR(PANEL, "AuxNativeMasterRead timeout! retry: %d", ucRetryCnt);
            continue;
        }
        if (Hv_Cal_EdpTx_GetAuxTransRsp(enPortIndex, pstEdpTxAuxTransInfo->ucAuxCmd) != HV_FALSE)
        {
            HV_LOG_ERROR(PANEL, "AuxNativeMasterRead NACK or DEFER! retry: %d", ucRetryCnt);
            Hv_Vos_Delayus(1);

            Hv_Cal_EdpTx_AuxTransStart(enPortIndex, HV_FALSE);
            continue;
        }
        else
        {
            //HV_LOG_INFO(PANEL, "AuxNativeMasterRead OK!");
            HV_R32_DECL_VAR();
            pstEdpTxAuxTransInfo->ucDataLen = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_BC, uiAddrOffset, regr_00_aux_rsp_len);
            pstEdpTxAuxTransInfo->aucData[0] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D0, uiAddrOffset, regr_00_aux_trans_rdata0);
            pstEdpTxAuxTransInfo->aucData[1] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D0, uiAddrOffset, regr_00_aux_trans_rdata1);
            pstEdpTxAuxTransInfo->aucData[2] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D0, uiAddrOffset, regr_00_aux_trans_rdata2);
            pstEdpTxAuxTransInfo->aucData[3] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D0, uiAddrOffset, regr_00_aux_trans_rdata3);
            pstEdpTxAuxTransInfo->aucData[4] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D4, uiAddrOffset, regr_00_aux_trans_rdata4);
            pstEdpTxAuxTransInfo->aucData[5] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D4, uiAddrOffset, regr_00_aux_trans_rdata5);
            pstEdpTxAuxTransInfo->aucData[6] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D4, uiAddrOffset, regr_00_aux_trans_rdata6);
            pstEdpTxAuxTransInfo->aucData[7] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D4, uiAddrOffset, regr_00_aux_trans_rdata7);
            pstEdpTxAuxTransInfo->aucData[8] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D8, uiAddrOffset, regr_00_aux_trans_rdata8);
            pstEdpTxAuxTransInfo->aucData[9] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D8, uiAddrOffset, regr_00_aux_trans_rdata9);
            pstEdpTxAuxTransInfo->aucData[10] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D8, uiAddrOffset, regr_00_aux_trans_rdata10);
            pstEdpTxAuxTransInfo->aucData[11] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_D8, uiAddrOffset, regr_00_aux_trans_rdata11);
            pstEdpTxAuxTransInfo->aucData[12] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_DC, uiAddrOffset, regr_00_aux_trans_rdata12);
            pstEdpTxAuxTransInfo->aucData[13] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_DC, uiAddrOffset, regr_00_aux_trans_rdata13);
            pstEdpTxAuxTransInfo->aucData[14] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_DC, uiAddrOffset, regr_00_aux_trans_rdata14);
            pstEdpTxAuxTransInfo->aucData[15] = HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_DC, uiAddrOffset, regr_00_aux_trans_rdata15);

            HV_LOG_DEBUG(PANEL, "read abData0 :0x%x", pstEdpTxAuxTransInfo->aucData[0]);
            HV_LOG_DEBUG(PANEL, "read abData1 :0x%x", pstEdpTxAuxTransInfo->aucData[1]);
            HV_LOG_DEBUG(PANEL, "read abData2 :0x%x", pstEdpTxAuxTransInfo->aucData[2]);
            HV_LOG_DEBUG(PANEL, "read abData3 :0x%x", pstEdpTxAuxTransInfo->aucData[3]);
            HV_LOG_DEBUG(PANEL, "read abData4 :0x%x", pstEdpTxAuxTransInfo->aucData[4]);
            HV_LOG_DEBUG(PANEL, "read abData5 :0x%x", pstEdpTxAuxTransInfo->aucData[5]);
            return HV_SUCCESS;
        }
    }
    return HV_FAILURE;
}

VOID Hv_Cal_EdpTx_SetHpdSoftMode(EdpHpdPortIndex enEdpHpdPort, UCHAR8 ucSoftMode)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enEdpHpdPort);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_A4, uiAddrOffset, reg_00_hpd_sw_en, ucSoftMode);
    return;
}

UCHAR8 Hv_Cal_EdpTx_GetHpdStatus(EdpHpdPortIndex enEdpHpdPort)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enEdpHpdPort);

    HV_R32_DECL_VAR();
    return HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_BC, uiAddrOffset, regr_00_edptx_hpd);
}

UCHAR8 Hv_Cal_EdpTx_GetHpdEvt(EdpHpdPortIndex enEdpHpdPort)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enEdpHpdPort);

    HV_R32_DECL_VAR();
    return HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_BC, uiAddrOffset, regr_00_edptx_hpd_evt);
}

VOID Hv_Cal_EdpTx_AuxTransStart(EdpTxPortIndex enPortIndex, BOOL bTrigger)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);

    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_B8, uiAddrOffset, reg_00_aux_trans_start, bTrigger);
    return;
}

VOID Hv_Cal_EdpTx_ClearAuxTransStaus(EdpTxPortIndex enPortIndex)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);

    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_A4, uiAddrOffset, reg_00_aux_trans_clr, HV_TRUE);
    /* 10us */
    Hv_Vos_Delayus(10);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_A4,uiAddrOffset, reg_00_aux_trans_clr, HV_FALSE);

    return;
}

UCHAR8 Hv_Cal_EdpTx_GetAuxTransDone(EdpTxPortIndex enPortIndex)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    HV_R32_DECL_VAR();

    return (UCHAR8) HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_BC, uiAddrOffset, regr_00_aux_trans_done);
}

UCHAR8 Hv_Cal_EdpTx_GetAuxTransTimeOut(EdpTxPortIndex enPortIndex)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    HV_R32_DECL_VAR();

    return (UCHAR8) HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_BC, uiAddrOffset, regr_00_aux_rsp_timeout);
}

UCHAR8 Hv_Cal_EdpTx_GetAuxTransRsp(EdpTxPortIndex enPortIndex, UCHAR8 ucCmd)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    UCHAR8 ucAuxRsp = 0;
    HV_R32_DECL_VAR();
    ucAuxRsp = (UCHAR8) HV_R32_FIELD_EX(TX_EDPTX_TOP_REG_00_BC, uiAddrOffset, regr_00_aux_trans_rsp);

    if ((ucCmd == EDPTX_NATIVE_AUX_W) || (ucCmd == EDPTX_NATIVE_AUX_R))
    {
        return (ucAuxRsp & 3);
    }
    else
    {
        return ((ucAuxRsp & 12) >> 2);
    }
}

VOID Hv_Cal_EdpTx_SetSourcePhyAnaValue(UCHAR8 ucSwingLevel, UCHAR8 ucPreEmpLevel)
{
    /*[SwingLevel][Pre-emphLevel]*/
    HvEdpTxSourcePhyAnaValue astPhyAnaValueTab[4][4] = {                                            // swing_main, tapi, adj
                                            {{20, 0, 4}, {19, 4, 2}, {23, 8, 2}, {29, 14, 2}},      //set0 314,0  set1 241，3.7	set2	set3
                                            {{20, 0, 5}, {20, 4, 3}, {21, 7, 3}, {27, 13, 3}},      //set4 367,0  set5 314，3.5	set6	set7
                                            {{25, 0, 5}, {19, 4, 4}, {24, 8, 3}, {31, 15, 3}},      //set8 393,0  set9 361，3.7	set10	set11
                                            {{30, 0, 5}, {23, 5, 4}, {23, 8, 4}, {29, 14, 4}}       //set12 550,0 set13 440，3.8	set14	set15
                                            };
    HvEdpTxSourcePhyAnaValue stPhyPhyAnaValue = astPhyAnaValueTab[ucSwingLevel][ucPreEmpLevel];

    HV_W32_FIELD(TX_COMBOTX_PHY_1_34, reg_txphy_00_ib_source_adj, stPhyPhyAnaValue.ucIbSourceAdj);

    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_0, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_0, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_1, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_1, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_2, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_2, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_3, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_3, stPhyPhyAnaValue.ucPreEmphVale);

    HV_W32_FIELD(TX_COMBOTX_PHY_1_74, reg_txphy_01_ib_source_adj, stPhyPhyAnaValue.ucIbSourceAdj);

    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_0, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_0, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_1, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_1, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_2, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_2, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_3, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_3, stPhyPhyAnaValue.ucPreEmphVale);

    HV_W32_FIELD(TX_COMBOTX_PHY_1_B4, reg_txphy_02_ib_source_adj, stPhyPhyAnaValue.ucIbSourceAdj);

    HV_W32_FIELD(TX_COMBOTX_PHY_1_A4, reg_txphy_02_swing_main_0, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_A8, reg_txphy_02_swing_tapi_0, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_A4, reg_txphy_02_swing_main_1, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_A8, reg_txphy_02_swing_tapi_1, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_A4, reg_txphy_02_swing_main_2, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_A8, reg_txphy_02_swing_tapi_2, stPhyPhyAnaValue.ucPreEmphVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_A4, reg_txphy_02_swing_main_3, stPhyPhyAnaValue.ucSwingMainVale);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_A8, reg_txphy_02_swing_tapi_3, stPhyPhyAnaValue.ucPreEmphVale);
    return;
}

VOID Hv_Cal_EdpTx_SetTxPhy00SwingMain(UCHAR8 ucSwing0, UCHAR8 ucSwing1, UCHAR8 ucSwing2, UCHAR8 ucSwing3)
{
    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_0, ucSwing0);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_1, ucSwing1);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_2, ucSwing2);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_24, reg_txphy_00_swing_main_3, ucSwing3);
    return;
}

VOID Hv_Cal_EdpTx_SetTxPhy01SwingMain(UCHAR8 ucSwing0, UCHAR8 ucSwing1, UCHAR8 ucSwing2, UCHAR8 ucSwing3)
{
    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_0, ucSwing0);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_1, ucSwing1);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_2, ucSwing2);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_64, reg_txphy_01_swing_main_3, ucSwing3);
    return;
}

VOID Hv_Cal_EdpTx_SetTxPhy00SwingTapi(UCHAR8 ucPreEmph0, UCHAR8 ucPreEmph1, UCHAR8 ucPreEmph2, UCHAR8 ucPreEmph3)
{
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_0, ucPreEmph0);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_1, ucPreEmph1);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_2, ucPreEmph2);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_28, reg_txphy_00_swing_tapi_3, ucPreEmph3);
    return;
}

VOID Hv_Cal_EdpTx_SetTxPhy01SwingTapi(UCHAR8 ucPreEmph0, UCHAR8 ucPreEmph1, UCHAR8 ucPreEmph2, UCHAR8 ucPreEmph3)
{
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_0, ucPreEmph0);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_1, ucPreEmph1);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_2, ucPreEmph2);
    HV_W32_FIELD(TX_COMBOTX_PHY_1_68, reg_txphy_01_swing_tapi_3, ucPreEmph3);
    return;
}

VOID Hv_Cal_EdpTx_SendTpsPattern(EdpTxPortIndex enPortIndex, EdpTxTpsPattTyp enTpsType)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    switch (enTpsType)
    {
        case EDPTX_SEND_TPS1:
        {
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_en, HV_TRUE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_38, uiAddrOffset, reg_00_edptx_eq_done, HV_FALSE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_tps1_done, HV_FALSE);
            break;
        }
        case EDPTX_SEND_TPS2:
        {
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_60, uiAddrOffset, reg_00_edptx_eq_mode, 0);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_en, HV_TRUE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_tps1_done, HV_TRUE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_38, uiAddrOffset, reg_00_edptx_eq_done, 0);
            break;
        }
        case EDPTX_SEND_TPS3:
        {
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_60, uiAddrOffset, reg_00_edptx_eq_mode, 1);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_en, HV_TRUE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_tps1_done, HV_TRUE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_38, uiAddrOffset, reg_00_edptx_eq_done, HV_FALSE);
            break;
        }
        case EDPTX_SEND_TPS4:
        {
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_60, uiAddrOffset, reg_00_edptx_eq_mode, 2);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_en, HV_TRUE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_tps1_done, HV_TRUE);
            HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_38, uiAddrOffset, reg_00_edptx_eq_done, HV_FALSE);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

VOID Hv_Cal_EdpTx_SetEdptxScrambDis(EdpTxPortIndex enPortIndex, BOOL bEn)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_58, uiAddrOffset, reg_00_edptx_scramb_dis, bEn);
    return;
}

VOID Hv_Cal_EdpTx_InitLink(EdpTxPortIndex enPortIndex, UCHAR8 ucLaneNum)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    UCHAR8 ucLaneEn = 0;

    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_en, HV_FALSE);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_58, uiAddrOffset, reg_00_edptx_lane_en, HV_FALSE);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_tps1_done, HV_FALSE);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_38, uiAddrOffset, reg_00_edptx_eq_done, HV_FALSE);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_60, uiAddrOffset, reg_00_edptx_train_mode, 0);

    /* 20us */
    Hv_Vos_Delayus(20);
    /* 判断lane数量，根据lane数量确定ucLaneEn（开启的lane数量）*/
    if (ucLaneNum == 4)
    {
        ucLaneEn = 15;
    }
    else if (ucLaneNum == 2)
    {
        ucLaneEn = 3;
    }
    else
    {
        ucLaneEn = 1;
    }

    /* full link training phy模式使用leve0 */
    Hv_Cal_EdpTx_SetSourcePhyAnaValue(0, 0);
    HV_W32_FIELD_EX(TX_COMBOTX_PHY_1_20, uiAddrOffset, reg_txphy_00_pre_emphasis_en, ucLaneEn);
    //HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_1C, uiAddrOffset, reg_00_edptx_lane_num, 4);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_58, uiAddrOffset, reg_00_edptx_lane_en, ucLaneEn);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_58, uiAddrOffset, reg_00_edptx_scramb_dis, HV_TRUE);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_en, HV_TRUE);
    return;
}

VOID Hv_Cal_EdpTX_SetEdptxEqDone(EdpTxPortIndex enPortIndex, BOOL bDone)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_tps1_done, HV_TRUE);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_38, uiAddrOffset, reg_00_edptx_eq_done, bDone);
    return;
}

VOID Hv_Cal_EdpTX_RetEdptxEnable(EdpTxPortIndex enPortIndex, BOOL bEn)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enPortIndex);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_84, uiAddrOffset, reg_00_edptx_en, bEn);
    return;
}

VOID Hv_Cal_EdpTx_SendIdlePatternEn(EdpTxPortIndex enEdpTxPort, BOOL bEn)
{
    UINT32 uiAddrOffset = EDP_TX_ADDR_OFFSET(enEdpTxPort);
    HV_W32_FIELD_EX(TX_EDPTX_TOP_REG_00_58, uiAddrOffset, reg_00_edptx_idle_patt_en, bEn);
    return;
}

USHORT16 Hv_Cal_EdpTX_GetKtxPairNum(VOID)
{
    USHORT16 usPairNum = 0;
    HV_R32_DECL_VAR(); 
    usPairNum = (USHORT16)HV_R32_FIELD(TX_KTX_POST_TOP_00, reg_ktx_port_num) * (USHORT16)HV_R32_FIELD(TX_KTX_POST_TOP_00, reg_ktx_pair_num);
    return usPairNum;
}

VOID Hv_Cal_EdpTx_SetAssrEn(EdpTxPortIndex enPort, BOOL bEn)
{
    if (EDP_TX_PROT_INDEX0 == enPort)
    {
        HV_W32_FIELD(TX_EDPTX_TOP_REG_00_58, reg_00_edptx_alternate_sr, bEn);
    }
    else
    {
        HV_W32_FIELD(TX_EDPTX_TOP_REG_01_58, reg_01_edptx_alternate_sr, bEn);
    }
    return;
}