/**********************************************************************************************************************
*  Copyright (C), 2022-2026, SMARTLOGIC TECHNOLOGY LTD.
*  File Name: ecpri_pma.s.c
*  Create Date: 23/08/18
*  Description: eCPRI PMA Module Source File
*  Change History: 
*      <author>      <time>      <version>   <desc>
*    1. ShangH      23/08/18        1.0       Build this module
**********************************************************************************************************************/


/* -------------------------------------------------- <INC FILE> --------------------------------------------------- */
#include "ecpri_pma.h"


/* --------------------------------------------------- <VAR DEF> --------------------------------------------------- */


/* -------------------------------------------------- <FUNC DEF> --------------------------------------------------- */
/**********************************************************************************************************************
*  Function: ecpri_pma_rst
*  Description: eCPRI PMA reset
*  Input: none
*  Output: none
*  Return: none
*  Others: none
**********************************************************************************************************************/
void ecpri_pma_rst(void)
{
    /* cancel JECS PMA's reset */
    do_write(&JECS_CRG_PMA16_RST_CTRL, do_read_volatile(&JECS_CRG_PMA16_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA8_RST_CTRL, do_read_volatile(&JECS_CRG_PMA8_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA9_RST_CTRL, do_read_volatile(&JECS_CRG_PMA9_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA10_RST_CTRL, do_read_volatile(&JECS_CRG_PMA10_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA11_RST_CTRL, do_read_volatile(&JECS_CRG_PMA11_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA12_RST_CTRL, do_read_volatile(&JECS_CRG_PMA12_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA13_RST_CTRL, do_read_volatile(&JECS_CRG_PMA13_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA14_RST_CTRL, do_read_volatile(&JECS_CRG_PMA14_RST_CTRL) | BIT24);
    do_write(&JECS_CRG_PMA15_RST_CTRL, do_read_volatile(&JECS_CRG_PMA15_RST_CTRL) | BIT24);
}

/**********************************************************************************************************************
*  Function: ecpri_pma_cfg
*  Description: eCPRI PMA common config
*  Input: 
*    <name>                    <type>                      <desc>
*     ecpri_option              uint32_t                    eCPRI option
*  Output: none
*  Return: none
*  Others: none
**********************************************************************************************************************/
void ecpri_pma_cfg(uint32_t ecpri_option)
{
    uint32_t ate_ref_range                 = 0;
    uint32_t ate_ref_clk_div2_en           = 0;
    uint32_t ate_ref_raw_clk_div2_en       = 0;
    uint32_t ate_ref_clk_mplla_div         = 0;
    uint32_t ate_lane_ref_sel              = 0;
    uint32_t ate_mplla_fb_clk_div4_en      = 0;
    uint32_t ate_mplla_multiplier          = 0;
    uint32_t ate_mplla_tx_clk_div          = 0;
    uint32_t ate_mplla_word_clk_div        = 0;
    uint32_t ate_mplla_ssc_en              = 0;
    uint32_t ate_mplla_ssc_up_spread       = 0;
    uint32_t ate_mplla_ssc_peak            = 0;
    uint32_t ate_mplla_ssc_step_size       = 0;
    uint32_t ate_mplla_frac_en             = 0;
    uint32_t ate_mplla_frac_quot           = 0;
    uint32_t ate_mplla_frac_den            = 0;
    uint32_t ate_mplla_frac_rem            = 0;
    uint32_t ate_refa_lane_clk_en          = 0;
    uint32_t ate_mplla_init_cal_disable    = 0;
    uint32_t ate_mplla_bw_threshold        = 0;
    uint32_t ate_mplla_bw_high             = 0;
    uint32_t ate_mplla_bw_low              = 0;
    uint32_t ate_mplla_ctl_buf_bypass      = 0;
    uint32_t ate_mplla_short_lock_en       = 0;
    uint32_t ate_rx_term_offset            = 0;
    uint32_t ate_txdn_term_offset          = 0;
    uint32_t ate_txup_term_offset          = 0;
    uint32_t ate_sup_misc                  = 0;
    uint32_t ate_rx_vref_ctrl              = 0;
    uint32_t ate_rx_ref_ld_val             = 0;
    uint32_t ate_rx_vco_ld_val             = 0;
    uint32_t ate_rx_cdr_ppm_max            = 0;

    /* lane */
    uint32_t ate_tx_misc                   = 0;
    uint32_t ate_tx_dcc_ctrl_diff_range    = 0;
    uint32_t ate_tx_dcc_ctrl_cm_range      = 0;
    uint32_t ate_tx_width                  = 0;
    uint32_t ate_tx_ropll_cp_ctl_intg      = 0;
    uint32_t ate_tx_ropll_cp_ctl_prop      = 0;
    uint32_t ate_tx_ropll_rc_filter        = 0;
    uint32_t ate_tx_ropll_v2i_mode         = 0;
    uint32_t ate_tx_ropll_vco_low_freq     = 0;
    uint32_t ate_tx_ropll_postdiv          = 0;
    uint32_t ate_tx_rate                   = 0;
    uint32_t ate_tx_ropll_div16p5_clk_en   = 0;
    uint32_t ate_tx_ropll_125mhz_clk_en    = 0;
    uint32_t ate_tx_term_ctrl              = 0;
    uint32_t ate_tx_dly_cal_en             = 0;
    uint32_t ate_tx_pll_word_clk_freq      = 0;
    uint32_t ate_tx_dig_ropll_div_clk_sel  = 0;
    uint32_t ate_tx_dual_cntx_en           = 0;
    uint32_t ate_tx_ropll_bypass           = 0;
    uint32_t ate_tx_ropll_refdiv           = 0;
    uint32_t ate_tx_ropll_refsel           = 0;
    uint32_t ate_tx_ropll_fbdiv            = 0;
    uint32_t ate_tx_ropll_div_clk_en       = 0;
    uint32_t ate_tx_ropll_out_div          = 0;
    uint32_t ate_tx_ropll_word_clk_en      = 0;
    uint32_t ate_tx_ropll_word_clk_div_sel = 0;
    uint32_t ate_tx_fastedge_en            = 0;
    uint32_t ate_tx_eq_main                = 0;
    uint32_t ate_tx_eq_post                = 0;
    uint32_t ate_tx_eq_pre                 = 0;
    uint32_t ate_tx_align_wide_xfer_en     = 0;
    uint32_t ate_rx_eq_att_lvl             = 0;
    uint32_t ate_rx_eq_ctle_boost          = 0;
    uint32_t ate_rx_eq_ctle_pole           = 0;
    uint32_t ate_rx_eq_afe_rate            = 0;
    uint32_t ate_rx_eq_vga_gain            = 0;
    uint32_t ate_rx_eq_afe_config          = 0;
    uint32_t ate_rx_eq_dfe_tap1            = 0;
    uint32_t ate_rx_eq_dfe_tap2            = 0;
    uint32_t ate_rx_delta_iq               = 0;
    uint32_t ate_rx_cdr_vco_config         = 0;
    uint32_t ate_rx_dcc_ctrl_diff_range    = 0;
    uint32_t ate_rx_dcc_ctrl_cm_range      = 0;
    uint32_t ate_rx_sigdet_lf_threshold    = 0;
    uint32_t ate_rx_sigdet_hf_threshold    = 0;
    uint32_t ate_rx_misc                   = 0;
    uint32_t ate_rx_term_ctrl              = 0;
    uint32_t ate_rx_width                  = 0;
    uint32_t ate_rx_dig_div_clk_sel        = 0;
    uint32_t ate_rx_div_clk_en             = 0;
    uint32_t ate_rx_div_clk_sel            = 0;
    uint32_t ate_rx_rate                   = 0;
    uint32_t ate_rx_dfe_bypass             = 0;
    uint32_t ate_rx_offcan_cont            = 0;
    uint32_t ate_rx_adapt_cont             = 0;
    uint32_t ate_rx_eq_dfe_float_en        = 0;
    uint32_t ate_rx_div16p5_clk_en         = 0;
    uint32_t ate_rx_125mhz_clk_en          = 0;
    uint32_t ate_rx_cdr_ssc_en             = 0;
    uint32_t ate_rx_sigdet_hf_en           = 0;
    uint32_t ate_rx_sigdet_lfps_filter_en  = 0;
    uint32_t ate_rx_term_acdc              = 0;
    uint32_t ate_rx_adapt_sel              = 0;
    uint32_t ate_rx_adapt_mode             = 0;

    uint32_t ate_ref_clk_mpllb_div         = 0;
    uint32_t ate_mpllb_fb_clk_div4_en      = 0;
    uint32_t ate_mpllb_multiplier          = 0;
    uint32_t ate_mpllb_tx_clk_div          = 0;
    uint32_t ate_mpllb_word_clk_div        = 0;
    uint32_t ate_mpllb_ssc_en              = 0;
    uint32_t ate_mpllb_ssc_up_spread       = 0;
    uint32_t ate_mpllb_ssc_peak            = 0;
    uint32_t ate_mpllb_ssc_step_size       = 0;
    uint32_t ate_mpllb_frac_en             = 0;
    uint32_t ate_mpllb_frac_quot           = 0;
    uint32_t ate_mpllb_frac_den            = 0;
    uint32_t ate_mpllb_frac_rem            = 0;
    uint32_t ate_refb_lane_clk_en          = 0;
    uint32_t ate_mpllb_init_cal_disable    = 0;
    uint32_t ate_mpllb_bw_high             = 0;
    uint32_t ate_mpllb_bw_low              = 0;
    uint32_t ate_mpllb_bw_threshold        = 0;
    uint32_t ate_mpllb_ctl_buf_bypass      = 0;
    uint32_t ate_mpllb_short_lock_en       = 0;

    /* const */
    uint32_t ate_ref_repeat_clk_sel        = 1;
    uint32_t ate_ref_repeat_clk_en         = 1;
    uint32_t ate_refa_clk_sel              = 1;
    uint32_t ate_refb_clk_sel              = 1;
    uint32_t ate_refa_clk_en               = 1;
    uint32_t ate_refb_clk_en               = 0;
    uint32_t ate_rx_vref_ctrl_mux_sel      = 1;
    uint32_t ate_mplla_force_en            = 0;
    uint32_t ate_mpllb_force_en            = 0;
    uint32_t ate_pma_pwr_stable            = 1;
    uint32_t ate_pg_reset                  = 0;
    uint32_t ate_pg_mode_en                = 0;
    uint32_t ate_pcs_pwr_stable            = 1;
    uint32_t ate_rx_pstate                 = 2;
    uint32_t ate_rx_invert                 = 0;
    uint32_t ate_rx_term_en                = 1;
    uint32_t ate_rx_lpd                    = 0;
    uint32_t ate_tx_pstate                 = 2;
    uint32_t ate_tx_lpd                    = 0;
    uint32_t ate_tx_mpll_en                = 1;
    uint32_t ate_tx_clk_rdy                = 1;
    uint32_t ate_tx_invert                 = 0;

    /* input para check */
    if ((ECPRI_OPTION_10G != ecpri_option) && (ECPRI_OPTION_25G != ecpri_option))
    {
        return;
    }

    if (ECPRI_OPTION_10G == ecpri_option)
    {
        ate_ref_range                 = 4;
        ate_ref_clk_div2_en           = 0;
        ate_ref_raw_clk_div2_en       = 1;
        ate_ref_clk_mplla_div         = 1;
        ate_lane_ref_sel              = 0;
        ate_mplla_fb_clk_div4_en      = 0;
        ate_mplla_multiplier          = 120;
        ate_mplla_tx_clk_div          = 1;
        ate_mplla_word_clk_div        = 2;
        ate_mplla_ssc_en              = 0;
        ate_mplla_ssc_up_spread       = 0;
        ate_mplla_ssc_peak            = 0;
        ate_mplla_ssc_step_size       = 0;
        ate_mplla_frac_en             = 0;
        ate_mplla_frac_quot           = 0;
        ate_mplla_frac_den            = 0;
        ate_mplla_frac_rem            = 0;
        ate_refa_lane_clk_en          = 0;
        ate_mplla_init_cal_disable    = 0;
        ate_mplla_bw_threshold        = 75;
        ate_mplla_bw_high             = 1583;
        ate_mplla_bw_low              = 1583;
        ate_mplla_ctl_buf_bypass      = 0;
        ate_mplla_short_lock_en       = 0;
        ate_rx_term_offset            = 0;
        ate_txdn_term_offset          = 0;
        ate_txup_term_offset          = 0;
        ate_sup_misc                  = 3;
        ate_rx_vref_ctrl              = 5;
        ate_rx_ref_ld_val             = 21;
        ate_rx_vco_ld_val             = 1386;
        ate_rx_cdr_ppm_max            = 18;

        /* lane */
        ate_tx_misc                   = 0;
        ate_tx_dcc_ctrl_diff_range    = 8;
        ate_tx_dcc_ctrl_cm_range      = 8;
        ate_tx_width                  = 4;
        ate_tx_ropll_cp_ctl_intg      = 79;
        ate_tx_ropll_cp_ctl_prop      = 79;
        ate_tx_ropll_rc_filter        = 4;
        ate_tx_ropll_v2i_mode         = 3;
        ate_tx_ropll_vco_low_freq     = 2;
        ate_tx_ropll_postdiv          = 1;
        ate_tx_rate                   = 1;
        ate_tx_ropll_div16p5_clk_en   = 1;
        ate_tx_ropll_125mhz_clk_en    = 0;
        ate_tx_term_ctrl              = 0;
        ate_tx_dly_cal_en             = 0;
        ate_tx_pll_word_clk_freq      = 6;
        ate_tx_dig_ropll_div_clk_sel  = 0;
        ate_tx_dual_cntx_en           = 0;
        ate_tx_ropll_bypass           = 0;
        ate_tx_ropll_refdiv           = 5;
        ate_tx_ropll_refsel           = 0;
        ate_tx_ropll_fbdiv            = 11;
        ate_tx_ropll_div_clk_en       = 0;
        ate_tx_ropll_out_div          = 4;
        ate_tx_ropll_word_clk_en      = 1;
        ate_tx_ropll_word_clk_div_sel = 2;
        ate_tx_fastedge_en            = 0;
        ate_tx_eq_main                = 24;
        ate_tx_eq_post                = 0;
        ate_tx_eq_pre                 = 0;
        ate_tx_align_wide_xfer_en     = 0;
        ate_rx_eq_att_lvl             = 0;
        ate_rx_eq_ctle_boost          = 16;
        ate_rx_eq_ctle_pole           = 1;
        ate_rx_eq_afe_rate            = 6;
        ate_rx_eq_vga_gain            = 16;
        ate_rx_eq_afe_config          = 1300;
        ate_rx_eq_dfe_tap1            = 12;
        ate_rx_eq_dfe_tap2            = 128;
        ate_rx_delta_iq               = 6;
        ate_rx_cdr_vco_config         = 1027;
        ate_rx_dcc_ctrl_diff_range    = 11;
        ate_rx_dcc_ctrl_cm_range      = 11;
        ate_rx_sigdet_lf_threshold    = 4;
        ate_rx_sigdet_hf_threshold    = 2;
        ate_rx_misc                   = 0;
        ate_rx_term_ctrl              = 0;
        ate_rx_width                  = 4;
        ate_rx_dig_div_clk_sel        = 0;
        ate_rx_div_clk_en             = 0;
        ate_rx_div_clk_sel            = 0;
        ate_rx_rate                   = 1;
        ate_rx_dfe_bypass             = 0;
        ate_rx_offcan_cont            = 1;
        ate_rx_adapt_cont             = 1;
        ate_rx_eq_dfe_float_en        = 0;
        ate_rx_div16p5_clk_en         = 1;
        ate_rx_125mhz_clk_en          = 0;
        ate_rx_cdr_ssc_en             = 0;
        ate_rx_sigdet_hf_en           = 0;
        ate_rx_sigdet_lfps_filter_en  = 0;
        ate_rx_term_acdc              = 1;
        ate_rx_adapt_sel              = 0;
        ate_rx_adapt_mode             = 4;
    }

    if (ECPRI_OPTION_25G == ecpri_option)
    {
        ate_ref_range                 = 4;
        ate_ref_clk_div2_en           = 0;
        ate_ref_raw_clk_div2_en       = 1;
        ate_ref_clk_mplla_div         = 1;
        ate_lane_ref_sel              = 0;
        ate_mplla_fb_clk_div4_en      = 0;
        ate_mplla_multiplier          = 120;
        ate_mplla_tx_clk_div          = 1;
        ate_mplla_word_clk_div        = 2;
        ate_mplla_ssc_en              = 0;
        ate_mplla_ssc_up_spread       = 0;
        ate_mplla_ssc_peak            = 0;
        ate_mplla_ssc_step_size       = 0;
        ate_mplla_frac_en             = 0;
        ate_mplla_frac_quot           = 0;
        ate_mplla_frac_den            = 0;
        ate_mplla_frac_rem            = 0;
        ate_refa_lane_clk_en          = 0;
        ate_mplla_init_cal_disable    = 0;
        ate_mplla_bw_threshold        = 75;
        ate_mplla_bw_high             = 1583;
        ate_mplla_bw_low              = 1583;
        ate_mplla_ctl_buf_bypass      = 0;
        ate_mplla_short_lock_en       = 0;
        ate_rx_term_offset            = 0;
        ate_txdn_term_offset          = 0;
        ate_txup_term_offset          = 0;
        ate_sup_misc                  = 3;
        ate_rx_vref_ctrl              = 5;
        ate_rx_ref_ld_val             = 17;
        ate_rx_vco_ld_val             = 1403;
        ate_rx_cdr_ppm_max            = 19;

        /* lane */
        ate_tx_misc                   = 0;
        ate_tx_dcc_ctrl_diff_range    = 8;
        ate_tx_dcc_ctrl_cm_range      = 8;
        ate_tx_width                  = 4;
        ate_tx_ropll_cp_ctl_intg      = 105;
        ate_tx_ropll_cp_ctl_prop      = 67;
        ate_tx_ropll_rc_filter        = 4;
        ate_tx_ropll_v2i_mode         = 3;
        ate_tx_ropll_vco_low_freq     = 2;
        ate_tx_ropll_postdiv          = 0;
        ate_tx_rate                   = 0;
        ate_tx_ropll_div16p5_clk_en   = 1;
        ate_tx_ropll_125mhz_clk_en    = 0;
        ate_tx_term_ctrl              = 0;
        ate_tx_dly_cal_en             = 0;
        ate_tx_pll_word_clk_freq      = 6;
        ate_tx_dig_ropll_div_clk_sel  = 0;
        ate_tx_dual_cntx_en           = 0;
        ate_tx_ropll_bypass           = 0;
        ate_tx_ropll_refdiv           = 4;
        ate_tx_ropll_refsel           = 0;
        ate_tx_ropll_fbdiv            = 11;
        ate_tx_ropll_div_clk_en       = 0;
        ate_tx_ropll_out_div          = 4;
        ate_tx_ropll_word_clk_en      = 1;
        ate_tx_ropll_word_clk_div_sel = 2;
        ate_tx_fastedge_en            = 0;
        ate_tx_eq_main                = 24;
        ate_tx_eq_post                = 0;
        ate_tx_eq_pre                 = 0;
        ate_tx_align_wide_xfer_en     = 1;
        ate_rx_eq_att_lvl             = 0;
        ate_rx_eq_ctle_boost          = 20;
        ate_rx_eq_ctle_pole           = 3;
        ate_rx_eq_afe_rate            = 1;
        ate_rx_eq_vga_gain            = 16;
        ate_rx_eq_afe_config          = 2364;
        ate_rx_eq_dfe_tap1            = 12;
        ate_rx_eq_dfe_tap2            = 128;
        ate_rx_delta_iq               = 3;
        ate_rx_cdr_vco_config         = 34;
        ate_rx_dcc_ctrl_diff_range    = 11;
        ate_rx_dcc_ctrl_cm_range      = 11;
        ate_rx_sigdet_lf_threshold    = 4;
        ate_rx_sigdet_hf_threshold    = 2;
        ate_rx_misc                   = 0;
        ate_rx_term_ctrl              = 0;
        ate_rx_width                  = 4;
        ate_rx_dig_div_clk_sel        = 0;
        ate_rx_div_clk_en             = 0;
        ate_rx_div_clk_sel            = 0;
        ate_rx_rate                   = 0;
        ate_rx_dfe_bypass             = 0;
        ate_rx_offcan_cont            = 1;
        ate_rx_adapt_cont             = 1;
        ate_rx_eq_dfe_float_en        = 1;
        ate_rx_div16p5_clk_en         = 1;
        ate_rx_125mhz_clk_en          = 0;
        ate_rx_cdr_ssc_en             = 0;
        ate_rx_sigdet_hf_en           = 0;
        ate_rx_sigdet_lfps_filter_en  = 0;
        ate_rx_term_acdc              = 1;
        ate_rx_adapt_sel              = 0;
        ate_rx_adapt_mode             = 4;
    }

    ate_tx_term_ctrl           = ate_tx_term_ctrl + 8;
    ate_rx_term_ctrl           = ate_rx_term_ctrl + 8;

    ate_ref_clk_mpllb_div      = ate_ref_clk_mplla_div;
    ate_mpllb_fb_clk_div4_en   = ate_mplla_fb_clk_div4_en;
    ate_mpllb_multiplier       = ate_mplla_multiplier;
    ate_mpllb_tx_clk_div       = ate_mplla_tx_clk_div;
    ate_mpllb_word_clk_div     = ate_mplla_word_clk_div;
    ate_mpllb_ssc_en           = ate_mplla_ssc_en;
    ate_mpllb_ssc_up_spread    = ate_mplla_ssc_up_spread;
    ate_mpllb_ssc_peak         = ate_mplla_ssc_peak;
    ate_mpllb_ssc_step_size    = ate_mplla_ssc_step_size;
    ate_mpllb_frac_en          = ate_mplla_frac_en;
    ate_mpllb_frac_quot        = ate_mplla_frac_quot;
    ate_mpllb_frac_den         = ate_mplla_frac_den;
    ate_mpllb_frac_rem         = ate_mplla_frac_rem;
    ate_refb_lane_clk_en       = ate_refa_lane_clk_en;
    ate_mpllb_init_cal_disable = ate_mplla_init_cal_disable;
    ate_mpllb_bw_high          = ate_mplla_bw_high;
    ate_mpllb_bw_low           = ate_mplla_bw_low;
    ate_mpllb_bw_threshold     = ate_mplla_bw_threshold;
    ate_mpllb_ctl_buf_bypass   = ate_mplla_ctl_buf_bypass;
    ate_mpllb_short_lock_en    = ate_mplla_short_lock_en;

    do_write(&JECS_PMA1_REF_CLK_CTRL, (ate_ref_clk_mpllb_div << 12) + (ate_ref_clk_mplla_div << 8) + (ate_ref_repeat_clk_sel << 4) + ate_ref_repeat_clk_en);
    do_write(&JECS_PMA1_REFB_CLK_CTRL2, (ate_ref_raw_clk_div2_en << 8) + (ate_ref_range << 4) + ate_refb_lane_clk_en);
    do_write(&JECS_PMA1_REFA_CLK_CTRL2, (ate_ref_raw_clk_div2_en << 8) + (ate_ref_range << 4) + ate_refa_lane_clk_en);
    do_write(&JECS_PMA1_BROADCAST_LANE_REFCLK_SEL, ate_lane_ref_sel);
    do_write(&JECS_PMA1_MPLLA_PARAM6, (ate_mplla_fb_clk_div4_en << 4));
    do_write(&JECS_PMA1_MPLLB_PARAM6, (ate_mpllb_fb_clk_div4_en << 4));
    do_write(&JECS_PMA1_MPLLA_PARAM5, (ate_mplla_word_clk_div << 8) + (ate_mplla_tx_clk_div << 4) + ate_mplla_short_lock_en);
    do_write(&JECS_PMA1_MPLLB_PARAM5, (ate_mpllb_word_clk_div << 8) + (ate_mpllb_tx_clk_div << 4) + ate_mpllb_short_lock_en);
    do_write(&JECS_PMA1_REFA_CLK_CTRL1, (ate_refa_clk_sel << 8) + (ate_refa_clk_en << 4) + ate_ref_clk_div2_en);
    do_write(&JECS_PMA1_REFB_CLK_CTRL1, (ate_refb_clk_sel << 8) + (ate_refb_clk_en << 4) + ate_ref_clk_div2_en);
    do_write(&JECS_PMA1_MPLLA_SSC_CTRL2, ate_mplla_ssc_peak);
    do_write(&JECS_PMA1_MPLLB_SSC_CTRL2, ate_mpllb_ssc_peak);
    do_write(&JECS_PMA1_MPLLA_SSC_CTRL5, ate_mplla_ssc_step_size);
    do_write(&JECS_PMA1_MPLLB_SSC_CTRL5, ate_mpllb_ssc_step_size);
    do_write(&JECS_PMA1_MPLLA_FRAC_CTRL1, ate_mplla_frac_den);
    do_write(&JECS_PMA1_MPLLB_FRAC_CTRL1, ate_mpllb_frac_den);
    do_write(&JECS_PMA1_MPLLA_FRAC_CTRL2, ate_mplla_frac_en);
    do_write(&JECS_PMA1_MPLLB_FRAC_CTRL2, ate_mpllb_frac_en);
    do_write(&JECS_PMA1_MPLLA_FRAC_CTRL3, ate_mplla_frac_quot);
    do_write(&JECS_PMA1_MPLLB_FRAC_CTRL3, ate_mpllb_frac_quot);
    do_write(&JECS_PMA1_MPLLA_FRAC_CTRL4, ate_mplla_frac_rem);
    do_write(&JECS_PMA1_MPLLB_FRAC_CTRL4, ate_mpllb_frac_rem);
    do_write(&JECS_PMA1_MPLLA_PARAM3, (ate_mplla_ctl_buf_bypass << 8) + ate_mplla_bw_threshold);
    do_write(&JECS_PMA1_MPLLB_PARAM3, (ate_mpllb_ctl_buf_bypass << 8) + ate_mpllb_bw_threshold);
    do_write(&JECS_PMA1_MPLLA_SSC_CTRL1, ate_mplla_ssc_en);
    do_write(&JECS_PMA1_MPLLB_SSC_CTRL1, ate_mpllb_ssc_en);
    do_write(&JECS_PMA1_MPLLA_SSC_CTRL4, ate_mplla_ssc_up_spread);
    do_write(&JECS_PMA1_MPLLB_SSC_CTRL4, ate_mpllb_ssc_up_spread);
    do_write(&JECS_PMA1_SUP_MISC, ate_sup_misc);
    do_write(&JECS_PMA1_MPLLA_PARAM4, (ate_mplla_init_cal_disable << 12) + ate_mplla_multiplier);
    do_write(&JECS_PMA1_MPLLB_PARAM4, (ate_mpllb_init_cal_disable << 12) + ate_mpllb_multiplier);
    do_write(&JECS_PMA1_RTUNE_CTRL1, ate_rx_term_offset);
    do_write(&JECS_PMA1_RTUNE_CTRL2, ate_txdn_term_offset);
    do_write(&JECS_PMA1_RTUNE_CTRL3, ate_txup_term_offset);
    do_write(&JECS_PMA1_MPLLA_PARAM1, ate_mplla_bw_high);
    do_write(&JECS_PMA1_MPLLB_PARAM1, ate_mpllb_bw_high);
    do_write(&JECS_PMA1_MPLLA_PARAM2, ate_mplla_bw_low);
    do_write(&JECS_PMA1_MPLLB_PARAM2, ate_mpllb_bw_low);
    do_write(&JECS_PMA1_RX_BIAS_CURRENT_CTRL, (ate_rx_vref_ctrl_mux_sel << 8) + ate_rx_vref_ctrl);
    do_write(&JECS_PMA1_MPLLA_FORCE_EN, ate_mplla_force_en);
    do_write(&JECS_PMA1_MPLLB_FORCE_EN, ate_mpllb_force_en);
    do_write(&JECS_PMA1_POWER_GATING_SIGNAL1, (ate_pma_pwr_stable << 12) + (ate_pg_reset << 8) + (ate_pg_mode_en << 4) + ate_pcs_pwr_stable);

    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM7, (ate_rx_ref_ld_val << 8) + (ate_rx_rate << 4) + ate_rx_pstate);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM8, ate_rx_vco_ld_val);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_DATAPATH_SETTING1, (ate_rx_invert << 12) + (ate_rx_cdr_ssc_en << 8) + ate_rx_cdr_ppm_max);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_CONTROL2, (ate_tx_term_ctrl << 8) + ate_tx_misc);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_REQ_PARAM2, (ate_tx_width << 4) + ate_tx_rate);
    do_write(&JECS_PMA1_BROADCAST_ETH_CLK_CTRL, (ate_tx_pll_word_clk_freq << 12) + (ate_tx_ropll_div16p5_clk_en << 8) + (ate_tx_ropll_125mhz_clk_en << 4) + ate_rx_125mhz_clk_en);
    do_write(&JECS_PMA1_BROADCAST_TX_DIV_CLK_CTRL, ate_tx_dig_ropll_div_clk_sel);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_CONTROL, (ate_rx_term_en << 8) + (ate_rx_term_ctrl << 4) + ate_rx_term_acdc);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM4, (ate_rx_eq_ctle_pole << 8) + ate_rx_eq_ctle_boost);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM3, (ate_rx_eq_att_lvl << 8) + (ate_rx_eq_afe_rate << 4) + ate_rx_dfe_bypass);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM9, ate_rx_width);
    do_write(&JECS_PMA1_BROADCAST_RX_EQ_CTRL2, (ate_rx_eq_vga_gain << 8) + ate_rx_eq_dfe_tap2);
    do_write(&JECS_PMA1_BROADCAST_RX_EQ_CTRL1, (ate_rx_eq_dfe_float_en << 12) + ate_rx_eq_afe_config);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM2, (ate_rx_delta_iq << 12) + ate_rx_cdr_vco_config);
    do_write(&JECS_PMA1_BROADCAST_RX_ADAPT_CTRL, ate_rx_adapt_sel);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_ADAPT_SETTING, (ate_rx_offcan_cont << 8) + (ate_rx_adapt_mode << 4) + ate_rx_adapt_cont);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_EQ1, ate_tx_eq_main);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_EQ2, ate_tx_eq_post);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_EQ3, ate_tx_eq_pre);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM6, (ate_rx_misc << 8));
    do_write(&JECS_PMA1_BROADCAST_RX_DCC_CTRL, (ate_rx_dcc_ctrl_diff_range << 4) + ate_rx_dcc_ctrl_cm_range);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_REQ_PARAM5, (ate_rx_lpd << 12) + ate_rx_eq_dfe_tap1);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_DATAPATH_SETTING2, (ate_rx_sigdet_lf_threshold << 12) + (ate_rx_sigdet_hf_threshold << 8) + (ate_rx_sigdet_hf_en << 4) + ate_rx_div16p5_clk_en);
    do_write(&JECS_PMA1_BROADCAST_RECEIVER_DATAPATH_SETTING3, ate_rx_sigdet_lfps_filter_en);
    do_write(&JECS_PMA1_BROADCAST_TRANS_REQ_CTRL2, (ate_tx_ropll_cp_ctl_prop << 8) + (ate_tx_ropll_bypass << 7) + ate_tx_ropll_cp_ctl_intg);
    do_write(&JECS_PMA1_BROADCAST_TRANS_REQ_CTRL4, (ate_tx_ropll_v2i_mode << 14) + (ate_tx_ropll_refsel << 12) + (ate_tx_ropll_refdiv << 8) + (ate_tx_ropll_rc_filter << 4) + ate_tx_ropll_postdiv);
    do_write(&JECS_PMA1_BROADCAST_TRANS_REQ_CTRL3, (ate_tx_ropll_out_div << 8) + (ate_tx_ropll_div_clk_en << 7) + ate_tx_ropll_fbdiv);
    do_write(&JECS_PMA1_BROADCAST_TRANS_REQ_CTRL5, (ate_tx_ropll_word_clk_en << 8) + (ate_tx_ropll_word_clk_div_sel << 4) + ate_tx_ropll_vco_low_freq);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_REQ_PARAM1, (ate_tx_pstate << 8) + (ate_tx_mpll_en << 4) + ate_tx_lpd);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_DATAPATH_CLKRDY, ate_tx_clk_rdy);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_DATAPATH_SETTING, (ate_tx_invert << 4) + ate_tx_align_wide_xfer_en);
    do_write(&JECS_PMA1_BROADCAST_TRANS_REQ_CTRL1, (ate_tx_fastedge_en << 8) + (ate_tx_dcc_ctrl_diff_range << 4) + ate_tx_dcc_ctrl_cm_range);
    do_write(&JECS_PMA1_BROADCAST_CONTEXT_RESTORE_CTRL3, ate_tx_dual_cntx_en);
    do_write(&JECS_PMA1_BROADCAST_TRANS_INTERFACE_CTRL, ate_tx_dly_cal_en);
    do_write(&JECS_PMA1_BROADCAST_RX_DIV_CLK_CTRL, (ate_rx_div_clk_sel << 8) + (ate_rx_div_clk_en << 4) + ate_rx_dig_div_clk_sel);
}

