/**
 * @file hv_cal_PLL.c
 * @brief PLL模块提供的驱动层
 * @details 该模块接口提供给Driver层应用使用。
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 20220822
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History: 
 * <table>
 * <tr><th>作者                       <th>日期              <th>描述
 * <tr><td>HiView SoC Software Team <td>20220822        <td>Create and first Version.
 * </table>
**/
#include "hv_cal_PLL.h"
#include "hv_vos_Comm.h"
#include "HV_REGS_HT7315.h"
#include "hv_comm_Assert.h"
#include "hv_comm_SSCConfig.h"
#include "hv_comm_Define.h"

#define HV_RX_DPLL_STEP                 0x0100

/* default ref clk is 27M */
static UCHAR8 s_ucRefClk   = 27;
/* default modilation freq is 30k */
static UCHAR8 s_ucModeFreq = 30;
/* modilation step */
static UCHAR8 s_ucModeStep = 0;

/**
 * @brief set sscg period.
 * @param[in] enType: vbo/edp/ddr.  uiPeriod: period
 */
VOID Hv_Cal_Sscg_SetPeriod(SscgType enType, UINT32 uiPeriod)
{
    switch (enType)
    {
        case SSCG_VBO:
        {
            HV_W32_FIELD(SYS_SH06_TOP_60, reg_ptcdpll_ssc_period, uiPeriod);
            break;
        }
        case SSCG_EDP:
        {
            HV_W32_FIELD(TX_COMBOTX_PHY_0_84, reg_txpll_0_ssc_period, uiPeriod);
            break;
        }
        case SSCG_DDR:
        {
            HV_W32_FIELD(SYS_SH01_PLL_FNPLL_SSSCG_1, reg_sh1_sscg_period0, uiPeriod);
            HV_W32_FIELD(SYS_SH01_PLL_FNPLL_SSSCG_1, reg_sh1_sscg_period1, 1);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

/**
 * @brief set sscg step.
 * @param[in] enType: vbo/edp/ddr.  uiStep: step
 */
VOID Hv_Cal_Sscg_SetStep(SscgType enType, UINT32 uiStep)
{
    switch (enType)
    {
        case SSCG_VBO:
        {
            HV_W32_FIELD(SYS_SH06_TOP_60, reg_ptcdpll_ssc_step, uiStep);
            break;
        }
        case SSCG_EDP:
        {
            HV_W32_FIELD(TX_COMBOTX_PHY_0_84, reg_txpll_0_ssc_step, uiStep);
            break;
        }
        case SSCG_DDR:
        {
            HV_W32_FIELD(SYS_SH01_PLL_FNPLL_SSCG_0, reg_sh1_sscg_step , uiStep);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

/**
 * @brief get sscg fb.
 * @param[in] enType: vbo/edp/ddr.
 * @param[out] enType: puiFbint puiFbfrac:fb divider
 */
VOID Hv_Cal_Sscg_GetFbdivider(SscgType enType, UINT32 *puiFbint, UINT32 *puiFbfrac)
{
    HV_R32_DECL_VAR();
    switch (enType)
    {
        case SSCG_VBO:
        {
            *puiFbint   = HV_R32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_int);
            *puiFbfrac  = HV_R32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_frac);
            break;
        }
        case SSCG_EDP:
        {
            *puiFbint   = HV_R32_FIELD(TX_COMBOTX_PHY_0_08, reg_txpll_0_fbdiv_int);
            *puiFbfrac  = HV_R32_FIELD(TX_COMBOTX_PHY_0_08, reg_txpll_0_fbdiv_frac);
            break;
        }
        case SSCG_DDR:
        {
            *puiFbint   = HV_R32_FIELD(SYS_SH01_PLL_FNPLL_SSSCG_2, reg_sh1_sscg_fbdiv_int);
            *puiFbfrac  = HV_R32_FIELD(SYS_SH01_PLL_FNPLL_SSSCG_2, reg_sh1_sscg_fbdiv_frac);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

/**
 * @brief set sscg period & step.
 * @param[in] enType: vbo/edp/ddr.
 */
VOID Hv_Cal_Sscg_SetStepPerod(SscgType enType)
{
    UINT32 uiPeriod = 0;
    UINT32 uiStep   = 0;
    UINT32 uiFbint  = 0;
    UINT32 uiFbfrac = 0;

    Hv_Cal_Sscg_GetFbdivider(enType, &uiFbint, &uiFbfrac);
    HV_LOGI("sscg type %d, s_ucModeStep %d, s_ucModeFreq %d\n", enType, s_ucModeStep, s_ucModeFreq);
    if ((s_ucModeStep == 0) || (s_ucModeFreq == 0))
    {
        uiPeriod = 0;
        uiStep = 0;
    }
    else
    {
        uiPeriod = (1000 * s_ucRefClk / s_ucModeFreq - 2) / 4;
        uiStep   = (uiFbint * 0xffff + uiFbfrac) * s_ucModeStep / 1000 / uiPeriod;
    }

    HV_LOGI("sscg type %d, period %d, step %d\n", enType, uiPeriod, uiStep);
    Hv_Cal_Sscg_SetPeriod(enType, uiPeriod);
    Hv_Cal_Sscg_SetStep(enType, uiStep);

    return;
}

/**
 * @brief set sscg enable.
 * @param[in] enType: vbo/edp/ddr.  bEnble: on/off
 */
VOID Hv_Cal_Sscg_Enalbe(SscgType enType, BOOL bEnble)
{
    Hv_Cal_Sscg_SetStepPerod(enType);

    switch (enType)
    {
        case SSCG_VBO:
        {
            HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_updt, 1);
            HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_updt, 0);
            HV_W32_FIELD(SYS_SH06_TOP_5C, reg_ptcdpll_ssc_en, bEnble?1:0);
            break;
        }
        case SSCG_EDP:
        {
            HV_W32_FIELD(TX_COMBOTX_PHY_0_80, reg_txpll_0_ssc_fbdiv_updt, 1);
            HV_W32_FIELD(TX_COMBOTX_PHY_0_80, reg_txpll_0_ssc_fbdiv_updt, 0);
            HV_W32_FIELD(TX_COMBOTX_PHY_0_80, reg_txpll_0_ssc_en, bEnble?1:0);
            break;
        }
        case SSCG_DDR:
        {
            HV_W32_FIELD(SYS_SH01_PLL_FNPLL_SSCG_0, reg_sh1_sscg_sscg_en, bEnble?1:0);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

/**
 * @brief set sscg freq.
  * @param[in] enType: vbo/edp/ddr.  uiFreq: modulation frequency: 0-100(k)
 */
VOID Hv_Cal_Sscg_SetSscgFreq(SscgType enType, UCHAR8 ucFreq)
{
    if (ucFreq > 100)
    {
        ucFreq = 100;
    }
    s_ucModeFreq = ucFreq;
    Hv_Cal_Sscg_SetStepPerod(enType);
    return;
}

/**
 * @brief set sscg freq.
  * @param[in] enType: vbo/edp/ddr.  uiFreq: modulation step: 0-20(0-2%)
 */
VOID Hv_Cal_Sscg_SetSscgStep(SscgType enType, UCHAR8 ucStep)
{
    if (ucStep > 20)
    {
        ucStep = 20;
    }
    s_ucModeStep = ucStep;
    Hv_Cal_Sscg_SetStepPerod(enType);
    return;
}

/**
 * @brief set sscg spread.
  * @param[in] enType: vbo/edp/ddr.
  * @param[in] ucFreq: vbo/edp/ddr.  uiFreq: modulation frequency: 0-100(k)
  * @param[in] ucStep: vbo/edp/ddr.  uiFreq: modulation step: 0-20(0%-2%)
 */
VOID Hv_Cal_Sscg_SetSscg(SscgType enType, UCHAR8 ucStep, UCHAR8 ucFreq)
{
    if (ucStep > 20)
    {
        ucStep = 20;
    }
    s_ucModeStep = ucStep;

    if (ucFreq > 100)
    {
        ucFreq = 100;
    }
    s_ucModeFreq = ucFreq;

    Hv_Cal_Sscg_SetStepPerod(enType);
    return;
}

/**
 * @brief set sscg mode.
  * @param[in] enType: ddr. vbo/tx use up&down. uiFreq: modulation ucMode: up/down/center
 */
VOID Hv_Cal_Sscg_SetSscgMode(SscgType enType, UCHAR8 ucMode)
{
    switch (enType)
    {
        case SSCG_DDR:
        {
            HV_W32_FIELD(SYS_SH01_PLL_FNPLL_SSCG_0, reg_sh1_sscg_mode, ucMode);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

/**
 * @brief initialize sscg.
 */
VOID Hv_Cal_Sscg_Init(VOID)
{
    /* tx sscg mode default value is wrong, must set before use. */
    HV_W32_FIELD(TX_COMBOTX_PHY_0_80, reg_txpll_0_ssc_patt_set , 4);

    /* sscg must frac mode. */
#ifdef CONFIG_USER_PANEL_TYPE_VBOTX
    HV_W32_FIELD(TX_COMBOTX_PHY_0_00, reg_txpll_0_div_mode, 0); //从1改成0，解决部分VBO屏兼容性问题
#else
    HV_W32_FIELD(TX_COMBOTX_PHY_0_00, reg_txpll_0_div_mode, 1);
#endif
    HV_W32_FIELD(SYS_SH06_TOP_3C, reg_ptcdpll_div_mode, 1);

#ifdef DDR_SPREAD_EN
    s_ucModeStep = DDR_SPREAD_STEP;
    s_ucModeFreq = DDR_SPREAD_FREQ;
    Hv_Cal_Sscg_Enalbe(SSCG_DDR, HV_ENABLE);
    HV_LOGI("ddr spread on\n");
#endif

#ifdef EDP_SPREAD_EN
    s_ucModeFreq = EDP_SPREAD_FREQ;
    s_ucModeStep = EDP_SPREAD_STEP;
    Hv_Cal_Sscg_Enalbe(SSCG_EDP, HV_ENABLE);
#endif

#ifdef VBO_SPREAD_EN
    s_ucModeFreq = VBO_SPREAD_FREQ;
    s_ucModeStep = VBO_SPREAD_STEP;
    Hv_Cal_Sscg_Enalbe(SSCG_VBO, HV_ENABLE);
#endif
    return;
}


Status Hv_Cal_PLL_SetAudioLaneClock(LinkPortIndex enAudioRefPortIndex)
{
    switch (enAudioRefPortIndex)
    {
        case LINK_PORT_INDEX_DP_RX0:
        {
            HV_W32_FIELD(RX_RX_PHY_2C, reg_lane_clk_src_aud_sel, 0x00);
            break;
        }

        case LINK_PORT_INDEX_DP_RX1:
        {
            HV_W32_FIELD(RX_RX_PHY_2C, reg_lane_clk_src_aud_sel, 0x01);
            break;
        }

        case LINK_PORT_INDEX_HDMI_RX0:
        {
            HV_W32_FIELD(RX_RX_PHY_2C, reg_lane_clk_src_aud_sel, 0x20);
            break;
        }

        case LINK_PORT_INDEX_HDMI_RX1:
        {
            HV_W32_FIELD(RX_RX_PHY_2C, reg_lane_clk_src_aud_sel, 0x30);
            break;
        }

        default:
        {
            return HV_FAILURE;
        }
    }

    return HV_SUCCESS;
}

Status Hv_Cal_PLL_RxDpllInit(UCHAR8 ucPortIndex)
{
    HV_W32_FIELD_EX(RX_RX_DPLL_00_08, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_prediv, 0x1);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_08, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_fbdiv_int, 0x2C);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_38, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_clkdet_en, 0x1);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_38, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_clkdet_window_size, 0x6978);

    /*
        [3:0] rxdpll0 relclk sel
                 8'd0: osc clk 
                 8'd1: apb clk 
                 8'd2: axi  clk
                 8'd3: dpll clk
                 8'd4: depends on reg_lane_clk_pll_src_sel[7:0]
        [7:4] rxdpll1 relclk sel
                 8'd0: osc clk 
                 8'd1: apb clk 
                 8'd2: axi  clk
                 8'd3: dpll clk
                 8'd4: depends on reg_lane_clk_pll_src_sel[15:8]
    */

    HV_W32_FIELD(RX_RX_PHY_30, reg_rx_dpll_ref_sel, 0x0);

    HV_W32_FIELD(RX_RX_PHY_30, reg_rx_dpll_sw_rstn, 0x3);

    /*
        rxdpll clk mac sel
        [3:0] rxdpll clk for vbo
                4'd0 rxdpll0 pg0_0
                4'd1 apb clk
                4'd2 axi clk
                4'd3 dpll clk
        [7:4] rxdpll clk for dp0
                …
        [11:8] rxdpll clk for dp0 mst
                …
        [15:12] rxdpll clk for hdmi21
        [19:16] rxdpll clk for mute0
    */

    HV_W32_MASK(RX_RX_PHY_34, 0xFF0000, 0x100000);
    HV_W32_MASK(RX_RX_PHY_34, 0x00F0, 0x0);

    HV_W32(RX_RX_PHY_38, 0x30);

    /*lock detcet init*/
    HV_W32_FIELD_EX(RX_RX_DPLL_00_20, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_fw_mode, 0);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_20, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_fw_value, 0);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_20, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_det_win, 5);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_24, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_locked_num, 3);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_24, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_unlocked_num, 2);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_24, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_lock_err_range, 5);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_24, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_fast_err_range, 5);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_24, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_lockdet_no_clk_th, 127);
    
    return HV_SUCCESS;
}


Status Hv_Cal_PLL_CheckRxDpllLock(UCHAR8 ucPortIndex)
{
    HV_R32_DECL_VAR();
    UINT32 uiRefNoClk = HV_R32_FIELD_EX(RX_RX_DPLL_00_B4, ucPortIndex * HV_RX_DPLL_STEP,regr_00_rx_dpll_lockdet_ref_no_clk);
    UINT32 uiVcoNoCk  = HV_R32_FIELD_EX(RX_RX_DPLL_00_B4, ucPortIndex * HV_RX_DPLL_STEP,regr_00_rx_dpll_lockdet_vco_no_clk);
    UINT32 uiPllLock  = HV_R32_FIELD_EX(RX_RX_DPLL_00_B4, ucPortIndex * HV_RX_DPLL_STEP,regr_00_rx_dpll_lockdet_pll_lock);

    return (0x0 == uiRefNoClk) && (0x0 == uiVcoNoCk) && (0x1 == uiPllLock);
    
}

VOID Hv_Cal_PLL_ResetRxDpll(UCHAR8 ucPortIndex)
{
    HV_W32_FIELD_EX(RX_RX_DPLL_00_00, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_rstn, 0);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_00, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_en, 0);
    Hv_Vos_Delayus(200);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_00, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_rstn, 1);
    HV_W32_FIELD_EX(RX_RX_DPLL_00_00, ucPortIndex * HV_RX_DPLL_STEP, reg_00_rx_dpll_en, 1);
    return;
}

