/*******************************************************************************
 * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions.
 *
 * SPDX-License-Identifier: MIT
 *
 * MPFS HAL Embedded Software
 *
 */

/*******************************************************************************
 * @file mss_sgmii.c
 * @author Microchip-FPGA Embedded Systems Solutions
 * @brief sgmii related functions
 *
 */

#include <string.h>
#include <stdio.h>
#include "mpfs_hal/mss_hal.h"
#include "simulation.h"

#ifdef  MPFS_HAL_HW_CONFIG

static PART_TYPE silicon_variant = PART_NOT_DETERMINED;

/*
 * local functions
 */
static void setup_sgmii_rpc_per_config(void);
#ifdef SGMII_SUPPORT
static uint32_t sgmii_channel_setup(void);
#endif

/*
 * local variable
 */
static uint32_t sro_dll_90_code;

/*
 * local functions
 */
static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold);

/*
 * extern functions
 */
extern void sgmii_mux_config(uint8_t option);


uint32_t sgmii_setup(void)
{
#ifdef SGMII_SUPPORT
    /*
     * Check if any tx/Rx channels enabled
     */
    if((LIBERO_SETTING_SGMII_MODE & (TX_RX_CH_EN_MASK<<TX_RX_CH_EN_OFFSET)) != 0U)
    {
        while (sgmii_channel_setup() != 0)
        {

        }
    }
    else
    {
        sgmii_off_mode();
        sgmii_mux_config(RPC_REG_UPDATE);
    }
#else
    {
        sgmii_off_mode();
        sgmii_mux_config(RPC_REG_UPDATE);
    }
#endif
    return(0UL);
}


/**
 *
 * @param sgmii_instruction
 * @return
 */
