diff options
author | Stephen Glancy <sglancy@us.ibm.com> | 2016-09-19 15:54:11 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-09-26 11:32:26 -0400 |
commit | 54d5006a06b398555c0bb5b7f190949f5c065ca2 (patch) | |
tree | cd52892e201cc74dd003f135a5e127c386c7d205 | |
parent | 33bce25d8d756219bb10aab368e0b3772fb66a3d (diff) | |
download | talos-hostboot-54d5006a06b398555c0bb5b7f190949f5c065ca2.tar.gz talos-hostboot-54d5006a06b398555c0bb5b7f190949f5c065ca2.zip |
Added WR VREF register API and reset procedures
Added code for the following DP16 registers:
WR_VREF_CONFIG0
WR_VREF_CONFIG1
WR_VREF_STATUS0
WR_VREF_STATUS1
WR_VREF_ERROR_MASK
WR_VREF_ERROR
WR_VREF_VALUE_RP0
WR_VREF_VALUE_RP1
WR_VREF_VALUE_RP2
WR_VREF_VALUE_RP3
Modified reset on WC:
WC_RTT_WR_SWAP_ENABLE
TK on whether SEQ registers need to be handled:
WR_TERM_SWAP0
WR_TERM_SWAP1
Change-Id: Ic5d64e92e6f2976d86b07ea64867decf7e8d37c0
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29908
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com>
Reviewed-by: Brian R. Silver <bsilver@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29909
Reviewed-by: Hostboot Team <hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
4 files changed, 1105 insertions, 1 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C index 47956d355..52b619276 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C @@ -646,6 +646,9 @@ fapi2::ReturnCode phy_scominit(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target // Resets all of the IO impedances FAPI_TRY( mss::reset_io_impedances(p) ); + // Resets all WR VREF related registers + FAPI_TRY( mss::dp16::reset_wr_vref_registers(p)); + // // Workarounds // diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C index 5db8449d3..02c90dd7f 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C @@ -44,6 +44,7 @@ #include <lib/phy/dp16.H> #include <lib/phy/write_cntrl.H> +#include <lib/dimm/rank.H> #include <lib/utils/scom.H> #include <lib/utils/pos.H> #include <lib/utils/c_str.H> @@ -254,6 +255,100 @@ const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::PR_STATIC_OFFSET_REG MCA_DDRPHY_DP16_WRCLK_PR_P0_4, }; +////////////////////////////////////// +// Defines all WR VREF registers // +////////////////////////////////////// +// Definition of the WR VREF config0 register +const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_CONFIG0_REG = +{ + MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0, + MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_1, + MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_2, + MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_3, + MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_4, +}; +// Definition of the WR VREF config1 register +const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_CONFIG1_REG = +{ + MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_0, + MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_1, + MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_2, + MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_3, + MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_4, +}; +// Definition of the WR VREF status0 register +const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_STATUS0_REG = +{ + MCA_DDRPHY_DP16_WR_VREF_STATUS0_P0_0, + MCA_DDRPHY_DP16_WR_VREF_STATUS0_P0_1, + MCA_DDRPHY_DP16_WR_VREF_STATUS0_P0_2, + MCA_DDRPHY_DP16_WR_VREF_STATUS0_P0_3, + MCA_DDRPHY_DP16_WR_VREF_STATUS0_P0_4, +}; +// Definition of the WR VREF status1 register +const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_STATUS1_REG = +{ + MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_0, + MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_1, + MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_2, + MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_3, + MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_4, +}; +// Definition of the error mask registers element is DP16 number, first is mask 0 second is mask 1 +const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_ERROR_MASK_REG = +{ + { MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0, MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK1_P0_0 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_1, MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK1_P0_1 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_2, MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK1_P0_2 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_3, MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK1_P0_3 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_4, MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK1_P0_4 }, +}; +// Definition of the error registers element is DP16 number, first is error 0 second is error 1 +const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_ERROR_REG = +{ + { MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0, MCA_DDRPHY_DP16_WR_VREF_ERROR1_P0_0 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_1, MCA_DDRPHY_DP16_WR_VREF_ERROR1_P0_1 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_2, MCA_DDRPHY_DP16_WR_VREF_ERROR1_P0_2 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_3, MCA_DDRPHY_DP16_WR_VREF_ERROR1_P0_3 }, + { MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_4, MCA_DDRPHY_DP16_WR_VREF_ERROR1_P0_4 }, +}; +// Definition of the VREF value registers for RP0 element is DP16 number, first is value 0 second is value 1 +const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_VALUE_RP0_REG = +{ + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR0_P0_0 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_1, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR0_P0_1 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_2, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR0_P0_2 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_3, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR0_P0_3 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_4, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR0_P0_4 }, +}; +// Definition of the VREF value registers for RP1 element is DP16 number, first is value 0 second is value 1 +const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_VALUE_RP1_REG = +{ + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR1_P0_0, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR1_P0_0 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR1_P0_1, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR1_P0_1 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR1_P0_2, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR1_P0_2 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR1_P0_3, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR1_P0_3 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR1_P0_4, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR1_P0_4 }, +}; +// Definition of the VREF value registers for RP2 element is DP16 number, first is value 0 second is value 1 +const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_VALUE_RP2_REG = +{ + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR2_P0_0, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR2_P0_0 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR2_P0_1, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR2_P0_1 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR2_P0_2, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR2_P0_2 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR2_P0_3, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR2_P0_3 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR2_P0_4, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR2_P0_4 }, +}; +// Definition of the VREF value registers for RP3 element is DP16 number, first is value 0 second is value 1 +const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::WR_VREF_VALUE_RP3_REG = +{ + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR3_P0_0, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR3_P0_0 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR3_P0_1, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR3_P0_1 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR3_P0_2, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR3_P0_2 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR3_P0_3, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR3_P0_3 }, + { MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR3_P0_4, MCA_DDRPHY_DP16_WR_VREF_VALUE1_RANK_PAIR3_P0_4 }, +}; + /// /// @brief Given a RD_VREF value, create a PHY 'standard' bit field for that percentage. /// @tparam T fapi2 Target Type - derived @@ -1253,5 +1348,302 @@ fapi_try_exit: return fapi2::current_err; } +//////////////////////////////////////////////////// +// reset procedures for all the WR VREF registers // +//////////////////////////////////////////////////// +/// +/// @brief Reset wr vref config0 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_config0( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + // builds up the base register value + fapi2::buffer<uint64_t> l_config0_data; + l_config0_data.clearBit<TT::WR_VREF_CONFIG0_FULL_1D>() + // TK putting hardcoded defaults here - revisit how to handle this (values should be obtained through characterization) + // smallest available step size - algorithm adds 1 so this is a 1 not a 0 + .insertFromRight<TT::WR_VREF_CONFIG0_2D_SMALL_STEP_VAL, TT::WR_VREF_CONFIG0_2D_SMALL_STEP_VAL_LEN>(0b000) + // step size of 4 - algorithm adds 1 so this is a 4, not a 3 + .insertFromRight<TT::WR_VREF_CONFIG0_2D_BIG_STEP_VAL, TT::WR_VREF_CONFIG0_2D_BIG_STEP_VAL_LEN>(0b0011) + // for intermediary bits, skip all 7, aka only run one bit on each DRAM for intermediary bits + .insertFromRight<TT::WR_VREF_CONFIG0_NUM_BITS_TO_SKIP, TT::WR_VREF_CONFIG0_NUM_BITS_TO_SKIP_LEN>(0b111) + // run for two VREFs looking for an increase - this is register value + 1 to the algorithm, so it's a 1, not a 0 + .insertFromRight<TT::WR_VREF_CONFIG0_NUM_NO_INC_COMP, TT::WR_VREF_CONFIG0_NUM_NO_INC_COMP_LEN>(0b001); + + // Whether the 2D VREF is enabled or not varies by the calibration attribute + constexpr uint16_t WR_VREF_CAL_ENABLED_BIT = 7; + fapi2::buffer<uint16_t> l_cal_steps_enabled; + FAPI_TRY( mss::cal_step_enable(i_target, l_cal_steps_enabled) ); + + // adds the information to the buffer + l_config0_data.writeBit<TT::WR_VREF_CONFIG0_1D_ONLY_SWITCH>(l_cal_steps_enabled.getBit<WR_VREF_CAL_ENABLED_BIT>()); + + //blast out the scoms + FAPI_TRY( mss::scom_blastah(i_target, TT::WR_VREF_CONFIG0_REG, l_config0_data) ); + + // return success + return fapi2::FAPI2_RC_SUCCESS; + + // handle errors +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Reset wr vref config1 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_config1( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + //constants to make the compiler happy + constexpr uint64_t RANGE_CROSSOVER = 0b0011000; + constexpr uint64_t SINGLE_RANGE_MAX = 0b0110010; + + // builds up the base register value + fapi2::buffer<uint64_t> l_config1_data; + // default to algorithm to use range 1 + l_config1_data.clearBit<TT::WR_VREF_CONFIG1_CTR_RANGE_SELECT>() + // JEDEC standard value for Range 2 to 1 crossover + .insertFromRight<TT::WR_VREF_CONFIG1_CTR_RANGE_CROSSOVER, TT::WR_VREF_CONFIG1_CTR_RANGE_CROSSOVER_LEN>(RANGE_CROSSOVER) + // JEDEC standard value for a single range max + .insertFromRight<TT::WR_VREF_CONFIG1_CTR_SINGLE_RANGE_MAX, + TT::WR_VREF_CONFIG1_CTR_SINGLE_RANGE_MAX_LEN>(SINGLE_RANGE_MAX); + + // blast out the scoms + return mss::scom_blastah(i_target, TT::WR_VREF_CONFIG1_REG, l_config1_data) ; +} + + +/// +/// @brief Reset wr vref status0 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_status0( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + // reset to all 0's + return mss::scom_blastah(i_target, TT::WR_VREF_STATUS0_REG, 0x0000 ) ; +} + +/// +/// @brief Reset wr vref status1 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_status1( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + // reset to all 0's + return mss::scom_blastah(i_target, TT::WR_VREF_STATUS1_REG, 0x0000 ) ; +} + +/// +/// @brief Reset wr vref error_mask - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_error_mask( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + // set all errors to be informational - masked off + // TK update this post characterization + // Note: the 0xffff includes the workaround for HW375535 - Error register latching + return mss::scom_blastah(i_target, TT::WR_VREF_ERROR_MASK_REG, 0xFFFF ) ; +} + +/// +/// @brief Reset wr vref error - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_error( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + // clears all errors + return mss::scom_blastah(i_target, TT::WR_VREF_ERROR_REG, 0x0000 ) ; +} + +/// +/// @brief Resets the WR VREF values by rank pair for given registers +/// @tparam uint64_t RP the rankpair to reset +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_rp_registers registers to reset +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t RP > +fapi2::ReturnCode reset_wr_vref_value_by_rp( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const std::vector< std::pair<uint64_t, uint64_t> >& i_rp_registers ) +{ + // traits definition + typedef dp16Traits<fapi2::TARGET_TYPE_MCA> TT; + + // declares constants for the VREF train attributes - UT will fail if the ATTR changes + // Value start location and length + constexpr uint8_t VREF_VALUE_LOC = 2; + constexpr uint8_t VREF_VALUE_LEN = TT::WR_VREF_VALUE_VALUE_DRAM_EVEN_LEN; + // VREF range start location - it's only one bit + constexpr uint8_t VREF_RANGE_LOC = 7; + + // declares variables + uint64_t l_dimm = 0; + uint64_t l_rank = 0; + std::vector< uint64_t > l_prp; + uint8_t l_vref_value[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {}; + uint8_t l_vref_range[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {}; + fapi2::buffer<uint64_t> l_vref_reg_data; + + // sets up the rank pair information + FAPI_TRY(mss::rank::primary_ranks(i_target, l_prp)); + + // if this rank is declared, set up it's values + // if not use the defaults of dimm = 0, rank = 0 - doesn't matter as this rank won't be calibrated + if(l_prp.size() > RP) + { + l_dimm = l_prp[RP] / MAX_RANK_PER_DIMM; + l_rank = l_prp[RP] % MAX_RANK_PER_DIMM; + } + + FAPI_INF("%s %s RP %d found! using DIMM%d and Rank%d", + mss::c_str(i_target), ((l_prp.size() <= RP) ? "no" : ""), RP, 0, 0); + + // gets the VREF information + FAPI_TRY( mss::eff_vref_dq_train_value(i_target, &l_vref_value[0][0])); + FAPI_TRY( mss::eff_vref_dq_train_range(i_target, &l_vref_range[0][0])); + + //sets up the data + { + uint64_t l_value = 0; + const fapi2::buffer<uint8_t> l_vref_val_buf = l_vref_value[l_dimm][l_rank]; + l_vref_val_buf.extractToRight<VREF_VALUE_LOC, VREF_VALUE_LEN>(l_value); + + const fapi2::buffer<uint8_t> l_vref_range_buf = l_vref_range[l_dimm][l_rank]; + const auto l_range = l_vref_range_buf.getBit<VREF_RANGE_LOC>(); + + l_vref_reg_data.writeBit<TT::WR_VREF_VALUE_RANGE_DRAM_EVEN>(l_range) + .writeBit<TT::WR_VREF_VALUE_RANGE_DRAM_ODD>(l_range) + .insertFromRight<TT::WR_VREF_VALUE_VALUE_DRAM_EVEN, TT::WR_VREF_VALUE_VALUE_DRAM_EVEN_LEN>(l_value) + .insertFromRight<TT::WR_VREF_VALUE_VALUE_DRAM_ODD, TT::WR_VREF_VALUE_VALUE_DRAM_ODD_LEN>(l_value); + } + + //blasts out the scoms + FAPI_INF("%s RP %d getting reset to values 0x%04lx", mss::c_str(i_target), RP, l_vref_value); + FAPI_TRY(mss::scom_blastah(i_target, i_rp_registers, l_vref_reg_data )); + + // return success + return fapi2::FAPI2_RC_SUCCESS; + + // handle errorss +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Reset wr vref value rank pair 0 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_value_rp0( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + return reset_wr_vref_value_by_rp<0>(i_target, TT::WR_VREF_VALUE_RP0_REG); +} + +/// +/// @brief Reset wr vref value rank pair 1 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_value_rp1( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + return reset_wr_vref_value_by_rp<1>(i_target, TT::WR_VREF_VALUE_RP1_REG); +} + +/// +/// @brief Reset wr vref value rank pair 2 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_value_rp2( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + return reset_wr_vref_value_by_rp<2>(i_target, TT::WR_VREF_VALUE_RP2_REG); +} + +/// +/// @brief Reset wr vref value rank pair3 - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_value_rp3( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // traits definition + typedef dp16Traits<TARGET_TYPE_MCA> TT; + + return reset_wr_vref_value_by_rp<3>(i_target, TT::WR_VREF_VALUE_RP3_REG); +} + +/// +/// @brief Resets all WR VREF registers - specialization for MCA +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template<> +fapi2::ReturnCode reset_wr_vref_registers( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) +{ + // resets all of the below registers + FAPI_TRY( reset_wr_vref_config0(i_target)); + FAPI_TRY( reset_wr_vref_config1(i_target)); + FAPI_TRY( reset_wr_vref_status0(i_target)); + FAPI_TRY( reset_wr_vref_status1(i_target)); + FAPI_TRY( reset_wr_vref_error_mask(i_target)); + FAPI_TRY( reset_wr_vref_error(i_target)); + FAPI_TRY( reset_wr_vref_value_rp0(i_target)); + FAPI_TRY( reset_wr_vref_value_rp1(i_target)); + FAPI_TRY( reset_wr_vref_value_rp2(i_target)); + FAPI_TRY( reset_wr_vref_value_rp3(i_target)); + + // return success + return fapi2::FAPI2_RC_SUCCESS; + + // handle errors +fapi_try_exit: + return fapi2::current_err; +} + } // close namespace dp16 } // close namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H index f6f2ea3b4..7485232bc 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H @@ -43,6 +43,7 @@ #include <lib/utils/scom.H> #include <lib/utils/find.H> +#include <lib/mss_attribute_accessors.H> namespace mss { @@ -119,6 +120,9 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA> // Number of DP instances static constexpr uint64_t DP_COUNT = 5; + // Maximum number of DRAM's per DP + static constexpr uint64_t MAX_DRAM_PER_DP = 4; + // Number of instances of the DLL per DP16. Used for checking parameters, the rest of the // code assumes 2 DLL per DP16. There are no DLL in Centaur so we don't need to worry about // any of this for some time. @@ -153,6 +157,18 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA> static const std::vector< uint64_t > IO_TX_FET_SLICE_REG; static const std::vector< uint64_t > IO_TX_PFET_TERM_REG; + //WR VREF registers + static const std::vector< uint64_t > WR_VREF_CONFIG0_REG; + static const std::vector< uint64_t > WR_VREF_CONFIG1_REG; + static const std::vector< uint64_t > WR_VREF_STATUS0_REG; + static const std::vector< uint64_t > WR_VREF_STATUS1_REG; + static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_ERROR_MASK_REG; + static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_ERROR_REG; + static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP0_REG; + static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP1_REG; + static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP2_REG; + static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP3_REG; + enum { DLL_CNTL_INIT_RXDLL_CAL_RESET = MCA_DDRPHY_DP16_DLL_CNTL0_P0_0_01_INIT_RXDLL_CAL_RESET, @@ -200,6 +216,81 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA> IO_TX_PFET_TERM_EN_P_WR = MCA_DDRPHY_DP16_IO_TX_PFET_TERM_P0_0_01_EN_P_WR, IO_TX_PFET_TERM_EN_P_WR_LEN = MCA_DDRPHY_DP16_IO_TX_PFET_TERM_P0_0_01_EN_P_WR_LEN, + //////////////////////////////////////// + // WR VREF register field information // + //////////////////////////////////////// + // CONFIG0 + WR_VREF_CONFIG0_1D_ONLY_SWITCH = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_1D_CHICKEN_SWITCH, + WR_VREF_CONFIG0_FULL_1D = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_RUN_FULL_1D, + WR_VREF_CONFIG0_2D_SMALL_STEP_VAL = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_2D_SMALL_STEP_VAL , + WR_VREF_CONFIG0_2D_SMALL_STEP_VAL_LEN = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_2D_SMALL_STEP_VAL_LEN, + WR_VREF_CONFIG0_2D_BIG_STEP_VAL = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_2D_BIG_STEP_VAL, + WR_VREF_CONFIG0_2D_BIG_STEP_VAL_LEN = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_2D_BIG_STEP_VAL_LEN, + WR_VREF_CONFIG0_NUM_BITS_TO_SKIP = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_NUM_BITS_TO_SKIP, + WR_VREF_CONFIG0_NUM_BITS_TO_SKIP_LEN = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_NUM_BITS_TO_SKIP_LEN, + WR_VREF_CONFIG0_NUM_NO_INC_COMP = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_NUM_NO_INC_COMP, + WR_VREF_CONFIG0_NUM_NO_INC_COMP_LEN = MCA_DDRPHY_DP16_WR_VREF_CONFIG0_P0_0_01_CTR_NUM_NO_INC_COMP_LEN, + + // CONFIG1 + WR_VREF_CONFIG1_CTR_RANGE_SELECT = MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_0_01_CTR_RANGE_SELECT, + WR_VREF_CONFIG1_CTR_RANGE_CROSSOVER = MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_0_01_CTR_RANGE_CROSSOVER, + WR_VREF_CONFIG1_CTR_RANGE_CROSSOVER_LEN = MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_0_01_CTR_RANGE_CROSSOVER_LEN, + WR_VREF_CONFIG1_CTR_SINGLE_RANGE_MAX = MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_0_01_CTR_SINGLE_RANGE_MAX, + WR_VREF_CONFIG1_CTR_SINGLE_RANGE_MAX_LEN = MCA_DDRPHY_DP16_WR_VREF_CONFIG1_P0_0_01_CTR_SINGLE_RANGE_MAX_LEN, + + // ERROR_MASK0/1 - note: all of these are one bit masks for error flags + WR_VREF_ERROR_MASK_MAX_RANGE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_MAX_RANGE , + WR_VREF_ERROR_MASK_MIN_RANGE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_MIN_RANGE , + WR_VREF_ERROR_MASK_TWO_RANGE_BEST_CASE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_TWO_RANGE_BEST_CASE , + WR_VREF_ERROR_MASK_BIT_STEP_DELTA_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_BIT_STEP_DELTA , + WR_VREF_ERROR_MASK_STEP_RANGE_EDGE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_STEP_RANGE_EDGE , + WR_VREF_ERROR_MASK_NO_INCREASE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_NO_INCREASE , + WR_VREF_ERROR_MASK_1D_EYE_NOISE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_1D_EYE_NOISE , + WR_VREF_ERROR_MASK_BAD_BIT_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_BAD_BIT , + WR_VREF_ERROR_MASK_MAX_RANGE_MASK_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_MAX_RANGE_MASK1 , + WR_VREF_ERROR_MASK_MIN_RANGE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_MIN_RANGE_MASK1 , + WR_VREF_ERROR_MASK_TWO_RANGE_BEST_CASE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_TWO_RANGE_BEST_CASE_MASK1, + WR_VREF_ERROR_MASK_BIT_STEP_DELTA_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_BIT_STEP_DELTA_MASK1 , + WR_VREF_ERROR_MASK_STEP_RANGE_EDGE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_STEP_RANGE_EDGE_MASK1 , + WR_VREF_ERROR_MASK_NO_INCREASE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_NO_INCREASE_MASK1 , + WR_VREF_ERROR_MASK_1D_EYE_NOISE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_1D_EYE_NOISE_MASK1 , + WR_VREF_ERROR_MASK_BAD_BIT_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR_MASK0_P0_0_01_BAD_BIT_MASK1 , + + // ERROR0/1 - note: all of these are one bit error flags + WR_VREF_ERROR_MAX_RANGE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_MAX_RANGE_ERR0 , + WR_VREF_ERROR_MIN_RANGE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_MIN_RANGE_ERR0 , + WR_VREF_ERROR_TWO_RANGE_BEST_CASE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_TWO_RANGE_BEST_CASE_ERR0 , + WR_VREF_ERROR_BIT_STEP_DELTA_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_BIT_STEP_DELTA_ERR0 , + WR_VREF_ERROR_STEP_RANGE_EDGE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_STEP_RANGE_EDGE_ERR0 , + WR_VREF_ERROR_NO_INCREASE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_NO_INCREASE_ERR0 , + WR_VREF_ERROR_1D_EYE_NOISE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_1D_EYE_NOISE_ERR0 , + WR_VREF_ERROR_BAD_BIT_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_BAD_BIT_ERR0 , + WR_VREF_ERROR_MAX_RANGE_MASK_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_MAX_RANGE_ERR1 , + WR_VREF_ERROR_MIN_RANGE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_MIN_RANGE_ERR1 , + WR_VREF_ERROR_TWO_RANGE_BEST_CASE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_TWO_RANGE_BEST_CASE_ERR1 , + WR_VREF_ERROR_BIT_STEP_DELTA_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_BIT_STEP_DELTA_ERR1 , + WR_VREF_ERROR_STEP_RANGE_EDGE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_STEP_RANGE_EDGE_ERR1 , + WR_VREF_ERROR_NO_INCREASE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_NO_INCREASE_ERR1 , + WR_VREF_ERROR_1D_EYE_NOISE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_1D_EYE_NOISE_ERR1 , + WR_VREF_ERROR_BAD_BIT_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_ERROR0_P0_0_01_BAD_BIT_ERR1 , + + // STATUS0 + WR_VREF_STATUS0_WRRD_CNT = MCA_DDRPHY_DP16_WR_VREF_STATUS0_P0_0_01_CTR_NUM_WRRDREQ_CNT , + WR_VREF_STATUS0_WRRD_CNT_LEN = MCA_DDRPHY_DP16_WR_VREF_STATUS0_P0_0_01_CTR_NUM_WRRDREQ_CNT_LEN , + + // STATUS1 + WR_VREF_STATUS1_VREFREQ_CNT = MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_0_01_CTR_NUM_VREFREQ_CNT , + WR_VREF_STATUS1_VREFREQ_CNT_LEN = MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_0_01_CTR_NUM_VREFREQ_CNT_LEN , + WR_VREF_STATUS1_CUR_VREF = MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_0_01_CTR_CUR , + WR_VREF_STATUS1_CUR_VREF_LEN = MCA_DDRPHY_DP16_WR_VREF_STATUS1_P0_0_01_CTR_CUR_LEN, + + // VALUE0/1 for all rankpairs + WR_VREF_VALUE_RANGE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_RANGE_DRAM0 , + WR_VREF_VALUE_VALUE_DRAM_EVEN = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_VALUE_DRAM0 , + WR_VREF_VALUE_VALUE_DRAM_EVEN_LEN = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_VALUE_DRAM0_LEN , + WR_VREF_VALUE_RANGE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_RANGE_DRAM1 , + WR_VREF_VALUE_VALUE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_VALUE_DRAM1 , + WR_VREF_VALUE_VALUE_DRAM_ODD_LEN = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_VALUE_DRAM1_LEN , }; }; @@ -969,6 +1060,612 @@ fapi_try_exit: return fapi2::current_err; } +//////////////////////////////////////// +// all the WR VREF scom accessors // +//////////////////////////////////////// +/// +/// @brief Read WR_VREF_CONFIG0 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_config0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_TRY( mss::getScom(i_target, TT::WR_VREF_CONFIG0_REG[I], o_data) ); + FAPI_INF("WR VREF config0 dp16%d: 0x%016lx", I, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_CONFIG1 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_config1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_TRY( mss::getScom(i_target, TT::WR_VREF_CONFIG1_REG[I], o_data) ); + FAPI_INF("WR VREF config1 dp16%d: 0x%016lx", I, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_STATUS0 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_status0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_TRY( mss::getScom(i_target, TT::WR_VREF_STATUS0_REG[I], o_data) ); + FAPI_INF("WR VREF status0 dp16%d: 0x%016lx", I, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_STATUS1 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_status1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_TRY( mss::getScom(i_target, TT::WR_VREF_STATUS1_REG[I], o_data) ); + FAPI_INF("WR VREF status1 dp16%d: 0x%016lx", I, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_ERROR_MASK register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_error_mask( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_ERROR_MASK_REG[I].first : TT::WR_VREF_ERROR_MASK_REG[I].second); + FAPI_TRY( mss::getScom(i_target, l_addr, o_data) ); + + FAPI_INF("WR VREF Error mask reg dp16%d, DRAM%d: 0x%016lx", I, D, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_ERROR register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_error( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_ERROR_REG[I].first : TT::WR_VREF_ERROR_REG[I].second); + FAPI_TRY( mss::getScom(i_target, l_addr, o_data) ); + + FAPI_INF("WR VREF Error reg dp16%d, DRAM%d: 0x%016lx", I, D, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_VALUE_RP0 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_value_rp0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP0_REG[I].first : TT::WR_VREF_VALUE_RP0_REG[I].second); + FAPI_TRY( mss::getScom(i_target, l_addr, o_data) ); + + FAPI_INF("WR VREF Value reg RP0 dp16%d, DRAM%d: 0x%016lx", I, D, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_VALUE_RP1 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_value_rp1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP1_REG[I].first : TT::WR_VREF_VALUE_RP1_REG[I].second); + FAPI_TRY( mss::getScom(i_target, l_addr, o_data) ); + + FAPI_INF("WR VREF Value reg RP1 dp16%d, DRAM%d: 1x%116lx", I, D, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_VALUE_RP2 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_value_rp2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP2_REG[I].first : TT::WR_VREF_VALUE_RP2_REG[I].second); + FAPI_TRY( mss::getScom(i_target, l_addr, o_data) ); + + FAPI_INF("WR VREF Value reg RP2 dp16%d, DRAM%d: 2x%216lx", I, D, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Read WR_VREF_VALUE_RP3 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode read_wr_vref_value_rp3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP3_REG[I].first : TT::WR_VREF_VALUE_RP3_REG[I].second); + FAPI_TRY( mss::getScom(i_target, l_addr, o_data) ); + + FAPI_INF("WR VREF Value reg RP3 dp16%d, DRAM%d: 3x%316lx", I, D, o_data); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_CONFIG0 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_config0( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_INF("WR VREF config0 dp16%d: 0x%016lx", I, i_data); + FAPI_TRY( mss::putScom(i_target, TT::WR_VREF_CONFIG0_REG[I], i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_CONFIG1 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_config1( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_INF("WR VREF config1 dp16%d: 0x%016lx", I, i_data); + FAPI_TRY( mss::putScom(i_target, TT::WR_VREF_CONFIG1_REG[I], i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_STATUS0 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_status0( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_INF("WR VREF status0 dp16%d: 0x%016lx", I, i_data); + FAPI_TRY( mss::putScom(i_target, TT::WR_VREF_STATUS0_REG[I], i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_STATUS1 register +/// @tparam I DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_status1( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + + FAPI_INF("WR VREF status1 dp16%d: 0x%016lx", I, i_data); + FAPI_TRY( mss::putScom(i_target, TT::WR_VREF_STATUS1_REG[I], i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_ERROR_MASK register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_error_mask( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + FAPI_INF("WR VREF Error mask reg dp16%d, DRAM%d: 0x%016lx", I, D, i_data); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_ERROR_MASK_REG[I].first : TT::WR_VREF_ERROR_MASK_REG[I].second); + FAPI_TRY( mss::putScom(i_target, l_addr, i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_ERROR register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_error( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + FAPI_INF("WR VREF Error reg dp16%d, DRAM%d: 0x%016lx", I, D, i_data); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_ERROR_REG[I].first : TT::WR_VREF_ERROR_REG[I].second); + FAPI_TRY( mss::putScom(i_target, l_addr, i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_VALUE_RP0 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_value_rp0( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + FAPI_INF("WR VREF Value reg RP0 dp16%d, DRAM%d: 0x%016lx", I, D, i_data); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP0_REG[I].first : TT::WR_VREF_VALUE_RP0_REG[I].second); + FAPI_TRY( mss::putScom(i_target, l_addr, i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_VALUE_RP1 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_value_rp1( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + FAPI_INF("WR VREF Value reg RP1 dp16%d, DRAM%d: 1x%116lx", I, D, i_data); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP1_REG[I].first : TT::WR_VREF_VALUE_RP1_REG[I].second); + FAPI_TRY( mss::putScom(i_target, l_addr, i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_VALUE_RP2 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_value_rp2( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + FAPI_INF("WR VREF Value reg RP2 dp16%d, DRAM%d: 2x%216lx", I, D, i_data); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP2_REG[I].first : TT::WR_VREF_VALUE_RP2_REG[I].second); + FAPI_TRY( mss::putScom(i_target, l_addr, i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief write WR_VREF_VALUE_RP3 register +/// @tparam I DP16 instance +/// @tparam D DRAM within the DP16 instance +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_data the value to set into the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t I, uint64_t D, fapi2::TargetType T, typename TT = dp16Traits<T> > +inline fapi2::ReturnCode write_wr_vref_value_rp3( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert( I < TT::DP_COUNT, "dp16 instance out of range"); + static_assert( D < TT::MAX_DRAM_PER_DP, "number of DRAM out of range"); + + FAPI_INF("WR VREF Value reg RP3 dp16%d, DRAM%d: 3x%316lx", I, D, i_data); + + // DRAM 0/1 vs 2/s's address + const uint64_t l_addr = ((D < 2) ? TT::WR_VREF_VALUE_RP3_REG[I].first : TT::WR_VREF_VALUE_RP3_REG[I].second); + FAPI_TRY( mss::putScom(i_target, l_addr, i_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +//////////////////////////////////////////////////// +// reset procedures for all the WR VREF registers // +//////////////////////////////////////////////////// +/// +/// @brief Reset wr vref config0 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_config0( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref config1 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_config1( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref status0 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_status0( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref status1 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_status1( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref error_mask +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_error_mask( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref error +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_error( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref value rank pair 0 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_value_rp0( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref value rank pair 1 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_value_rp1( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref value rank pair 2 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_value_rp2( const fapi2::Target<T>& i_target ); + +/// +/// @brief Reset wr vref value rank pair3 +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_value_rp3( const fapi2::Target<T>& i_target ); + + +/// +/// @brief Resets all WR VREF registers +/// @tparam T fapi2 Target Type - derived +/// @tparam TT traits type defaults to dp16Traits<T> +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< fapi2::TargetType T, typename TT = dp16Traits<T> > +fapi2::ReturnCode reset_wr_vref_registers( const fapi2::Target<T>& i_target ); + } // close namespace dp16 } // close namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H index bf42eb207..c224f28c9 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H @@ -39,6 +39,7 @@ #include <fapi2.H> #include <p9_mc_scom_addresses.H> #include <lib/utils/scom.H> +#include <lib/utils/conversions.H> #include <lib/eff_config/timing.H> namespace mss @@ -119,6 +120,8 @@ class wcTraits<fapi2::TARGET_TYPE_MCA> RTT_WR_SWAP_ENABLE_P0_WL = MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0_WL, RTT_WR_SWAP_ENABLE_P0_CTR = MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0_CTR, + VREF_COUNTER_RESET_VAL = MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0_CTR_VREF_COUNTER_RESET_VAL, + VREF_COUNTER_RESET_VAL_LEN = MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0_CTR_VREF_COUNTER_RESET_VAL_LEN, }; }; @@ -463,8 +466,17 @@ inline fapi2::ReturnCode reset_rtt_wr_swap_enable( const fapi2::Target<T>& i_tar FAPI_TRY( read_rtt_wr_swap_enable(i_target, l_data) ); // Per John Bialas 1/16: The enable RTT_SWAP bit is causing problems. + // Per Glancy 9/16 DD1 has an issue w/ the WR_CTR RTT swap, it's only for WR VREF cal l_data.clearBit<TT::RTT_WR_SWAP_ENABLE_P0_WL>(); - l_data.setBit<TT::RTT_WR_SWAP_ENABLE_P0_CTR>(); + l_data.clearBit<TT::RTT_WR_SWAP_ENABLE_P0_CTR>(); + + // taken from JEDEC DDR4 SPEC 2015 specification + // specific value is for tVREFDQE/tVREFDQX - both are 150 ns + { + constexpr uint64_t VREFDQ_LATCH_TIME_NS = 150; + const uint64_t l_vref_counter_reset = ns_to_cycles(i_target, VREFDQ_LATCH_TIME_NS); + l_data.insertFromRight<TT::VREF_COUNTER_RESET_VAL, TT::VREF_COUNTER_RESET_VAL_LEN>(l_vref_counter_reset); + } FAPI_DBG("wc_rtt_wr_swap_enable reset 0x%llx", l_data); FAPI_TRY( write_rtt_wr_swap_enable(i_target, l_data) ); |