Status Hv_Cal_PLL_SetRxDpllFbdiv(ChannelType enChannelCfg, UINT32 uiValue)
{
    HV_W32_FIELD_EX(RX_RX_DPLL_00_08, enChannelCfg * HV_RX_DPLL_STEP, reg_00_rx_dpll_fbdiv_int, uiValue);

    return HV_SUCCESS;
}

Status Hv_Cal_PLL_SetRxDpllPreDiv(ChannelType enChannelCfg, UINT32 uiValue)
{
    HV_W32_FIELD_EX(RX_RX_DPLL_00_08, enChannelCfg * HV_RX_DPLL_STEP, reg_00_rx_dpll_prediv, uiValue);

    return HV_SUCCESS;
}

Status Hv_Cal_PLL_SetRxDpllPostdivIP(ChannelType enChannelCfg, UINT32 uiValue)
{
    HV_W32_FIELD_EX(RX_RX_DPLL_00_0C, enChannelCfg * HV_RX_DPLL_STEP, reg_00_rx_dpll_postdiv0, uiValue); 
    //HV_W32_FIELD_EX(RX_RX_DPLL_00_0C, enChannelCfg * HV_HDMIRX_DPLL_STEP, reg_00_rx_dpll_postdiv1, uiValue); 
    //HV_W32_FIELD_EX(RX_RX_DPLL_00_0C, enChannelCfg * HV_HDMIRX_DPLL_STEP, reg_00_rx_dpll_postdiv2, uiValue); 
    return HV_SUCCESS;
}