#ifdef SGMII_SUPPORT
static uint32_t sgmii_channel_setup(void)
{
    static SGMII_TRAINING_SM sgmii_training_state = SGMII_SETUP_INIT;
    static uint32_t status = SGMII_IN_SETUP;
    static uint32_t timer_out;

    /*
     * Initialise NWC
     *      Clocks
     *      SGMII
     *      DDR
     *      IOMUX
     */

    switch(sgmii_training_state)
    {
        case SGMII_SETUP_INIT:
            status = SGMII_IN_SETUP;
            CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = \
                    (0x01 << 8U) | 1U; /* PERIPH   soft reset */
            CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;
            setup_sgmii_rpc_per_config();         /* load RPC SGMII_MODE register ext */

            /* Enable the Bank controller */
            /*
             * Set soft reset on IP to load RPC to SCB regs (dynamic mode)
             * Bring the sgmii bank controller out of reset =- ioscb_bank_ctrl_sgmii
             */
            IOSCB_BANK_CNTL_SGMII->soft_reset = 1U;  /* DPC_BITS NV_MAP  reset */
            sgmii_training_state = SGMII_IO_EN;
            break;

        case SGMII_IO_EN:
            /*
             * Check the IO_EN signal here.
             * This is an output from the bank controller power detector, which are
             * turned on using MSS_IO_EN
             */
            /* aro_ioen_bnk  - PVT calibrator IOEN  */
            timer_out++;
            if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (0x01U<<6U)) != 0U)
            {
                timer_out=0U;
                sgmii_training_state = SGMII_RAMP_TIMER;
            }
            break;

        case SGMII_RAMP_TIMER:
            /*
             * IO power ramp wait time
             * After IOEN is received from power detectors DDR and SGMii, extra time
             * required for voltage to ramp.
             * This time will come from the user- Dependent on ramp time of power
             * supply
             * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
             *
             */
            timer_out++;
            if(timer_out >= 0xFU)
            {
                timer_out=0U;
                sgmii_training_state = SGMII_IO_SETUP;
            }
            break;

        case SGMII_IO_SETUP:
            /*
             * fixme- not sure if we should be setting this register
             * From regmap detail:
             * bit 8 of MSS_RESET_CR
             * Asserts a reset the SGMII block containing the MSS reference clock
             * input.
             * Warning that setting this bit causes the external reference clock
             * input to the
             * MSS PLL to disappear.
             * It is advisable to use the SGMII channel soft resets in the PHY
             * instead of this bit.
             * However if E51 software wants to set this bit, the MSS clock source
             * should be switched over to the standby source in advance.
             */
            SCB_REGS->MSS_RESET_CR.MSS_RESET_CR = 0;

            /*
             * I ran the sim past the place where we set the nvmap_reset in the
             * SOFT_RESET_SGMII register and it did not result in any
             * change from the DLL default bits.
             * But I traced the 'flashing' signal on one of these regs back to
             * 'dll0_soft_reset_nv_map' (not 'pll0_soft_reset_periph').
             * Now the only place I can find 'dll0_soft_reset_nv_map' is in SCB
             * space...ie 0x3e10_0000 SOFT_RESET register.
             *
             */
            /*
             * so we have to use scb register to reset as no APB register available
             * to soft reset the IP
             * ioscb_dll_sgmii
             * */
            IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U);  /*  reset sgmii DLL */

            /*
              * I have discovered the problem with the tx channels (soft reset issue)
              * So we require the:
              *
              * sgmiiphy_lane 01 soft-reset register (0x3650_0000) to be written to
              * with 0x1 (to set the nv_map bit[0] =1 (self clears))
              * same for sgmiiphy_lane 23 soft-reset register (0x3651_0000).
              *
              * This will result in the rpc bits for the Lane controls to get loaded.
              * Not happening currently.
              *
              * The soft_reset_sgmii occurs in the mss_ddr.c line 436, so I suppose
              * we put the 2 new soft reset writes after that.
              *
              */
            {
                /* sgmiiphy_lane 01 soft-reset register (0x3650_0000) */
                SGMIIPHY_LANE01->soft_reset = 0x000000001U;
                /* sgmiiphy_lane 23 soft-reset register (0x3650_0000) */
                SGMIIPHY_LANE23->soft_reset = 0x000000001U;
            }

            /*
             * Kick-off calibration, by taking calibration IP out of reset
             */
            /*
             * Soft reset
             */
            {
                /* PVT soft reset - APB*/
                /* reg_pvt_soft_reset_periph  */
                CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL        = (0x01U<< 10U) | (0x7FU<<0U);
                /* reg_pvt_soft_reset_periph  */
                CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL        = (0x7FU<<0U);
                /* PVT soft reset - SCB */
                /* make sure out of reset */
                IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB    = 0x1U;
                /* make sure out of reset */
                IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB    = 0x0U;
            }
            sgmii_training_state = SGMII_WAIT_FOR_CALIB_COMPLETE;
            break;

        case SGMII_WAIT_FOR_CALIB_COMPLETE:
            /*
             * Verify calibration
             * Bank 5 PVT calibrator can be controlled by MSS firmware through APB
             * registers to do initial calibration and re-calibration. During startup,
             * the initial calibration can be started by default when MSS releases SGMII
             * reset. Re-calibration is enabled by default with reg_pvt_calib_start/lock
             * bits being set to 1 before startup, and MSS firmware can start
             * re-calibration after startup by toggling  pvt_calib_start/lock bits per
             * PVT calibrator spec.
             *
             */
            if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (1U << 14U)) == (1U << 14U))
            {
                sgmii_training_state = SGMII_ASSERT_CALIB_LOCK;
            }
            break;

        case SGMII_ASSERT_CALIB_LOCK:
            /*
             * now assert calib lock
             *    calibrated pcode and ncode will be written.
             * */

            CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT |= 0x40000000UL;
            IOSCB_IO_CALIB_SGMII->IOC_REG0       |= (0x01U<<14U);
            sgmii_training_state = SGMII_SET_UP_PLL;
            break;

        case SGMII_SET_UP_PLL:
            /*
              * SGMii Step 3)   Wait for PLL and DLL lock
              * Delay codes generated
              */

            /* 0U => configure using scb, 1U => NVMAP reset */
            sgmii_mux_config(RPC_REG_UPDATE);
            /* 0U => configure using scb, 1U => NVMAP reset */
            sgmii_pll_config_scb(RPC_REG_UPDATE);

            timer_out=0U;
            sgmii_training_state = SGMII_WAIT_FOR_MSS_LOCK;
            break;

        case SGMII_WAIT_FOR_MSS_LOCK:
            if (CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL & (1U<<7U))
            {
                sgmii_training_state = SGMII_WAIT_FOR_DLL_LOCK;
            }
            break;

        case SGMII_WAIT_FOR_DLL_LOCK:
            if (CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL & (1U<<23U))
            {
                sgmii_training_state = SGMII_TURN_ON_MACS;
            }
            break;

        case SGMII_TURN_ON_MACS:
            /*
             * Provide mac clocks
             * The nw_config register for mac0 (0x2011_0004): I am forcing 'gigabit' and
             * 'tbi' bits = 11.
             * The same for Mac1.
             * This starts up the tx_mac_clocks for the 2 macs.
             *
             */
            /* the mac clocks need to be turned on when setting up the sgmii */
            (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
            (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
            GEM_A_LO->network_config |= (0x01U << 10U) | (0x01U << 11U);   /* GEM0 */
            GEM_B_LO->network_config |= (0x01U << 10U) | (0x01U << 11U);   /* GEM1 */
            sgmii_training_state = SGMII_DETERMINE_SILICON_VARIANT;
            break;

        case SGMII_DETERMINE_SILICON_VARIANT:
            /*
             * Determine Silicon variant from generated dll generated sro_dll_90_code
             */
            sro_dll_90_code = ((CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL >> 16U) & 0x7FU);

            if(CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & (01U<<31U)) /* bit31 == 1 => post rev B silicon */
            {
                silicon_variant = PART_REVC_OR_LATER;
                set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST, EARLY_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST);
            }
            else
            {
                /*
                 * SS  part expect  < 13
                 * typical-typical  or FF expect  > 13
                 */
                if(sro_dll_90_code < MIN_DLL_90_CODE_VALUE_INDICATING_TT_PART_REVB) /* SS part */
                {
                    silicon_variant = SS_PART_REVB;
                    set_early_late_thresholds(LATE_EYE_WIDTH_SS_PART_REVB, EARLY_EYE_WIDTH_SS_PART_REVB);
                }
                else
                {
                    silicon_variant = TT_PART_REVB;
                    set_early_late_thresholds(LATE_TT_PART_REVB, EARLY_TT_PART_REVB);
                }
            }
            sgmii_training_state = SGMII_RESET_CHANNELS;
            break;

        case SGMII_RESET_CHANNELS:
            /*
             * DLL soft reset                   - Already configured
             * PVT soft reset                   - Already configured
             * Bank controller soft reset       - Already configured
             * CLKMUX soft reset                - Already configured
             * Lane0 soft reset                 - must be soft reset here
             * Lane1 soft reset                 - must be soft reset here
             *
             *      __IO  uint32_t               reg_lane0_soft_reset_periph :1;  bit 13
             *      __IO  uint32_t               reg_lane1_soft_reset_periph :1;  bit 14
             */
            CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL  = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
            CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL  = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
            if(silicon_variant == PART_REVC_OR_LATER)
            {
                timer_out=0U;
                sgmii_training_state = SGMII_WAIT_10MS;
            }
            else
            {
                sgmii_training_state = SGMII_CHANNELS_UP;
            }
            break;

        case SGMII_WAIT_10MS:
            timer_out++;
            if(timer_out >= 0xFFFU)
            {
                timer_out=0U;
                sgmii_training_state = SGMII_CHECK_REVC_RESULT;
            }
            break;

        case SGMII_CHECK_REVC_RESULT:
            if ( (CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & ARO_REF_PCODE_MASK) > ARO_REF_PCODE_REVC_THRESHOLD )
            {
                /* OK, we are good */
                sgmii_training_state = SGMII_CHANNELS_UP;
            }
            else
            {
                /* need to adjust eye values */
                set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER, EARLY_EYE_WIDTH_PART_REVC_OR_LATER);
                /*
                 * Now reset the channels
                 */
                CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL  = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
                CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL  = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
                /* OK, we are good */
                sgmii_training_state = SGMII_CHANNELS_UP;
            }
            break;

        case SGMII_CHANNELS_UP:
            /*
             * SGMii Step 4)    Monitor the DLL codes for Voltage and Temp variation
             * MSS E51 software sets the magnitude value of variation to flag.
             * MSS E51 software can poll this flag.
             * Re-calibration, if needed, is controlled by E51 software if needed.
             * ML step 4- This is a monitoring step- to be run constantly in the back
             * ground
             */
            status = SGMII_FINISHED_SETUP;
            break;
    } /* end of switch statement */

    return(status);
}
#endif