/**********************************************************************************************************************
*  Function: ecpri_pma_init
*  Description: eCPRI PMA init
*  Input: 
*    <name>                    <type>                      <desc>
*     ecpri_option              uint32_t                    eCPRI option
*  Output: none
*  Return: none
*  Others: none
**********************************************************************************************************************/
void ecpri_pma_init(uint32_t ecpri_option)
{
    uint32_t i = 0;

    /* PMA protocol selection */
    do_write(&JECS_CTRL_PROTOCOL_SEL, do_read_volatile(&JECS_CTRL_PROTOCOL_SEL) | BIT1);
    do_write(&JECS_PMA1_CPRI_PCS_STATUS_CTRL, 0);
    do_write(&JECS_PMA1_PCS_BIT_REV_CTRL, 0x111);

    /* PCS signal detection selected by manual */
    do_write(&JECS_PMA1_CPRI_SIGDET, BIT4 | BIT0);
    do_write(&JECS_PMA1_TX_CLK_SEL, 0x1);

    do_write(&JECS_PHY_BS_CTRL, (BIT4 + (7 << 6)));

    /* eCPRI PMA common config */
    ecpri_pma_cfg(ecpri_option);

    /* define EQ para */
    do_write(&JECS_PMA1_BROADCAST_EQ_INIT_C0, 0x40);
    do_write(&JECS_PMA1_BROADCAST_EQ_INIT_CN1, 0x4); //c-1
    do_write(&JECS_PMA1_BROADCAST_EQ_INIT_CP1, 0x1c);
    do_write(&JECS_PMA1_BROADCAST_EQ_PRESET_C0, 92); //c0
    do_write(&JECS_PMA1_BROADCAST_EQ_PRESET_CN1, 4); //c-1 pre
    do_write(&JECS_PMA1_BROADCAST_EQ_PRESET_CP1, 0); //c+1

    do_write(&JECS_PMA1_PHY_RESET, 0x1); //phy_reset=1
    do_write(&JECS_PMA1_SRAM_CTRL, 0x101); //sram_bootload_bypass=1
    do_write(&JECS_PMA1_PHY_RESET, 0x0); //phy_reset=0
    while ((do_read_volatile(&JECS_PMA1_SRAM_STATUS) & BIT0) != BIT0); //check sram_init_done=1

    /* eCPRI PMA clock config start */
    for (i = 0; i < 16384; i++)
    {
        do_write((JECS_PMA1_CFG + 0xc000ul * 4 + i * 4), do_read_volatile(&pma_fw[i]));
    }

    do_write((JECS_PMA1_CFG + 0x101ul * 4), do_read_volatile(JECS_PMA1_CFG + 0x101ul * 4) | BIT1);

    for (i = 0; i < 16384; i++)
    {
        do_write((JECS_PMA1_CFG + 0xc000ul * 4 + i * 4), do_read_volatile(&pma_fw[i+16384]));
    }
    /* eCPRI PMA clock config end */

    /* SRAM ECC enable and init done */
    do_write(&JECS_PMA1_SRAM_CTRL, 0x1101); //sram_ext_ld_done=1
}