Status Hv_Cal_PLL_SetRxDpllPostdiv0_XIP(ChannelType enChannelCfg, UINT32 uiValue)
{
    /*简化操作固定为1*/
    HV_W32_FIELD_EX(RX_RX_DPLL_00_10, enChannelCfg * HV_RX_DPLL_STEP, reg_00_rx_dpll_postdiv0_0, uiValue); 
    HV_W32_FIELD_EX(RX_RX_DPLL_00_10, enChannelCfg * HV_RX_DPLL_STEP, reg_00_rx_dpll_postdiv0_1, uiValue);  
    return HV_SUCCESS;
}

Status Hv_Cal_PLL_SetRxDpllFrac(ChannelType enChannelCfg, UINT32 uiValue)
{
    /*设置小数部分*/
    HV_W32_FIELD_EX(RX_RX_DPLL_00_08, enChannelCfg * HV_RX_DPLL_STEP, reg_00_rx_dpll_fbdiv_frac, uiValue); 
    return HV_SUCCESS;
}

Status Hv_Cal_PLL_ConfigRxDpllSel(UINT32 uiRxPllIndex, LinkPortIndex enReleasePortIndex, LinkPortIndex enBindPortIndex)
{
    HV_ASSERT_TRUE(uiRxPllIndex < HV_BOARD_CONFIG_MAX_RXPLL_PORT_NUM);

    if(enReleasePortIndex == enBindPortIndex)
    {
        return HV_SUCCESS;
    }

    switch(enReleasePortIndex)
    {
        case LINK_PORT_INDEX_DP_RX0:
        {
            /*
             * Reg_rx_dpll_clk_mac_en
             * rxdpll clk mac en
             * [0] rxdpll clk for dp0
             * [1] rxdpll clk for dp1 
             * [2] rxdpll clk for hdmi21 0
             * [3] rxdpll clk for hdmi21 1
             */
            HV_W32_MASK(RX_RX_PHY_38, BIT_0, 0);
            break;
        }
        case LINK_PORT_INDEX_DP_RX1:
        {
            HV_W32_MASK(RX_RX_PHY_38, BIT_1, 0);
            break;
        }
        case LINK_PORT_INDEX_HDMI_RX0:
        {
            HV_W32_MASK(RX_RX_PHY_38, BIT_2, 0);
            break;
        }
        case LINK_PORT_INDEX_HDMI_RX1:
        {
            HV_W32_MASK(RX_RX_PHY_38, BIT_3, 0);
            break;
        }
        default:
        {
            break;
        }
    }

    switch(enBindPortIndex)
    {
        case LINK_PORT_INDEX_DP_RX0:
        {
            /***************************************
             * rxdpll clk mac sel
             * [3:0] rxdpll clk for dp0
             *         4'd0 rxdpll0 pg0_0
             *         4'd1 rxdpll1 pg0_0
             *         4'd2 pix_glb_clk
             *         4'd3 pix_glb_clk
             * [7:4] rxdpll clk for dp1
             *         ?
             * [11:8] rxdpll clk for hdmi21_0
             *         ?
             * [15:12] rxdpll clk for hdmi21_1
             * [19:16] rxdpll clk for mute0
             * [23:20] rxdpll clk for mute1
             ***************************************/
            HV_W32_MASK(RX_RX_PHY_34, 0xF, uiRxPllIndex);
            /*
             * Reg_rx_dpll_clk_mac_en
             * rxdpll clk mac en
             * [0] rxdpll clk for dp0
             * [1] rxdpll clk for dp1 
             * [2] rxdpll clk for hdmi21 0
             * [3] rxdpll clk for hdmi21 1
             */
            HV_W32_MASK(RX_RX_PHY_38, BIT_0, BIT_0);
            break;
        }

        case LINK_PORT_INDEX_DP_RX1:
        {
            HV_W32_MASK(RX_RX_PHY_34, 0xF0, uiRxPllIndex << 4);
            HV_W32_MASK(RX_RX_PHY_38, BIT_1, BIT_1);
            break;
        }

        case LINK_PORT_INDEX_HDMI_RX0:
        {
            HV_W32_MASK(RX_RX_PHY_34, 0xF00, uiRxPllIndex << 8);
            HV_W32_MASK(RX_RX_PHY_38, BIT_2, BIT_2);
            break;
        }

        case LINK_PORT_INDEX_HDMI_RX1:
        {
            HV_W32_MASK(RX_RX_PHY_34, 0xF000, uiRxPllIndex << 12);
            HV_W32_MASK(RX_RX_PHY_38, BIT_3, BIT_3);
            break;
        }

        default:
        {
            return HV_FAILURE;
        }
    }

    return HV_SUCCESS;
}

