From c00a806435284d3ffd4eb1e6e1142ac8723a8ab2 Mon Sep 17 00:00:00 2001 From: Andre Marin Date: Thu, 11 May 2017 11:28:21 -0500 Subject: [PATCH] Remove ZQCAL redundant CCS inst, move to draminit_training Lab requested to move ZQCL to draminit_training to control (with granularity) all enabled cal steps from an attribute in training. Also removing redundant ZQCAL being sent out for both a-side/b-side and addr_mirroring since this only applies to MRS cmds. Added new attribute proposal for CAL_STEPS_ENABLE to account for LRDIMM training steps and more control bits such as INITIAL_PAT_WR and WR_VRE_LATCH Change-Id: Ibb758af74966a5dd659bf3dda86f283f73956bca Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38648 Reviewed-by: Louis Stermole Tested-by: Jenkins Server Tested-by: Hostboot CI Reviewed-by: JACOB L. HARVEY Reviewed-by: Matt K. Light Reviewed-by: Thi N. Tran Reviewed-by: Daniel M. Crowell Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38650 Tested-by: Jenkins OP Build CI Tested-by: FSP CI Jenkins --- .../memory/lib/dimm/ddr4/data_buffer_ddr4.H | 1 + .../hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C | 54 +------- .../hwp/memory/lib/dimm/ddr4/zqcal.C | 131 ++++++++++++++++++ .../hwp/memory/lib/dimm/ddr4/zqcal.H | 61 ++++++++ .../procedures/hwp/memory/lib/dimm/eff_dimm.C | 29 ++-- .../hwp/memory/lib/mss_attribute_accessors.H | 71 ++++++---- .../hwp/memory/lib/phy/cal_timers.H | 2 +- .../procedures/hwp/memory/lib/phy/ddr_phy.C | 107 +++++++------- .../procedures/hwp/memory/lib/phy/ddr_phy.H | 20 +-- .../p9/procedures/hwp/memory/lib/phy/dp16.C | 5 +- .../hwp/memory/lib/shared/mss_const.H | 47 ++++--- .../memory/lib/workarounds/dp16_workarounds.C | 6 +- .../memory/lib/workarounds/dp16_workarounds.H | 2 +- .../lib/workarounds/wr_vref_workarounds.C | 4 +- .../lib/workarounds/wr_vref_workarounds.H | 4 +- .../hwp/memory/p9_mss_draminit_training.C | 45 +++--- .../hwp/memory/p9_mss_draminit_training.H | 6 +- .../procedures/hwp/memory/p9_mss_eff_config.C | 1 + .../attribute_info/memory_mcs_attributes.xml | 44 ++++-- .../generic/memory/lib/utils/mss_math.H | 30 ++++ .../common/xmltohb/attribute_types.xml | 46 ++++-- 21 files changed, 480 insertions(+), 236 deletions(-) diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H index 445ea8cea5b..c6dc9c2d2a1 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H @@ -43,6 +43,7 @@ #include #include #include +#include namespace mss { diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C index 850244d4afa..515f4529668 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C @@ -84,11 +84,7 @@ fapi2::ReturnCode mrs_load( const fapi2::Target& i_target, { FAPI_INF("ddr4::mrs_load %s", mss::c_str(i_target)); - fapi2::buffer l_cal_steps; - uint64_t tDLLK = 0; - uint8_t l_dimm_type = 0; - - static std::vector< mrs_data > l_mrs_data = + static const std::vector< mrs_data > MRS_DATA = { // JEDEC ordering of MRS per DDR4 power on sequence { 3, mrs03, mrs03_decode, mss::tmrd() }, @@ -97,17 +93,15 @@ fapi2::ReturnCode mrs_load( const fapi2::Target& i_target, { 4, mrs04, mrs04_decode, mss::tmrd() }, { 2, mrs02, mrs02_decode, mss::tmrd() }, { 1, mrs01, mrs01_decode, mss::tmrd() }, - - // We need to wait either tmod or tmrd before zqcl. - { 0, mrs00, mrs00_decode, std::max(mss::tmrd(), mss::tmod(i_target)) }, + // We need to wait tmod before zqcl, a non-mrs command + { 0, mrs00, mrs00_decode, mss::tmod(i_target) }, }; std::vector< uint64_t > l_ranks; FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); - FAPI_TRY( mss::tdllk(i_target, tDLLK) ); // Load MRS - for (const auto& d : l_mrs_data) + for (const auto& d : MRS_DATA) { for (const auto& r : l_ranks) { @@ -115,46 +109,6 @@ fapi2::ReturnCode mrs_load( const fapi2::Target& i_target, } } - // Load ZQ Cal Long instruction only if the bit in the cal steps says to do so. - FAPI_TRY( mss::cal_step_enable(i_target, l_cal_steps) ); - - if (l_cal_steps.getBit() != 0) - { - for (const auto& r : l_ranks) - { - // Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS - ccs::instruction_t l_inst_a_side = ccs::zqcl_command(i_target, r); - ccs::instruction_t l_inst_b_side; - - FAPI_TRY( mss::address_mirror(i_target, r, l_inst_a_side) ); - l_inst_b_side = mss::address_invert(l_inst_a_side); - - l_inst_a_side.arr1.insertFromRight(tDLLK + mss::tzqinit()); - l_inst_b_side.arr1.insertFromRight(tDLLK + mss::tzqinit()); - - // There's nothing to decode here. - FAPI_INF("ZQCL 0x%016llx:0x%016llx %s:rank %d a-side", - l_inst_a_side.arr0, l_inst_a_side.arr1, mss::c_str(i_target), r); - FAPI_INF("ZQCL 0x%016llx:0x%016llx %s:rank %d b-side", - l_inst_b_side.arr0, l_inst_b_side.arr1, mss::c_str(i_target), r); - - // Add both to the CCS program - io_inst.push_back(l_inst_a_side); - io_inst.push_back(l_inst_b_side); - } - } - - // For LRDIMMs, program BCW to send ZQCal Long command to all databuffers - // in broadcast mode - FAPI_TRY( eff_dimm_type(i_target, l_dimm_type) ); - - if( l_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) - { - FAPI_TRY( set_command_space(i_target, command::ZQCL, io_inst) ); - } - fapi_try_exit: return fapi2::current_err; } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C index 562c2f0644c..b92c9086dce 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C @@ -22,3 +22,134 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file zqcal.C +/// @brief Subroutines to send ZQCL commands +/// +// *HWP HWP Owner: Andre Marin +// *HWP HWP Backup: Jacob Harvey +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#include +#include + +#include +#include +#include +#include + +using fapi2::TARGET_TYPE_MCBIST; +using fapi2::TARGET_TYPE_MCA; +using fapi2::TARGET_TYPE_DIMM; + +namespace mss +{ + +/// +/// @brief Setup DRAM ZQCL +/// Specializaton for TARGET_TYPE_DIMM +/// @param[in] i_target the target associated with this cal +/// @param[in] i_rank the current rank +/// @param[in,out] io_inst a vector of CCS instructions we should add to +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +template<> +fapi2::ReturnCode setup_dram_zqcal( const fapi2::Target& i_target, + const uint64_t i_rank, + std::vector< ccs::instruction_t >& io_inst) +{ + ccs::instruction_t l_inst; + + uint64_t tDLLK = 0; + FAPI_TRY( mss::tdllk(i_target, tDLLK) ); + + // Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS + l_inst = ccs::zqcl_command(i_target, i_rank); + + l_inst.arr1.insertFromRight(tDLLK + mss::tzqinit()); + + // There's nothing to decode here. + FAPI_INF("ZQCL 0x%016llx:0x%016llx %s:rank %d", + l_inst.arr0, l_inst.arr1, mss::c_str(i_target), i_rank); + + // Add both to the CCS program + io_inst.push_back(l_inst); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Setup LRDIMM data buffer ZQCL +/// Specializaton for TARGET_TYPE_DIMM +/// @param[in] i_target the target associated with this cal +/// @param[in,out] io_inst a vector of CCS instructions we should add to +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +template<> +fapi2::ReturnCode setup_data_buffer_zqcal( const fapi2::Target& i_target, + std::vector< ccs::instruction_t >& io_inst) +{ + // For LRDIMMs, program BCW to send ZQCal Long command to all data buffers + // in broadcast mode + uint8_t l_dimm_type = 0; + FAPI_TRY( eff_dimm_type(i_target, l_dimm_type) ); + + if( l_dimm_type != fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) + { + FAPI_INF("%s Skipping LRDIMM data buffer ZQCL, only done on LRDIMMs", mss::c_str(i_target)); + return fapi2::FAPI2_RC_SUCCESS; + } + + FAPI_TRY( ddr4::set_command_space(i_target, ddr4::command::ZQCL, io_inst) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Setup and execute DRAM ZQCL +/// Specializaton for TARGET_TYPE_MCA +/// @param[in] i_target the target associated with this cal +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +template<> +fapi2::ReturnCode setup_and_execute_zqcal( const fapi2::Target& i_target, + const fapi2::buffer& i_cal_steps_enabled) +{ + mss::ccs::program l_program; + + for ( const auto& d : mss::find_targets(i_target) ) + { + // If this bit isn't set, nothing to do here... + if ( i_cal_steps_enabled.getBit() ) + { + std::vector l_ranks; + FAPI_TRY( mss::rank::ranks(d, l_ranks) ); + + for( const auto& r : l_ranks) + { + FAPI_TRY( mss::setup_dram_zqcal(d, r, l_program.iv_instructions) ); + }// ranks + } + + // If this bit isn't set, nothing to do here... + if ( i_cal_steps_enabled.getBit() ) + { + FAPI_TRY( mss::setup_data_buffer_zqcal(d, l_program.iv_instructions) ); + } + }// dimm + + // execute ZQCAL instructions + FAPI_TRY( mss::ccs::execute(mss::find_target(i_target), l_program, i_target) ); + +fapi_try_exit: + return fapi2::current_err; +} + +} // ns mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H index 8f56e3975c3..e7e546a7c15 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H @@ -22,3 +22,64 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file zqcal.H +/// @brief Subroutines to send ZQCL commands +/// +// *HWP HWP Owner: Andre Marin +// *HWP HWP Backup: Jacob Harvey +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_ZQCAL_H_ +#define _MSS_ZQCAL_H_ + +#include +#include +#include + +namespace mss +{ + +/// +/// @brief Setup DRAM ZQCL +/// @tparam T the target type associated with this cal +/// @tparam TT the target type of the CCS instruction +/// @param[in] i_target the target associated with this cal +/// @param[in] i_rank the current rank +/// @param[in,out] io_inst a vector of CCS instructions we should add to +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +template< fapi2::TargetType T, fapi2::TargetType TT > +fapi2::ReturnCode setup_dram_zqcal( const fapi2::Target& i_target, + const uint64_t i_rank, + std::vector< ccs::instruction_t >& io_inst); + +/// +/// @brief Setup LRDIMM data buffer ZQCL +/// @tparam T the target type associated with this cal +/// @tparam TT the target type of the CCS instruction +/// @param[in] i_target the target associated with this cal +/// @param[in,out] io_inst a vector of CCS instructions we should add to +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +template< fapi2::TargetType T, fapi2::TargetType TT > +fapi2::ReturnCode setup_data_buffer_zqcal( const fapi2::Target& i_target, + std::vector< ccs::instruction_t >& io_inst); + +/// +/// @brief Setup and execute DRAM ZQCL +/// @tparam T, the target type associated with this cal +/// @param[in] i_target the target associated with this cal +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +template< fapi2::TargetType T > +fapi2::ReturnCode setup_and_execute_zqcal( const fapi2::Target& i_target, + const fapi2::buffer& i_cal_steps_enabled); + +}// mss + +#endif diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C index f8ca3941768..a9af406ca4e 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C @@ -4574,20 +4574,17 @@ fapi_try_exit: /// fapi2::ReturnCode eff_dimm::cal_step_enable() { - // These constexpr values are taken from the defiitions in ATTR_MSS_CAL_STEP_ENABLE - // RD/WR VREF correspond to 0x0400 and 0x0100 respectively. - constexpr uint64_t ONLY_1D = 0xFAC0; - constexpr uint64_t RD_VREF_WR_VREF_1D = 0xFFC0; - const uint16_t l_cal_step_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? ONLY_1D : RD_VREF_WR_VREF_1D); + const uint32_t l_cal_step_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? + RUN_CAL_SKIP_WR_RD_2D_VREF : RUN_ALL_CAL_STEPS); FAPI_DBG("%s %s running HW VREF cal. cal_step value: 0x%0x VREF", mss::c_str(iv_mcs), mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? "not" : "", l_cal_step_value); // Sets up the vector - std::vector l_cal_step(PORTS_PER_MCS, l_cal_step_value); + std::vector l_cal_step(PORTS_PER_MCS, l_cal_step_value); - // Sets the values - return FAPI_ATTR_SET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, iv_mcs, UINT16_VECTOR_TO_1D_ARRAY(l_cal_step, PORTS_PER_MCS)); + // Sets the value + return FAPI_ATTR_SET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, iv_mcs, UINT32_VECTOR_TO_1D_ARRAY(l_cal_step, PORTS_PER_MCS)); } /// @@ -4597,8 +4594,9 @@ fapi2::ReturnCode eff_dimm::cal_step_enable() fapi2::ReturnCode eff_dimm::rdvref_enable_bit() { // This enables which bits should be run for RD VREF, all 1's indicates that all bits should be run - constexpr uint64_t DISABLE = 0x0000; - constexpr uint64_t ENABLE = 0xFFFF; + constexpr uint16_t DISABLE = 0x0000; + constexpr uint16_t ENABLE = 0xFFFF; + const uint16_t l_vref_enable_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? DISABLE : ENABLE); FAPI_DBG("%s %s running HW VREF cal. VREF enable value: 0x%0x", mss::c_str(iv_mcs), @@ -4608,16 +4606,21 @@ fapi2::ReturnCode eff_dimm::rdvref_enable_bit() std::vector l_vref_enable(PORTS_PER_MCS, l_vref_enable_value); // Sets the values - return FAPI_ATTR_SET(fapi2::ATTR_MSS_RDVREF_CAL_ENABLE, iv_mcs, UINT16_VECTOR_TO_1D_ARRAY(l_vref_enable, - PORTS_PER_MCS)); + return FAPI_ATTR_SET(fapi2::ATTR_MSS_RDVREF_CAL_ENABLE, + iv_mcs, + UINT16_VECTOR_TO_1D_ARRAY(l_vref_enable, PORTS_PER_MCS)); } /// -/// @brief Determines and sets ATTR_MSS_PHY_SEQ_REFRESH_ +/// @brief Determines and sets ATTR_MSS_PHY_SEQ_REFRESH /// @return fapi2::FAPI2_RC_SUCCESS if okay /// fapi2::ReturnCode eff_dimm::phy_seq_refresh() { + // default setting is to turn on this workaround, this + // isn't an ec_chip_feature attribute because there is no + // known fix for this coming in DD2.0 modules. But the + // lab wants a control switch constexpr size_t ENABLE = 1; FAPI_DBG("Setting PHY_SEQ_REFRESH to %d on %s", ENABLE, mss::c_str(iv_mcs)); diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H index 3fa215f8911..c15ab7e8fe1 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H @@ -9265,19 +9265,24 @@ fapi_try_exit: /// /// @brief ATTR_MSS_CAL_STEP_ENABLE getter /// @param[in] const ref to the fapi2::Target -/// @param[out] ref to the value uint16_t +/// @param[out] ref to the value uint32_t /// @note Generated by gen_accessors.pl generateParameters (D) /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK -/// @note A bit map of vector denoting valid cal steps to run (0 is left most bit) [0] -/// EXT_ZQCAL [1] WR_LEVEL [2] DQS_ALIGN [3] RDCLK_ALIGN [4] READ_CTR [5] -/// READ_CTR_2D_VREF [6] WRITE_CTR [7] WRITE_CTR_2D_VREF [8] COARSE_WR [9] COARSE_RD -/// [10]:[15] Reserved for future use COARSE_WR and COARSE_RD will be consumed -/// together to form -/// COARSE_LVL. +/// @note A bit map of vector denoting valid steps to run (0 is left most bit) [0] +/// DRAM_ZQCAL [1] DB_ZQCAL (LRDIMM) [2] MREP (LRDIMM) [3] MRD - Coarse (LRDIMM) [4] +/// MRD - Fine (LRDIMM) [5] WR_LEVEL [6] INITIAL_PAT_WR [7] WR_VREF_LATCH [8] DWL +/// (LRDIMM) [9] MWD - Coarse (LRDIMM) [10] MWD - Fine (LRDIMM) [11] HWL (LRDIMM) +/// [12] DQS_ALIGN [13] RDCLK_ALIGN [14] READ_CTR_2D_VREF [15] READ_CTR [16] +/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20]:[31] +/// Reserved for future use COARSE_WR and COARSE_RD will be consumed together to +/// form COARSE_LVL. WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is +/// enabled, as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. Note: +/// LRDIMM steps will only be enabled for LRDIMMs and won't run on +/// RDIMMs. /// -inline fapi2::ReturnCode cal_step_enable(const fapi2::Target& i_target, uint16_t& o_value) +inline fapi2::ReturnCode cal_step_enable(const fapi2::Target& i_target, uint32_t& o_value) { - uint16_t l_value[2]; + uint32_t l_value[2]; FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, i_target.getParent(), l_value) ); o_value = l_value[mss::index(i_target)]; @@ -9292,19 +9297,24 @@ fapi_try_exit: /// /// @brief ATTR_MSS_CAL_STEP_ENABLE getter /// @param[in] const ref to the fapi2::Target -/// @param[out] ref to the value uint16_t +/// @param[out] ref to the value uint32_t /// @note Generated by gen_accessors.pl generateParameters (D.1) /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK -/// @note A bit map of vector denoting valid cal steps to run (0 is left most bit) [0] -/// EXT_ZQCAL [1] WR_LEVEL [2] DQS_ALIGN [3] RDCLK_ALIGN [4] READ_CTR [5] -/// READ_CTR_2D_VREF [6] WRITE_CTR [7] WRITE_CTR_2D_VREF [8] COARSE_WR [9] COARSE_RD -/// [10]:[15] Reserved for future use COARSE_WR and COARSE_RD will be consumed -/// together to form -/// COARSE_LVL. +/// @note A bit map of vector denoting valid steps to run (0 is left most bit) [0] +/// DRAM_ZQCAL [1] DB_ZQCAL (LRDIMM) [2] MREP (LRDIMM) [3] MRD - Coarse (LRDIMM) [4] +/// MRD - Fine (LRDIMM) [5] WR_LEVEL [6] INITIAL_PAT_WR [7] WR_VREF_LATCH [8] DWL +/// (LRDIMM) [9] MWD - Coarse (LRDIMM) [10] MWD - Fine (LRDIMM) [11] HWL (LRDIMM) +/// [12] DQS_ALIGN [13] RDCLK_ALIGN [14] READ_CTR_2D_VREF [15] READ_CTR [16] +/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20]:[31] +/// Reserved for future use COARSE_WR and COARSE_RD will be consumed together to +/// form COARSE_LVL. WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is +/// enabled, as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. Note: +/// LRDIMM steps will only be enabled for LRDIMMs and won't run on +/// RDIMMs. /// -inline fapi2::ReturnCode cal_step_enable(const fapi2::Target& i_target, uint16_t& o_value) +inline fapi2::ReturnCode cal_step_enable(const fapi2::Target& i_target, uint32_t& o_value) { - uint16_t l_value[2]; + uint32_t l_value[2]; auto l_mca = i_target.getParent(); FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, l_mca.getParent(), l_value) ); @@ -9320,17 +9330,22 @@ fapi_try_exit: /// /// @brief ATTR_MSS_CAL_STEP_ENABLE getter /// @param[in] const ref to the fapi2::Target -/// @param[out] uint16_t* memory to store the value +/// @param[out] uint32_t* memory to store the value /// @note Generated by gen_accessors.pl generateParameters (E) /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK -/// @note A bit map of vector denoting valid cal steps to run (0 is left most bit) [0] -/// EXT_ZQCAL [1] WR_LEVEL [2] DQS_ALIGN [3] RDCLK_ALIGN [4] READ_CTR [5] -/// READ_CTR_2D_VREF [6] WRITE_CTR [7] WRITE_CTR_2D_VREF [8] COARSE_WR [9] COARSE_RD -/// [10]:[15] Reserved for future use COARSE_WR and COARSE_RD will be consumed -/// together to form -/// COARSE_LVL. +/// @note A bit map of vector denoting valid steps to run (0 is left most bit) [0] +/// DRAM_ZQCAL [1] DB_ZQCAL (LRDIMM) [2] MREP (LRDIMM) [3] MRD - Coarse (LRDIMM) [4] +/// MRD - Fine (LRDIMM) [5] WR_LEVEL [6] INITIAL_PAT_WR [7] WR_VREF_LATCH [8] DWL +/// (LRDIMM) [9] MWD - Coarse (LRDIMM) [10] MWD - Fine (LRDIMM) [11] HWL (LRDIMM) +/// [12] DQS_ALIGN [13] RDCLK_ALIGN [14] READ_CTR_2D_VREF [15] READ_CTR [16] +/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20]:[31] +/// Reserved for future use COARSE_WR and COARSE_RD will be consumed together to +/// form COARSE_LVL. WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is +/// enabled, as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. Note: +/// LRDIMM steps will only be enabled for LRDIMMs and won't run on +/// RDIMMs. /// -inline fapi2::ReturnCode cal_step_enable(const fapi2::Target& i_target, uint16_t* o_array) +inline fapi2::ReturnCode cal_step_enable(const fapi2::Target& i_target, uint32_t* o_array) { if (o_array == nullptr) { @@ -9338,10 +9353,10 @@ inline fapi2::ReturnCode cal_step_enable(const fapi2::Target& i_target ) template inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target& i_target, poll_parameters& i_poll, - const fapi2::buffer& i_cal_steps_enabled) + const fapi2::buffer& i_cal_steps_enabled) { uint64_t l_write_cntr_cycles = 0; uint64_t l_total_cycles = 0; 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 240b3a25995..c4b1c3292ff 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 @@ -795,26 +795,25 @@ fapi_try_exit: /// template<> fapi2::ReturnCode setup_cal_config( const fapi2::Target& i_target, - const std::vector i_rank_pairs, - fapi2::buffer i_cal_steps_enabled) + const std::vector& i_rank_pairs, + const fapi2::buffer& i_cal_steps_enabled) { fapi2::buffer l_cal_config; uint8_t l_sim = 0; - uint8_t cal_abort_on_error = 0; - + uint8_t l_cal_abort_on_error = 0; - FAPI_TRY( mss::cal_abort_on_error(cal_abort_on_error) ); + FAPI_TRY( mss::cal_abort_on_error(l_cal_abort_on_error) ); FAPI_TRY( mss::is_simulation(l_sim) ); // This is the buffer which will be written to CAL_CONFIG0. It starts // life assuming no cal sequences, no rank pairs - but we set the abort-on-error // bit ahead of time. - l_cal_config.writeBit(cal_abort_on_error); + l_cal_config.writeBit(l_cal_abort_on_error); // Sadly, the bits in the register don't align directly with the bits in the attribute. // So, arrange the bits accordingly and write the config register. { - // Skip EXT_ZQCAL as it's not in the config register - we do it outside. + // Skip DRAM_ZQCAL as it's not in the config register - we do it outside. // Loop (unrolled because static) over the remaining bits. l_cal_config.writeBit( i_cal_steps_enabled.getBit()); @@ -834,7 +833,8 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target& // Always turn on initial pattern write in h/w, never for sim (makes the DIMM behavioral lose it's mind) if (!l_sim) { - l_cal_config.setBit(); + l_cal_config.writeBit( + i_cal_steps_enabled.getBit()); } } @@ -903,11 +903,14 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target& l_vrefdq_train_range_override, l_vrefdq_train_value_override) ); - // Latches the VREF's - FAPI_TRY( mss::ddr4::latch_wr_vref_commands_by_rank_pair(i_target, - l_rp, - l_vrefdq_train_range_override, - l_vrefdq_train_value_override) ); + // Latches the VREF's, if and only if the latching bit is set + if(i_cal_steps_enabled.getBit()) + { + FAPI_TRY( mss::ddr4::latch_wr_vref_commands_by_rank_pair(i_target, + l_rp, + l_vrefdq_train_range_override, + l_vrefdq_train_value_override) ); + } } // Note: This rank encoding isn't used if the cal is initiated from the CCS engine @@ -915,15 +918,15 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target& // Configure the rank pairs for (const auto& rp : i_rank_pairs) { - l_cal_config.setBit(MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_RANK_PAIR + rp); + FAPI_TRY( l_cal_config.setBit(MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_RANK_PAIR + rp) ); } - FAPI_INF("cal_config for %s: 0x%lx (steps: 0x%lx)", - mss::c_str(i_target), uint16_t(l_cal_config), uint16_t(i_cal_steps_enabled)); + FAPI_INF("cal_config for %s: 0x%04lx (steps: 0x%08lx)", + mss::c_str(i_target), uint16_t(l_cal_config), uint32_t(i_cal_steps_enabled)); FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0, l_cal_config) ); - // Setsup the workarounds - FAPI_TRY(mss::workarounds::dp16::rd_vref_vref_sense_setup(i_target)); + // Sets up the workarounds + FAPI_TRY( mss::workarounds::dp16::rd_vref_vref_sense_setup(i_target) ); fapi_try_exit: return fapi2::current_err; @@ -933,12 +936,12 @@ fapi_try_exit: /// @brief Setup all the cal config register /// @param[in] i_target the target associated with this cal setup /// @param[in] i_rank one currently configured rank pairs -/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable /// @return FAPI2_RC_SUCCESS iff setup was successful /// fapi2::ReturnCode setup_cal_config( const fapi2::Target& i_target, const uint64_t i_rank, - const fapi2::buffer i_cal_steps_enabled) + const fapi2::buffer& i_cal_steps_enabled) { std::vector< uint64_t > l_ranks({i_rank}); return setup_cal_config(i_target, l_ranks, i_cal_steps_enabled); @@ -949,7 +952,7 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target& /// Specializaton for TARGET_TYPE_MCA /// @param[in] i_target the target associated with this cal /// @param[in] i_rp one of the currently configured rank pairs -/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable /// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override /// @return FAPI2_RC_SUCCESS iff setup was successful /// @note This is a helper function. Library users are required to call setup_and_execute_cal @@ -957,7 +960,7 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target& template<> fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target& i_target, const uint64_t i_rp, - const fapi2::buffer i_cal_steps_enabled, + const fapi2::buffer& i_cal_steps_enabled, const uint8_t i_abort_on_error) { const auto& l_mcbist = mss::find_target(i_target); @@ -967,9 +970,11 @@ fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target()) && - (mss::bit_count(static_cast(i_cal_steps_enabled)) != 1)) + (mss::bit_count(uint32_t(i_cal_steps_enabled)) != 1)) { - FAPI_ERR("WR_LEVEL cal step requires special terminations, so must be run separately from other cal steps"); + FAPI_ERR("WR_LEVEL cal step requires special terminations, so must be run separately from other cal steps (0x%08llx)", + i_cal_steps_enabled ); + fapi2::Assert(false); } @@ -1010,30 +1015,22 @@ fapi_try_exit: /// Specializaton for TARGET_TYPE_MCA /// @param[in] i_target the target associated with this cal /// @param[in] i_rp one of the currently configured rank pairs -/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable /// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override /// @return FAPI2_RC_SUCCESS iff setup was successful /// template<> fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target& i_target, const uint64_t i_rp, - const fapi2::buffer i_cal_steps_enabled, + const fapi2::buffer& i_cal_steps_enabled, const uint8_t i_abort_on_error) { const auto& l_mcbist = mss::find_target(i_target); FAPI_INF("ABORT_ON_ERROR is %d", i_abort_on_error); + // We run the cal steps in three chunks: pre-write-leveling, write-leveling, post-wirte-leveling. // This is because write-leveling requires a special set of termination values. - // Run cal steps before WR_LEVEL if selected - if (i_cal_steps_enabled.getBit()) - { - FAPI_DBG("%s Running EXT_ZQCAL step on RP%d", mss::c_str(i_target), i_rp); - fapi2::buffer l_steps_to_execute; - l_steps_to_execute.setBit(); - FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) ); - } - // Run WR_LEVEL step (with overridden termination values) if selected if (i_cal_steps_enabled.getBit()) { @@ -1041,7 +1038,7 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target > l_rtt_inst; FAPI_DBG("%s Running WR_LEVEL step on RP%d", mss::c_str(i_target), i_rp); - fapi2::buffer l_steps_to_execute; + fapi2::buffer l_steps_to_execute; l_steps_to_execute.setBit(); // Setup WR_LEVEL specific terminations @@ -1070,14 +1067,15 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target ()) + if(i_cal_steps_enabled.getBit()) { // Sets up the cal steps in the buffer - fapi2::buffer l_steps_to_execute; + fapi2::buffer l_steps_to_execute; l_steps_to_execute.setBit(); + l_steps_to_execute.writeBit(i_cal_steps_enabled.getBit()); - FAPI_INF("%s Running DQS align on RP%d 0x%04x", mss::c_str(i_target), i_rp, - uint16_t(l_steps_to_execute)); + FAPI_INF("%s Running DQS align on RP%d 0x%04x", + mss::c_str(i_target), i_rp, l_steps_to_execute); // Undertake the calibration steps FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) ); @@ -1087,14 +1085,15 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target ()) + // Run cal steps between RDCLK_ALIGN and RD_CTR if any are selected - note RDCLK_ALIGN takes place after WR_LEVEL + if (i_cal_steps_enabled.getBit()) { // Sets up the cal steps in the buffer - fapi2::buffer l_steps_to_execute; - i_cal_steps_enabled.extract - (l_steps_to_execute); + fapi2::buffer l_steps_to_execute; + + i_cal_steps_enabled.extract(l_steps_to_execute); FAPI_INF("%s Running rd_clk align through read centering vref on RP%d 0x%04x", mss::c_str(i_target), i_rp, l_steps_to_execute); @@ -1111,17 +1110,17 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target()) + if (i_cal_steps_enabled.getBit()) { - fapi2::buffer l_steps_to_execute = i_cal_steps_enabled; + FAPI_DBG("%s Running remaining cal steps on RP%d", mss::c_str(i_target), i_rp); + fapi2::buffer l_steps_to_execute = i_cal_steps_enabled; - // Clear until we hit write centering - l_steps_to_execute.clearBit(); + // Clear all steps we've run previously + l_steps_to_execute.clearBit() + .clearBit() + .clearBit() + .clearBit(); - FAPI_INF("%s Running remaining cal steps after read centering on RP%d 0x%04x", mss::c_str(i_target), i_rp, - uint16_t(l_steps_to_execute)); - - // Undertake the calibration steps FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) ); } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H index f3a4cd89daa..195c540ce68 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H @@ -131,31 +131,31 @@ fapi2::ReturnCode process_initial_cal_errors( const fapi2::Target& i_target ) /// @tparam T, the target type of the MCA/MBA /// @param[in] i_target the target associated with this cal setup /// @param[in] i_rank_pairs the vector of currently configured rank pairs -/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable /// @return FAPI2_RC_SUCCESS iff setup was successful /// template< fapi2::TargetType T > fapi2::ReturnCode setup_cal_config( const fapi2::Target& i_target, - const std::vector i_rank_pairs, - const fapi2::buffer i_cal_steps_enabled); + const std::vector& i_rank_pairs, + const fapi2::buffer& i_cal_steps_enabled); /// /// @brief Setup all the cal config register /// @param[in] i_target the target associated with this cal setup /// @param[in] i_rank one currently configured rank pairs -/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable /// @return FAPI2_RC_SUCCESS iff setup was successful /// fapi2::ReturnCode setup_cal_config( const fapi2::Target& i_target, const uint64_t i_rank, - const fapi2::buffer i_cal_steps_enabled); + const fapi2::buffer& i_cal_steps_enabled); /// /// @brief Execute a set of PHY cal steps -/// @tparam T, the target type of the MCA/MBA +/// @tparam T the target type associated with this cal /// @param[in] i_target the target associated with this cal /// @param[in] i_rp one of the currently configured rank pairs -/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable /// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override /// @return FAPI2_RC_SUCCESS iff setup was successful /// @note This is a helper function. Library users are required to call setup_and_execute_cal @@ -163,7 +163,7 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target& template< fapi2::TargetType T > fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target& i_target, const uint64_t i_rp, - const fapi2::buffer i_cal_steps_enabled, + const fapi2::buffer& i_cal_steps_enabled, const uint8_t i_abort_on_error); /// @@ -171,14 +171,14 @@ fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target& i_target, /// @tparam T, the target type of the MCA/MBA /// @param[in] i_target the target associated with this cal /// @param[in] i_rp one of the currently configured rank pairs -/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer representing the cal steps to enable /// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override /// @return FAPI2_RC_SUCCESS iff setup was successful /// template< fapi2::TargetType T > fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target& i_target, const uint64_t i_rp, - const fapi2::buffer i_cal_steps_enabled, + const fapi2::buffer& i_cal_steps_enabled, const uint8_t i_abort_on_error); // TODO RTC:167929 Can ODT VPD processing be shared between RD and WR? 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 bce9f0de60a..601fe19f29f 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 @@ -1807,12 +1807,11 @@ fapi2::ReturnCode reset_wr_vref_config0( const fapi2::Target& i .insertFromRight(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 l_cal_steps_enabled; + fapi2::buffer 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(l_cal_steps_enabled.getBit()); + l_config0_data.writeBit(!l_cal_steps_enabled.getBit()); //blast out the scoms FAPI_TRY( mss::scom_blastah(i_target, TT::WR_VREF_CONFIG0_REG, l_config0_data) ); diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H index fe9ef268070..99cd8bae463 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H @@ -37,6 +37,7 @@ #define _MSS_CONST_H_ #include +#include namespace mss { @@ -145,23 +146,37 @@ enum states // Static consts describing the bits used in the cal_step_enable attribute // These are bit positions. 0 is the left most bit. -enum cal_steps +enum cal_steps : uint64_t { - EXT_ZQCAL = 0, - WR_LEVEL = 1, - DQS_ALIGN = 2, - RDCLK_ALIGN = 3, - READ_CTR = 4, - READ_CTR_2D_VREF = 5, - WRITE_CTR = 6, - WRITE_CTR_2D_VREF = 7, - COARSE_WR = 8, - COARSE_RD = 9, - // We can do math here, so this pretties up the code - // Note: a function was investigated but abandoned due to unresolvable compile issues - // Note: for STEPS_FROM_DQS_ALIGN_TO_AFTER_RD_CTR_LEN - READ_CTR/READ_CTR_2D_VREF are run together pick the larger of the steps - STEPS_FROM_RDCLK_ALIGN_TO_AFTER_RD_CTR_VREF_LEN = (READ_CTR_2D_VREF - RDCLK_ALIGN) + 1, - STEPS_FROM_WR_CTR_TO_COARSE_RD_LEN = (COARSE_RD - WRITE_CTR) + 1, + DRAM_ZQCAL = 0, ///< DRAM ZQ Calibration Long + DB_ZQCAL = 1, ///< (LRDIMM) Data Buffer ZQ Calibration Long + MREP = 2, ///< (LRDIMM) DRAM Interface MDQ Receive Enable Phase + MRD_COARSE = 3, ///< (LRDIMM) DRAM-to-DB Read Delay - Coarse + MRD_FINE = 4, ///< (LRDIMM) DRAM-to-DB Read Delay - Fine + WR_LEVEL = 5, ///< Write Leveling + INITIAL_PAT_WR = 6, ///< Initial Pattern Write + WR_VREF_LATCH = 7, ///< Write VREF Latching + DWL = 8, ///< (LRDIMM) DRAM Interface Write Leveling + MWD_COARSE = 9, ///< (LRDIMM) DB-to-DRAM Write Delay - Coarse + MWD_FINE = 10, ///< (LRDIMM) DB-to-DRAM Write Delay - Fine + HWL = 11, ///< (LRDIMM) Host Interface Write Leveling + DQS_ALIGN = 12, ///< DQS (read) alignment + RDCLK_ALIGN = 13, ///< Alignment of the internal SysClk to the Read clock + READ_CTR_2D_VREF = 14, ///< Read Vref + READ_CTR = 15, ///< Read Centering + WRITE_CTR_2D_VREF = 16, ///< Write Vref + WRITE_CTR = 17, ///< Write Centering + COARSE_WR = 18, ///< Initial Coarse Pattern Write + COARSE_RD = 19, ///< Coarse Read Centering + + // Not *exactly* a cal step but go w/it + RUN_ALL_CAL_STEPS = 0xFFFFF000, + RUN_CAL_SKIP_WR_RD_2D_VREF = 0xFFFD7000, + + DRAM_ZQCAL_TO_WR_LEVEL_LEN = inclusive_range(DRAM_ZQCAL, WR_LEVEL), + INITIAL_PAT_WR_TO_RD_CTR_LEN = inclusive_range(INITIAL_PAT_WR, READ_CTR), + WR_VREF_TO_COARSE_RD_LEN = inclusive_range(WRITE_CTR_2D_VREF, COARSE_RD), + RDCLK_ALIGN_TO_RD_CTR_LEN = inclusive_range(RDCLK_ALIGN, READ_CTR), }; // Static consts for DDR4 voltages used in p9_mss_volt diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C index c15b5bb03dd..f9f1ec552fe 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C @@ -182,7 +182,7 @@ fapi2::ReturnCode rd_vref_vref_sense_setup( const fapi2::Target& i_target, - const fapi2::buffer& i_cal_steps_enabled ) + const fapi2::buffer& i_cal_steps_enabled ) { // Only runs on the last cal steps (coarse wr/rd) if (i_cal_steps_enabled.getBit() || @@ -439,7 +439,7 @@ fapi2::ReturnCode dqs_align_workaround(const fapi2::Target l_passing_values; uint64_t l_num_loops = 0; - uint8_t l_dram_width[2] = {}; + uint8_t l_dram_width[mss::PORTS_PER_MCS] = {}; bool l_is_x8 = false; // Let's check to see if we can run the workaround @@ -487,7 +487,7 @@ fapi2::ReturnCode dqs_align_workaround(const fapi2::Target().setBit(); + const auto l_dqs_align_cal = fapi2::buffer().setBit(); FAPI_TRY(mss::execute_cal_steps_helper( i_target, i_rp, l_dqs_align_cal, i_abort_on_error)); } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H index aa0aba56950..ff41fc8d6f9 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H @@ -278,7 +278,7 @@ fapi2::ReturnCode rd_vref_vref_sense_setup( const fapi2::Target& i_target, - const fapi2::buffer& i_cal_steps_enabled ); + const fapi2::buffer& i_cal_steps_enabled ); namespace dqs_align { diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.C index eb14c0c2578..59791b9b678 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -59,7 +59,7 @@ namespace wr_vref /// fapi2::ReturnCode execute( const fapi2::Target& i_target, const uint64_t i_rp, - const fapi2::buffer& i_cal_steps_enabled, + const fapi2::buffer& i_cal_steps_enabled, uint8_t& o_vrefdq_train_range, uint8_t& o_vrefdq_train_value ) { diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.H index aef4b234230..eb80bf52ae8 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -61,7 +61,7 @@ namespace wr_vref // TODO RTC:166422 update training code to set cal step enable and consume it everywhere locally fapi2::ReturnCode execute( const fapi2::Target& i_target, const uint64_t i_rp, - const fapi2::buffer& i_cal_steps_enabled, + const fapi2::buffer& i_cal_steps_enabled, uint8_t& o_vrefdq_train_range, uint8_t& o_vrefdq_train_value ); diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C index bb184b3474f..4dc0ba7a48f 100644 --- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C +++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C @@ -41,6 +41,7 @@ #include #include #include +#include using fapi2::TARGET_TYPE_MCBIST; using fapi2::TARGET_TYPE_MCA; @@ -55,12 +56,12 @@ extern "C" /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode p9_mss_draminit_training( const fapi2::Target& i_target, - const uint16_t i_special_training, + const uint32_t i_special_training, const uint8_t i_abort_on_error) { // Keep track of the last error seen by a port fapi2::ReturnCode l_port_error = fapi2::FAPI2_RC_SUCCESS; - fapi2::buffer l_cal_steps_enabled = i_special_training; + fapi2::buffer l_cal_steps_enabled = i_special_training; FAPI_INF("Start draminit training"); @@ -99,12 +100,25 @@ extern "C" for( const auto& p : mss::find_targets(i_target)) { // Keep track of the last error seen by a rank pair - fapi2::ReturnCode l_rank_pair_error = fapi2::FAPI2_RC_SUCCESS; + fapi2::ReturnCode l_rank_pair_error(fapi2::FAPI2_RC_SUCCESS); // Returned from set_rank_pairs, it tells us how many rank pairs // we configured on this port. std::vector l_pairs; + // Grab the attribute which contains the information on what cal steps we should run + // if the i_specal_training bits have not been specified. + if (i_special_training == 0) + { + FAPI_TRY( mss::cal_step_enable(p, l_cal_steps_enabled) ); + } + + FAPI_DBG("cal steps enabled: 0x%x special training: 0x%x", l_cal_steps_enabled, i_special_training); + + // ZQCAL (for DRAMs and LRDIMM data buffers) isn't a PHY calibration, + // so we don't add it in the PHY calibration setup and do it separately here. + FAPI_TRY( mss::setup_and_execute_zqcal(p, l_cal_steps_enabled) ); + FAPI_TRY( mss::putScom(p, MCA_DDRPHY_PC_INIT_CAL_ERROR_P0, 0) ); FAPI_TRY( mss::putScom(p, MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0, 0) ); @@ -124,18 +138,7 @@ extern "C" FAPI_TRY( mss::rank::get_rank_pairs(p, l_pairs) ); // Setup the config register - // - // Grab the attribute which contains the information on what cal steps we should run - // if the i_specal_training bits have not been specified. - // TODO RTC:166422 update training code to set cal step enable and consume it everywhere locally - if (i_special_training == 0) - { - FAPI_TRY( mss::cal_step_enable(p, l_cal_steps_enabled) ); - } - FAPI_DBG("cal steps enabled: 0x%x special training: 0x%x", l_cal_steps_enabled, i_special_training); - - // Check to see if we're supposed to reset the delay values before starting training // don't reset if we're running special training - assumes there's a checkpoint which has valid state. if ((l_reset_disable == fapi2::ENUM_ATTR_MSS_MRW_RESET_DELAY_BEFORE_CAL_YES) && (i_special_training == 0)) { @@ -150,26 +153,23 @@ extern "C" // THE PROCESSING OF THE ERRORS. (it's hard to figure out which DIMM failed, too) BRS. for (const auto& rp : l_pairs) { - uint8_t cal_abort_on_error = i_abort_on_error; + uint8_t l_cal_abort_on_error = i_abort_on_error; if (i_abort_on_error == CAL_ABORT_SENTINAL) { - FAPI_TRY( mss::cal_abort_on_error(cal_abort_on_error) ); + FAPI_TRY( mss::cal_abort_on_error(l_cal_abort_on_error) ); } // Execute selected cal steps FAPI_TRY( mss::setup_and_execute_cal(p, rp, l_cal_steps_enabled, i_abort_on_error) ); - // Conducts workarounds after training if needed - FAPI_TRY( mss::workarounds::dp16::post_training_workarounds( p, l_cal_steps_enabled ) ); - // If we're aborting on error we can just FAPI_TRY. If we're not, we don't want to exit if there's // an error but we want to log the error and keep on keeping on. if ((fapi2::current_err = mss::process_initial_cal_errors(p)) != fapi2::FAPI2_RC_SUCCESS) { fapi2::logError(fapi2::current_err); - if (cal_abort_on_error) + if (l_cal_abort_on_error) { goto fapi_try_exit; } @@ -177,7 +177,10 @@ extern "C" // Keep tack of the last cal error we saw. l_rank_pair_error = fapi2::current_err; } - } + }// rank pairs + + // Conducts workarounds after training if needed + FAPI_TRY( mss::workarounds::dp16::post_training_workarounds( p, l_cal_steps_enabled ) ); // Once we've trained all the rank pairs we can record the bad bits in the attributes if we have an error // This error is the most recent error seen on a port, too, so we keep track of that. diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.H index 2ee19ad402a..62dc6a4c1d7 100644 --- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.H +++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,7 +38,7 @@ #include typedef fapi2::ReturnCode (*p9_mss_draminit_training_FP_t) (const fapi2::Target&, - const uint16_t, + const uint32_t, const uint8_t); // Use a special sentinal to let you know you need to read the attribute (which is 1/0) @@ -55,7 +55,7 @@ extern "C" /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode p9_mss_draminit_training( const fapi2::Target& i_target, - const uint16_t i_special_training = 0, + const uint32_t i_special_training = 0, const uint8_t i_abort_on_error = CAL_ABORT_SENTINAL); } diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C index cfb4d0f5923..6d96875fa6d 100644 --- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C +++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C @@ -194,6 +194,7 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target FAPI_TRY( l_eff_dimm->dram_rtt_nom () ); FAPI_TRY( l_eff_dimm->dram_rtt_wr () ); FAPI_TRY( l_eff_dimm->dram_rtt_park() ); + FAPI_TRY( l_eff_dimm->phy_seq_refresh() ); // Sets up the calibration steps FAPI_TRY( l_eff_dimm->cal_step_enable() ); diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml index 31cee2e3d66..400cf851653 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml @@ -1930,22 +1930,38 @@ ATTR_MSS_CAL_STEP_ENABLE TARGET_TYPE_MCS - A bit map of vector denoting valid cal steps to run (0 is left most bit) - [0] EXT_ZQCAL - [1] WR_LEVEL - [2] DQS_ALIGN - [3] RDCLK_ALIGN - [4] READ_CTR - [5] READ_CTR_2D_VREF - [6] WRITE_CTR - [7] WRITE_CTR_2D_VREF - [8] COARSE_WR - [9] COARSE_RD - [10]:[15] Reserved for future use - COARSE_WR and COARSE_RD will be consumed together to form COARSE_LVL. + A bit map of vector denoting valid steps to run (0 is left most bit) + [0] DRAM_ZQCAL + [1] DB_ZQCAL (LRDIMM) + [2] MREP (LRDIMM) + [3] MRD - Coarse (LRDIMM) + [4] MRD - Fine (LRDIMM) + [5] WR_LEVEL + [6] INITIAL_PAT_WR + [7] WR_VREF_LATCH + [8] DWL (LRDIMM) + [9] MWD - Coarse (LRDIMM) + [10] MWD - Fine (LRDIMM) + [11] HWL (LRDIMM) + [12] DQS_ALIGN + [13] RDCLK_ALIGN + [14] READ_CTR_2D_VREF + [15] READ_CTR + [16] WRITE_CTR_2D_VREF + [17] WRITE_CTR + [18] COARSE_WR + [19] COARSE_RD + [20]:[31] Reserved for future use + + COARSE_WR and COARSE_RD will be consumed together to form COARSE_LVL. + + WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is enabled, + as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. + + Note: LRDIMM steps will only be enabled for LRDIMMs and won't run on RDIMMs. - uint16 + uint32 2 cal_step_enable diff --git a/src/import/generic/memory/lib/utils/mss_math.H b/src/import/generic/memory/lib/utils/mss_math.H index 2c587384e56..b4eca948556 100644 --- a/src/import/generic/memory/lib/utils/mss_math.H +++ b/src/import/generic/memory/lib/utils/mss_math.H @@ -22,3 +22,33 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +// *HWP HWP Owner: Andre Marin +// *HWP HWP Backup: Jacob Harvey +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_MATH_H_ +#define _MSS_MATH_H_ + +#include + +namespace mss +{ +/// +/// @brief Calculates inclusive range +/// @tparam T input and output type +/// @param[in] i_start starting point +/// @param[in] i_end ending point +/// @return inclusive range calculation +/// +// TODO RTC:174277 - create unit test structure for generic/memory +template +inline constexpr T inclusive_range( const T i_start, const T i_end) +{ + return (i_end - i_start) + 1; +} + +}// mss + +#endif diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index c777158a9ed..5dc44fb3f95 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -10315,23 +10315,39 @@ firmware notes: Used as override attribute for pstate procedure MSS_CAL_STEP_ENABLE - A bit map ofvector denoting valid cal steps to run (0 is left most bit) - [0] EXT_ZQCAL - [1] WR_LEVEL - [2] DQS_ALIGN - [3] RDCLK_ALIGN - [4] READ_CTR - [5] READ_CTR_2D_VREF - [6] WRITE_CTR - [7] WRITE_CTR_2D_VREF - [8] COARSE_WR - [9] COARSE_RD - [10]:[15] Reserved for future use - COARSE_WR and COARSE_RD will be consumed together to form COARSE_LVL. + A bit map of vector denoting valid steps to run (0 is left most bit) + [0] DRAM_ZQCAL + [1] DB_ZQCAL (LRDIMM) + [2] MREP (LRDIMM) + [3] MRD - Coarse (LRDIMM) + [4] MRD - Fine (LRDIMM) + [5] WR_LEVEL + [6] INITIAL_PAT_WR + [7] WR_VREF_LATCH + [8] DWL (LRDIMM) + [9] MWD - Coarse (LRDIMM) + [10] MWD - Fine (LRDIMM) + [11] HWL (LRDIMM) + [12] DQS_ALIGN + [13] RDCLK_ALIGN + [14] READ_CTR_2D_VREF + [15] READ_CTR + [16] WRITE_CTR_2D_VREF + [17] WRITE_CTR + [18] COARSE_WR + [19] COARSE_RD + [20]:[31] Reserved for future use + + COARSE_WR and COARSE_RD will be consumed together to form COARSE_LVL. + + WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is enabled, + as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. + + Note: LRDIMM steps will only be enabled for LRDIMMs and won't run on RDIMMs. - - + + 2 volatile-zeroed