diff options
author | Chris Steffen <cwsteffen@us.ibm.com> | 2016-08-23 09:16:28 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-09-09 14:04:23 -0400 |
commit | 00afe5381181cd79773a6b99a1a79e361b2ceaa1 (patch) | |
tree | 9c69663397cc53c4ea6dd54f7f64cc954a4c790d /src/import/chips | |
parent | 7e9dbe112504b4767c404c35f3bb6c5216d5eed0 (diff) | |
download | talos-hostboot-00afe5381181cd79773a6b99a1a79e361b2ceaa1.tar.gz talos-hostboot-00afe5381181cd79773a6b99a1a79e361b2ceaa1.zip |
P9 I/O Xbus Dccal/Linktrain Update
Dccal
- Added a mode flag to pick which calibration needs to be run.
- Updated to shorten timers for simulation
- Updated wrapper to call the dccal procedure multiple times.
Linktrain
- Updated linktraining to shorten timers for simulation
Change-Id: I455d335182d5840e2f9534de5e95563ecd4c34c7
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29007
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Gary A. Peterson <garyp@us.ibm.com>
Reviewed-by: Richard J. Knight <rjknight@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29008
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips')
9 files changed, 799 insertions, 1502 deletions
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_common.C b/src/import/chips/p9/procedures/hwp/io/p9_io_common.C index 108e6df48..fb43fa5cd 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_common.C +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_common.C @@ -53,16 +53,14 @@ /** * @brief Shorten timers if we are running in simulation * a right aligned value. - * @param[in] i_target FAPI2 Target - * @param[in] i_groups Clock groups + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock group * @return Field Data */ -fapi2::ReturnCode p9_io_xbus_shorten_timers( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const std::vector < uint8_t >& i_groups ) +fapi2::ReturnCode p9_io_xbus_shorten_timers( const XBUS_TGT i_tgt, const uint8_t i_grp ) { FAPI_IMP( "p9_io_xbus_shorten_timers: I/O EDI+ Xbus Entering" ); - const uint8_t LANE_00 = 0; + const uint8_t LN0 = 0; uint64_t reg_data = 0; uint8_t l_is_sim = 0; @@ -70,45 +68,42 @@ fapi2::ReturnCode p9_io_xbus_shorten_timers( if( l_is_sim ) { - for( auto grp : i_groups ) - { - FAPI_TRY( io::read( EDIP_RX_CTL_MODE7_EO_PG, i_target, grp, LANE_00, reg_data ), - "read edip_rx_ctl_mode7_eo_pg failed" ); - io::set( EDIP_RX_ABORT_CHECK_TIMEOUT_SEL, 0x0, reg_data ); - io::set( EDIP_RX_POLLING_TIMEOUT_SEL, 0x0, reg_data ); - FAPI_TRY( io::write( EDIP_RX_CTL_MODE7_EO_PG, i_target, grp, LANE_00, reg_data ), - "write edip_rx_ctl_mode7_eo_pg failed" ); + FAPI_TRY( io::read( EDIP_RX_CTL_MODE7_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "read edip_rx_ctl_mode7_eo_pg failed" ); + io::set( EDIP_RX_ABORT_CHECK_TIMEOUT_SEL, 0x0, reg_data ); + io::set( EDIP_RX_POLLING_TIMEOUT_SEL, 0x0, reg_data ); + FAPI_TRY( io::write( EDIP_RX_CTL_MODE7_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "write edip_rx_ctl_mode7_eo_pg failed" ); - FAPI_TRY( io::rmw( EDIP_RX_SERVO_CHG_CFG, i_target, grp, LANE_00, 0x0 ), - "rmw edip_rx_rx_servo_chg_cfg failed" ); + FAPI_TRY( io::rmw( EDIP_RX_SERVO_CHG_CFG, i_tgt, i_grp, LN0, 0x0 ), + "rmw edip_rx_rx_servo_chg_cfg failed" ); - FAPI_TRY( io::read( EDIP_RX_CTL_MODE14_EO_PG, i_target, grp, LANE_00, reg_data ), - "read edip_rx_ctl_mode14_eo_pg failed" ); - io::set( EDIP_RX_AMP_INIT_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_AMP_RECAL_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_PEAK_INIT_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_PEAK_RECAL_TIMEOUT, 0x0, reg_data ); - FAPI_TRY( io::write( EDIP_RX_CTL_MODE14_EO_PG, i_target, grp, LANE_00, reg_data ), - "write edip_rx_ctl_mode14_eo_pg failed" ); + FAPI_TRY( io::read( EDIP_RX_CTL_MODE14_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "read edip_rx_ctl_mode14_eo_pg failed" ); + io::set( EDIP_RX_AMP_INIT_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_AMP_RECAL_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_PEAK_INIT_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_PEAK_RECAL_TIMEOUT, 0x0, reg_data ); + FAPI_TRY( io::write( EDIP_RX_CTL_MODE14_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "write edip_rx_ctl_mode14_eo_pg failed" ); - FAPI_TRY( io::read( EDIP_RX_CTL_MODE15_EO_PG, i_target, grp, LANE_00, reg_data ), - "read edip_rx_ctl_mode15_eo_pg failed" ); - io::set( EDIP_RX_AMIN_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_CM_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_OFF_INIT_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_OFF_RECAL_TIMEOUT, 0x0, reg_data ); - FAPI_TRY( io::write( EDIP_RX_CTL_MODE15_EO_PG, i_target, grp, LANE_00, reg_data ), - "write edip_rx_ctl_mode15_eo_pg failed" ); + FAPI_TRY( io::read( EDIP_RX_CTL_MODE15_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "read edip_rx_ctl_mode15_eo_pg failed" ); + io::set( EDIP_RX_AMIN_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_CM_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_OFF_INIT_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_OFF_RECAL_TIMEOUT, 0x0, reg_data ); + FAPI_TRY( io::write( EDIP_RX_CTL_MODE15_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "write edip_rx_ctl_mode15_eo_pg failed" ); - FAPI_TRY( io::read( EDIP_RX_CTL_MODE16_EO_PG, i_target, grp, LANE_00, reg_data ), - "read edip_rx_ctl_mode16_eo_pg failed" ); - io::set( EDIP_RX_AMP_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_BER_TIMEOUT, 0x0, reg_data ); - io::set( EDIP_RX_USERDEF_TIMEOUT, 0x0, reg_data ); - FAPI_TRY( io::write( EDIP_RX_CTL_MODE16_EO_PG, i_target, grp, LANE_00, reg_data ), - "write edip_rx_ctl_mode16_eo_pg failed" ); - } + FAPI_TRY( io::read( EDIP_RX_CTL_MODE16_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "read edip_rx_ctl_mode16_eo_pg failed" ); + io::set( EDIP_RX_AMP_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_BER_TIMEOUT, 0x0, reg_data ); + io::set( EDIP_RX_USERDEF_TIMEOUT, 0x0, reg_data ); + FAPI_TRY( io::write( EDIP_RX_CTL_MODE16_EO_PG, i_tgt, i_grp, LN0, reg_data ), + "write edip_rx_ctl_mode16_eo_pg failed" ); } fapi_try_exit: diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_common.H b/src/import/chips/p9/procedures/hwp/io/p9_io_common.H index 0d1d3c7a8..efefdc1d0 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_common.H +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_common.H @@ -51,15 +51,22 @@ //----------------------------------------------------------------------------- #include <fapi2.H> -/** - * @brief Shorten timers if we are running in simulation - * a right aligned value. - * @param[in] i_target FAPI2 Target - * @param[in] i_groups Clock groups - * @return Field Data - */ -fapi2::ReturnCode p9_io_xbus_shorten_timers( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const std::vector < uint8_t >& i_groups ); +typedef fapi2::Target<fapi2::TARGET_TYPE_XBUS> XBUS_TGT; + +extern "C" +{ + + /** + * @brief Shorten timers if we are running in simulation + * a right aligned value. + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock group + * @return Field Data + */ + fapi2::ReturnCode p9_io_xbus_shorten_timers( + const XBUS_TGT i_tgt, + const uint8_t i_grp ); + +} #endif /* P9_IO_COMMON_H_ */ diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C index 7b41ca00e..0ae2cc52c 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C @@ -55,32 +55,43 @@ #include <p9_io_xbus_dccal.H> #include <p9_io_scom.H> #include <p9_io_regs.H> +#include <p9_io_common.H> //----------------------------------------------------------------------------- // Function Declarations //----------------------------------------------------------------------------- + +/** + * @brief Tx Z Impedance Calibration State Machine + * @param[in] i_tgt FAPI2 Target + * @retval ReturnCode + */ +fapi2::ReturnCode tx_zcal_run_bus( const XBUS_TGT i_tgt ); + /** * @brief Tx Z Impedance Calibration - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group - * @param[in] i_flags Dccal Attribute Flags + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ -fapi2::ReturnCode tx_zcal( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group ); +fapi2::ReturnCode tx_zcal_set_grp( const XBUS_TGT i_tgt, const uint8_t i_grp ); /** - * @brief Rx Dc Calibration - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group + * @brief Rx Dc Calibration Poll + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ -fapi2::ReturnCode rx_dccal( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group ); +fapi2::ReturnCode rx_dccal_poll_grp( const XBUS_TGT i_tgt, const uint8_t i_grp ); +/** + * @brief Rx Dc Calibration Start + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group + * @retval ReturnCode + */ +fapi2::ReturnCode rx_dccal_start_grp( const XBUS_TGT i_tgt, const uint8_t i_grp ); //----------------------------------------------------------------------------- // Function Definitions @@ -89,45 +100,48 @@ fapi2::ReturnCode rx_dccal( /** * @brief A I/O EDI+ Procedure that runs Rx Dccal and Tx Z Impedance calibration * on every instance of the XBUS on a per group level. - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group + * @param[in] i_mode Selects which operation to perform + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ fapi2::ReturnCode p9_io_xbus_dccal( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group ) + const XbusDccalMode i_mode, + const XBUS_TGT i_tgt, + const uint8_t i_grp ) { FAPI_IMP( "p9_io_xbus_dccal: I/O EDI+ Xbus Entering" ); - uint8_t l_dccal_flags = 0x0; - char l_target_string[fapi2::MAX_ECMD_STRING_LEN]; - fapi2::toString( i_target, l_target_string, fapi2::MAX_ECMD_STRING_LEN ); - // Check if Tx Impedance Calibration or Rx Dc Calibration has been run. - FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_IO_XBUS_DCCAL_FLAGS, i_target, l_dccal_flags ) ); + char l_tgtStr[fapi2::MAX_ECMD_STRING_LEN]; + fapi2::toString( i_tgt, l_tgtStr, fapi2::MAX_ECMD_STRING_LEN ); + FAPI_DBG( "I/O EDI+ Xbus Dccal %s:g%d", l_tgtStr, i_grp ); - FAPI_DBG( "I/O EDI+ Xbus Dccal %s:g%d Flags Tx(%d) Rx(%d)", - l_target_string, i_group, - ( l_dccal_flags & fapi2::ENUM_ATTR_IO_XBUS_DCCAL_FLAGS_TX ) ? 1 : 0, - ( l_dccal_flags & fapi2::ENUM_ATTR_IO_XBUS_DCCAL_FLAGS_RX ) ? 1 : 0 ); + switch( i_mode ) + { + case XbusDccalMode::Noop: // Runs nothing, can be used for dry runs + FAPI_IMP( "I/O EDI+ Xbus Dccal Noop" ); + break; - /////////////////////////////////////////////////////////////////////////// - /// Tx Impedance Calibraiton (Zcal) - /////////////////////////////////////////////////////////////////////////// - FAPI_TRY( tx_zcal( i_target, i_group ), - "p9_io_xbus_dccal: I/O Edi+ Xbus Tx Z Calibration Run Failed" ); + case XbusDccalMode::TxZcalRunBus: // Runs Tx Zcal on a per bus basis + FAPI_TRY( tx_zcal_run_bus( i_tgt ), "I/O Edi+ Xbus Tx Z-Cal Run Bus Failed" ); + break; - l_dccal_flags |= fapi2::ENUM_ATTR_IO_XBUS_DCCAL_FLAGS_TX; - FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_IO_XBUS_DCCAL_FLAGS, i_target, l_dccal_flags ) ); + case XbusDccalMode::TxZcalSetGrp: // Sets Tx Zcal Group Settings based on the bus results + FAPI_TRY( tx_zcal_set_grp( i_tgt, i_grp ), "I/O Edi+ Xbus Tx Z-Cal Set Grp Failed" ); + break; - /////////////////////////////////////////////////////////////////////////// - /// Rx DC Calibraiton - /////////////////////////////////////////////////////////////////////////// - FAPI_TRY( rx_dccal( i_target, i_group ), - "p9_io_xbus_dccal: I/O Edi+ Xbus Rx DC Calibration Run Failed" ); + case XbusDccalMode::RxDccalStartGrp: // Starts Rx Dccal on a per group basis + FAPI_TRY( rx_dccal_start_grp( i_tgt, i_grp ), "I/O Edi+ Xbus Rx DC Cal Start Failed" ); + break; - l_dccal_flags |= fapi2::ENUM_ATTR_IO_XBUS_DCCAL_FLAGS_RX; - FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_IO_XBUS_DCCAL_FLAGS, i_target, l_dccal_flags ) ); + case XbusDccalMode::RxDccalCheckGrp: // Checks/polls Rx Dccal on a per group basis + FAPI_TRY( rx_dccal_poll_grp( i_tgt, i_grp ), "I/O Edi+ Xbus Rx DC Cal Poll Failed" ); + break; + default: + FAPI_ERR( "I/O EDI+ Xbus Dccal No Valid Mode" ); + break; + } fapi_try_exit: FAPI_IMP( "p9_io_xbus_dccal: I/O EDI+ Xbus Exiting" ); @@ -217,41 +231,42 @@ fapi2::ReturnCode tx_zcal_verify_results( /** * @brief Tx Z Impedance Calibration State Machine - * @param[in] i_target FAPI2 Target - * @param[in] io_pval Tx Zcal P-value - * @param[in] io_nval Tx Zcal N-value + * @param[in] i_tgt FAPI2 Target * @retval ReturnCode */ -fapi2::ReturnCode tx_zcal_run_sm( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - uint32_t& io_pval, - uint32_t& io_nval ) +fapi2::ReturnCode tx_zcal_run_bus( const XBUS_TGT i_tgt ) { const uint64_t DLY_20MS = 20000000; const uint64_t DLY_10US = 10000; const uint64_t DLY_10MIL_CYCLES = 10000000; const uint64_t DLY_1MIL_CYCLES = 1000000; const uint32_t TIMEOUT = 200; - const uint8_t GROUP_00 = 0; - const uint8_t LANE_00 = 0; + const uint8_t GRP0 = 0; + const uint8_t LN0 = 0; uint32_t l_count = 0; uint64_t l_data = 0; + uint8_t l_is_sim = 0; FAPI_IMP( "tx_zcal_run_sm: I/O EDI+ Xbus Entering" ); + /////////////////////////////////////////////////////////////////////////// + /// Simulation Speed Up + /////////////////////////////////////////////////////////////////////////// + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim) ); -#if 0 //////////////////////////////////// - // To speed up simulation, xbus_unit model + pie driver - // without these settings: 50 million cycles - // with these settings: 13 million cycles - io::set( EDIP_TX_ZCAL_SM_MIN_VAL, 50, l_data ); - io::set( EDIP_TX_ZCAL_SM_MAX_VAL, 52, l_data ); - FAPI_TRY( io::write( EDIP_TX_IMPCAL_SWO2_PB, i_target, GROUP_00, LANE_00, l_data ) ); -#endif /////////////////////////////////// + if( l_is_sim ) + { + // To speed up simulation, xbus_unit model + pie driver + // without these settings: 50 million cycles + // with these settings: 13 million cycles + io::set( EDIP_TX_ZCAL_SM_MIN_VAL, 50, l_data ); + io::set( EDIP_TX_ZCAL_SM_MAX_VAL, 52, l_data ); + FAPI_TRY( io::write( EDIP_TX_IMPCAL_SWO2_PB, i_tgt, GRP0, LN0, l_data ) ); + } // Request to start Tx Impedance Calibration // The Done bit is read only pulse, must use pie driver or system model in sim - FAPI_TRY( io::rmw( EDIP_TX_ZCAL_REQ, i_target, GROUP_00, LANE_00, 1 ), + FAPI_TRY( io::rmw( EDIP_TX_ZCAL_REQ, i_tgt, GRP0, LN0, 1 ), "tx_zcal_run_sm: RMW Tx Zcal Req Failed"); // Delay before we start polling. 20ms was use from past p8 learning @@ -259,7 +274,7 @@ fapi2::ReturnCode tx_zcal_run_sm( "tx_zcal_run_sm: Fapi Delay Failed." ); // Poll Until Tx Impedance Calibration is done or errors out - FAPI_TRY( io::read( EDIP_TX_IMPCAL_PB, i_target, GROUP_00, LANE_00, l_data ), + FAPI_TRY( io::read( EDIP_TX_IMPCAL_PB, i_tgt, GRP0, LN0, l_data ), "tx_zcal_run_sm: Reading Tx Impcal Pb Failed" ); while( ( ++l_count < TIMEOUT ) && @@ -271,41 +286,24 @@ fapi2::ReturnCode tx_zcal_run_sm( FAPI_TRY( fapi2::delay( DLY_10US, DLY_1MIL_CYCLES ), "tx_zcal_run_sm: Fapi Delay Failed." ); - FAPI_TRY( io::read( EDIP_TX_IMPCAL_PB, i_target, GROUP_00, LANE_00, l_data ), + FAPI_TRY( io::read( EDIP_TX_IMPCAL_PB, i_tgt, GRP0, LN0, l_data ), "tx_zcal_run_sm: Reading Tx Impcal Pb Failed" ); } - if( io::get( EDIP_TX_ZCAL_ERROR, l_data ) == 1 ) + + if( io::get( EDIP_TX_ZCAL_DONE, l_data ) == 1 ) { - FAPI_ERR( "tx_zcal_run_sm: WARNING: Tx Z Calibration Error" ); - FAPI_DBG( "tx_zcal_run_sm: Using Default Segments." ); + FAPI_DBG( "tx_zcal_run_sm: I/O EDI+ Xbus Tx Zcal Poll Completed(%d/%d).", l_count, TIMEOUT ); } - else if( io::get( EDIP_TX_ZCAL_DONE, l_data ) == 0 ) + else if( io::get( EDIP_TX_ZCAL_ERROR, l_data ) == 1 ) { - FAPI_ERR( "tx_zcal_run_sm: WARNING: Tx Z Calibration Timeout: Loops(%d)", l_count ); - FAPI_DBG( "tx_zcal_run_sm: Using Default Segments." ); + FAPI_ERR( "tx_zcal_run_sm: WARNING: Tx Z Calibration Error" ); } else { - FAPI_DBG( "tx_zcal_run_sm: Tx Impedance Calibration Successful." ); - FAPI_DBG( "tx_zcal_run_sm: Using zCal Results." ); - - FAPI_TRY( io::read( EDIP_TX_ZCAL_P, i_target, GROUP_00, LANE_00, l_data ), - "tx_zcal_run_sm: tx_impcal_pval_pb read fail" ); - - // We need to convert the 8R value to a 4R equivalent - io_pval = io::get( EDIP_TX_ZCAL_P, l_data ) / 2; - - FAPI_TRY( io::read( EDIP_TX_ZCAL_N, i_target, GROUP_00, LANE_00, l_data ), - "tx_zcal_run_sm: tx_impcal_nval_pb read fail" ); - - // We need to convert the 8R value to a 4R equivalent - io_nval = io::get( EDIP_TX_ZCAL_N, l_data ) / 2; + FAPI_ERR( "tx_zcal_run_sm: WARNING: Tx Z Calibration Timeout: Loops(%d)", l_count ); } - FAPI_TRY( tx_zcal_verify_results( io_pval, io_nval ), - "tx_zcal_run_sm: Tx Z Cal Get Results Failed" ); - fapi_try_exit: FAPI_IMP( "tx_zcal_run_sm: I/O EDI+ Xbus Exiting" ); return fapi2::current_err; @@ -314,20 +312,20 @@ fapi_try_exit: /** * @brief Tx Z Impedance Calibration Apply Segments. The results of the Tx Impedance * calibrationMargining and FFE Precursor - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @param[in] i_pval Tx Zcal P-value * @param[in] i_nval Tx Zcal N-value * @retval ReturnCode */ fapi2::ReturnCode tx_zcal_apply( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - const uint32_t& i_pval, - const uint32_t& i_nval ) + const XBUS_TGT i_tgt, + const uint8_t i_grp, + const uint32_t i_pval, + const uint32_t i_nval ) { FAPI_IMP( "tx_zcal_apply: I/O EDI+ Xbus Entering" ); - const uint8_t LANE_00 = 0; + const uint8_t LN0 = 0; const uint8_t PRE_WIDTH = 5; const uint8_t MAIN_WIDTH = 13; // 4R Total = ( 1R * 4 ) + (2R * 2 ); @@ -360,10 +358,10 @@ fapi2::ReturnCode tx_zcal_apply( // 0.00% = 0(0x00) / 128 // During normal operation we will not use margining :: min(0, 0%) max(0.5, 50%) - FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_IO_XBUS_TX_MARGIN_RATIO, i_target, l_margin_ratio ) ); + FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_IO_XBUS_TX_MARGIN_RATIO, i_tgt, l_margin_ratio ) ); // -4.8% FFE Precursor Tap Weight :: min(0.0, 0%) max(0.115, 11.5%) - FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_IO_XBUS_TX_FFE_PRECURSOR, i_target, l_ffe_pre_coef ) ); + FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_IO_XBUS_TX_FFE_PRECURSOR, i_tgt, l_ffe_pre_coef ) ); /////////////////////////////////////////////////////////////////////////// // Set P val enables @@ -533,40 +531,40 @@ fapi2::ReturnCode tx_zcal_apply( // the entire register. To convert the 4R values to needed register values, // we will add the appropriate amount and shift to convert to 1R or // 1R + a 2R. - FAPI_TRY( io::rmw( EDIP_TX_PSEG_PRE_EN, i_target, i_group, LANE_00, convert_4r_with_2r( p_en_pre, PRE_WIDTH ) ), + FAPI_TRY( io::rmw( EDIP_TX_PSEG_PRE_EN, i_tgt, i_grp, LN0, convert_4r_with_2r( p_en_pre, PRE_WIDTH ) ), "tx_zcal_apply: Pseg Pre Enable RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_PSEG_PRE_SEL, i_target, i_group, LANE_00, convert_4r_with_2r( p_sel_pre, PRE_WIDTH ) ), + FAPI_TRY( io::rmw( EDIP_TX_PSEG_PRE_SEL, i_tgt, i_grp, LN0, convert_4r_with_2r( p_sel_pre, PRE_WIDTH ) ), "tx_zcal_apply: Pseg Pre Select RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_NSEG_PRE_EN, i_target, i_group, LANE_00, convert_4r_with_2r( n_en_pre, PRE_WIDTH ) ), + FAPI_TRY( io::rmw( EDIP_TX_NSEG_PRE_EN, i_tgt, i_grp, LN0, convert_4r_with_2r( n_en_pre, PRE_WIDTH ) ), "tx_zcal_apply: Nseg Pre Enable RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_NSEG_PRE_SEL, i_target, i_group, LANE_00, convert_4r_with_2r( n_sel_pre, PRE_WIDTH ) ), + FAPI_TRY( io::rmw( EDIP_TX_NSEG_PRE_SEL, i_tgt, i_grp, LN0, convert_4r_with_2r( n_sel_pre, PRE_WIDTH ) ), "tx_zcal_apply: Nseg Pre Select RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_PSEG_MARGINPD_EN, i_target, i_group, LANE_00, convert_4r( p_en_margin_pd ) ), + FAPI_TRY( io::rmw( EDIP_TX_PSEG_MARGINPD_EN, i_tgt, i_grp, LN0, convert_4r( p_en_margin_pd ) ), "tx_zcal_apply: Pseg Margin Enable RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_PSEG_MARGINPU_EN, i_target, i_group, LANE_00, convert_4r( p_en_margin_pu ) ), + FAPI_TRY( io::rmw( EDIP_TX_PSEG_MARGINPU_EN, i_tgt, i_grp, LN0, convert_4r( p_en_margin_pu ) ), "tx_zcal_apply: Pseg Margin Enable RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_NSEG_MARGINPD_EN, i_target, i_group, LANE_00, convert_4r( n_en_margin_pd ) ), + FAPI_TRY( io::rmw( EDIP_TX_NSEG_MARGINPD_EN, i_tgt, i_grp, LN0, convert_4r( n_en_margin_pd ) ), "tx_zcal_apply: Nseg Margin Enable RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_NSEG_MARGINPU_EN, i_target, i_group, LANE_00, convert_4r( n_en_margin_pu ) ), + FAPI_TRY( io::rmw( EDIP_TX_NSEG_MARGINPU_EN, i_tgt, i_grp, LN0, convert_4r( n_en_margin_pu ) ), "tx_zcal_apply: Nseg Margin Enable RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_MARGINPD_SEL, i_target, i_group, LANE_00, convert_4r( sel_margin_pd ) ), + FAPI_TRY( io::rmw( EDIP_TX_MARGINPD_SEL, i_tgt, i_grp, LN0, convert_4r( sel_margin_pd ) ), "tx_zcal_apply: Margin PD Select RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_MARGINPU_SEL, i_target, i_group, LANE_00, convert_4r( sel_margin_pu ) ), + FAPI_TRY( io::rmw( EDIP_TX_MARGINPU_SEL, i_tgt, i_grp, LN0, convert_4r( sel_margin_pu ) ), "tx_zcal_apply: Margin PU Select RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_PSEG_MAIN_EN, i_target, i_group, LANE_00, convert_4r_with_2r( p_en_main, MAIN_WIDTH ) ), + FAPI_TRY( io::rmw( EDIP_TX_PSEG_MAIN_EN, i_tgt, i_grp, LN0, convert_4r_with_2r( p_en_main, MAIN_WIDTH ) ), "tx_zcal_apply: Pseg Main RMW Fail" ); - FAPI_TRY( io::rmw( EDIP_TX_NSEG_MAIN_EN, i_target, i_group, LANE_00, convert_4r_with_2r( n_en_main, MAIN_WIDTH ) ), + FAPI_TRY( io::rmw( EDIP_TX_NSEG_MAIN_EN, i_tgt, i_grp, LN0, convert_4r_with_2r( n_en_main, MAIN_WIDTH ) ), "tx_zcal_apply: Nseg Main RMW Fail" ); fapi_try_exit: @@ -576,94 +574,68 @@ fapi_try_exit: /** * @brief Tx Z Impedance Calibration - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group - * @param[in] i_flags Dccal Attribute Flags + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ -fapi2::ReturnCode tx_zcal( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group ) +fapi2::ReturnCode tx_zcal_set_grp( const XBUS_TGT i_tgt, const uint8_t i_grp ) { - FAPI_IMP( "tx_zcal: I/O EDI+ Xbus Entering" ); - uint32_t l_pval = 25 * 4; // Nominal 25 Segments 1R * 4 = 4R - uint32_t l_nval = 25 * 4; // Nominal 25 Segments 1R * 4 = 4R + FAPI_IMP( "tx_zcal_set_grp: I/O EDI+ Xbus Entering" ); - FAPI_TRY( tx_zcal_run_sm( i_target, l_pval, l_nval ), "Tx Zcal Run SM Failed" ); + const uint8_t GRP0 = 0; + const uint8_t LN0 = 0; + const uint32_t DEFAULT_SEGMENTS = 25 * 4; // Nominal 25 Segments 1R * 4 = 4R + uint32_t l_pval = DEFAULT_SEGMENTS; + uint32_t l_nval = DEFAULT_SEGMENTS; + uint64_t l_data = 0; - // Convert the results of the zCal to actual segments. - FAPI_TRY( tx_zcal_apply( i_target, i_group, l_pval, l_nval ), - "Tx Zcal Apply Segments Failed" ); -fapi_try_exit: - FAPI_IMP( "tx_zcal: I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} + FAPI_TRY( io::read( EDIP_TX_IMPCAL_PB, i_tgt, GRP0, LN0, l_data ), + "tx_zcal_run_sm: Reading Tx Impcal Pb Failed" ); + if( io::get( EDIP_TX_ZCAL_DONE, l_data ) == 1 ) + { + FAPI_DBG( "Using zCal Results." ); -/** - * @brief Rx Dc Calibration Poll - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group - * @retval ReturnCode - */ -fapi2::ReturnCode rx_dccal_poll( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group ) -{ - FAPI_IMP( "rx_dc_cal_poll: I/O EDI+ Xbus Entering" ); - const uint8_t TIMEOUT = 200; - const uint64_t DLY_100MS = 100000000; - const uint64_t DLY_100MIL_CYCLES = 100000000; - const uint64_t DLY_10MS = 10000000; - const uint64_t DLY_50MIL_CYCLES = 50000000; - const uint8_t LANE_00 = 0; - uint8_t l_poll_count = 0; - uint64_t l_data = 0; + FAPI_TRY( io::read( EDIP_TX_ZCAL_P, i_tgt, GRP0, LN0, l_data ), + "tx_impcal_pval_pb read fail" ); - // In the pervasive unit model, this takes 750,000,000 sim cycles to finish - // on a group. This equates to 30 loops with 25,000,000 delay each. + // We need to convert the 8R value to a 4R equivalent + l_pval = io::get( EDIP_TX_ZCAL_P, l_data ) / 2; - // Delay before we start polling. 100ms was use from past p8 learning - FAPI_TRY( fapi2::delay( DLY_100MS, DLY_100MIL_CYCLES ), - "rx_dc_cal_poll: Fapi Delay Failed." ); + FAPI_TRY( io::read( EDIP_TX_ZCAL_N, i_tgt, GRP0, LN0, l_data ), + "tx_impcal_nval_pb read fail" ); - do - { - FAPI_DBG( "rx_dc_cal_poll: I/O EDI+ Xbus Rx Dccal Polling Count(%d/%d).", - l_poll_count, TIMEOUT ); + // We need to convert the 8R value to a 4R equivalent + l_nval = io::get( EDIP_TX_ZCAL_N, l_data ) / 2; - FAPI_TRY( fapi2::delay( DLY_10MS, DLY_50MIL_CYCLES ), - "rx_dc_cal_poll: Fapi Delay Failed." ); - FAPI_TRY( io::read( EDIP_RX_DC_CALIBRATE_DONE, i_target, i_group, LANE_00, l_data ), - "rx_dc_cal_poll: Read Dccal Done Failed" ); + FAPI_TRY( tx_zcal_verify_results( l_pval, l_nval ), "Tx Z Cal Verify Results Failed" ); + } + else + { + FAPI_ERR( "WARNING: Using Default Tx Zcal Segments." ); } - while( ( ++l_poll_count < TIMEOUT ) && !io::get( EDIP_RX_DC_CALIBRATE_DONE, l_data ) ); - - FAPI_ASSERT( ( io::get( EDIP_RX_DC_CALIBRATE_DONE, l_data ) == 1 ), - fapi2::IO_XBUS_RX_DCCAL_TIMEOUT().set_TARGET( i_target ).set_GROUP( i_group ), - "rx_dc_cal_poll: Rx Dccal Timeout: Loops(%d) delay(%d ns, %d cycles)", - l_poll_count, DLY_10MS, DLY_50MIL_CYCLES ); - FAPI_DBG( "rx_dc_cal_poll: I/O EDI+ Xbus Rx Dccal Successful." ); + // Convert the results of the zCal to actual segments. + FAPI_TRY( tx_zcal_apply( i_tgt, i_grp, l_pval, l_nval ), "Tx Zcal Apply Segments Failed" ); fapi_try_exit: - FAPI_IMP( "rx_dc_cal_poll: I/O EDI+ Xbus Exiting" ); + FAPI_IMP( "tx_zcal_set_grp: I/O EDI+ Xbus Exiting" ); return fapi2::current_err; } /** * @brief Rx Dc Calibration Set Lanes Invalid - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @param[in] i_data Data to Set Lanes Invalid * @retval ReturnCode */ fapi2::ReturnCode set_lanes_invalid( - const fapi2::Target<fapi2::TARGET_TYPE_XBUS>& i_target, - const uint8_t& i_group, - const uint8_t& i_data ) + const XBUS_TGT i_tgt, + const uint8_t i_grp, + const uint8_t i_data ) { const uint8_t XBUS_LANES = 17; @@ -671,7 +643,7 @@ fapi2::ReturnCode set_lanes_invalid( for( uint8_t lane = 0; lane < XBUS_LANES; ++lane ) { - FAPI_TRY( io::rmw( EDIP_RX_LANE_INVALID, i_target, i_group, lane, i_data ), + FAPI_TRY( io::rmw( EDIP_RX_LANE_INVALID, i_tgt, i_grp, lane, i_data ), "set_lanes_invalid: RMW Invalid Lane Failed" ); } @@ -682,30 +654,28 @@ fapi_try_exit: /** * @brief Start Cleanup Pll - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ -fapi2::ReturnCode start_cleanup_pll( - const fapi2::Target<fapi2::TARGET_TYPE_XBUS>& i_target, - const uint8_t& i_group ) +fapi2::ReturnCode start_cleanup_pll( const XBUS_TGT i_tgt, const uint8_t i_grp ) { FAPI_IMP( "start_cleanup_pll: I/O EDI+ Xbus Entering" ); - const uint8_t LANE_00 = 0; + const uint8_t LN0 = 0; uint64_t reg_data = 0; - FAPI_TRY( io::read( EDIP_RX_CTL_CNTL4_E_PG, i_target, i_group, LANE_00, reg_data ), + FAPI_TRY( io::read( EDIP_RX_CTL_CNTL4_E_PG, i_tgt, i_grp, LN0, reg_data ), "read edip_rx_ctl_cntl4_e_pg failed" ); io::set( EDIP_RX_WT_PLL_REFCLKSEL, 0x1, reg_data ); io::set( EDIP_RX_PLL_REFCLKSEL_SCOM_EN, 0x1, reg_data ); - FAPI_TRY( io::write( EDIP_RX_CTL_CNTL4_E_PG, i_target, i_group, LANE_00, reg_data ), + FAPI_TRY( io::write( EDIP_RX_CTL_CNTL4_E_PG, i_tgt, i_grp, LN0, reg_data ), "write edip_rx_ctl_cntl4_e_pg failed" ); FAPI_TRY( fapi2::delay( 150000, 0 ), " Fapi Delay Failed." ); - FAPI_TRY( io::rmw( EDIP_RX_WT_CU_PLL_PGOOD, i_target, i_group, LANE_00, 0x1 ), + FAPI_TRY( io::rmw( EDIP_RX_WT_CU_PLL_PGOOD, i_tgt, i_grp, LN0, 0x1 ), "rmw edip_rx_wt_cu_pll_pgood failed" ); FAPI_TRY( fapi2::delay( 5000, 0 ), " Fapi Delay Failed." ); @@ -713,11 +683,11 @@ fapi2::ReturnCode start_cleanup_pll( // The PLL Lock bit is not getting updated. According to AET it is locked. #if 0 - FAPI_TRY( io::read( EDIP_RX_WT_CU_BYP_PLL_LOCK, i_target, i_group, LANE_00, reg_data ), + FAPI_TRY( io::read( EDIP_RX_WT_CU_BYP_PLL_LOCK, i_tgt, i_group, LANE_00, reg_data ), "read edip_rx_wt_cu_byp_pll_lock failed" ); FAPI_ASSERT( ( io::get( EDIP_RX_WT_CU_BYP_PLL_LOCK, reg_data ) == 1 ), - fapi2::IO_XBUS_RX_CLEANUP_PLL_NOT_LOCKED().set_TARGET( i_target ).set_GROUP( i_group ), + fapi2::IO_XBUS_RX_CLEANUP_PLL_NOT_LOCKED().set_TARGET( i_tgt ).set_GROUP( i_group ), "start_cleanup_pll: Cleanup Pll Not Locking" ); #endif @@ -729,26 +699,24 @@ fapi_try_exit: /** * @brief Stop Cleanup Pll - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ -fapi2::ReturnCode stop_cleanup_pll( - const fapi2::Target<fapi2::TARGET_TYPE_XBUS>& i_target, - const uint8_t& i_group ) +fapi2::ReturnCode stop_cleanup_pll( const XBUS_TGT i_tgt, const uint8_t i_grp ) { FAPI_IMP( "stop_cleanup_pll: I/O EDI+ Xbus Entering" ); - const uint8_t LANE_00 = 0; + const uint8_t LN0 = 0; uint64_t reg_data = 0; - FAPI_TRY( io::read( EDIP_RX_CTL_CNTL4_E_PG, i_target, i_group, LANE_00, reg_data ), + FAPI_TRY( io::read( EDIP_RX_CTL_CNTL4_E_PG, i_tgt, i_grp, LN0, reg_data ), "read edip_rx_ctl_cntl4_e_pg failed" ); io::set( EDIP_RX_WT_PLL_REFCLKSEL, 0, reg_data ); io::set( EDIP_RX_PLL_REFCLKSEL_SCOM_EN, 0, reg_data ); io::set( EDIP_RX_WT_CU_PLL_PGOOD, 0, reg_data ); - FAPI_TRY( io::write( EDIP_RX_CTL_CNTL4_E_PG, i_target, i_group, LANE_00, reg_data ), + FAPI_TRY( io::write( EDIP_RX_CTL_CNTL4_E_PG, i_tgt, i_grp, LN0, reg_data ), "write edip_rx_ctl_cntl4_e_pg failed" ); FAPI_TRY( fapi2::delay( 110500, 0 ), " Fapi Delay Failed." ); @@ -760,16 +728,19 @@ fapi_try_exit: /** * @brief Rx Dc Calibration - * @param[in] i_target FAPI2 Target - * @param[in] i_group Clock Group + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ -fapi2::ReturnCode rx_dccal ( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group ) +fapi2::ReturnCode rx_dccal_start_grp( const XBUS_TGT i_tgt, const uint8_t i_grp ) { - FAPI_IMP( "rx_dc_cal: I/O EDI+ Xbus Entering" ); - const uint8_t LANE_00 = 0; + FAPI_IMP( "rx_dccal_start_grp: I/O EDI+ Xbus Entering" ); + const uint8_t LN0 = 0; + + /////////////////////////////////////////////////////////////////////////// + /// Simulation Speed Up + /////////////////////////////////////////////////////////////////////////// + FAPI_TRY( p9_io_xbus_shorten_timers( i_tgt, i_grp ), "Shorten Timers Failed." ); //////////////////////////////////////////////////////////////////////////// /// Start Rx Dccal @@ -778,51 +749,100 @@ fapi2::ReturnCode rx_dccal ( // Must set lane invalid bit to 0 to run rx dccal, this enables us to run // dccal on the specified lane. These bits are normally set by wiretest // although we are not running that now. - FAPI_TRY( set_lanes_invalid( i_target, i_group, 0 ), - "rx_dc_cal: Error Setting Lane Invalid to 0" ); + FAPI_TRY( set_lanes_invalid( i_tgt, i_grp, 0 ), + "Error Setting Lane Invalid to 0" ); // We must start the cleanup pll to have a clock that clocks the // dccal logic. This function locks the rx cleanup pll to the internal // grid clock reference. - FAPI_TRY( start_cleanup_pll( i_target, i_group ), "rx_dc_cal: Starting Cleanup Pll" ); + FAPI_TRY( start_cleanup_pll( i_tgt, i_grp ), "rx_dc_cal: Starting Cleanup Pll" ); // Clear the rx dccal done bit in case rx dccal was previously run. - FAPI_TRY( io::rmw( EDIP_RX_DC_CALIBRATE_DONE, i_target, i_group, LANE_00, 0), - "rx_dc_cal: RMW Dccal Done Failed" ); + FAPI_TRY( io::rmw( EDIP_RX_DC_CALIBRATE_DONE, i_tgt, i_grp, LN0, 0), + "RMW Dccal Done Failed" ); // Start DC Calibrate, this iniates the rx dccal state machine - FAPI_TRY( io::rmw( EDIP_RX_START_DC_CALIBRATE, i_target, i_group, LANE_00, 1 ), - "rx_dc_cal: RMW Start Dccal Failed" ); + FAPI_TRY( io::rmw( EDIP_RX_START_DC_CALIBRATE, i_tgt, i_grp, LN0, 1 ), + "RMW Start Dccal Failed" ); + + FAPI_DBG( "I/O EDI+ Xbus Rx Dccal Complete on Group(%d)", i_grp ); + + +fapi_try_exit: + FAPI_IMP( "rx_dccal_start_grp: I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} + + + + + +/** + * @brief Rx Dc Calibration + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group + * @retval ReturnCode + */ +fapi2::ReturnCode rx_dccal_poll_grp( const XBUS_TGT i_tgt, const uint8_t i_grp ) +{ + FAPI_IMP( "rx_dccal_poll_grp: I/O EDI+ Xbus Entering" ); + const uint8_t TIMEOUT = 200; + const uint64_t DLY_100MS = 100000000; + const uint64_t DLY_10MS = 10000000; + const uint64_t DLY_1MIL_CYCLES = 1000000; + const uint8_t LN0 = 0; + uint8_t l_poll_count = 0; + uint64_t l_data = 0; //////////////////////////////////////////////////////////////////////////// /// Poll Rx Dccal //////////////////////////////////////////////////////////////////////////// + // In the pervasive unit model, this takes 750,000,000 sim cycles to finish + // on a group. This equates to 30 loops with 25,000,000 delay each. + + // Delay before we start polling. 100ms was use from past p8 learning + FAPI_TRY( fapi2::delay( DLY_100MS, DLY_1MIL_CYCLES ), + "rx_dc_cal_poll: Fapi Delay Failed." ); + + do + { + FAPI_DBG( "I/O EDI+ Xbus Rx Dccal Polling Count(%d/%d).", l_poll_count, TIMEOUT ); + + FAPI_TRY( fapi2::delay( DLY_10MS, DLY_1MIL_CYCLES ), "Fapi Delay Failed." ); + + FAPI_TRY( io::read( EDIP_RX_DC_CALIBRATE_DONE, i_tgt, i_grp, LN0, l_data ), + "Read Dccal Done Failed" ); + } + while( ( ++l_poll_count < TIMEOUT ) && !io::get( EDIP_RX_DC_CALIBRATE_DONE, l_data ) ); + + FAPI_ASSERT( ( io::get( EDIP_RX_DC_CALIBRATE_DONE, l_data ) == 1 ), + fapi2::IO_XBUS_RX_DCCAL_TIMEOUT().set_TARGET( i_tgt ).set_GROUP( i_grp ), + "Rx Dccal Timeout: Loops(%d) delay(%d ns, %d cycles)", + l_poll_count, DLY_10MS, DLY_1MIL_CYCLES ); - // Poll to see if rx dccal is done on the specified target / group. - FAPI_TRY( rx_dccal_poll( i_target, i_group ), "rx_dc_cal: Poll Rx DcCal Failed" ); + FAPI_DBG( "I/O EDI+ Xbus Rx Dccal Successful." ); //////////////////////////////////////////////////////////////////////////// /// Cleanup Rx Dccal //////////////////////////////////////////////////////////////////////////// // Stop DC Calibrate - FAPI_TRY( io::rmw( EDIP_RX_START_DC_CALIBRATE, i_target, i_group, LANE_00, 0 ), - "rx_dc_cal: Stopping Dccal Failed" ); + FAPI_TRY( io::rmw( EDIP_RX_START_DC_CALIBRATE, i_tgt, i_grp, LN0, 0 ), + "Stopping Dccal Failed" ); // We must stop the cleanup pll to cleanup after ourselves. Wiretest will // turn this back on. This function will turn off the cleanup pll and // switch it back to bus clock reference. - FAPI_TRY( stop_cleanup_pll( i_target, i_group ), "rx_dc_cal: Stopping Cleanup Pll" ); + FAPI_TRY( stop_cleanup_pll( i_tgt, i_grp ), "rx_dc_cal: Stopping Cleanup Pll" ); // Restore the invalid bits, Wiretest will modify these as training is run. - FAPI_TRY( set_lanes_invalid( i_target, i_group, 1 ), - "rx_dc_cal: Error Setting Lane Invalid to 1" ); + FAPI_TRY( set_lanes_invalid( i_tgt, i_grp, 1 ), "Error Setting Lane Invalid to 1" ); - FAPI_DBG( "rx_dc_cal: I/O EDI+ Xbus Rx Dccal Complete on Group(%d)", i_group ); + FAPI_DBG( "I/O EDI+ Xbus Rx Dccal Complete on Group(%d)", i_grp ); fapi_try_exit: - FAPI_IMP( "rx_dc_cal: I/O EDI+ Xbus Exiting" ); + FAPI_IMP( "rx_dccal_poll_grp: I/O EDI+ Xbus Exiting" ); return fapi2::current_err; } diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.H b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.H index 033f375d4..8923a051c 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.H +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.H @@ -42,9 +42,19 @@ //----------------------------------------------------------------------------- #include <fapi2.H> +typedef fapi2::Target<fapi2::TARGET_TYPE_XBUS> XBUS_TGT; -typedef fapi2::ReturnCode (*p9_io_xbus_dccal_FP_t) -( const fapi2::Target < fapi2::TARGET_TYPE_XBUS>&, const uint8_t& ); + +enum XbusDccalMode : uint8_t +{ + Noop = 0x00, // Runs nothing, can be used for dry runs + TxZcalRunBus = 0x01, // Runs Tx Zcal on a per bus basis + TxZcalSetGrp = 0x02, // Sets Tx Zcal Group Settings based on the bus results + RxDccalStartGrp = 0x03, // Starts Rx Dccal on a per group basis + RxDccalCheckGrp = 0x04 // Checks/polls Rx Dccal on a per group basis +}; + +typedef fapi2::ReturnCode (*p9_io_xbus_dccal_FP_t)( const XbusDccalMode, const XBUS_TGT, const uint8_t ); extern "C" { @@ -52,12 +62,15 @@ extern "C" /** * @brief A I/O EDI+ Procedure that runs Rx Dccal and Tx Z Impedance calibration * on every group of the EDI+ XBUS. - * @param[in] i_target FAPI2 Target + * @param[in] i_mode XbusDccalMode -- selects what operation to perform + * @param[in] i_tgt FAPI2 Target + * @param[in] i_grp Clock Group * @retval ReturnCode */ fapi2::ReturnCode p9_io_xbus_dccal( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group ); + const XbusDccalMode i_mode, + const XBUS_TGT i_tgt , + const uint8_t i_grp ); } // extern "C" diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.mk b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.mk index dde2f8a09..dd152e4bb 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.mk +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.mk @@ -23,4 +23,5 @@ # # IBM_PROLOG_END_TAG PROCEDURE=p9_io_xbus_dccal +OBJS+=p9_io_common.o $(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.C b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.C index f0ede95ed..2f7cf99f3 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.C +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.C @@ -63,6 +63,7 @@ #include <p9_io_xbus_clear_firs.H> #include <p9_io_scom.H> #include <p9_io_regs.H> +#include <p9_io_common.H> //----------------------------------------------------------------------------- // Definitions @@ -87,766 +88,173 @@ inline State operator& (const State& a, const State& b ) } /** - * @brief Starts I/O Training on Xbus (EDI Plus). The slave target must start - * training before the master. This function also assumes that dccal( tx - * impedance calibration and rx offset calibration) are complete. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Reperesents the clock group - * @param[in] i_wderf Represents which training substeps are run. - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode linktrain_start( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - const State& i_wderf ); - -/** - * @brief This function polls the EDI Plus training logic until the training - * is complete. During the case of an error/timeout, the code will log - * FFDC data, which is added to the original error. - * @param[in] i_mtarget Master Xbus Target - * @param[in] i_mgroup Master Clock Group - * @param[in] i_starget Slave Xbus Target - * @param[in] i_sgroup Slave Clock Group - * @param[in] i_started The started EDI Plus training substeps - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode linktrain_poll( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup, - const State& i_started ); - -/** * @brief Adds I/O FFDC Link data to the Error - * @param[in] i_mtarget Master Target - * @param[in] i_mgroup Master Group - * @param[in] i_starget Slave Target - * @param[in] i_sgroup Slave Group - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode add_linktrain_failed_ffdc( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ); - -/** - * @brief Adds I/O FFDC Link data to the Error - * @param[in] i_mtarget Master Target - * @param[in] i_mgroup Master Group - * @param[in] i_starget Slave Target - * @param[in] i_sgroup Slave Group - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode add_linktrain_timeout_ffdc( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ); - -/** - * @brief Find which target is the master target. If neither target is the master, - * then we will throw an error. The master / slave target will be set and passed - * by reference. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Clock Group - * @param[in] i_connected_target Connected Fapi2 Target - * @param[in] i_connected_group Connected Clock Group - * @param[out] o_mtarget Master Fapi2 Target - * @param[out] o_mgroup Master Clock Group - * @param[out] o_starget Slave Fapi2 Target - * @param[out] o_sgroup Slave Clock Group - * @retval ReturnCode - */ -fapi2::ReturnCode find_master_endpoint( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_connected_target, - const uint8_t& i_connected_group, - fapi2::Target < fapi2::TARGET_TYPE_XBUS >& o_mtarget, - uint8_t& o_mgroup, - fapi2::Target < fapi2::TARGET_TYPE_XBUS >& o_starget, - uint8_t& o_sgroup ); - -/** - * @brief Enables the Tx Serializer Sync on Xbus (EDI Plus). - * @param[in] i_mtarget Master Fapi2 Target - * @param[in] i_mgroup Master clock group - * @param[in] i_mtarget Slave Fapi2 Target - * @param[in] i_mgroup Slave clock group - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode tx_serializer_sync_power_on( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ); - -/** - * @brief Disables the Tx Serializer Sync on Xbus (EDI Plus). - * @param[in] i_mtarget Master Fapi2 Target - * @param[in] i_mgroup Master clock group - * @param[in] i_mtarget Slave Fapi2 Target - * @param[in] i_mgroup Slave clock group - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode tx_serializer_sync_power_off( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ); - -/** - * @brief Reads bad lane vector data from the - * passed target and stores the data in the vector. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Clock Group - * @param[out] o_data Data Vector of bad lane vector data - * @retval ReturnCode - */ -fapi2::ReturnCode set_bad_lane_data( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - std::vector< uint8_t >& io_data ); - -/** - * @brief Copmares the bad lane vector pre and post training. If the data is - * the same, then we will want to clear the firs, since the firs have already - * been recorded. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Clock Group - * @param[out] o_data Data Vector of bad lane vector data - * @retval ReturnCode - */ -fapi2::ReturnCode evaluate_bad_lane_data( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - std::vector< uint8_t >& io_data ); - - -/** - * @brief A HWP that runs on every instance of the XBUS(EDI+) - * @param[in] i_target Reference to the Master Target - * @param[in] i_group Master Target Clock Group - * @param[in] i_ctarget Reference to the Slave Target - * @param[in] i_cgroup Slave Target Clock Group - * @retval ReturnCode - */ -fapi2::ReturnCode p9_io_xbus_linktrain( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_ctarget, - const uint8_t& i_cgroup ) -{ - FAPI_IMP( "p9_io_xbus_linktrain: P9 I/O EDI+ Xbus Entering" ); - fapi2::Target < fapi2::TARGET_TYPE_XBUS > l_mtarget; - fapi2::Target < fapi2::TARGET_TYPE_XBUS > l_starget; - uint8_t l_mgroup = 0; - uint8_t l_sgroup = 0; - std::vector < uint8_t > l_master_bad_lane_vector = { 0, 0, 0, 0 }; - std::vector < uint8_t > l_slave_bad_lane_vector = { 0, 0, 0, 0 }; - char l_target_string[fapi2::MAX_ECMD_STRING_LEN]; - char l_ctarget_string[fapi2::MAX_ECMD_STRING_LEN]; - fapi2::toString( i_target, l_target_string, fapi2::MAX_ECMD_STRING_LEN ); - fapi2::toString( i_ctarget, l_ctarget_string, fapi2::MAX_ECMD_STRING_LEN ); - - FAPI_DBG( "I/O Xbus Targets: Target(%s:g%d) Connected(%s:g%d)", - l_target_string, i_group, - l_ctarget_string, i_cgroup ); - - // Find which target is the master target. If neither target is the master, - // then we will throw an error. The master / slave target will be set - // and passed by reference. - FAPI_TRY( find_master_endpoint( - i_target, i_group, - i_ctarget, i_cgroup, - l_mtarget, l_mgroup, - l_starget, l_sgroup ), - "Find Master Endpoint Failed" ); - - FAPI_TRY( set_bad_lane_data( l_mtarget, l_mgroup, l_master_bad_lane_vector ), - "Pre Training: Get Bad Lane Vector Failed on Master" ); - - FAPI_TRY( set_bad_lane_data( l_starget, l_sgroup, l_slave_bad_lane_vector ), - "Pre Training: Get Bad Lane Vector Failed on Slave" ); - - // Clock Serializer Init -- isn't strictly necessary but does line up the - // clock serializer counter wit the data slices. - FAPI_TRY( tx_serializer_sync_power_on( l_mtarget, l_mgroup, l_starget, l_sgroup ), - "tx_serializer_sync_power_on Failed." ); - - // Start Slave Target Link Training - FAPI_TRY( linktrain_start( l_starget, l_sgroup, State::WDERF ), - "P9 IO Xbus Linktrain Start Slave Training Failed" ); - - // Start Master Target Link Training - FAPI_TRY( linktrain_start( l_mtarget, l_mgroup, State::WDERF ), - "P9 IO Xbus Linktrain Start Master Training Failed." ); - - // Poll for Training to Complete on Master Target - FAPI_TRY( linktrain_poll( l_mtarget, l_mgroup, l_starget, l_sgroup, State::WDERF ), - "P9 IO Xbus Linktrain Polling Failed" ); - - // Disable the Tx Serializer Sync - FAPI_TRY( tx_serializer_sync_power_off( l_mtarget, l_mgroup, l_starget, l_sgroup ), - "tx_serializer_sync_power_off Failed."); - - FAPI_TRY( set_bad_lane_data( l_mtarget, l_mgroup, l_master_bad_lane_vector ), - "Post Training: Get Bad Lane Vector Failed on Master" ); - - FAPI_TRY( set_bad_lane_data( l_starget, l_sgroup, l_slave_bad_lane_vector ), - "Post Training: Get Bad Lane Vector Failed on Master" ); - - FAPI_TRY( evaluate_bad_lane_data( l_mtarget, l_mgroup, l_master_bad_lane_vector ), - "Post Training: Evaluate Firs Failed on Master" ); - - FAPI_TRY( evaluate_bad_lane_data( l_starget, l_sgroup, l_slave_bad_lane_vector ), - "Post Training: Evaluate Firs Failed on Slave" ); - - -fapi_try_exit: - FAPI_IMP( "p9_io_xbus_linktrain: P9 I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} - -/** - * @brief Find which target is the master target. If neither target is the master, - * then we will throw an error. The master / slave target will be set and passed - * by reference. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Clock Group - * @param[in] i_connected_target Connected Fapi2 Target - * @param[in] i_connected_group Connected Clock Group - * @param[out] o_mtarget Master Fapi2 Target - * @param[out] o_mgroup Master Clock Group - * @param[out] o_starget Slave Fapi2 Target - * @param[out] o_sgroup Slave Clock Group - * @retval ReturnCode - */ -fapi2::ReturnCode find_master_endpoint( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_connected_target, - const uint8_t& i_connected_group, - fapi2::Target < fapi2::TARGET_TYPE_XBUS >& o_mtarget, - uint8_t& o_mgroup, - fapi2::Target < fapi2::TARGET_TYPE_XBUS >& o_starget, - uint8_t& o_sgroup ) -{ - uint8_t l_master_mode = 0; - uint8_t l_cmaster_mode = 0; - - FAPI_IMP( "find_master_endpoint: P9 I/O EDI+ Xbus Entering" ); - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_MASTER_MODE, i_target, l_master_mode) ); - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_MASTER_MODE, i_connected_target, l_cmaster_mode) ); - - if( l_master_mode == fapi2::ENUM_ATTR_IO_XBUS_MASTER_MODE_TRUE ) - { - FAPI_DBG( "find_master_endpoint: Target is Master" ); - o_mtarget = i_target; - o_mgroup = i_group; - o_starget = i_connected_target; - o_sgroup = i_connected_group; - } - else if( l_cmaster_mode == fapi2::ENUM_ATTR_IO_XBUS_MASTER_MODE_TRUE ) - { - FAPI_DBG( "find_master_endpoint: Connected target is Master" ); - o_mtarget = i_connected_target; - o_mgroup = i_connected_group; - o_starget = i_target; - o_sgroup = i_group; - } - else - { - FAPI_ASSERT( false, fapi2::IO_XBUS_NOT_MASTER() - .set_TARGET( i_target ) - .set_CTARGET( i_connected_target ), - "find_master_endpoint: Neither target or connected target is master." ); - } - -fapi_try_exit: - FAPI_IMP( "find_master_endpoint: P9 I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} - -/** - * @brief Reads bad lane vector data from the - * passed target and stores the data in the vector. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Clock Group - * @param[out] o_data Data Vector of bad lane vector data - * @retval ReturnCode - */ -fapi2::ReturnCode set_bad_lane_data( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - std::vector< uint8_t >& io_data ) -{ - FAPI_IMP( "set_bad_lane_data: P9 I/O EDI+ Xbus Entering" ); - const uint8_t LANE_00 = 0; - const uint8_t LAST_BAD_LANE_0_15 = 0; - const uint8_t LAST_BAD_LANE_16_23 = 1; - const uint8_t CURRENT_BAD_LANE_0_15 = 2; - const uint8_t CURRENT_BAD_LANE_16_23 = 3; - uint64_t l_data = 0; - - FAPI_TRY( io::read( EDIP_RX_LANE_BAD_VEC_0_15, i_target, i_group, LANE_00, l_data ), - "rmw to edip_rx_lane_bad_vec_0_15 failed." ); - - io_data[LAST_BAD_LANE_0_15] = io_data[CURRENT_BAD_LANE_0_15]; - io_data[CURRENT_BAD_LANE_0_15] = io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ); - - FAPI_TRY( io::read( EDIP_RX_LANE_BAD_VEC_16_23, i_target, i_group, LANE_00, l_data ), - "rmw to edip_rx_lane_bad_vec_16_23 failed." ); - - io_data[LAST_BAD_LANE_16_23] = io_data[CURRENT_BAD_LANE_16_23]; - io_data[CURRENT_BAD_LANE_16_23] = io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ); - -fapi_try_exit: - FAPI_IMP( "set_bad_lane_data: P9 I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} - - -/** - * @brief Copmares the bad lane vector pre and post training. If the data is - * the same, then we will want to clear the firs, since the firs have already - * been recorded. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Clock Group - * @param[out] o_data Data Vector of bad lane vector data - * @retval ReturnCode - */ -fapi2::ReturnCode evaluate_bad_lane_data( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - std::vector< uint8_t >& io_data ) -{ - FAPI_IMP( "evaluate_bad_lane_data: P9 I/O EDI+ Xbus Entering" ); - const uint8_t LANE_00 = 0; - const uint8_t PRE_LANE_0_15 = 0; - const uint8_t PRE_LANE_16_23 = 1; - const uint8_t POST_LANE_0_15 = 2; - const uint8_t POST_LANE_16_23 = 3; - uint64_t l_data = 0; - - // If the bad lane vector matches pre to post training, then the same bad - // lanes that were previously found, were found again. These bad lanes have - // already been reported. So we will clear the first related to these bad - // lanes - if( ( io_data[PRE_LANE_0_15] == io_data[POST_LANE_0_15] ) && - ( io_data[PRE_LANE_16_23] == io_data[POST_LANE_16_23] ) ) - { - // If the entire bad lane vector equals 0, then we don't need to clear - // any firs. - if( io_data[POST_LANE_0_15] != 0 || io_data[POST_LANE_16_23] != 0 ) - { - FAPI_TRY( p9_io_xbus_clear_firs( i_target, i_group ) ); - - // Clear BUS0_SPARE_DEPLOYED ( Bit 9 ). - FAPI_TRY( io::read( EDIP_SCOM_FIR_PB, i_target, i_group, LANE_00, l_data ) ); - l_data &= 0xFF7FFFFFFFFFFFFFull; - FAPI_TRY( io::write( EDIP_SCOM_FIR_PB, i_target, i_group, LANE_00, l_data ) ); - } - } - -fapi_try_exit: - FAPI_IMP( "evaluate_bad_lane_data: P9 I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} - - -/** - * @brief Enables the Tx Serializer Sync on Xbus (EDI Plus). - * @param[in] i_mtarget Master Fapi2 Target - * @param[in] i_mgroup Master clock group - * @param[in] i_mtarget Slave Fapi2 Target - * @param[in] i_mgroup Slave clock group - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode tx_serializer_sync_power_on( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ) -{ - FAPI_IMP( "tx_serializer_sync_power_on: I/O EDI+ Xbus Entering" ); - const uint8_t XBUS_LANES = 17; - const uint8_t LANE_00 = 0; - - FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_mtarget, i_mgroup, LANE_00, 0 ), - "master rmw to edip_tx_clk_unload_clk_disable failed." ); - FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_starget, i_sgroup, LANE_00, 0 ), - "slave rmw to edip_tx_clk_unload_clk_disable failed." ); - - FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_mtarget, i_mgroup, LANE_00, 0 ), - "master rmw to edip_tx_clk_run_count failed." ); - FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_starget, i_sgroup, LANE_00, 0 ), - "slave rmw to edip_tx_clk_run_count failed." ); - - FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_mtarget, i_mgroup, LANE_00, 1 ), - "master rmw to edip_tx_clk_run_count failed." ); - FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_starget, i_sgroup, LANE_00, 1 ), - "slave rmw to edip_tx_clk_run_count failed." ); - - FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_mtarget, i_mgroup, LANE_00, 1 ), - "master rmw to edip_tx_clk_unload_clk_disable failed." ); - FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_starget, i_sgroup, LANE_00, 1 ), - "slave rmw to edip_tx_clk_unload_clk_disable failed." ); - - for( uint8_t lane = 0; lane < XBUS_LANES; ++lane ) - { - FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_mtarget, i_mgroup, lane, 0x0 ), - "master rmw to edip_tx_unload_clk_disable Failed" ); - FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_starget, i_sgroup, lane, 0x0 ), - "slave rmw to edip_tx_unload_clk_disable Failed" ); - } - -fapi_try_exit: - FAPI_IMP( "tx_serializer_sync_power_on: I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} - -/** - * @brief Disables the Tx Serializer Sync on Xbus (EDI Plus). - * @param[in] i_mtarget Master Fapi2 Target - * @param[in] i_mgroup Master clock group - * @param[in] i_mtarget Slave Fapi2 Target - * @param[in] i_mgroup Slave clock group - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode tx_serializer_sync_power_off( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ) -{ - FAPI_IMP( "tx_serializer_sync_power_off: I/O EDI+ Xbus Entering" ); - const uint8_t XBUS_LANES = 17; - - for( uint8_t lane = 0; lane < XBUS_LANES; ++lane ) - { - FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_mtarget, i_mgroup, lane, 0x1 ), - "master rmw to edip_tx_unload_clk_disable Failed" ); - FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_starget, i_sgroup, lane, 0x1 ), - "slave rmw to edip_tx_unload_clk_disable Failed" ); - } - -fapi_try_exit: - FAPI_IMP( "tx_serializer_sync_power_off: I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} - - -/** - * @brief Starts I/O Training on Xbus (EDI Plus). The slave target must start - * training before the master. This function also assumes that dccal( tx - * impedance calibration and rx offset calibration) are complete. - * @param[in] i_target Fapi2 Target - * @param[in] i_group Reperesents the clock group - * @param[in] i_wderf Represents which training substeps are run. - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode linktrain_start( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, - const uint8_t& i_group, - const State& i_wderf ) -{ - FAPI_IMP("linktrain_start: P9 I/O EDI+ Xbus Entering"); - const uint8_t LANE_00 = 0; - - FAPI_TRY( io::rmw( - EDIP_RX_START_WDERF_ALIAS, - i_target, - i_group, - LANE_00, - static_cast<uint64_t>(i_wderf ) ), - "linktrain_start: rmw to start wderf failed." ); - -fapi_try_exit: - FAPI_IMP("linktrain_start: P9 I/O EDI+ Xbus Exiting"); - return fapi2::current_err; -} - -/** - * @brief This function polls the EDI Plus training logic until the training - * is complete. During the case of an error/timeout, the code will log - * FFDC data, which is added to the original error. - * @param[in] i_mtarget Master Xbus Target - * @param[in] i_mgroup Master Clock Group - * @param[in] i_starget Slave Xbus Target - * @param[in] i_sgroup Slave Clock Group - * @param[in] i_started The started EDI Plus training substeps + * @param[in] i_mtgt Master Target + * @param[in] i_stgt Slave Target + * @param[in] i_grp Clock Group * @retval fapi2::ReturnCode */ -fapi2::ReturnCode linktrain_poll( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup, - const State& i_started ) +fapi2::ReturnCode add_linktrain_ffdc( + const XBUS_TGT i_mtgt, + const XBUS_TGT i_stgt, + const uint8_t i_grp, + const bool i_timeout ) { - FAPI_IMP( "linktrain_poll: P9 I/O EDI+ Xbus Entering" ); - - const uint8_t MAXLOOPS = 100; - const uint64_t DELAY_1MS = 1000000; - const uint64_t DELAY_SIM_CYCLES = 20000000; - const uint8_t LANE_00 = 0; - uint8_t l_loops = 0; - uint64_t l_reg_data = 0; - State l_done_state = State::NONE; - State l_failed_state = State::NONE; - - - // In the P9 EDI+ Xbus unit model, polling finishes in - // 17 loops @ 20 million cycles = 340 million cycles - // For hardware timeout, we used what was used in p8, 1ms @ 100 cycles for - // a max of 100ms to complete training. - while( ++l_loops < MAXLOOPS ) - { - // Get Done/Failed WDERF Status - FAPI_TRY( io::read( EDIP_RX_CTL_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_reg_data ) ); - l_done_state = static_cast<State>( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_reg_data ) ); - l_failed_state = static_cast<State>( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_reg_data ) ); - - // Check if all substeps are complete - if( i_started == ( i_started & l_done_state ) ) - { - break; - } - - // Check if any substeps have failed. - if( l_failed_state != State::NONE ) - { - break; - } - - FAPI_TRY( fapi2::delay( DELAY_1MS, DELAY_SIM_CYCLES ) ); - } - - // Check the error conditions. - if( l_failed_state != State::NONE ) - { - FAPI_ERR( "I/O EDI+ Xbus Link Training Failed." ); - FAPI_TRY( add_linktrain_failed_ffdc( i_mtarget, i_mgroup, i_starget, i_sgroup ) ); - } - else if( i_started != ( i_started & l_done_state ) ) - { - FAPI_ERR( "I/O EDI+ Xbus Link Training Timeout." ); - FAPI_TRY( add_linktrain_timeout_ffdc( i_mtarget, i_mgroup, i_starget, i_sgroup ) ); - } - else - { - FAPI_INF( "linktrain_poll: P9 I/O EDI+ Xbus Training Successful in %d loops.", l_loops ); - } + const uint8_t LN0 = 0; + const uint32_t INVALID_FFDC = 0xFFFFFFFF; + uint64_t l_data = 0; -fapi_try_exit: - FAPI_IMP( "linktrain_poll: P9 I/O EDI+ Xbus Exiting" ); - return fapi2::current_err; -} - - -/** - * @brief Adds I/O FFDC Link data to the Error - * @param[in] i_mtarget Master Target - * @param[in] i_mgroup Master Group - * @param[in] i_starget Slave Target - * @param[in] i_sgroup Slave Group - * @retval fapi2::ReturnCode - */ -fapi2::ReturnCode add_linktrain_failed_ffdc( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ) -{ - const uint8_t LANE_00 = 0; - const uint32_t INVALID_FFDC = 0xFFFFFFFF; - uint64_t l_data = 0; + // Return Codes: + // l_ffdc_rc -- Passed by reference and is used to create the ffdc. This return code + // will be returned at the end of the function fapi2::ReturnCode l_ffdc_rc = 0; + + // l_rc -- Used during the data collection and will not cause the function to fail, + // only will cause invalid data if the scoms fail. fapi2::ReturnCode l_rc = 0; - // Note the return code, the return code is passed by reference and this same return code will - // be returned at the end of the function. The return code used in the data collection will - // not be passed back. - fapi2::IO_XBUS_LINKTRAIN_FAIL ffdc( fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, l_ffdc_rc ); + // Create the FFDC Error + fapi2::IO_XBUS_LINKTRAIN_ERROR ffdc( fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, l_ffdc_rc ); - ffdc.set_M_TARGET( i_mtarget ); - ffdc.set_M_GROUP ( i_mgroup ); - ffdc.set_S_TARGET( i_starget ); - ffdc.set_S_GROUP ( i_sgroup ); + ffdc.set_M_TARGET( i_mtgt ); + ffdc.set_S_TARGET( i_stgt ); + ffdc.set_GROUP ( i_grp ); + ffdc.set_TIMEOUT ( i_timeout ); - //////////////////////////////////////////////////////////////////////////// - // Master /////////////////////////////////////////////////////////////////////////// - l_rc = io::read( EDIP_RX_CTL_CNTL1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + // Master Common + /////////////////////////////////////////////////////////////////////////// + l_rc = io::read( EDIP_RX_CTL_CNTL1_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_WDERF_START ( io::get( EDIP_RX_START_WDERF_ALIAS, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WDERF_START ( io::get( EDIP_RX_START_WDERF_ALIAS, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_WDERF_START ( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT1_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_WDERF_DONE ( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_data ) ); + ffdc.set_M_WDERF_FAILED( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WDERF_DONE ( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_data ) ); - ffdc.set_M_WDERF_FAILED( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_WDERF_DONE ( INVALID_FFDC ); ffdc.set_M_WDERF_FAILED( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT2_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT2_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_LANE_BAD_0_15( io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_LANE_BAD_0_15( io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_LANE_BAD_0_15( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT4_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT4_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_LANE_BAD_16_23( io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_LANE_BAD_16_23( io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_LANE_BAD_16_23( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_MODE11_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_MODE11_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_LANE_DISABLED_VEC_0_15( io::get( EDIP_RX_LANE_DISABLED_VEC_0_15, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_LANE_DISABLED_VEC_0_15( io::get( EDIP_RX_LANE_DISABLED_VEC_0_15, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_LANE_DISABLED_VEC_0_15( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_MODE12_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_MODE12_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_LANE_DISABLED_VEC_16_23( io::get( EDIP_RX_LANE_DISABLED_VEC_16_23, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_LANE_DISABLED_VEC_16_23( io::get( EDIP_RX_LANE_DISABLED_VEC_16_23, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_LANE_DISABLED_VEC_16_23( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_MAIN_INIT_STATE( io::get( EDIP_RX_MAIN_INIT_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_MAIN_INIT_STATE( io::get( EDIP_RX_MAIN_INIT_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_MAIN_INIT_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Wiretest - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + /////////////////////////////////////////////////////////////////////////// + // Master Wiretest + /////////////////////////////////////////////////////////////////////////// + l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_WIRETEST_WTM_STATE( io::get( EDIP_RX_WTM_STATE, l_data ) ); + ffdc.set_M_WIRETEST_WTR_STATE( io::get( EDIP_RX_WTR_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WIRETEST_WTM_STATE( io::get( EDIP_RX_WTM_STATE, l_data ) ); - ffdc.set_M_WIRETEST_WTR_STATE( io::get( EDIP_RX_WTR_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_WIRETEST_WTM_STATE( INVALID_FFDC ); ffdc.set_M_WIRETEST_WTR_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT3_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT3_EO_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_WIRETEST_WTL_SM_STATUS( io::get( EDIP_RX_WTL_SM_STATUS, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WIRETEST_WTL_SM_STATUS( io::get( EDIP_RX_WTL_SM_STATUS, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_WIRETEST_WTL_SM_STATUS( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_GLBSM_STAT2_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_GLBSM_STAT2_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_WTR_BAD_LANE_COUNT( io::get( EDIP_RX_WTR_BAD_LANE_COUNT, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WTR_BAD_LANE_COUNT( io::get( EDIP_RX_WTR_BAD_LANE_COUNT, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_WTR_BAD_LANE_COUNT( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT5_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT5_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_CLK_LANE_BAD_CODE ( io::get( EDIP_RX_WT_CLK_LANE_BAD_CODE, l_data ) ); + ffdc.set_M_WT_CLK_LANE_INVERTED( io::get( EDIP_RX_WT_CLK_LANE_INVERTED, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_CLK_LANE_BAD_CODE ( io::get( EDIP_RX_WT_CLK_LANE_BAD_CODE, l_data ) ); - ffdc.set_M_WT_CLK_LANE_INVERTED( io::get( EDIP_RX_WT_CLK_LANE_INVERTED, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_CLK_LANE_BAD_CODE ( INVALID_FFDC ); ffdc.set_M_WT_CLK_LANE_INVERTED( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Deskew + /////////////////////////////////////////////////////////////////////////// + // Master Deskew + /////////////////////////////////////////////////////////////////////////// - // Eye Opt - l_rc = io::read( EDIP_RX_GLBSM_STAT1_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + /////////////////////////////////////////////////////////////////////////// + // Master Eye Optimization + /////////////////////////////////////////////////////////////////////////// + l_rc = io::read( EDIP_RX_GLBSM_STAT1_EO_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_EYE_OPT_STATE( io::get( EDIP_RX_EYE_OPT_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_EYE_OPT_STATE( io::get( EDIP_RX_EYE_OPT_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_EYE_OPT_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_CNTL13_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_CNTL13_EO_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_HIST_MIN_EYE_WIDTH( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH, l_data ) ); + ffdc.set_M_HIST_MIN_EYE_WIDTH_LANE( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_LANE, l_data ) ); + ffdc.set_M_HIST_MIN_EYE_WIDTH_VALID( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_VALID, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_HIST_MIN_EYE_WIDTH( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH, l_data ) ); - ffdc.set_M_HIST_MIN_EYE_WIDTH_LANE( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_LANE, l_data ) ); - ffdc.set_M_HIST_MIN_EYE_WIDTH_VALID( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_VALID, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_HIST_MIN_EYE_WIDTH ( INVALID_FFDC ); ffdc.set_M_HIST_MIN_EYE_WIDTH_LANE ( INVALID_FFDC ); @@ -854,28 +262,24 @@ fapi2::ReturnCode add_linktrain_failed_ffdc( l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Repair - l_rc = io::read( EDIP_RX_GLBSM_STAT4_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + /////////////////////////////////////////////////////////////////////////// + // Master Repair + /////////////////////////////////////////////////////////////////////////// + l_rc = io::read( EDIP_RX_GLBSM_STAT4_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_RPR_STATE( io::get( EDIP_RX_RPR_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_RPR_STATE( io::get( EDIP_RX_RPR_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_RPR_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_GLBSM_STAT9_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_GLBSM_STAT9_E_PG, i_mtgt, i_grp, LN0, l_data ); + ffdc.set_M_BAD_LANE1 ( io::get( EDIP_RX_BAD_LANE1, l_data ) ); + ffdc.set_M_BAD_LANE2 ( io::get( EDIP_RX_BAD_LANE2, l_data ) ); + ffdc.set_M_BAD_LANE_CODE( io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_BAD_LANE1 ( io::get( EDIP_RX_BAD_LANE1, l_data ) ); - ffdc.set_M_BAD_LANE2 ( io::get( EDIP_RX_BAD_LANE2, l_data ) ); - ffdc.set_M_BAD_LANE_CODE( io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_M_BAD_LANE1 ( INVALID_FFDC ); ffdc.set_M_BAD_LANE2 ( INVALID_FFDC ); @@ -883,177 +287,144 @@ fapi2::ReturnCode add_linktrain_failed_ffdc( l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Deskew - - // Func Mode + /////////////////////////////////////////////////////////////////////////// + // Master Functional Mode + /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// - // Slave + // Slave Common /////////////////////////////////////////////////////////////////////////// - l_rc = io::read( EDIP_RX_CTL_CNTL1_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_CNTL1_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_WDERF_START ( io::get( EDIP_RX_START_WDERF_ALIAS, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WDERF_START ( io::get( EDIP_RX_START_WDERF_ALIAS, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_WDERF_START ( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT1_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT1_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_WDERF_DONE ( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_data ) ); + ffdc.set_S_WDERF_FAILED( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WDERF_DONE ( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_data ) ); - ffdc.set_S_WDERF_FAILED( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_WDERF_DONE ( INVALID_FFDC ); ffdc.set_S_WDERF_FAILED( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT2_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT2_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_LANE_BAD_0_15( io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_BAD_0_15( io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_LANE_BAD_0_15( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT4_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT4_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_LANE_BAD_16_23( io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_BAD_16_23( io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_LANE_BAD_16_23( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_MODE11_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_MODE11_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_LANE_DISABLED_VEC_0_15( io::get( EDIP_RX_LANE_DISABLED_VEC_0_15, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_DISABLED_VEC_0_15( io::get( EDIP_RX_LANE_DISABLED_VEC_0_15, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_LANE_DISABLED_VEC_0_15( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_MODE12_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_MODE12_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_LANE_DISABLED_VEC_16_23( io::get( EDIP_RX_LANE_DISABLED_VEC_16_23, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_DISABLED_VEC_16_23( io::get( EDIP_RX_LANE_DISABLED_VEC_16_23, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_LANE_DISABLED_VEC_16_23( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_MAIN_INIT_STATE( io::get( EDIP_RX_MAIN_INIT_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_MAIN_INIT_STATE( io::get( EDIP_RX_MAIN_INIT_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_MAIN_INIT_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Wiretest - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + /////////////////////////////////////////////////////////////////////////// + // Slave Wiretest + /////////////////////////////////////////////////////////////////////////// + l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_WIRETEST_WTM_STATE( io::get( EDIP_RX_WTM_STATE, l_data ) ); + ffdc.set_S_WIRETEST_WTR_STATE( io::get( EDIP_RX_WTR_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WIRETEST_WTM_STATE( io::get( EDIP_RX_WTM_STATE, l_data ) ); - ffdc.set_S_WIRETEST_WTR_STATE( io::get( EDIP_RX_WTR_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_WIRETEST_WTM_STATE( INVALID_FFDC ); ffdc.set_S_WIRETEST_WTR_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT3_EO_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT3_EO_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_WIRETEST_WTL_SM_STATUS( io::get( EDIP_RX_WTL_SM_STATUS, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WIRETEST_WTL_SM_STATUS( io::get( EDIP_RX_WTL_SM_STATUS, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_WIRETEST_WTL_SM_STATUS( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_GLBSM_STAT2_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_GLBSM_STAT2_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_WTR_BAD_LANE_COUNT( io::get( EDIP_RX_WTR_BAD_LANE_COUNT, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WTR_BAD_LANE_COUNT( io::get( EDIP_RX_WTR_BAD_LANE_COUNT, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_WTR_BAD_LANE_COUNT( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_STAT5_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_STAT5_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_CLK_LANE_BAD_CODE ( io::get( EDIP_RX_WT_CLK_LANE_BAD_CODE, l_data ) ); + ffdc.set_S_WT_CLK_LANE_INVERTED( io::get( EDIP_RX_WT_CLK_LANE_INVERTED, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_CLK_LANE_BAD_CODE ( io::get( EDIP_RX_WT_CLK_LANE_BAD_CODE, l_data ) ); - ffdc.set_S_WT_CLK_LANE_INVERTED( io::get( EDIP_RX_WT_CLK_LANE_INVERTED, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_CLK_LANE_BAD_CODE ( INVALID_FFDC ); ffdc.set_S_WT_CLK_LANE_INVERTED( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Deskew + /////////////////////////////////////////////////////////////////////////// + // Slave Deskew + /////////////////////////////////////////////////////////////////////////// - // Eye Opt - l_rc = io::read( EDIP_RX_GLBSM_STAT1_EO_PG, i_starget, i_sgroup, LANE_00, l_data ); + /////////////////////////////////////////////////////////////////////////// + // Slave Eye Optimization + /////////////////////////////////////////////////////////////////////////// + l_rc = io::read( EDIP_RX_GLBSM_STAT1_EO_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_EYE_OPT_STATE( io::get( EDIP_RX_EYE_OPT_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_EYE_OPT_STATE( io::get( EDIP_RX_EYE_OPT_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_EYE_OPT_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_CTL_CNTL13_EO_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_CTL_CNTL13_EO_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_HIST_MIN_EYE_WIDTH( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH, l_data ) ); + ffdc.set_S_HIST_MIN_EYE_WIDTH_LANE( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_LANE, l_data ) ); + ffdc.set_S_HIST_MIN_EYE_WIDTH_VALID( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_VALID, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_HIST_MIN_EYE_WIDTH( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH, l_data ) ); - ffdc.set_S_HIST_MIN_EYE_WIDTH_LANE( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_LANE, l_data ) ); - ffdc.set_S_HIST_MIN_EYE_WIDTH_VALID( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_VALID, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_HIST_MIN_EYE_WIDTH ( INVALID_FFDC ); ffdc.set_S_HIST_MIN_EYE_WIDTH_LANE ( INVALID_FFDC ); @@ -1061,28 +432,24 @@ fapi2::ReturnCode add_linktrain_failed_ffdc( l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Repair - l_rc = io::read( EDIP_RX_GLBSM_STAT4_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + /////////////////////////////////////////////////////////////////////////// + // Slave Repair + /////////////////////////////////////////////////////////////////////////// + l_rc = io::read( EDIP_RX_GLBSM_STAT4_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_RPR_STATE( io::get( EDIP_RX_RPR_STATE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_RPR_STATE( io::get( EDIP_RX_RPR_STATE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_RPR_STATE( INVALID_FFDC ); l_rc = fapi2::FAPI2_RC_SUCCESS; } - l_rc = io::read( EDIP_RX_GLBSM_STAT9_E_PG, i_starget, i_sgroup, LANE_00, l_data ); + l_rc = io::read( EDIP_RX_GLBSM_STAT9_E_PG, i_stgt, i_grp, LN0, l_data ); + ffdc.set_S_BAD_LANE1 ( io::get( EDIP_RX_BAD_LANE1, l_data ) ); + ffdc.set_S_BAD_LANE2 ( io::get( EDIP_RX_BAD_LANE2, l_data ) ); + ffdc.set_S_BAD_LANE_CODE( io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_BAD_LANE1 ( io::get( EDIP_RX_BAD_LANE1, l_data ) ); - ffdc.set_S_BAD_LANE2 ( io::get( EDIP_RX_BAD_LANE2, l_data ) ); - ffdc.set_S_BAD_LANE_CODE( io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ); - } - else + if( l_rc != fapi2::FAPI2_RC_SUCCESS ) { ffdc.set_S_BAD_LANE1 ( INVALID_FFDC ); ffdc.set_S_BAD_LANE2 ( INVALID_FFDC ); @@ -1090,9 +457,9 @@ fapi2::ReturnCode add_linktrain_failed_ffdc( l_rc = fapi2::FAPI2_RC_SUCCESS; } - // Deskew - - // Func Mode + /////////////////////////////////////////////////////////////////////////// + // Slave Functional Mode + /////////////////////////////////////////////////////////////////////////// // Log FFDC ffdc.execute(); @@ -1100,436 +467,414 @@ fapi2::ReturnCode add_linktrain_failed_ffdc( return l_ffdc_rc; } - /** - * @brief Adds I/O FFDC Link data to the Timeout Error - * @param[in] i_mtarget Master Target - * @param[in] i_mgroup Master Group - * @param[in] i_starget Slave Target - * @param[in] i_sgroup Slave Group + * @brief Starts I/O Training on Xbus (EDI Plus). The slave target must start + * training before the master. This function also assumes that dccal( tx + * impedance calibration and rx offset calibration) are complete. + * @param[in] i_tgt Fapi2 Target + * @param[in] i_grp Reperesents the clock group + * @param[in] i_wderf Represents which training substeps are run. * @retval fapi2::ReturnCode */ -fapi2::ReturnCode add_linktrain_timeout_ffdc( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ) +fapi2::ReturnCode linktrain_start( + const XBUS_TGT i_tgt, + const uint8_t i_grp, + const State i_wderf ) { - const uint8_t LANE_00 = 0; - const uint32_t INVALID_FFDC = 0xFFFFFFFF; - uint64_t l_data = 0; - fapi2::ReturnCode l_ffdc_rc = 0; - fapi2::ReturnCode l_rc = 0; - - // Note the return code, the return code is passed by reference and this same return code will - // be returned at the end of the function. The return code used in the data collection will - // not be passed back. - fapi2::IO_XBUS_LINKTRAIN_TIMEOUT ffdc( fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, l_ffdc_rc ); + FAPI_IMP("linktrain_start: P9 I/O EDI+ Xbus Entering"); + const uint8_t LN0 = 0; - ffdc.set_M_TARGET( i_mtarget ); - ffdc.set_M_GROUP ( i_mgroup ); - ffdc.set_S_TARGET( i_starget ); - ffdc.set_S_GROUP ( i_sgroup ); + FAPI_TRY( io::rmw( EDIP_RX_START_WDERF_ALIAS, i_tgt, i_grp, LN0, static_cast<uint64_t>(i_wderf ) ), + "linktrain_start: rmw to start wderf failed." ); - //////////////////////////////////////////////////////////////////////////// - // Master - /////////////////////////////////////////////////////////////////////////// - l_rc = io::read( EDIP_RX_CTL_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); +fapi_try_exit: + FAPI_IMP("linktrain_start: P9 I/O EDI+ Xbus Exiting"); + return fapi2::current_err; +} - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WDERF_START ( io::get( EDIP_RX_START_WDERF_ALIAS, l_data ) ); - ffdc.set_M_WDERF_DONE ( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_data ) ); - ffdc.set_M_WDERF_FAILED( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_data ) ); - } - else - { - ffdc.set_M_WDERF_START ( INVALID_FFDC ); - ffdc.set_M_WDERF_DONE ( INVALID_FFDC ); - ffdc.set_M_WDERF_FAILED( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } +/** + * @brief This function polls the EDI Plus training logic until the training + * is complete. During the case of an error/timeout, the code will log + * FFDC data, which is added to the original error. + * @param[in] i_mtgt Master Target + * @param[in] i_stgt Slave Target + * @param[in] i_grp Clock Group + * @param[in] i_started The started EDI Plus training substeps + * @retval fapi2::ReturnCode + */ +fapi2::ReturnCode linktrain_poll( + const XBUS_TGT i_mtgt, + const XBUS_TGT i_stgt, + const uint8_t i_grp, + const State i_started ) +{ + FAPI_IMP( "linktrain_poll: P9 I/O EDI+ Xbus Entering" ); - l_rc = io::read( EDIP_RX_CTL_STAT2_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + const uint8_t MAXLOOPS = 100; + const uint64_t DELAY_1MS = 1000000; + const uint64_t DELAY_SIM_CYCLES = 2000000; // Set lower due to sim speed up + const uint8_t LN0 = 0; + uint8_t l_loops = 0; + uint64_t l_reg_data = 0; + State l_done_state = State::NONE; + State l_failed_state = State::NONE; - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_LANE_BAD_0_15( io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ) ); - } - else + // In the P9 EDI+ Xbus unit model, polling finishes in + // 17 loops @ 20 million cycles = 340 million cycles + // For hardware timeout, we used what was used in p8, 1ms @ 100 cycles for + // a max of 100ms to complete training. + while( ++l_loops < MAXLOOPS ) { - ffdc.set_M_LANE_BAD_0_15( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + // Get Done/Failed WDERF Status + FAPI_TRY( io::read( EDIP_RX_CTL_STAT1_E_PG, i_mtgt, i_grp, LN0, l_reg_data ) ); + l_done_state = static_cast<State>( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_reg_data ) ); + l_failed_state = static_cast<State>( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_reg_data ) ); + // Check if all substeps are complete + if( i_started == ( i_started & l_done_state ) ) + { + break; + } - l_rc = io::read( EDIP_RX_CTL_STAT4_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + // Check if any substeps have failed. + if( l_failed_state != State::NONE ) + { + break; + } - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_LANE_BAD_16_23( io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ) ); - } - else - { - ffdc.set_M_LANE_BAD_16_23( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + FAPI_TRY( fapi2::delay( DELAY_1MS, DELAY_SIM_CYCLES ) ); } - l_rc = io::read( EDIP_RX_CTL_MODE11_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_LANE_DISABLED_VEC_0_15( io::get( EDIP_RX_LANE_DISABLED_VEC_0_15, l_data ) ); - } - else + // Check the error conditions. + if( l_failed_state != State::NONE ) { - ffdc.set_M_LANE_DISABLED_VEC_0_15( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + FAPI_ERR( "I/O EDI+ Xbus Link Training Failed." ); + FAPI_TRY( add_linktrain_ffdc( i_mtgt, i_stgt, i_grp, false ) ); } - - l_rc = io::read( EDIP_RX_CTL_MODE12_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) + else if( i_started != ( i_started & l_done_state ) ) { - ffdc.set_M_LANE_DISABLED_VEC_16_23( io::get( EDIP_RX_LANE_DISABLED_VEC_16_23, l_data ) ); + FAPI_ERR( "I/O EDI+ Xbus Link Training Timeout." ); + FAPI_TRY( add_linktrain_ffdc( i_mtgt, i_stgt, i_grp, true ) ); } else { - ffdc.set_M_LANE_DISABLED_VEC_16_23( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + FAPI_INF( "linktrain_poll: P9 I/O EDI+ Xbus Training Successful in %d loops.", l_loops ); } - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); +fapi_try_exit: + FAPI_IMP( "linktrain_poll: P9 I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_MAIN_INIT_STATE( io::get( EDIP_RX_MAIN_INIT_STATE, l_data ) ); - } - else - { - ffdc.set_M_MAIN_INIT_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } - // Wiretest - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WIRETEST_WTM_STATE( io::get( EDIP_RX_WTM_STATE, l_data ) ); - ffdc.set_M_WIRETEST_WTR_STATE( io::get( EDIP_RX_WTR_STATE, l_data ) ); - } - else - { - ffdc.set_M_WIRETEST_WTM_STATE( INVALID_FFDC ); - ffdc.set_M_WIRETEST_WTR_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } +/** + * @brief Find which target is the master target. If neither target is the master, + * then we will throw an error. The master / slave target will be set and passed + * by reference. + * @param[in] i_tgt Fapi2 Target + * @param[in] i_ctgt Connected Fapi2 Target + * @param[out] o_mtgt Master Fapi2 Target + * @param[out] o_stgt Slave Fapi2 Target + * @retval ReturnCode + */ +fapi2::ReturnCode find_master_endpoint( + const XBUS_TGT i_tgt, + const XBUS_TGT i_ctgt, + XBUS_TGT& o_mtgt, + XBUS_TGT& o_stgt ) +{ + uint8_t l_master_mode = 0; + uint8_t l_cmaster_mode = 0; - l_rc = io::read( EDIP_RX_CTL_STAT3_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_IMP( "find_master_endpoint: P9 I/O EDI+ Xbus Entering" ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_WIRETEST_WTL_SM_STATUS( io::get( EDIP_RX_WTL_SM_STATUS, l_data ) ); - } - else - { - ffdc.set_M_WIRETEST_WTL_SM_STATUS( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_MASTER_MODE, i_tgt, l_master_mode) ); - l_rc = io::read( EDIP_RX_GLBSM_STAT2_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_MASTER_MODE, i_ctgt, l_cmaster_mode) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) + // Check if both targets are master -- Bad + if( l_master_mode == fapi2::ENUM_ATTR_IO_XBUS_MASTER_MODE_TRUE && + l_cmaster_mode == fapi2::ENUM_ATTR_IO_XBUS_MASTER_MODE_TRUE ) { - ffdc.set_M_WTR_BAD_LANE_COUNT( io::get( EDIP_RX_WTR_BAD_LANE_COUNT, l_data ) ); + FAPI_ASSERT( false, fapi2::IO_XBUS_NOT_MASTER() + .set_TARGET( i_tgt ) + .set_CTARGET( i_ctgt ), + "Both Targets have the I/O EDIP Master Mode bits set." ); } - else + // Check if the first target is a master + else if( l_master_mode == fapi2::ENUM_ATTR_IO_XBUS_MASTER_MODE_TRUE ) { - ffdc.set_M_WTR_BAD_LANE_COUNT( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + FAPI_DBG( "find_master_endpoint: Target is Master" ); + o_mtgt = i_tgt; + o_stgt = i_ctgt; } - - l_rc = io::read( EDIP_RX_CTL_STAT5_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) + // Check if the connected target is a master + else if( l_cmaster_mode == fapi2::ENUM_ATTR_IO_XBUS_MASTER_MODE_TRUE ) { - ffdc.set_M_CLK_LANE_BAD_CODE ( io::get( EDIP_RX_WT_CLK_LANE_BAD_CODE, l_data ) ); - ffdc.set_M_WT_CLK_LANE_INVERTED( io::get( EDIP_RX_WT_CLK_LANE_INVERTED, l_data ) ); + FAPI_DBG( "find_master_endpoint: Connected target is Master" ); + o_mtgt = i_ctgt; + o_stgt = i_tgt; } + // Neither target is the master -- Bad else { - ffdc.set_M_CLK_LANE_BAD_CODE ( INVALID_FFDC ); - ffdc.set_M_WT_CLK_LANE_INVERTED( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + FAPI_ASSERT( false, fapi2::IO_XBUS_NOT_MASTER() + .set_TARGET( i_tgt ) + .set_CTARGET( i_ctgt ), + "find_master_endpoint: Neither target or connected target is master." ); } - // Deskew +fapi_try_exit: + FAPI_IMP( "find_master_endpoint: P9 I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} - // Eye Opt - l_rc = io::read( EDIP_RX_GLBSM_STAT1_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); +/** + * @brief Enables the Tx Serializer Sync on Xbus (EDI Plus). + * @param[in] i_mtgt Master Fapi2 Target + * @param[in] i_stgt Slave Fapi2 Target + * @param[in] i_ grp Clock group + * @retval fapi2::ReturnCode + */ +fapi2::ReturnCode tx_serializer_sync_power_on( + const XBUS_TGT i_mtgt, + const XBUS_TGT i_stgt, + const uint8_t i_grp ) +{ + FAPI_IMP( "tx_serializer_sync_power_on: I/O EDI+ Xbus Entering" ); + const uint8_t XBUS_LANES = 17; + const uint8_t LN0 = 0; - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_EYE_OPT_STATE( io::get( EDIP_RX_EYE_OPT_STATE, l_data ) ); - } - else - { - ffdc.set_M_EYE_OPT_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_mtgt, i_grp, LN0, 0 ), + "master rmw to edip_tx_clk_unload_clk_disable failed." ); + FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_stgt, i_grp, LN0, 0 ), + "slave rmw to edip_tx_clk_unload_clk_disable failed." ); - l_rc = io::read( EDIP_RX_CTL_CNTL13_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_mtgt, i_grp, LN0, 0 ), + "master rmw to edip_tx_clk_run_count failed." ); + FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_stgt, i_grp, LN0, 0 ), + "slave rmw to edip_tx_clk_run_count failed." ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_HIST_MIN_EYE_WIDTH( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH, l_data ) ); - ffdc.set_M_HIST_MIN_EYE_WIDTH_LANE( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_LANE, l_data ) ); - ffdc.set_M_HIST_MIN_EYE_WIDTH_VALID( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_VALID, l_data ) ); - } - else - { - ffdc.set_M_HIST_MIN_EYE_WIDTH ( INVALID_FFDC ); - ffdc.set_M_HIST_MIN_EYE_WIDTH_LANE ( INVALID_FFDC ); - ffdc.set_M_HIST_MIN_EYE_WIDTH_VALID( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_mtgt, i_grp, LN0, 1 ), + "master rmw to edip_tx_clk_run_count failed." ); + FAPI_TRY( io::rmw( EDIP_TX_CLK_RUN_COUNT, i_stgt, i_grp, LN0, 1 ), + "slave rmw to edip_tx_clk_run_count failed." ); - // Repair - l_rc = io::read( EDIP_RX_GLBSM_STAT4_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_mtgt, i_grp, LN0, 1 ), + "master rmw to edip_tx_clk_unload_clk_disable failed." ); + FAPI_TRY( io::rmw( EDIP_TX_CLK_UNLOAD_CLK_DISABLE, i_stgt, i_grp, LN0, 1 ), + "slave rmw to edip_tx_clk_unload_clk_disable failed." ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_RPR_STATE( io::get( EDIP_RX_RPR_STATE, l_data ) ); - } - else + for( uint8_t lane = 0; lane < XBUS_LANES; ++lane ) { - ffdc.set_M_RPR_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_mtgt, i_grp, lane, 0x0 ), + "master rmw to edip_tx_unload_clk_disable Failed" ); + FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_stgt, i_grp, lane, 0x0 ), + "slave rmw to edip_tx_unload_clk_disable Failed" ); } - l_rc = io::read( EDIP_RX_GLBSM_STAT9_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); +fapi_try_exit: + FAPI_IMP( "tx_serializer_sync_power_on: I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_M_BAD_LANE1 ( io::get( EDIP_RX_BAD_LANE1, l_data ) ); - ffdc.set_M_BAD_LANE2 ( io::get( EDIP_RX_BAD_LANE2, l_data ) ); - ffdc.set_M_BAD_LANE_CODE( io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ); - } - else +/** + * @brief Disables the Tx Serializer Sync on Xbus (EDI Plus). + * @param[in] i_mtgt Master Fapi2 Target + * @param[in] i_mtgt Slave Fapi2 Target + * @param[in] i_grp Clock group + * @retval fapi2::ReturnCode + */ +fapi2::ReturnCode tx_serializer_sync_power_off( + const XBUS_TGT i_mtgt, + const XBUS_TGT i_stgt, + const uint8_t i_grp ) +{ + FAPI_IMP( "tx_serializer_sync_power_off: I/O EDI+ Xbus Entering" ); + const uint8_t XBUS_LANES = 17; + + for( uint8_t lane = 0; lane < XBUS_LANES; ++lane ) { - ffdc.set_M_BAD_LANE1 ( INVALID_FFDC ); - ffdc.set_M_BAD_LANE2 ( INVALID_FFDC ); - ffdc.set_M_BAD_LANE_CODE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_mtgt, i_grp, lane, 0x1 ), + "master rmw to edip_tx_unload_clk_disable Failed" ); + FAPI_TRY( io::rmw( EDIP_TX_UNLOAD_CLK_DISABLE, i_stgt, i_grp, lane, 0x1 ), + "slave rmw to edip_tx_unload_clk_disable Failed" ); } - // Deskew +fapi_try_exit: + FAPI_IMP( "tx_serializer_sync_power_off: I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} - // Func Mode +/** + * @brief Reads bad lane vector data from the + * passed target and stores the data in the vector. + * @param[in] i_target Fapi2 Target + * @param[in] i_group Clock Group + * @param[out] o_data Data of bad lane vector data + * @retval ReturnCode + */ +fapi2::ReturnCode get_bad_lane_data( + const XBUS_TGT i_tgt, + const uint8_t i_grp, + uint32_t& o_data ) +{ + FAPI_IMP( "P9 I/O EDI+ Xbus Entering" ); + const uint8_t LN0 = 0; + uint64_t l_data = 0; - /////////////////////////////////////////////////////////////////////////// - // Slave - /////////////////////////////////////////////////////////////////////////// - l_rc = io::read( EDIP_RX_CTL_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_TRY( io::read( EDIP_RX_LANE_BAD_VEC_0_15, i_tgt, i_grp, LN0, l_data ), + "rmw to edip_rx_lane_bad_vec_0_15 failed." ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WDERF_START ( io::get( EDIP_RX_START_WDERF_ALIAS, l_data ) ); - ffdc.set_S_WDERF_DONE ( io::get( EDIP_RX_WDERF_DONE_ALIAS, l_data ) ); - ffdc.set_S_WDERF_FAILED( io::get( EDIP_RX_WDERF_FAILED_ALIAS, l_data ) ); - } - else - { - ffdc.set_S_WDERF_START ( INVALID_FFDC ); - ffdc.set_S_WDERF_DONE ( INVALID_FFDC ); - ffdc.set_S_WDERF_FAILED( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + o_data = ( io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ) << 8 ) & 0x00FFFF00; - l_rc = io::read( EDIP_RX_CTL_STAT2_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_TRY( io::read( EDIP_RX_LANE_BAD_VEC_16_23, i_tgt, i_grp, LN0, l_data ), + "rmw to edip_rx_lane_bad_vec_16_23 failed." ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_BAD_0_15( io::get( EDIP_RX_LANE_BAD_VEC_0_15, l_data ) ); - } - else - { - ffdc.set_S_LANE_BAD_0_15( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + o_data |= ( io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ) & 0x000000FF ); +fapi_try_exit: + FAPI_IMP( "P9 I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} - l_rc = io::read( EDIP_RX_CTL_STAT4_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); +/** + * @brief Copmares the bad lane vector pre and post training. If the data is + * the same, then we will want to clear the firs, since the firs have already + * been recorded. + * @param[in] i_tgt Fapi2 Target + * @param[in] i_grp Clock Group + * @param[out] o_data Data Vector of bad lane vector data + * @retval ReturnCode + */ +fapi2::ReturnCode check_bad_lane_data( + const XBUS_TGT i_tgt, + const uint8_t i_grp, + uint32_t i_pre_bad_lane_data, + uint32_t i_post_bad_lane_data ) +{ + FAPI_IMP( "P9 I/O EDI+ Xbus Entering" ); + const uint8_t LN0 = 0; + uint64_t l_data = 0; - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_BAD_16_23( io::get( EDIP_RX_LANE_BAD_VEC_16_23, l_data ) ); - } - else + // If the bad lane vector matches pre to post training, then the same bad + // lanes that were previously found, were found again. These bad lanes have + // already been reported. So we will clear the first related to these bad + // lanes + if( i_pre_bad_lane_data == i_post_bad_lane_data ) { - ffdc.set_S_LANE_BAD_16_23( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } - - l_rc = io::read( EDIP_RX_CTL_MODE11_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_DBG( "I/O EDI+ Xbus Pre/Post Bad Lane Data Match" ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_DISABLED_VEC_0_15( io::get( EDIP_RX_LANE_DISABLED_VEC_0_15, l_data ) ); - } - else - { - ffdc.set_S_LANE_DISABLED_VEC_0_15( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + // If the entire bad lane vector equals 0, then we don't need to clear + // any firs. + if( i_pre_bad_lane_data != 0 ) + { + FAPI_DBG( "I/O EDI+ Xbus Clearing Firs" ); - l_rc = io::read( EDIP_RX_CTL_MODE12_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + FAPI_TRY( p9_io_xbus_clear_firs( i_tgt, i_grp ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_LANE_DISABLED_VEC_16_23( io::get( EDIP_RX_LANE_DISABLED_VEC_16_23, l_data ) ); - } - else - { - ffdc.set_S_LANE_DISABLED_VEC_16_23( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; + // Clear BUS0_SPARE_DEPLOYED ( Bit 9 ). + FAPI_TRY( io::read( EDIP_SCOM_FIR_PB, i_tgt, i_grp, LN0, l_data ) ); + l_data &= 0xFF7FFFFFFFFFFFFFull; + FAPI_TRY( io::write( EDIP_SCOM_FIR_PB, i_tgt, i_grp, LN0, l_data ) ); + } } - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_MAIN_INIT_STATE( io::get( EDIP_RX_MAIN_INIT_STATE, l_data ) ); - } - else - { - ffdc.set_S_MAIN_INIT_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } +fapi_try_exit: + FAPI_IMP( "P9 I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} - // Wiretest - l_rc = io::read( EDIP_RX_GLBSM_STAT1_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WIRETEST_WTM_STATE( io::get( EDIP_RX_WTM_STATE, l_data ) ); - ffdc.set_S_WIRETEST_WTR_STATE( io::get( EDIP_RX_WTR_STATE, l_data ) ); - } - else - { - ffdc.set_S_WIRETEST_WTM_STATE( INVALID_FFDC ); - ffdc.set_S_WIRETEST_WTR_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } +/** + * @brief A HWP that runs on every link of the XBUS(EDI+) + * @param[in] i_mode Linktraining Mode + * @param[in] i_tgt Reference to the Master Target + * @param[in] i_ctgt Reference to the Slave Target + * @param[in] i_grp Clock Group + * @retval ReturnCode + */ +fapi2::ReturnCode p9_io_xbus_linktrain( + const XBUS_TGT i_tgt, + const XBUS_TGT i_ctgt, + const uint8_t i_grp ) +{ + FAPI_IMP( "p9_io_xbus_linktrain: P9 I/O EDI+ Xbus Entering" ); + XBUS_TGT l_mtgt; + XBUS_TGT l_stgt; + uint32_t l_m_pre_bad_data = 0; + uint32_t l_m_post_bad_data = 0; + uint32_t l_s_pre_bad_data = 0; + uint32_t l_s_post_bad_data = 0; - l_rc = io::read( EDIP_RX_CTL_STAT3_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + char l_tgt_str[fapi2::MAX_ECMD_STRING_LEN]; + char l_ctgt_str[fapi2::MAX_ECMD_STRING_LEN]; + fapi2::toString( i_tgt, l_tgt_str, fapi2::MAX_ECMD_STRING_LEN ); + fapi2::toString( i_ctgt, l_ctgt_str, fapi2::MAX_ECMD_STRING_LEN ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WIRETEST_WTL_SM_STATUS( io::get( EDIP_RX_WTL_SM_STATUS, l_data ) ); - } - else - { - ffdc.set_S_WIRETEST_WTL_SM_STATUS( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + FAPI_DBG( "I/O Xbus Targets: Target(%s) Connected(%s) Group(%d)", + l_tgt_str, l_ctgt_str, i_grp ); - l_rc = io::read( EDIP_RX_GLBSM_STAT2_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + // Find which target is the master target. If neither target is the master, + // then we will throw an error. The master / slave target will be set + // and passed by reference. + FAPI_TRY( find_master_endpoint( i_tgt, i_ctgt, l_mtgt, l_stgt ), + "Find Master Endpoint Failed" ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_WTR_BAD_LANE_COUNT( io::get( EDIP_RX_WTR_BAD_LANE_COUNT, l_data ) ); - } - else - { - ffdc.set_S_WTR_BAD_LANE_COUNT( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } - l_rc = io::read( EDIP_RX_CTL_STAT5_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); + // Shorten timers if we are running in simulation + FAPI_TRY( p9_io_xbus_shorten_timers( l_mtgt, i_grp ) ); + FAPI_TRY( p9_io_xbus_shorten_timers( l_stgt, i_grp ) ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_CLK_LANE_BAD_CODE ( io::get( EDIP_RX_WT_CLK_LANE_BAD_CODE, l_data ) ); - ffdc.set_S_WT_CLK_LANE_INVERTED( io::get( EDIP_RX_WT_CLK_LANE_INVERTED, l_data ) ); - } - else - { - ffdc.set_S_CLK_LANE_BAD_CODE ( INVALID_FFDC ); - ffdc.set_S_WT_CLK_LANE_INVERTED( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } - // Deskew + // Record the Bad Lane Vectors Prior to link training. + FAPI_TRY( get_bad_lane_data( l_mtgt, i_grp, l_m_pre_bad_data ), + "Pre Training: Get Bad Lane Vector Failed on Master" ); + FAPI_TRY( get_bad_lane_data( l_stgt, i_grp, l_s_pre_bad_data ), + "Pre Training: Get Bad Lane Vector Failed on Slave" ); - // Eye Opt - l_rc = io::read( EDIP_RX_GLBSM_STAT1_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_EYE_OPT_STATE( io::get( EDIP_RX_EYE_OPT_STATE, l_data ) ); - } - else - { - ffdc.set_S_EYE_OPT_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + // Clock Serializer Init -- isn't strictly necessary but does line up the + // clock serializer counter wit the data slices. + FAPI_TRY( tx_serializer_sync_power_on( l_mtgt, l_stgt, i_grp ), + "tx_serializer_sync_power_on Failed." ); - l_rc = io::read( EDIP_RX_CTL_CNTL13_EO_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_HIST_MIN_EYE_WIDTH( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH, l_data ) ); - ffdc.set_S_HIST_MIN_EYE_WIDTH_LANE( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_LANE, l_data ) ); - ffdc.set_S_HIST_MIN_EYE_WIDTH_VALID( io::get( EDIP_RX_HIST_MIN_EYE_WIDTH_VALID, l_data ) ); - } - else - { - ffdc.set_S_HIST_MIN_EYE_WIDTH ( INVALID_FFDC ); - ffdc.set_S_HIST_MIN_EYE_WIDTH_LANE ( INVALID_FFDC ); - ffdc.set_S_HIST_MIN_EYE_WIDTH_VALID( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + // Start Slave/Master Target Link Training + FAPI_TRY( linktrain_start( l_stgt, i_grp, State::WDERF ), + "P9 IO Xbus Linktrain Start Slave Training Failed" ); + FAPI_TRY( linktrain_start( l_mtgt, i_grp, State::WDERF ), + "P9 IO Xbus Linktrain Start Master Training Failed." ); - // Repair - l_rc = io::read( EDIP_RX_GLBSM_STAT4_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_RPR_STATE( io::get( EDIP_RX_RPR_STATE, l_data ) ); - } - else - { - ffdc.set_S_RPR_STATE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + // Poll for Training to Complete on Master Target + FAPI_TRY( linktrain_poll( l_mtgt, l_stgt, i_grp, State::WDERF ), + "P9 IO Xbus Linktrain Polling Failed" ); - l_rc = io::read( EDIP_RX_GLBSM_STAT9_E_PG, i_mtarget, i_mgroup, LANE_00, l_data ); - if( l_rc == fapi2::FAPI2_RC_SUCCESS ) - { - ffdc.set_S_BAD_LANE1 ( io::get( EDIP_RX_BAD_LANE1, l_data ) ); - ffdc.set_S_BAD_LANE2 ( io::get( EDIP_RX_BAD_LANE2, l_data ) ); - ffdc.set_S_BAD_LANE_CODE( io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ); - } - else - { - ffdc.set_S_BAD_LANE1 ( INVALID_FFDC ); - ffdc.set_S_BAD_LANE2 ( INVALID_FFDC ); - ffdc.set_S_BAD_LANE_CODE( INVALID_FFDC ); - l_rc = fapi2::FAPI2_RC_SUCCESS; - } + // Disable the Tx Serializer Sync + FAPI_TRY( tx_serializer_sync_power_off( l_mtgt, l_stgt, i_grp ), + "tx_serializer_sync_power_off Failed."); - // Deskew - // Func Mode + // Record the Bad Lane Vectors after link training. + FAPI_TRY( get_bad_lane_data( l_mtgt, i_grp, l_m_post_bad_data ), + "Post Training: Get Bad Lane Vector Failed on Master" ); + FAPI_TRY( get_bad_lane_data( l_stgt, i_grp, l_s_post_bad_data ), + "Post Training: Get Bad Lane Vector Failed on Master" ); - // Log FFDC Error - ffdc.execute(); - return l_ffdc_rc; -} + // Check to see if the bad lanes match the bad lanes prior to link training. + // If so, then that error has already been logged and we can clear the firs. + FAPI_TRY( check_bad_lane_data( l_mtgt, i_grp, l_m_pre_bad_data, l_m_post_bad_data ), + "Post Training: Evaluate Firs Failed on Master" ); + FAPI_TRY( check_bad_lane_data( l_stgt, i_grp, l_s_pre_bad_data, l_s_post_bad_data ), + "Post Training: Evaluate Firs Failed on Slave" ); +fapi_try_exit: + FAPI_IMP( "p9_io_xbus_linktrain: P9 I/O EDI+ Xbus Exiting" ); + return fapi2::current_err; +} diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.H b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.H index 9ff0b38c2..5e05ebe3a 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.H +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.H @@ -46,28 +46,26 @@ //----------------------------------------------------------------------------- #include <fapi2.H> -typedef fapi2::ReturnCode (*p9_io_xbus_linktrain_FP_t)( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >&, - const uint8_t&, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >&, - const uint8_t& ); +typedef fapi2::Target<fapi2::TARGET_TYPE_XBUS> XBUS_TGT; + +typedef fapi2::ReturnCode (*p9_io_xbus_linktrain_FP_t) +( const XBUS_TGT, const XBUS_TGT, const uint8_t ); extern "C" { /** - * @brief A HWP that runs on every instance of the XBUS(EDI+) - * @param[in] i_mtarget Reference to the Master Target - * @param[in] i_mgroup Master Target Clock Group - * @param[in] i_starget Reference to the Slave Target - * @param[in] i_sgroup Slave Target Clock Group + * @brief A HWP that runs once on every link of the XBUS(EDI+). + * The HWP will train both ends of the link. + * @param[in] i_target Reference to the Target + * @param[in] i_ctarget Reference to the Connected Target + * @param[in] i_group Clock Group * @retval ReturnCode */ fapi2::ReturnCode p9_io_xbus_linktrain( - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_mtarget, - const uint8_t& i_mgroup, - const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_starget, - const uint8_t& i_sgroup ); + const XBUS_TGT i_target, + const XBUS_TGT i_ctarget, + const uint8_t i_group ); } // extern "C" diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.mk b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.mk index 6e42514f5..49fba76a8 100644 --- a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.mk +++ b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_linktrain.mk @@ -23,4 +23,5 @@ # # IBM_PROLOG_END_TAG PROCEDURE=p9_io_xbus_linktrain +OBJS+=p9_io_common.o $(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_io_xbus_linktrain_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_io_xbus_linktrain_errors.xml index bcc859853..4a497d5db 100644 --- a/src/import/chips/p9/procedures/xml/error_info/p9_io_xbus_linktrain_errors.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_io_xbus_linktrain_errors.xml @@ -32,95 +32,11 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_IO_XBUS_LINKTRAIN_TIMEOUT</rc> - <description>I/O Xbus WDERF Timeout</description> - <ffdc>M_GROUP</ffdc> - <ffdc>S_GROUP</ffdc> - <ffdc>M_WDERF_START</ffdc> - <ffdc>M_WDERF_DONE</ffdc> - <ffdc>M_WDERF_FAILED</ffdc> - <ffdc>M_LANE_BAD_0_15</ffdc> - <ffdc>M_LANE_BAD_16_23</ffdc> - <ffdc>M_LANE_DISABLED_VEC_0_15</ffdc> - <ffdc>M_LANE_DISABLED_VEC_16_23</ffdc> - <ffdc>M_MAIN_INIT_STATE</ffdc> - <!-- Master Wiretest Info --> - <ffdc>M_WIRETEST_WTM_STATE</ffdc> - <ffdc>M_WIRETEST_WTR_STATE</ffdc> - <ffdc>M_WIRETEST_WTL_SM_STATUS</ffdc> - <ffdc>M_WTR_BAD_LANE_COUNT</ffdc> - <ffdc>M_CLK_LANE_BAD_CODE</ffdc> - <ffdc>M_WT_CLK_LANE_INVERTED</ffdc> - <!-- Master Deskew Info --> - <!-- Master Eye Opt Info --> - <ffdc>M_EYE_OPT_STATE</ffdc> - <ffdc>M_HIST_MIN_EYE_WIDTH</ffdc> - <ffdc>M_HIST_MIN_EYE_WIDTH_LANE</ffdc> - <ffdc>M_HIST_MIN_EYE_WIDTH_VALID</ffdc> - <!-- Master Repair Info --> - <ffdc>M_RPR_STATE</ffdc> - <ffdc>M_BAD_LANE1</ffdc> - <ffdc>M_BAD_LANE2</ffdc> - <ffdc>M_BAD_LANE_CODE</ffdc> - <!-- Master Func Mode Info --> - <ffdc>S_WDERF_START</ffdc> - <ffdc>S_WDERF_DONE</ffdc> - <ffdc>S_WDERF_FAILED</ffdc> - <ffdc>S_LANE_BAD_0_15</ffdc> - <ffdc>S_LANE_BAD_16_23</ffdc> - <ffdc>S_LANE_DISABLED_VEC_0_15</ffdc> - <ffdc>S_LANE_DISABLED_VEC_16_23</ffdc> - <ffdc>S_MAIN_INIT_STATE</ffdc> - <!-- Slave Wiretest Info --> - <ffdc>S_WIRETEST_WTM_STATE</ffdc> - <ffdc>S_WIRETEST_WTR_STATE</ffdc> - <ffdc>S_WIRETEST_WTL_SM_STATUS</ffdc> - <ffdc>S_WTR_BAD_LANE_COUNT</ffdc> - <ffdc>S_CLK_LANE_BAD_CODE</ffdc> - <ffdc>S_WT_CLK_LANE_INVERTED</ffdc> - <!-- Slave Deskew Info --> - <!-- Slave Eye Opt Info --> - <ffdc>S_EYE_OPT_STATE</ffdc> - <ffdc>S_HIST_MIN_EYE_WIDTH</ffdc> - <ffdc>S_HIST_MIN_EYE_WIDTH_LANE</ffdc> - <ffdc>S_HIST_MIN_EYE_WIDTH_VALID</ffdc> - <!-- Slave Repair Info --> - <ffdc>S_RPR_STATE</ffdc> - <ffdc>S_BAD_LANE1</ffdc> - <ffdc>S_BAD_LANE2</ffdc> - <ffdc>S_BAD_LANE_CODE</ffdc> - <!-- Slave Func Mode Info --> - <callout> - <target>M_TARGET</target> - <priority>MEDIUM</priority> - </callout> - <callout> - <target>S_TARGET</target> - <priority>MEDIUM</priority> - </callout> - <callout> - <bus>M_TARGET,S_TARGET</bus> - <priority>HIGH</priority> - </callout> - <deconfigure> - <target>M_TARGET</target> - </deconfigure> - <deconfigure> - <target>S_TARGET</target> - </deconfigure> - <gard> - <target>M_TARGET</target> - </gard> - <gard> - <target>S_TARGET</target> - </gard> - </hwpError> - <!-- *********************************************************************** --> - <hwpError> - <rc>RC_IO_XBUS_LINKTRAIN_FAIL</rc> - <description>I/O Xbus WDERF Training fail was reported.</description> - <ffdc>M_GROUP</ffdc> - <ffdc>S_GROUP</ffdc> + <rc>RC_IO_XBUS_LINKTRAIN_ERROR</rc> + <description>I/O Xbus WDERF Training fail/timeout was reported.</description> + <ffdc>GROUP</ffdc> + <ffdc>TIMEOUT</ffdc> + <!-- Master Common Info --> <ffdc>M_WDERF_START</ffdc> <ffdc>M_WDERF_DONE</ffdc> <ffdc>M_WDERF_FAILED</ffdc> @@ -148,6 +64,7 @@ <ffdc>M_BAD_LANE2</ffdc> <ffdc>M_BAD_LANE_CODE</ffdc> <!-- Master Func Mode Info --> + <!-- Slave Common Info --> <ffdc>S_WDERF_START</ffdc> <ffdc>S_WDERF_DONE</ffdc> <ffdc>S_WDERF_FAILED</ffdc> |