Status Hv_Cal_PLL_ConfigRxDpllMuteSel(BOOL bSamePll)
{
    if(bSamePll)
    {
        HV_W32_MASK(RX_RX_PHY_34, 0xFF0000, 0);
    }
    else
    {
        HV_W32_MASK(RX_RX_PHY_34, 0xFF0000, 0x100000);
    }

    return HV_SUCCESS;
}

VOID Hv_Cal_DpuScaler_DtcDynamicPllEn(UINT32 uiValue)
{
    HV_W32_FIELD(SYS_SH06_TOP_5C, reg_ptcdpll_dynamic_en, uiValue);
    return;
}

BOOL Hv_Cal_DpuScaler_GetDtcDynamicPllEn(VOID)
{
    HV_R32_DECL_VAR();
    return HV_R32_FIELD(SYS_SH06_TOP_5C, reg_ptcdpll_dynamic_en);
}

VOID Hv_Cal_PLL_SetPtcdPllFbdiv(UINT32 uiValue)
{
    HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_int, uiValue);
    return;
}

VOID Hv_Cal_PLL_SetPtcdpllSscgPllnFrac(UINT32 uiValue)
{
    HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_frac, uiValue);
    return;
}

VOID Hv_Cal_PLL_SetPtcdpllPreDiv(UINT32 uiValue)
{
    HV_W32_FIELD(SYS_SH06_TOP_40, reg_ptcdpll_prediv, uiValue);
    return;
}