/**
 * setup_sgmii_rpc_per_config
 * Configures SGMII RPC TIP registers
 */
static void setup_sgmii_rpc_per_config(void)
{
    CFG_DDR_SGMII_PHY->SGMII_MODE.SGMII_MODE    = (LIBERO_SETTING_SGMII_MODE & ~REG_CDR_MOVE_STEP);
    CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL        = LIBERO_SETTING_CH0_CNTL;
    CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL        = LIBERO_SETTING_CH1_CNTL;
    CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL    = LIBERO_SETTING_RECAL_CNTL;
    CFG_DDR_SGMII_PHY->CLK_CNTL.CLK_CNTL        = LIBERO_SETTING_CLK_CNTL;
    /* ibuffmx_p and _n rx1, bit 22 and 23 , rx0, bit 20 and 21 */
    CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL    = LIBERO_SETTING_SPARE_CNTL;
    CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL        = LIBERO_SETTING_PLL_CNTL;
}

/**
 * SGMII Off mode
 */
void sgmii_off_mode(void)
{
    /*
     * do soft reset of SGMII TIP
     */
    CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = (0x01 << 8U) | 1U;
    CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;

    /*
     *
     */
    setup_sgmii_rpc_per_config();

    /*
     * Resetting the SCB register only required in already in dynamic mode. If
     * not reset, IO will not be configured.
     */
    IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U);         /*  reset sgmii */

}