/**********************************************************************************************************************
*  Function: ecpri_pma_rxtx_init
*  Description: eCPRI PMA RX/TX init
*  Input: 
*    <name>                    <type>                      <desc>
*     ecpri_option              uint32_t                    eCPRI option
*  Output: none
*  Return: none
*  Others: none
**********************************************************************************************************************/
void ecpri_pma_rxtx_init(uint32_t ecpri_option)
{
    /* input para check */
    if ((ECPRI_OPTION_10G != ecpri_option) && (ECPRI_OPTION_25G != ecpri_option))
    {
        return;
    }

    /* disable TX and RX reset */
    do_write(&JECS_PMA1_LANE0_TRANSMITTER_CONTROL1, 0x0);
    do_write(&JECS_PMA1_LANE0_RECEIVER_RESET, 0x0);

    /* wait TRX ACK done */
    while (do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_REQ_ACK) & BIT0);
    while (do_read_volatile(&JECS_PMA1_LANE0_TRANSMITTER_REQ_ACK) & BIT0);

    /* enable TX and RX request */
    do_write(&JECS_PMA1_LANE0_TRANSMITTER_REQ, 0x1);
    do_write(&JECS_PMA1_LANE0_RECEIVER_REQ, 0x1);

    /* wait ACK and disable request */
    while (!(do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_REQ_ACK) & BIT0));
    while (!(do_read_volatile(&JECS_PMA1_LANE0_TRANSMITTER_REQ_ACK) & BIT0));
    do_write(&JECS_PMA1_LANE0_TRANSMITTER_REQ, 0x0);
    do_write(&JECS_PMA1_LANE0_RECEIVER_REQ, 0x0);

    /* wait ACK done */
    while (do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_REQ_ACK) & BIT0);
    while (do_read_volatile(&JECS_PMA1_LANE0_TRANSMITTER_REQ_ACK) & BIT0);

    /* P0 PSTATE */
    do_write(&JECS_PMA1_LANE0_RECEIVER_REQ_PARAM7, do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_REQ_PARAM7) & 0xFFF0);
    do_write(&JECS_PMA1_LANE0_TRANSMITTER_REQ_PARAM1, do_read_volatile(&JECS_PMA1_LANE0_TRANSMITTER_REQ_PARAM1) & 0xFF);
    do_write(&JECS_PMA1_LANE0_TRANSMITTER_REQ, 0x1);
    do_write(&JECS_PMA1_LANE0_RECEIVER_REQ, 0x1);

    /* wait ACK and disable request */
    while (!(do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_REQ_ACK) & BIT0));
    while (!(do_read_volatile(&JECS_PMA1_LANE0_TRANSMITTER_REQ_ACK) & BIT0));
    do_write(&JECS_PMA1_LANE0_TRANSMITTER_REQ, 0x0);
    do_write(&JECS_PMA1_LANE0_RECEIVER_REQ, 0x0);

    /* wait ACK done */
    while (do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_REQ_ACK) & BIT0);
    while (do_read_volatile(&JECS_PMA1_LANE0_TRANSMITTER_REQ_ACK) & BIT0);

    /* enable data */
    do_write(&JECS_PMA1_LANE0_TRANSMITTER_DATAPATH_EN, 0x1);
    do_write(&JECS_PMA1_LANE0_RECEIVER_DATAPATH_EN, 0x1);

    /* set RX lf signal detect threshold */
    if (ECPRI_OPTION_25G == ecpri_option)
    {
        do_write(&JECS_PMA1_LANE0_RECEIVER_DATAPATH_SETTING2, ((do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_DATAPATH_SETTING2) & (~(BIT14 + BIT13))) | BIT12));
    }

    /* wait TX valid */
    while(do_read_volatile(&JECS_PMA1_LANE0_TRANS_PLL_STATE) == 0);

    /* wait RX valid */
    while(do_read_volatile(&JECS_PMA1_LANE0_RX_VALID_PHY) == 0);
}