VOID Hv_Cal_PLL_SetPtcdpllPostdivD(UINT32 uiValue)
{
    HV_W32_FIELD(SYS_SH06_TOP_48, reg_ptcdpll_postdiv0, uiValue); 

    HV_W32_FIELD(SYS_SH06_TOP_4C, reg_ptcdpll_postdiv0_0, 1);  
    return;
}

UINT32 Hv_Cal_PLL_GetPtcdpllPostdiv0(VOID)
{
    HV_R32_DECL_VAR();
    return HV_R32_FIELD(SYS_SH06_TOP_48, reg_ptcdpll_postdiv0);
}

UINT32 Hv_Cal_PLL_GetDtcFbdivInt(VOID)
{
    HV_R32_DECL_VAR();
    return HV_R32_FIELD(DISP_TOP_DTC_TOP_A8, regr_fbdiv_int_current);
}

UINT32 Hv_Cal_PLL_GetDtcFbdivFrac(VOID)
{
    HV_R32_DECL_VAR();
    return HV_R32_FIELD(DISP_TOP_DTC_TOP_A8, regr_fbdiv_frac_current);
}

VOID Hv_Cal_PLL_TogglePtcdUpdate(VOID)
{
    HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_updt, 0);
    HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_updt, 1);
    HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_updt, 0);
    return;
}