/**
 *
 */
void ddr_pvt_calibration(void)
{
    /*
     * R3.1
     * PVT calibration
     * Wait for IOEN from power detectors DDR and SGMII - IO enable signal from
     * System Control powers on
     *
     * From DDR phy SAC spec:
     *      MSS processor releases dce bus to send RPC bits to IO buffer,
     *      setting each to it's programmed mode and then asserts
     *      ioen high at end of this state.
     *
     *
     *      Following verification required for MSS IO Calibration (DDRPHY,
     *      SGMII and MSSIO)
     *          Auto-calibration supply ramp time settings
     *          Calibration in reset until ioen_bnk goes high, timer complete
     *          and setup of bits complete
     *              scbclk divider setting (/1)
     *              calibration clkdiv setting
     *              VS bit settings
     *          Initial non-calibrated codes to IOs (functional max codes)
     *          Calibration signal transitions
     *              pvt_calib_status ,        r in reg     DYN_CNTL
     *              reg_calib_reset,        w/r in reg     IOC_REG6
     *              calib_clkdiv,           w/r in reg     IOC_REG6
     *              soft_reset_periph_b,
     *              calib_lock,             w/r in reg     IOC_REG0
     *              calib_start,            w/r in reg     IOC_REG0
     *              calib_intrpt              r in reg
     *          Final calibration codes
     *          Lane latching of codes
     *          IO Glitching
     */
    volatile uint32_t timer_out=0U;

    #ifndef RENODE_DEBUG
    /* sro_ioen_out  */
    while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & (1U<<4U)) == 0U)
    {
        timer_out++;
        /*todo: add a fail break */
    }
    #endif

    /*
     * R3.2  Trigger timer and wait for completion
     * PVT calibration
     * After IOEN is received from power detectors DDR and SGMII, extra time
     * required for voltage to ramp.
     * This time will come from the user- Dependent on ramp time of power supply
     * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
     *
     */
    /*todo: implement proper timer- user will supply ramp time */
    timer_out=0U;
    while(timer_out < 0xFU)
    {
        timer_out++;
    }

    /*
     * R3.2 Initiate calibration:
     *
     * IOC_REG6
     *  bit 2:1 reg_calib_clkdiv
     *  bit 0  reg_calib_reset
     *
     *      DDRIO:  calib_reset: 1 -> 0
     *      mss_write(0x20007000 + 0x21C,0x00000004);
     *      DDRIO: calib_rst_b: 0 -> 1
     *      mss_write(0x20007000 + 0x220,0x00000000);
     *      SGMII: calib_rst_b: 0 -> 1
     *      mss_write(0x20007000 + 0xC1C,0x00000000);
     *
     */
    /*
     * Soft reset
     */
    /* PVT soft reset - APB*/
    /* DDRIO:  calib_reset: 1 -> 0, clk divider changed - from 2 - to 3 */
    CFG_DDR_SGMII_PHY->IOC_REG6.IOC_REG6               =    0x00000006U;

    /* PVT soft nv reset - SCB, should load from RPC */
    IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB       = 0x1U; /* make sure reset */
    IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB       = 0x0U; /* make sure reset */

    /*
     * R3.4 Wait for PVT calibration to complete
     * Check:
     * bit 2 sro_calib_status
     *
     * The G5 Memory controller needs to see that the IO calibration has
     * completed before kicking off DDR training.
     * It uses the calib_status signal as a flag for this.
     */
    timer_out=0U;
    #ifndef RENODE_DEBUG
    {
        /* PVT I/O - sro_calib_status -  wait for calibration to complete */
        while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
        {
            timer_out++;
        }
        /* PVT I/O - sro_calib_status -  wait for calibration to complete */
        while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
        {
            timer_out++;
        }
    }
    #endif
    /*
     * now assert calib lock
     *
     * */
    {
        CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0    &= ~(0x01U<<14U);
        IOSCB_IO_CALIB_DDR->IOC_REG0            &= ~(0x01U<<14U);
        CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0    |= (0x01U<<14U);
        IOSCB_IO_CALIB_DDR->IOC_REG0            |= (0x01U<<14U);
    }
}


