From cf4b39c8592ab1240bd618d0e8bfd60123e6de67 Mon Sep 17 00:00:00 2001 From: Mark Pizzutillo Date: Wed, 10 Jul 2019 17:23:23 -0500 Subject: Add PRBS training sequence to exp_omi_setup Change-Id: I85630e3959cd95317c5026f1efaaa8062c4bbbe6 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/80238 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Reviewed-by: STEPHEN GLANCY Reviewed-by: Louis Stermole Tested-by: PPE CI Tested-by: Hostboot CI Tested-by: HWSV CI Dev-Ready: Mark Pizzutillo Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/80331 Tested-by: Jenkins OP Build CI Reviewed-by: Daniel M Crowell --- .../chips/p9a/procedures/hwp/memory/lib/mc/omi.H | 564 +++++---------------- .../memory/lib/workarounds/p9a_omi_workarounds.C | 119 +++++ .../memory/lib/workarounds/p9a_omi_workarounds.H | 60 +++ .../p9a/procedures/hwp/memory/p9a_omi_train.C | 69 +-- 4 files changed, 349 insertions(+), 463 deletions(-) (limited to 'src/import/chips/p9a/procedures') diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H index 06471052e..5cf787640 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -56,327 +57,8 @@ namespace mss namespace mc { - -/// -/// @brief These values are the number of clock cycles and the times specified assume a 625ps period. -/// This timer value must be greater than the di/dt timer -/// -enum rx_cdr_timer -{ - CDR_TIMER_DISABLED = 0b0001, - CDR_TIMER_60NS = 0b0001, - CDR_TIMER_125NS = 0b0010, - CDR_TIMER_185NS = 0b0011, - CDR_TIMER_250NS = 0b0100, - CDR_TIMER_375NS = 0b0101, - CDR_TIMER_500NS = 0b0110, - CDR_TIMER_750NS = 0b0111, - CDR_TIMER_1US = 0b1000, - CDR_TIMER_2US = 0b1001, - CDR_TIMER_4US = 0b1010, - CDR_TIMER_8US = 0b1011, - CDR_TIMER_16US = 0b1100, - CDR_TIMER_32US = 0b1101, - CDR_TIMER_64US = 0b1110, - CDR_TIMER_128US = 0b1111 -}; - -/// -/// @brief Amount of time to wait after lane is turned on/off before another lane can be turned on/off -/// -enum didt_timer -{ - DIDT_TIMER_DISABLED = 0b0000, - DIDT_TIMER_5NS = 0b0001, - DIDT_TIMER_10NS = 0b0010, - DIDT_TIMER_15NS = 0b0011, - DIDT_TIMER_20NS = 0b0100, - DIDT_TIMER_30NS = 0b0101, - DIDT_TIMER_45NS = 0b0110, - DIDT_TIMER_60NS = 0b0111, - DIDT_TIMER_90NS = 0b1000, - DIDT_TIMER_125NS = 0b1001, - DIDT_TIMER_185NS = 0b1010, - DIDT_TIMER_250NS = 0b1011, - DIDT_TIMER_375NS = 0b1100, - DIDT_TIMER_500NS = 0b1101, - DIDT_TIMER_768NS = 0b1110, - DIDT_TIMER_1US = 0b1111 -}; - -/// -/// @brief Calibration timer - amount of time betweem re-calibration for a given lane -/// -enum recal_timer -{ - RECAL_TIMER_DISABLED = 0b000, - RECAL_TIMER_25MS = 0b001, - RECAL_TIMER_50MS = 0b010, - RECAL_TIMER_100MS = 0b011, - RECAL_TIMER_200MS = 0b100, - RECAL_TIMER_400MS = 0b101, - RECAL_TIMER_800MS = 0b110, - RECAL_TIMER_1600MS = 0b111 -}; - -/// -/// @brief PMU prescalar value -/// -enum pmu_prescalar -{ - PRESCALAR_16BIT = 0b000, - PRESCALAR_8BIT = 0b001, - PRESCALAR_20BIT = 0b100, -}; - - -/// -/// @brief PMU cntrx pair selector -/// -enum cntrl_pair_selector -{ - SEL_ODD = 0b00, - SEL_EVEN = 0b01, - SEL_BOTH_AND = 0b10, - SEL_BOTH_XOR = 0b11 -}; - /// -/// @brief PMU cntrx event selector -/// -enum cntrl_event_selector -{ - SIG_7_6 = 0b00, - SIG_5_4 = 0b01, - SIG_3_2 = 0b10, - SIG_1_0 = 0b11 -}; - -/// -/// @brief dl0 no forward progress timer -/// -enum no_forward_progress_timer -{ - NO_FORWARD_TIMER_1US = 0b0000, - NO_FORWARD_TIMER_2US = 0b0001, - NO_FORWARD_TIMER_4US = 0b0010, - NO_FORWARD_TIMER_8US = 0b0011, - NO_FORWARD_TIMER_16US = 0b0100, - NO_FORWARD_TIMER_32US = 0b0101, - NO_FORWARD_TIMER_64US = 0b0110, - NO_FORWARD_TIMER_128US = 0b0111, - NO_FORWARD_TIMER_256US = 0b1000, - NO_FORWARD_TIMER_512US = 0b1001, - NO_FORWARD_TIMER_1MS = 0b1010, - NO_FORWARD_TIMER_2MS = 0b1011, - NO_FORWARD_TIMER_4MS = 0b1100, - NO_FORWARD_TIMER_8MS = 0b1101, - NO_FORWARD_TIMER_16MS = 0b1110, - NO_FORWARD_TIMER_DISABLED = 0b1111 -}; - -/// -/// @brief dl0 PHY control mode - determines the amount of time needed to receive pattern A or pattern B -/// -enum phy_ctr_mode -{ - PHY_CTR_MODE_1US = 0b0000, - PHY_CTR_MODE_50US = 0b0001, - PHY_CTR_MODE_100US = 0b0010, - PHY_CTR_MODE_200US = 0b0011, - PHY_CTR_MODE_500US = 0b0100, - PHY_CTR_MODE_1MS = 0b0101, - PHY_CTR_MODE_2MS = 0b0110, - PHY_CTR_MODE_3MS = 0b0111, - PHY_CTR_MODE_4MS = 0b1000, - PHY_CTR_MODE_5MS = 0b1001, - PHY_CTR_MODE_6MS = 0b1010, - PHY_CTR_MODE_8MS = 0b1011, - PHY_CTR_MODE_10MS = 0b1100, - PHY_CTR_MODE_15MS = 0b1101, - PHY_CTR_MODE_30MS = 0b1110, - PHY_CTR_MODE_60MS = 0b1111 -}; - -/// -/// @brief dl0 supported link widths -/// -enum link_widths -{ - LINK_WIDTHS_X4PLUS1 = 0b1000, - LINK_WIDTHS_X16 = 0b0100, - LINK_WIDTHS_X8 = 0b0010, - LINK_WIDTHS_X4 = 0b0001 -}; - -/// -/// @brief dl0 train mode -/// -enum train_mode -{ - TX_ZEROS = 0b0000, - TX_PATTERN_A = 0b0001, - TX_PATTERN_B = 0b0010, - TX_SYNC_PATTERN = 0b0011, - TX_TRAINING_STATE1 = 0b0100, - TX_TRAINING_STATE2 = 0b0101, - TX_TRAINING_STATE3 = 0b0110, - TX_TRAINING_STATE0 = 0b0111, - ENABLE_AUTO_TRAINING = 0b1000 -}; - -/// -/// @brief Configuration override to select lane width for dynamic lane power down modes. -/// -enum lan_width_override -{ - TL_CTR_BY_SIDEBAND = 0b00, - DL_OVERRIDE_X2 = 0b01, - DL_OVERRIDE_X4 = 0b10, - DL_OVERRIDE_X8 = 0b11 -}; - -/// -/// @brief Number of consecutive pattern B seen before indicating received pattern B -/// -enum b_hysteresis -{ - B_HYSTERESIS_16 = 0b0000, - B_HYSTERESIS_24 = 0b0001, - B_HYSTERESIS_32 = 0b0010, - B_HYSTERESIS_40 = 0b0011, - B_HYSTERESIS_48 = 0b0100, - B_HYSTERESIS_56 = 0b0101, - B_HYSTERESIS_64 = 0b0110, - B_HYSTERESIS_72 = 0b0111, - B_HYSTERESIS_80 = 0b1000, - B_HYSTERESIS_96 = 0b1001, - B_HYSTERESIS_128 = 0b1010, - B_HYSTERESIS_256 = 0b1011, - B_HYSTERESIS_512 = 0b1100, - B_HYSTERESIS_1K = 0b1101, - B_HYSTERESIS_2K = 0b1110, - B_HYSTERESIS_4K = 0b1111 -}; - -/// -/// @brief Number of consecutive pattern A seen before indicating received pattern A. -/// -enum a_hysteresis -{ - A_HYSTERESIS_16 = 0b0000, - A_HYSTERESIS_24 = 0b0001, - A_HYSTERESIS_32 = 0b0010, - A_HYSTERESIS_48 = 0b0011, - A_HYSTERESIS_64 = 0b0100, - A_HYSTERESIS_96 = 0b0101, - A_HYSTERESIS_128 = 0b0110, - A_HYSTERESIS_256 = 0b0111, - A_HYSTERESIS_512 = 0b1000, - A_HYSTERESIS_1024 = 0b1001, - A_HYSTERESIS_2K = 0b1010, - A_HYSTERESIS_4K = 0b1011, - A_HYSTERESIS_8K = 0b1100, - A_HYSTERESIS_16K = 0b1101, - A_HYSTERESIS_32K = 0b1110, - A_HYSTERESIS_64K = 0b1111 -}; - -/// -/// @brief Lanes disabled -/// -enum -{ - LANE_DISABLED_NONE = 0b00000000, - LANE_DISABLED_7 = 0b00000001, - LANE_DISABLED_6 = 0b00000010, - LANE_DISABLED_5 = 0b00000100, - LANE_DISABLED_4 = 0b00001000, - LANE_DISABLED_3 = 0b00010000, - LANE_DISABLED_2 = 0b00100000, - LANE_DISABLED_1 = 0b01000000, - LANE_DISABLED_0 = 0b10000000 -}; - -/// -/// @brief dl0 inject crc direction -/// -enum crc_inject_dir -{ - CRC_DIR_RX = 0, - CRC_DIR_TX = 1 -}; - -/// -/// @brief dl0 crc injection rate -/// -enum crc_inject_rate -{ - CRC_INJ_RATE_1US = 0b0000, - CRC_INJ_RATE_8US = 0b0001, - CRC_INJ_RATE_64US = 0b0010, - CRC_INJ_RATE_512US = 0b0011, - CRC_INJ_RATE_4MS = 0b0100, - CRC_INJ_RATE_32MS = 0b0101, - CRC_INJ_RATE_256MS = 0b0110, - CRC_INJ_RATE_2S = 0b0111 -}; - -/// -/// @brief CFG_DL0_EDPL_TIME: dl0 edpl time window -/// -enum edpl_time_win -{ - EDPL_TIME_WIN_NO = 0b0000, - EDPL_TIME_WIN_4US = 0b0001, - EDPL_TIME_WIN_32US = 0b0010, - EDPL_TIME_WIN_256US = 0b0011, - EDPL_TIME_WIN_2MS = 0b0100, - EDPL_TIME_WIN_16MS = 0b0101, - EDPL_TIME_WIN_128MS = 0b0110, - EDPL_TIME_WIN_1S = 0b0111, - EDPL_TIME_WIN_8S = 0b1000, - EDPL_TIME_WIN_64S = 0b1001, - EDPL_TIME_WIN_512S = 0b1010, - EDPL_TIME_WIN_4KS = 0b1011, - EDPL_TIME_WIN_32KS = 0b1100, - EDPL_TIME_WIN_256KS = 0b1101, - EDPL_TIME_WIN_2MILLIONS = 0b1110, - EDPL_TIME_WIN_16MILLIONS = 0b1111 -}; - -/// -/// @brief CFG_DL0_EDPL_THRESHOLD: dl0 edpl threshold -/// -enum edpl_err_thres -{ - EDPL_ERR_THRES_DISABLED = 0b000, - EDPL_ERR_THRES_2 = 0b001, - EDPL_ERR_THRES_4 = 0b010, - EDPL_ERR_THRES_8 = 0b011, - EDPL_ERR_THRES_16 = 0b100, - EDPL_ERR_THRES_32 = 0b101, - EDPL_ERR_THRES_64 = 0b110, - EDPL_ERR_THRES_128 = 0b111 -}; - -/// -/// @brief CONFIG1_CFG_PREIPL_PRBS_TIME: config1 pre-ipl prbs time -/// -enum preipl_prbs_time -{ - PREIPL_PRBS_256US = 0b000, - PREIPL_PRBS_1US = 0b001, - PREIPL_PRBS_4MS = 0b010, - PREIPL_PRBS_16MS = 0b011, - PREIPL_PRBS_64MS = 0b100, - PREIPL_PRBS_256MS = 0b101, - PREIPL_PRBS_1S = 0b110, - PREIPL_PRBS_4S = 0b111 -}; - -/// -/// @brief Helper function to setup the CMN_CONFIG +/// @brief Function to setup the CMN_CONFIG /// @tparam PROC the proc type /// @tparam T the fapi2 target type of the target /// @tparam TT the class traits for the omi @@ -384,31 +66,31 @@ enum preipl_prbs_time /// @return FAPI2_RC_SUCCESS iff ok /// template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits> -fapi2::ReturnCode setup_mc_mcn_config_helper(const fapi2::Target& i_target) +fapi2::ReturnCode setup_mc_mcn_config(const fapi2::Target& i_target) { // The value is 0x042364008874630F fapi2::buffer l_val; // CFG_CMN_SPARE: Spare - l_val.template insertFromRight< TT::MC_REG0_CMN_CONFIG_SPARE, TT::MC_REG0_CMN_CONFIG_SPARE_LEN>(0); + l_val.insertFromRight< TT::MC_REG0_CMN_CONFIG_SPARE, TT::MC_REG0_CMN_CONFIG_SPARE_LEN>(0); - l_val.template insertFromRight - (CDR_TIMER_250NS); + l_val.insertFromRight + (mss::omi::rx_cdr_timer::CDR_TIMER_250NS); - l_val.template insertFromRight - (DIDT_TIMER_10NS); + l_val.insertFromRight + (mss::omi::didt_timer::DIDT_TIMER_10NS); - l_val.template writeBit(0); + l_val.writeBit(0); - l_val.template insertFromRight - (RECAL_TIMER_100MS); + l_val.insertFromRight + (mss::omi::recal_timer::RECAL_TIMER_100MS); // CFG_CMN_1US_TMR: Number of cycles in 1us. Needs to be changed based on clock frequency - l_val.template insertFromRight + l_val.insertFromRight (1600); // CFG_CMN_DBG_EN: Enable the debug logic - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_CMN_DBG_SEL: Debug select // 000 - zeros @@ -421,40 +103,48 @@ fapi2::ReturnCode setup_mc_mcn_config_helper(const fapi2::Target& i_target) // 11 bits from all 3 DLs plus // 33 bits from common macro 2 // 111 - zeros - l_val.template insertFromRight(0); + l_val.insertFromRight(0); // CFG_CMN_RD_RST: Reset the PMU counters when the PMU counters are read - l_val.template writeBit(1); + l_val.writeBit(1); - l_val.template insertFromRight - (PRESCALAR_16BIT); + l_val.insertFromRight + (mss::omi::pmu_prescalar::PRESCALAR_16BIT); // CFG_CMN_FREEZE: PMU freeze mode - when set, the PMU will stop all counters when 1 of the counters wraps. - l_val.template writeBit(1); + l_val.writeBit(1); // CFG_CMN_PORT_SEL: PMU port select - select which of the 8 groups of inputs will be used by the PMU. - l_val.template insertFromRight(0); - - l_val.template insertFromRight(SEL_EVEN); - l_val.template insertFromRight(SIG_1_0); - l_val.template insertFromRight(SEL_EVEN); - l_val.template insertFromRight(SIG_7_6); - l_val.template insertFromRight(SEL_EVEN); - l_val.template insertFromRight(SIG_3_2); - l_val.template insertFromRight(SEL_ODD); - l_val.template insertFromRight(SIG_1_0); + l_val.insertFromRight(0); + + l_val.insertFromRight( + mss::omi::cntrl_pair_selector::SEL_EVEN); + l_val.insertFromRight( + mss::omi::cntrl_event_selector::SIG_1_0); + l_val.insertFromRight( + mss::omi::cntrl_pair_selector::SEL_EVEN); + l_val.insertFromRight( + mss::omi::cntrl_event_selector::SIG_7_6); + l_val.insertFromRight( + mss::omi::cntrl_pair_selector::SEL_EVEN); + l_val.insertFromRight( + mss::omi::cntrl_event_selector::SIG_3_2); + l_val.insertFromRight( + mss::omi::cntrl_pair_selector::SEL_ODD); + l_val.insertFromRight( + mss::omi::cntrl_event_selector::SIG_1_0); // CFG_CMN_CNTRx_PE: PMU cntrx positive edge select - l_val.template writeBit(0); - l_val.template writeBit(0); - l_val.template writeBit(0); - l_val.template writeBit(0); + l_val.writeBit(0); + l_val.writeBit(0); + l_val.writeBit(0); + l_val.writeBit(0); // CFG_CMN_CNTRx_EN: PMU cntrx enable - l_val.template writeBit(1); - l_val.template writeBit(1); - l_val.template writeBit(1); - l_val.template writeBit(1); + l_val.writeBit(1); + l_val.writeBit(1); + l_val.writeBit(1); + l_val.writeBit(1); FAPI_TRY( mss::putScom(i_target, TT::MC_REG0_CMN_CONFIG, l_val) ); FAPI_TRY( mss::putScom(i_target, TT::MC_REG1_CMN_CONFIG, l_val) ); @@ -465,27 +155,30 @@ fapi_try_exit: } /// -/// @brief Helper function to set the CONFIG0 +/// @brief Function to set the CONFIG0 for the given train mode and backoff_en bit /// @tparam PROC the proc type /// @tparam T the fapi2 target type of the target /// @tparam TT the class traits for the omi /// @param[in] i_target the OMI target to operate on /// @param[in] i_train_mode training step to enable +/// @param[in] i_dl_x4_backoff_en backoff enable mode /// @return FAPI2_RC_SUCCESS iff ok /// template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits> -fapi2::ReturnCode setup_mc_config0_helper(const fapi2::Target& i_target, const uint8_t i_train_mode) +fapi2::ReturnCode setup_mc_config0( + const fapi2::Target& i_target, + const uint8_t i_train_mode, + const uint8_t i_dl_x4_backoff_en) { // The value is 0x8200040000152824 fapi2::buffer l_val; uint8_t l_dl_tx_ln_rev_en = 1; - uint8_t l_dl_x4_backoff_en = 1; // CFG_DL0_ENABLE: dl0 enabled - l_val.template writeBit(1); + l_val.writeBit(1); // CFG_DL0_CFG_SPARE: dl0 Spare - l_val.template insertFromRight(0); + l_val.insertFromRight(0); // CFG_DL0_CFG_TL_CREDITS: dl0 TL credits - Maximum number of credits that can be sent to the TL l_val.template @@ -496,23 +189,25 @@ fapi2::ReturnCode setup_mc_config0_helper(const fapi2::Target& i_target, cons // Bit 1 = Freeze afu, leave TL and DL running // Bit 2 = Trigger Internal Logic Analyzers // Bit 3 = Bring down the link - l_val.template insertFromRight(0); + l_val.template + insertFromRight(0); // CFG_DL0_TL_ERROR_ACTIONS: dl0 TL error actions // Bit 0 = Freeze all // Bit 1 = Freeze afu, leave TL and DL running // Bit 2 = Trigger Internal Logic Analyzers // Bit 3 = Bring down the link - l_val.template insertFromRight(0); + l_val.template + insertFromRight(0); - l_val.template insertFromRight(NO_FORWARD_TIMER_16US); + l_val.template + insertFromRight( + mss::omi::no_forward_progress_timer::NO_FORWARD_TIMER_16US); // CFG_DL0_REPLAY_RSVD_ENTRIES: dl0 replay buffers reserved - times 16 is the number of replay buffers reserved - l_val.template insertFromRight(0); + l_val.template + insertFromRight + (0); // CFG_DL0_DEBUG_SELECT: dl0 trace mux select // "000" = zeros @@ -523,70 +218,70 @@ fapi2::ReturnCode setup_mc_config0_helper(const fapi2::Target& i_target, cons // "101" = 11 bits of TX flit information // "110" = 11 bits of Tx training information // "111" = zeros - l_val.template insertFromRight + l_val.insertFromRight (0); // CFG_DL0_DEBUG_ENABLE: dl0 trace enable - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_DL2TL_DATA_PARITY_INJECT: dl0 inject a data parity error - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_DL2TL_CONTROL_PARITY_INJECT: dl0 inject a control parity error - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_ECC_UE_INJECTION: dl0 inject a ECC UE error - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_ECC_CE_INJECTION: dl0 inject a ECC CE error - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_FP_DISABLE: dl0 fastpath disabled - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_UNUSED2: dl0 Spare - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_TX_LN_REV_ENA: When set will allow dl0 to perform tx lane reversals. FAPI_TRY(mss::attr::get_omi_dl_ln_rev_enable(i_target, l_dl_tx_ln_rev_en), "Error from FAPI_ATTR_GET (ATTR_OMI_DL_LN_REV_ENABLE)"); - l_val.template writeBit(l_dl_tx_ln_rev_en); + l_val.writeBit(l_dl_tx_ln_rev_en); // CFG_DL0_128_130_ENCODING_ENABLED: dl0 128/130 encoding enabled - l_val.template writeBit(0); + l_val.writeBit(0); - l_val.template insertFromRight(PHY_CTR_MODE_50US); + l_val.template + insertFromRight( + mss::omi::phy_ctr_mode::PHY_CTR_MODE_50US); // CFG_DL0_RUNLANE_OVRD_ENABLE: When enabled, the dl0 will drive run lane to the PHY for all training states. - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_PWRMGT_ENABLE: dl0 power management enabled - l_val.template writeBit(1); + l_val.writeBit(1); // CFG_DL0_QUARTER_WIDTH_BACKOFF_ENABLE: dl0 x1 backoff enabled - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_HALF_WIDTH_BACKOFF_ENABLE: dl0 x4 backoff enabled - FAPI_TRY(mss::attr::get_omi_dl_x4_backoff_enable(i_target, l_dl_x4_backoff_en), - "Error from FAPI_ATTR_GET (ATTR_OMI_DL_X4_BACKOFF_ENABLE)"); - l_val.template writeBit(l_dl_x4_backoff_en); + l_val.writeBit(i_dl_x4_backoff_en); - l_val.template insertFromRight(LINK_WIDTHS_X8); + l_val.template + insertFromRight( + mss::omi::link_widths::LINK_WIDTHS_X8); // CFG_DL0_TRAIN_MODE: dl0 train mode - l_val.template insertFromRight - (i_train_mode); + l_val.insertFromRight( + i_train_mode); // CFG_DL0_VERSION: dl0 version number - l_val.template insertFromRight(9); + l_val.insertFromRight(9); // CFG_DL0_RETRAIN: dl0 retrain - Reset dl0 back to training state 4 - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_RESET: dl0 reset - Reset dl0 back to traning state 0 - l_val.template writeBit(0); + l_val.writeBit(0); FAPI_TRY( mss::putScom(i_target, TT::MC_REG2_DL0_CONFIG0, l_val) ); @@ -595,7 +290,7 @@ fapi_try_exit: } /// -/// @brief Helper function to set the CONFIG1 +/// @brief Function to setup the CONFIG1 /// @tparam PROC the proc type /// @tparam T the fapi2 target type of the target /// @tparam TT the class traits for the omi @@ -603,7 +298,7 @@ fapi_try_exit: /// @return FAPI2_RC_SUCCESS iff ok /// template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits> -fapi2::ReturnCode setup_mc_config1_helper(const fapi2::Target& i_target) +fapi2::ReturnCode setup_mc_config1(const fapi2::Target& i_target) { // The value is 0x0C00050000000059; fapi2::buffer l_val; @@ -613,19 +308,20 @@ fapi2::ReturnCode setup_mc_config1_helper(const fapi2::Target& i_target) FAPI_TRY( mss::attr::get_is_simulation( l_sim) ); // CFG_DL0_CFG1_PREIPL_PRBS - l_val.template insertFromRight(l_sim ? PREIPL_PRBS_1US : PREIPL_PRBS_256MS); + l_val.template + insertFromRight( + l_sim ? mss::omi::preipl_prbs_time::PREIPL_PRBS_1US : mss::omi::preipl_prbs_time::PREIPL_PRBS_256MS); // PRE-IPL PRBS Timing is not functional in Axone, so set to disable - l_val.template writeBit(0); // Disable + l_val.writeBit(0); // Disable - l_val.template insertFromRight(TL_CTR_BY_SIDEBAND); + l_val.insertFromRight( + mss::omi::lan_width_override::TL_CTR_BY_SIDEBAND); - l_val.template insertFromRight(B_HYSTERESIS_16); + l_val.insertFromRight( + mss::omi::b_hysteresis::B_HYSTERESIS_16); - l_val.template insertFromRight(A_HYSTERESIS_16); + l_val.insertFromRight( + mss::omi::a_hysteresis::A_HYSTERESIS_16); // CFG_DL0_B_PATTERN_LENGTH: Number of consecutive 1s and 0s needed to represent training Pattern // B=> "11111111111111110000000000000000" @@ -633,8 +329,8 @@ fapi2::ReturnCode setup_mc_config1_helper(const fapi2::Target& i_target) // "10" = four Xs => "111111111111XXXX000000000000XXXX" // "01" = one Xs => "111111111111111X000000000000000X" // "11" = same as "10" - l_val.template insertFromRight(0); + l_val.insertFromRight(0); // CFG_DL0_A_PATTERN_LENGTH: Number of consecutive 1s and 0s needed to represent training Pattern // A => "1111111100000000" @@ -642,63 +338,63 @@ fapi2::ReturnCode setup_mc_config1_helper(const fapi2::Target& i_target) // "10" = four Xs => "1111XXXX0000XXXX" // "01" = one Xs => "1111111X0000000X" // "11" = same as "10" - l_val.template insertFromRight(0); + l_val.insertFromRight(0); // CFG_DL0_TX_PERF_DEGRADED: "00" = if tx perf is degraded by 1% set error bit 25 // "01" = if tx perf is degraded by 2% set error bit 25 // "10" = if tx perf is degraded by 3% set error bit 25 // "11" = if tx perf is degraded by 4% set error bit 25 - l_val.template insertFromRight(1); + l_val.insertFromRight(1); // CFG_DL0_RX_PERF_DEGRADED: "00" = if rx performance is degraded by 1% set error bit 26 // "01" = if rx perf is degraded by 2% set error bit 26 // "10" = if rx perf is degraded by 3% set error bit 26 // "11" = if rx perf is degraded by 4% set error bit 26 - l_val.template insertFromRight(1); + l_val.insertFromRight(1); - l_val.template insertFromRight(LANE_DISABLED_NONE); + l_val.insertFromRight(mss::omi::LANE_DISABLED_NONE); - l_val.template insertFromRight(LANE_DISABLED_NONE); + l_val.insertFromRight(mss::omi::LANE_DISABLED_NONE); // CFG_DL0_RESET_ERR_HLD: dl0 reset the error hold register when it is read - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_RESET_ERR_CAP: dl0 reset the error capture register when it is read - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_RESET_TSHD_REG: dl0 reset the edpl threshold register when it is read - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_RESET_RMT_MSG: dl0 reset the remote register when it is read - l_val.template writeBit(0); + l_val.writeBit(0); // CFG_DL0_INJECT_CRC_DIRECTION: dl0 inject crc direction - l_val.template writeBit(CRC_DIR_RX); + l_val.writeBit(mss::omi::crc_inject_dir::CRC_DIR_RX); - l_val.template insertFromRight(CRC_INJ_RATE_1US); + l_val.insertFromRight(mss::omi::crc_inject_rate::CRC_INJ_RATE_1US); // CFG_DL0_INJECT_CRC_LANE: dl0 inject crc error on lane number l_val.template insertFromRight(0); // CFG_DL0_INJECT_CRC_ERROR: dl0 inject crc error enable - l_val.template writeBit(0); + l_val.writeBit(0); - l_val.template insertFromRight(EDPL_TIME_WIN_16MS); + l_val.insertFromRight(mss::omi::edpl_time_win::EDPL_TIME_WIN_16MS); - l_val.template insertFromRight(EDPL_ERR_THRES_16); + l_val.insertFromRight(mss::omi::edpl_err_thres::EDPL_ERR_THRES_16); // CFG_DL0_EDPL_ENA: dl0 error detection per lane "edpl" enable FAPI_TRY(mss::attr::get_mss_omi_edpl_disable(l_edpl_disable)); - l_val.template writeBit(l_edpl_disable ? 0 : 1); + l_val.writeBit(l_edpl_disable ? 0 : 1); FAPI_TRY( mss::putScom(i_target, TT::MC_REG2_DL0_CONFIG1, l_val) ); @@ -707,7 +403,7 @@ fapi_try_exit: } /// -/// @brief Helper function to set the DL0_CYA_BITS +/// @brief Function to set the DL0_CYA_BITS /// @tparam PROC the proc type /// @tparam T the fapi2 target type of the target /// @tparam TT the class traits for the omi @@ -715,7 +411,7 @@ fapi_try_exit: /// @return FAPI2_RC_SUCCESS iff ok /// template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits> -fapi2::ReturnCode setup_mc_cya_bits_helper(const fapi2::Target& i_target) +fapi2::ReturnCode setup_mc_cya_bits(const fapi2::Target& i_target) { fapi2::buffer l_val; @@ -730,7 +426,7 @@ fapi_try_exit: } /// -/// @brief Helper function to set the DL0_ERROR_ACTION +/// @brief Function to set the DL0_ERROR_ACTION /// @tparam PROC the memory controller type /// @tparam T the fapi2 target type of the target /// @tparam TT the class traits for the omi @@ -738,7 +434,7 @@ fapi_try_exit: /// @return FAPI2_RC_SUCCESS iff ok /// template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits> -fapi2::ReturnCode setup_mc_error_action_helper(const fapi2::Target& i_target) +fapi2::ReturnCode setup_mc_error_action(const fapi2::Target& i_target) { fapi2::buffer l_val; @@ -764,7 +460,7 @@ fapi_try_exit: /// -/// @brief Helper function to set the DL0_RMT_CONFIG +/// @brief Function to set the DL0_RMT_CONFIG /// @tparam PROC the proc type /// @tparam T the fapi2 target type of the target /// @tparam TT the class traits for the omi @@ -772,7 +468,7 @@ fapi_try_exit: /// @return FAPI2_RC_SUCCESS iff ok /// template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits> -fapi2::ReturnCode setup_mc_rmt_config_helper(const fapi2::Target& i_target) +fapi2::ReturnCode setup_mc_rmt_config(const fapi2::Target& i_target) { fapi2::buffer l_val; diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C index 4ad5a30e2..e4ac4af7c 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C @@ -22,3 +22,122 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file p9a_omi_workarounds.C +/// @brief Workarounds for p9a_omi_* procedures +/// +// *HWP HWP Owner: Mark Pizzutillo +// *HWP HWP Backup: Stephen Glancy +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: Memory + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ +namespace workarounds +{ +namespace mc +{ +/// +/// @brief Helper function to determine whether PRBS OMI workaround will be performed, that can be unit tested +/// +/// @param[in] i_ocmb_type OCMB type/name +/// @param[in] i_proc_type PROC type/name +/// @return true/false perform workaround +/// +bool is_prbs_omi_required_helper(const uint8_t i_ocmb_type, const uint8_t i_proc_type) +{ + // OMI Workaround Logic: + // Explorer+Axone: OMI/PROC-side workaround off + // Gemini+Axone: OMI/PROC-side workaround on + // Any+apollo: OMI/PROC-side workaround on + // P10: No workarounds required. Enums don't exist yet, so this must be revisited later + return ((i_proc_type != fapi2::ENUM_ATTR_NAME_AXONE) || (i_ocmb_type == fapi2::ENUM_ATTR_NAME_GEMINI)); // Gem && axone +} + +/// +/// @brief Determine whether to perform PRBS OMI workaround +/// +/// @param[in] i_ocmb_chip OCMB chip +/// @param[in] i_proc_chip PROC chip +/// @param[out] o_required workaround required +/// @return FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode is_prbs_omi_required( + const fapi2::Target i_ocmb_chip, + const fapi2::Target i_proc_chip, + bool& o_required) +{ + uint8_t l_ocmb_type = 0; + uint8_t l_proc_type = 0; + + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_ocmb_chip, l_ocmb_type), + "Error getting ATTR_NAME of %s", mss::c_str(i_ocmb_chip)); + + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_proc_chip, l_proc_type), + "Error getting ATTR_NAME of %s", mss::c_str(i_proc_chip)); + + o_required = is_prbs_omi_required_helper(l_ocmb_type, l_proc_type); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform the PRBS OMI workaround +/// +/// @param[in] i_omi OMI +/// @param[in] i_dl_x4_backoff_en backoff enable bit +/// @return fapi2::FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode prbs_omi( + const fapi2::Target i_omi, + const uint8_t i_dl_x4_backoff_en) +{ + FAPI_DBG("Performing PRBS OMI workaround on %s", mss::c_str(i_omi)); + + uint32_t l_prbs_time = 0; + uint64_t l_prbs_time_scaled = 0; + uint8_t l_sim = 0; + FAPI_TRY(mss::attr::get_is_simulation(l_sim)); + + // Get PRBS time + FAPI_TRY(mss::attr::get_omi_dl_preipl_prbs_time(i_omi, l_prbs_time), + "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)"); + l_prbs_time_scaled = l_prbs_time * mss::common_timings::DELAY_1MS; + + // *_CONFIG0 should be the last one written, since it starts the training. + // We are not using the pre-ipl PRBS auto training mode because it doesn't function properly in Axone + + // Enable training state 6 to send TS3 + FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_TRAINING_STATE3, i_dl_x4_backoff_en)); + + // Set configurable delay based on the PRBS ATTR and SIM mode + FAPI_TRY(fapi2::delay(l_prbs_time_scaled, mss::common_timings::DELAY_1US)); + FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns", + (l_sim ? mss::common_timings::DELAY_1US : l_prbs_time_scaled)); + + // Enable training state 1 to send Pattern A + FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_PATTERN_A, i_dl_x4_backoff_en)); + +fapi_try_exit: + return fapi2::current_err; +} + +} // mc +} // workarounds +} // mss diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H index e46bfe9eb..45828a2af 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H @@ -22,3 +22,63 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file p9a_omi_workarounds.H +/// @brief Workarounds for p9a_omi_* procedures +/// +// *HWP HWP Owner: Mark Pizzutillo +// *HWP HWP Backup: Stephen Glancy +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: Memory + +#ifndef P9A_OMI_WORKAROUNDS_H_ +#define P9A_OMI_WORKAROUNDS_H_ + +#include + +namespace mss +{ +namespace workarounds +{ +namespace mc +{ +/// +/// @brief Helper function to determine whether PRBS OMI workaround will be performed, that can be unit tested +/// +/// @param[in] i_ocmb_type OCMB type/name +/// @param[in] i_proc_type PROC type/name +/// @return true/false perform workaround +/// +bool is_prbs_omi_required_helper(const uint8_t i_ocmb_type, const uint8_t i_proc_type); + +/// +/// @brief Determine whether to perform PRBS OMI workaround +/// +/// @param[in] i_ocmb_chip OCMB chip +/// @param[in] i_proc_chip PROC chip +/// @param[out] o_required workaround required +/// @return FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode is_prbs_omi_required( + const fapi2::Target i_ocmb_chip, + const fapi2::Target i_proc_chip, + bool& o_required); + +/// +/// @brief Perform the PRBS OMI workaround +/// +/// @param[in] i_omi OMI +/// @param[in] i_dl_x4_backoff_en backoff enable bit +/// @return fapi2::FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode prbs_omi( + const fapi2::Target i_omi, + const uint8_t i_dl_x4_backoff_en); + +} // namespace mc +} // namespace workarounds +} // namespace mss + +#endif diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C index aeb0d9fe8..5913df90d 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -61,35 +62,45 @@ fapi2::ReturnCode p9a_omi_train( const fapi2::Target& i_ FAPI_INF("%s Start p9a_omi_train", mss::c_str(i_target)); - const auto l_mc = mss::find_target(i_target); - uint32_t l_prbs_time; - uint64_t PRBS_TIME; - uint8_t l_sim = 0; - - FAPI_TRY( mss::attr::get_is_simulation( l_sim) ); - - FAPI_TRY(mss::attr::get_omi_dl_preipl_prbs_time(i_target, l_prbs_time), - "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)"); - PRBS_TIME = l_prbs_time * mss::common_timings::DELAY_1MS; - - FAPI_TRY(mss::mc::setup_mc_mcn_config_helper(l_mc)); - FAPI_TRY(mss::mc::setup_mc_config1_helper(i_target)); - FAPI_TRY(mss::mc::setup_mc_cya_bits_helper(i_target)); - FAPI_TRY(mss::mc::setup_mc_error_action_helper(i_target)); - FAPI_TRY(mss::mc::setup_mc_rmt_config_helper(i_target)); - - // *_CONFIG0 should be the last one written, since it starts the training. - // We are not using the pre-ipl PRBS auto training mode because it doesn't function properly in Axone - // Enable training state 6 to send TS3 - FAPI_TRY(mss::mc::setup_mc_config0_helper(i_target, mss::mc::train_mode::TX_TRAINING_STATE3)); - // Set configurable delay based on the PRBS ATTR and SIM mode - FAPI_TRY(fapi2::delay(PRBS_TIME, mss::common_timings::DELAY_1US)); - FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns", - (l_sim ? mss::common_timings::DELAY_1US : PRBS_TIME)); - // Enable training state 1 to send Pattern A - FAPI_TRY(mss::mc::setup_mc_config0_helper(i_target, mss::mc::train_mode::TX_PATTERN_A)); - // Enable training state 8 for auto training - FAPI_TRY(mss::mc::setup_mc_config0_helper(i_target, mss::mc::train_mode::ENABLE_AUTO_TRAINING)); + const auto& l_mc = mss::find_target(i_target); + const auto& l_ocmbs = mss::find_targets(i_target); + + FAPI_TRY(mss::mc::setup_mc_mcn_config(l_mc)); + FAPI_TRY(mss::mc::setup_mc_config1(i_target)); + FAPI_TRY(mss::mc::setup_mc_cya_bits(i_target)); + FAPI_TRY(mss::mc::setup_mc_error_action(i_target)); + FAPI_TRY(mss::mc::setup_mc_rmt_config(i_target)); + + if(l_ocmbs.empty()) + { + // No ocmbs, no training needed + return fapi2::FAPI2_RC_SUCCESS; + } + + { + // Only one OCMB per OMI for axone + const auto& l_ocmb = l_ocmbs[0]; + const auto& l_proc = mss::find_target(l_ocmb); + uint8_t l_dl_x4_backoff_en = 0; + bool l_workaround_required = false; + + // Get BACKOFF_ENABLE CHIP_EC attribute + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, l_ocmb, l_dl_x4_backoff_en), + "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); + + // Determine if workaround will be performed, if so, perform it + FAPI_TRY(mss::workarounds::mc::is_prbs_omi_required(l_ocmb, l_proc, l_workaround_required)); + + if (l_workaround_required) + { + FAPI_TRY(mss::workarounds::mc::prbs_omi(i_target, l_dl_x4_backoff_en)); + } + + // Enable auto training + FAPI_TRY(mss::mc::setup_mc_config0(i_target, mss::omi::train_mode::ENABLE_AUTO_TRAINING, l_dl_x4_backoff_en)); + + return fapi2::FAPI2_RC_SUCCESS; + } fapi_try_exit: return fapi2::current_err; -- cgit v1.2.1