Status Hv_Cal_PLL_CheckPtcdPllLock(VOID)
{
    HV_R32_DECL_VAR();
    UINT32 uiRefNoClk = HV_R32_FIELD(SYS_SH06_TOP_EC,regr_ptcdpll_lock_det_ref_no_clk);
    UINT32 uiVcoNoCk  = HV_R32_FIELD(SYS_SH06_TOP_EC,regr_ptcdpll_lock_det_vco_no_clk);
    UINT32 uiPllLock  = HV_R32_FIELD(SYS_SH06_TOP_EC,regr_ptcdpll_lock_det_pll_lock);

    return (0x0 == uiRefNoClk) && (0x0 == uiVcoNoCk) && (0x1 == uiPllLock);
    
}
VOID Hv_Cal_PLL_PtcdReload(VOID)
{
    HV_R32_DECL_VAR();
    UINT32 uiFbdivInt = HV_R32_FIELD(SYS_SH06_TOP_D0, regr_ptcdpll_ssc_plln_int);
    UINT32 uiFbdivFrac = HV_R32_FIELD(SYS_SH06_TOP_D0, regr_ptcdpll_ssc_plln_frac);
    HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_int, uiFbdivInt);
    HV_W32_FIELD(SYS_SH06_TOP_64, reg_ptcdpll_ssc_plln_frac, uiFbdivFrac);

}

VOID Hv_Cal_PLL_PtcdpllInit(VOID)
{
    HV_W32_FIELD(SYS_SH06_TOP_3C, reg_ptcdpll_div_mode, 1);
    HV_W32_FIELD(SYS_SH06_TOP_3C, reg_ptcdpll_dac_en, 1);
    /*配置成1或3代表选择OSC晶振输入源*/
    HV_W32_FIELD(SYS_SH06_TOP_40, reg_ptcdpll_ckref_sel, 1);
    /*lock detcet init*/
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_lock_fw_mode, 0);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_lock_fw_value, 0);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_det_win, 5);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_locked_num, 3);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_unlocked_num, 2);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_lock_err_range, 5);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_fast_err_range, 5);
    HV_W32_FIELD(SYS_SH06_TOP_74, reg_ptcdpll_lock_det_no_clk_th, 127);

    return;
}

VOID Hv_Cal_PLL_SysPllInit(VOID)
{
    /*lock detcet init*/
    HV_W32_FIELD(SYS_SH06_TOP_68, reg_syspll_lockdet_lock_fw_mode, 0);
    HV_W32_FIELD(SYS_SH06_TOP_68, reg_syspll_lockdet_lock_fw_value, 0);
    HV_W32_FIELD(SYS_SH06_TOP_68, reg_syspll_lockdet_det_win, 5);
    HV_W32_FIELD(SYS_SH06_TOP_68, reg_syspll_lockdet_locked_num, 3);
    HV_W32_FIELD(SYS_SH06_TOP_68, reg_syspll_lockdet_unlocked_num, 2);
    HV_W32_FIELD(SYS_SH06_TOP_68, reg_syspll_lockdet_lock_err_range, 5);
    HV_W32_FIELD(SYS_SH06_TOP_68, reg_syspll_lockdet_fast_err_range, 5);
    HV_W32_FIELD(SYS_SH06_TOP_6C, reg_syspll_lockdet_no_clk_th, 127);

    return;
}

Status Hv_Cal_PLL_CheckSysPllLock(VOID)
{
    HV_R32_DECL_VAR();
    UINT32 uiRefNoClk = HV_R32_FIELD(SYS_SH06_TOP_E4,regr_syspll_lockdet_ref_no_clk);
    UINT32 uiVcoNoCk  = HV_R32_FIELD(SYS_SH06_TOP_E4,regr_syspll_lockdet_vco_no_clk);
    UINT32 uiPllLock  = HV_R32_FIELD(SYS_SH06_TOP_E4,regr_syspll_lockdet_pll_lock);

    return (0x0 == uiRefNoClk) && (0x0 == uiVcoNoCk) && (0x1 == uiPllLock);
    
}


VOID Hv_Cal_PLL_ToggleTxdUpdate(VOID)
{
    HV_W32_FIELD(TX_COMBOTX_PHY_0_80, reg_txpll_0_ssc_fbdiv_updt, 0);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_80, reg_txpll_0_ssc_fbdiv_updt, 1);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_80, reg_txpll_0_ssc_fbdiv_updt, 0);
    return;
}


Status Hv_Cal_PLL_CheckTxdPllLock(VOID)
{
    HV_R32_DECL_VAR();
    UINT32 uiRefNoClk = HV_R32_FIELD(TX_COMBOTX_PHY_0_D8,regr_txpll_0_lock_det_ref_no_clk);
    UINT32 uiVcoNoCk  = HV_R32_FIELD(TX_COMBOTX_PHY_0_DC,regr_txpll_0_lock_det_vco_no_clk);
    UINT32 uiPllLock  = HV_R32_FIELD(TX_COMBOTX_PHY_0_D8,regr_txpll_0_lock_det_pll_lock);

    return (0x0 == uiRefNoClk) && (0x0 == uiVcoNoCk) && (0x1 == uiPllLock);
    
}