/**********************************************************************************************************************
*  Function: ecpri_pma_rx_adapt
*  Description: eCPRI PMA RX adapt
*  Input: none
*  Output: none
*  Return: none
*  Others: none
**********************************************************************************************************************/
void ecpri_pma_rx_adapt(void)
{
    uint32_t i = 0;

    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_EQ1, 24);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_EQ2, 0);
    do_write(&JECS_PMA1_BROADCAST_TRANSMITTER_EQ3, 0);

    ucp_nop(100000);

    for (i = 0; i < 1; i++)
    {
        do_write(&JECS_PMA1_LANE0_RECEIVER_DATAPATH_EN, BIT4); //reg rx_data_en
        do_write(&JECS_PMA1_LANE0_RECEIVER_ADAPT_REQ, BIT4); //RX_ADAPT_IN_PROG

        do_write(&JECS_PMA1_LANE0_RECEIVER_RESET, do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_RESET) | BIT4); //rx0_reset 
        ucp_nop(5000);

        do_write(&JECS_PMA1_LANE0_RECEIVER_RESET, do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_RESET) & (~BIT4));

        /* wait ACK done */
        while (do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_ADAPT_REQ_ACK) & BIT0);

        /* PMA ACK done */
        do_write(&JECS_PMA1_LANE0_RECEIVER_DATAPATH_EN, (BIT4 + BIT0)); //reg

        /* wait RX_valid signal */
        while ((do_read_volatile(&JECS_PMA1_LANE0_RX_VALID_PHY) & BIT0) != 0x1);

        do_write(&JECS_PMA1_LANE0_RECEIVER_ADAPT_REQ, (BIT4 + BIT0)); //RX_ADAPT_IN_PROG + adapt req

        /* wait PMA RX adapt ACK */
        while (!(do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_ADAPT_REQ_ACK) & BIT0));

        do_write(&JECS_PMA1_LANE0_RECEIVER_ADAPT_REQ, BIT4);

        while (do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_ADAPT_REQ_ACK) & BIT0);

        do_write(&JECS_PMA1_LANE0_RECEIVER_ADAPT_REQ, 0);
    }
}

/**********************************************************************************************************************
*  Function: ecpri_pma_link_status_get
*  Description: eCPRI PMA link status get
*  Input: none
*  Output: none
*  Return: link status - true: link up; false: link down.
*  Others: none
**********************************************************************************************************************/
bool ecpri_pma_link_status_get(void)
{
    /* link status */
    bool link_status = false;
    /* count index */
    uint8_t i = 0;
    /* link count */
    uint8_t link_cnt = 0;

    for (i = 0; i < ECPRI_PMA_DET_NUM; i++)
    {
        ///* check PMA CPRI PCS status is link up or not */
        //if (0 != (do_read_volatile(&JECS_PMA1_CPRI_PCS_STATUS) & BIT0))
        /* check PMA receive link status is link up or not */
        if (0 != (do_read_volatile(&JECS_PMA1_LANE0_RECEIVER_DATAPATH_STATUS2) & BIT4))
        {
            link_cnt++;
        }
    }

    if (ECPRI_PMA_DET_THR <= link_cnt)
    {
        link_status = true;
    }

    return link_status;
}