/**
 *
 */
void ddr_pvt_recalibration(void)
{
    volatile uint32_t timer_out=0U;

    /*
     * now assert calib start
     *
     * */
    {
        CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0    &= ~(0x01U<<13U);
        IOSCB_IO_CALIB_DDR->IOC_REG0            &= ~(0x01U<<13U);
        CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0    |= (0x01U<<13U);
        IOSCB_IO_CALIB_DDR->IOC_REG0            |= (0x01U<<13U);
    }

    /*
     * R3.4 Wait for PVT calibration to complete
     * Check:
     * bit 2 sro_calib_status
     *
     * The G5 Memory controller needs to see that the IO calibration has
     * completed before kicking off DDR training.
     * It uses the calib_status signal as a flag for this.
     */
    timer_out=0U;
    #ifndef RENODE_DEBUG
    {
        /* PVT I/O - sro_calib_status -  wait for calibration to complete */
        while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
        {
            timer_out++;
        }
        /* PVT I/O - sro_calib_status -  wait for calibration to complete */
        while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
        {
            timer_out++;
        }
    }
    #endif
    /*
     * now assert calib lock
     *
     * */
    {
#if 0   /*
         * fixme: this appears to cause wite calibration to fail, investigating
         */
        CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0    &= ~(0x01U<<14U);
        IOSCB_IO_CALIB_DDR->IOC_REG0            &= ~(0x01U<<14U);
        CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0    |= (0x01U<<14U);
        IOSCB_IO_CALIB_DDR->IOC_REG0            |= (0x01U<<14U);
#endif
    }
}

/**
 * Set eye thresholds
 * @param n_late_threshold
 * @param p_early_threshold
 */
static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold)
{
    uint32_t n_eye_values;
    uint32_t p_eye_value;

    /*
     * Set the N eye width value
     * bits 31:29 for CH1, bits 28:26  for CH0 in spare control (N eye width value)
     */
    n_eye_values = (uint32_t)(n_late_threshold << SHIFT_TO_CH0_N_EYE_VALUE);
    n_eye_values |= (uint32_t)(n_late_threshold << SHIFT_TO_CH1_N_EYE_VALUE);

    CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL    = (LIBERO_SETTING_SPARE_CNTL & N_EYE_MASK) | n_eye_values;

    /*
     * Set P values
     */
    p_eye_value = (uint32_t)(p_early_threshold << SHIFT_TO_REG_RX0_EYEWIDTH);
    CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL        = ((LIBERO_SETTING_CH0_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX0_EN_FLAG_N;
    CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL        = ((LIBERO_SETTING_CH1_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX1_EN_FLAG_N;

}

#endif