VOID Hv_Cal_PLL_TxdPllInit(VOID)
{
    /*lock detcet init*/
    HV_W32_FIELD(TX_COMBOTX_PHY_0_90, reg_txpll_0_lock_det_lock_fw_mode, 0);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_90, reg_txpll_0_lock_det_lock_fw_value, 0);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_90, reg_txpll_0_lock_det_det_win, 5);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_90, reg_txpll_0_lock_det_locked_num, 3);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_90, reg_txpll_0_lock_det_unlocked_num, 2);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_90, reg_txpll_0_lock_det_lock_err_range, 5);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_90, reg_txpll_0_lock_det_fast_err_range, 5);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_94, reg_txpll_0_lock_det_no_clk_th, 127);

    return;
}

VOID Hv_Cal_PLL_AudioPllInit(VOID)
{
    /*lock detcet init*/
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_1, reg_audio_pll_lockdet_lock_fw_mode, 0);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_1, reg_audio_pll_lockdet_lock_fw_value, 0);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_1, reg_audio_pll_lockdet_det_win, 5);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_1, reg_audio_pll_lockdet_locked_num, 3);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_1, reg_audio_pll_lockdet_unlocked_num, 2);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_1, reg_audio_pll_lockdet_lock_err_range, 5);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_1, reg_audio_pll_lockdet_fast_err_range, 5);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_2, reg_audio_pll_lockdet_no_clk_th, 127);

    return;
}

Status Hv_Cal_PLL_CheckAudioPllLock(VOID)
{
    HV_R32_DECL_VAR();
    //UINT32 uiRefNoClk = HV_R32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_2,regr_audio_pll_lockdet_ref_no_clk);
    //UINT32 uiVcoNoCk  = HV_R32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_2,regr_audio_pll_lockdet_vco_no_clk);
    UINT32 uiPllLock  = HV_R32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_DET_2,regr_audio_pll_lockdet_pll_lock);

    return (0x1 == uiPllLock);
    
}


Status Hv_Cal_PLL_CheckFNPllLock(VOID)
{
    HV_R32_DECL_VAR();
    UINT32 uiRefNoClk = HV_R32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_RO_1,regr_sh1_pll_lock_det_ref_no_clk);
    UINT32 uiVcoNoCk  = HV_R32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_RO_1,regr_sh1_pll_lock_det_vco_no_clk);
    UINT32 uiPllLock  = HV_R32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_RO_1,regr_sh1_pll_lock_det_pll_lock);

    return (0x0 == uiRefNoClk) && (0x0 == uiVcoNoCk) && (0x1 == uiPllLock);
    
}


VOID Hv_Cal_PLL_FNPllInit(VOID)
{
    /*lock detcet init*/
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_0, reg_sh1_pll_lock_det_lock_fw_mode, 0);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_0, reg_sh1_pll_lock_det_lock_fw_value, 0);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_0, reg_sh1_pll_lock_det_det_win, 5);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_0, reg_sh1_pll_lock_det_locked_num, 3);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_0, reg_sh1_pll_lock_det_unlocked_num, 2);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_0, reg_sh1_pll_lock_det_lock_err_range, 5);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_0, reg_sh1_pll_lock_det_fast_err_range, 5);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_LOCK_DET_1, reg_sh1_pll_lock_det_no_clk_th, 127);

    return;
}

VOID Hv_Cal_PLL_ResetPtcdPll(VOID)
{
    HV_W32_FIELD(SYS_SH06_TOP_3C, reg_ptcdpll_rstn, 0);
    HV_W32_FIELD(SYS_SH06_TOP_3C, reg_ptcdpll_en, 0);
    Hv_Vos_Delayus(200);
    HV_W32_FIELD(SYS_SH06_TOP_3C, reg_ptcdpll_rstn, 1);
    HV_W32_FIELD(SYS_SH06_TOP_3C, reg_ptcdpll_en, 1);

    return;
}


VOID Hv_Cal_PLL_ResetSysPll(VOID)
{
    HV_W32_FIELD(SYS_SH06_TOP_28, reg_syspll_rstn, 0);
    HV_W32_FIELD(SYS_SH06_TOP_28, reg_syspll_en, 0);
    Hv_Vos_Delayus(200);
    HV_W32_FIELD(SYS_SH06_TOP_28, reg_syspll_rstn, 1);
    HV_W32_FIELD(SYS_SH06_TOP_28, reg_syspll_en, 1);

    return;

}

VOID Hv_Cal_PLL_ResetTxdPll(VOID)
{
    HV_W32_FIELD(TX_COMBOTX_PHY_0_00, reg_txpll_0_rstn, 0);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_00, reg_txpll_0_en, 0);
    Hv_Vos_Delayus(200);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_00, reg_txpll_0_rstn, 1);
    HV_W32_FIELD(TX_COMBOTX_PHY_0_00, reg_txpll_0_en, 1);

    return;

}

VOID Hv_Cal_PLL_ResetFNPll(VOID)
{
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_00, reg_fnpll_rstn, 0);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_00, reg_fnpll_en, 0);
    Hv_Vos_Delayus(200);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_00, reg_fnpll_rstn, 1);
    HV_W32_FIELD(SYS_SH01_PLL_FNPLL_00, reg_fnpll_en, 1);

    return;

}

VOID Hv_Cal_PLL_ResetAudioPll(VOID)
{
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_1, reg_audio_pll_0_rstn, 0);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_1, reg_audio_pll_0_en, 0);
    Hv_Vos_Delayus(200);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_1, reg_audio_pll_0_rstn, 1);
    HV_W32_FIELD(RX_AUDIO_TOP2_AUDIO_PLL_1, reg_audio_pll_0_en, 1);

    return;

}

VOID Hv_Cal_PLL_RXD_WaitUntilLock(UCHAR8 ucPortIndex)
{
    UINT32 uiRetry = 0;
    while(0 == Hv_Cal_PLL_CheckRxDpllLock(ucPortIndex))
    {
        uiRetry++;
        if(50 == uiRetry)
        {
            Hv_Cal_PLL_ResetRxDpll(ucPortIndex);
            uiRetry = 0;
        }
        Hv_Vos_Delayus(100); 
    }
    return;
}


UINT32 Hv_Cal_PLL_Ptcd_WaitUntilLock(VOID)
{
    UINT32 uiRetry = 0;    
    while(0 == Hv_Cal_PLL_CheckPtcdPllLock())
    {
        uiRetry++;
        if(200 == uiRetry)
        {
            Hv_Cal_PLL_ResetPtcdPll();
            //uiRetry = 0;
        }
        else if(800 == uiRetry)
        {
            HV_LOG_ERROR(SYSTEM, "##ptcd Pll unlock,error");
            return HV_FALSE;
        }
        Hv_Vos_Delayus(100); 
    }
    return HV_TRUE;
}

VOID Hv_Cal_PLL_Txd_WaitUntilLock(VOID)
{
    UINT32 uiRetry = 0;
    while(0 == Hv_Cal_PLL_CheckTxdPllLock())
    {
        uiRetry++;
        if(50 == uiRetry)
        {
            Hv_Cal_PLL_ResetTxdPll();
            uiRetry = 0;
        }
        Hv_Vos_Delayus(100); 
    }

    return;
}

VOID Hv_Cal_PLL_Sys_WaitUntilLock(VOID)
{
    UINT32 uiRetry = 0;
    while(0 == Hv_Cal_PLL_CheckSysPllLock())
    {
        uiRetry++;
        if(50 == uiRetry)
        {
            Hv_Cal_PLL_ResetSysPll();
            uiRetry = 0;
        }
        Hv_Vos_Delayus(100); 
    }
    return;
}

VOID Hv_Cal_PLL_Audio_WaitUntilLock(VOID)
{
    UINT32 uiRetry = 0;
    while(0 == Hv_Cal_PLL_CheckAudioPllLock())
    {
        uiRetry++;
        if(50 == uiRetry)
        {
            Hv_Cal_PLL_ResetAudioPll();
            //uiRetry = 0;
        }
        else if(200 == uiRetry)
        {
            HV_LOG_ERROR(AUDIO, "##Audio Pll unlock,error");
            return;
        }
        Hv_Vos_Delayus(100); 
    }
    return;
}

VOID Hv_Cal_PLL_FN_WaitUntilLock(VOID)
{
    UINT32 uiRetry = 0;
    while(0 == Hv_Cal_PLL_CheckFNPllLock())
    {
        uiRetry++;
        if(50 == uiRetry)
        {
            Hv_Cal_PLL_ResetFNPll();
            uiRetry = 0;
        }
        Hv_Vos_Delayus(100); 
    }
    return;
}

VOID Hv_Cal_PLL_FN_ClearPllLockFlag(VOID)
{
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_lock_fw_mode, 1);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_lock_fw_value, 0);
    Hv_Vos_Delayus(1);
    HV_W32_FIELD(SYS_SH06_TOP_70, reg_ptcdpll_lock_det_lock_fw_mode, 0);
    return;
}

VOID Hv_Cal_PLL_FN_ToggleDpuClkCapRst(VOID)
{
    HV_W32_FIELD(DISP_TOP_DTC_TOP1_00, reg_osc_clk_en, 0);
    HV_W32_FIELD(DISP_TOP_DTC_TOP1_04, reg_sr_clk_en, 0);
    Hv_Vos_Delayus(10); 
    HV_W32_FIELD(SYS_SH06_TOP_08, reg_disp_cap_rst_n, 0);
    Hv_Vos_Delayus(10); 
    HV_W32_FIELD(SYS_SH06_TOP_08, reg_disp_cap_rst_n, 1);
    Hv_Vos_Delayus(10); 
    HV_W32_FIELD(DISP_TOP_DTC_TOP1_04, reg_sr_clk_en, 1);
    Hv_Vos_Delayus(10); 
    HV_W32_FIELD(DISP_TOP_DTC_TOP1_00, reg_osc_clk_en, 1);
    return;
}



