diff options
author | Andre Marin <aamarin@us.ibm.com> | 2017-05-11 11:28:21 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-05-25 15:40:26 -0400 |
commit | c00a806435284d3ffd4eb1e6e1142ac8723a8ab2 (patch) | |
tree | f9bcc5b5a2975558553371a1fb3f7d6652858194 /src/import/chips/p9/procedures/hwp/memory | |
parent | 4d9e5a4a231d2a4a14231bc5a01d4590cb88d96d (diff) | |
download | talos-hostboot-c00a806435284d3ffd4eb1e6e1142ac8723a8ab2.tar.gz talos-hostboot-c00a806435284d3ffd4eb1e6e1142ac8723a8ab2.zip |
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 <stermole@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com>
Reviewed-by: Matt K. Light <mklight@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38650
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory')
18 files changed, 389 insertions, 207 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 445ea8cea..c6dc9c2d2 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 <lib/dimm/bcw_load_ddr4.H> #include <lib/phy/dp16.H> #include <lib/dimm/ddr4/control_word_ddr4.H> +#include <lib/eff_config/timing.H> 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 850244d4a..515f45296 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<TARGET_TYPE_DIMM>& i_target, { FAPI_INF("ddr4::mrs_load %s", mss::c_str(i_target)); - fapi2::buffer<uint16_t> l_cal_steps; - uint64_t tDLLK = 0; - uint8_t l_dimm_type = 0; - - static std::vector< mrs_data<TARGET_TYPE_MCBIST> > l_mrs_data = + static const std::vector< mrs_data<TARGET_TYPE_MCBIST> > 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<TARGET_TYPE_DIMM>& 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<TARGET_TYPE_DIMM>& 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<EXT_ZQCAL>() != 0) - { - for (const auto& r : l_ranks) - { - // Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS - ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst_a_side = ccs::zqcl_command<TARGET_TYPE_MCBIST>(i_target, r); - ccs::instruction_t<TARGET_TYPE_MCBIST> 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<MCBIST_CCS_INST_ARR1_00_IDLES, - MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(tDLLK + mss::tzqinit()); - l_inst_b_side.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, - MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(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 562c2f064..b92c9086d 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 <aamarin@us.ibm.com> +// *HWP HWP Backup: Jacob Harvey <jlharvey@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#include <vector> +#include <fapi2.H> + +#include <lib/dimm/ddr4/zqcal.H> +#include <lib/dimm/ddr4/data_buffer_ddr4.H> +#include <lib/ccs/ccs.H> +#include <lib/eff_config/timing.H> + +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<fapi2::TARGET_TYPE_DIMM>& i_target, + const uint64_t i_rank, + std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst) +{ + ccs::instruction_t<TARGET_TYPE_MCBIST> 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<TARGET_TYPE_MCBIST>(i_target, i_rank); + + l_inst.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, + MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(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<fapi2::TARGET_TYPE_DIMM>& i_target, + std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& 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<uint16_t> representing the cal steps to enable +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +template<> +fapi2::ReturnCode setup_and_execute_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const fapi2::buffer<uint32_t>& i_cal_steps_enabled) +{ + mss::ccs::program<TARGET_TYPE_MCBIST> l_program; + + for ( const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) ) + { + // If this bit isn't set, nothing to do here... + if ( i_cal_steps_enabled.getBit<DRAM_ZQCAL>() ) + { + std::vector<uint64_t> 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<DB_ZQCAL>() ) + { + FAPI_TRY( mss::setup_data_buffer_zqcal(d, l_program.iv_instructions) ); + } + }// dimm + + // execute ZQCAL instructions + FAPI_TRY( mss::ccs::execute(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(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 8f56e3975..e7e546a7c 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 <aamarin@us.ibm.com> +// *HWP HWP Backup: Jacob Harvey <jlharvey@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_ZQCAL_H_ +#define _MSS_ZQCAL_H_ + +#include <vector> +#include <fapi2.H> +#include <lib/ccs/ccs.H> + +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<T>& i_target, + const uint64_t i_rank, + std::vector< ccs::instruction_t<TT> >& 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<T>& i_target, + std::vector< ccs::instruction_t<TT> >& 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<uint16_t> 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<T>& i_target, + const fapi2::buffer<uint32_t>& 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 f8ca39417..a9af406ca 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<uint16_t> l_cal_step(PORTS_PER_MCS, l_cal_step_value); + std::vector<uint32_t> 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<uint16_t> 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 3fa215f89..c15ab7e8f 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<fapi2::TARGET_TYPE_MCA> -/// @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<fapi2::TARGET_TYPE_MCA>& i_target, uint16_t& o_value) +inline fapi2::ReturnCode cal_step_enable(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& 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<fapi2::TARGET_TYPE_MCS>(), 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<fapi2::TARGET_TYPE_DIMM> -/// @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<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value) +inline fapi2::ReturnCode cal_step_enable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value) { - uint16_t l_value[2]; + uint32_t l_value[2]; auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>(); FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, l_mca.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) ); @@ -9320,17 +9330,22 @@ fapi_try_exit: /// /// @brief ATTR_MSS_CAL_STEP_ENABLE getter /// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @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<fapi2::TARGET_TYPE_MCS>& i_target, uint16_t* o_array) +inline fapi2::ReturnCode cal_step_enable(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array) { if (o_array == nullptr) { @@ -9338,10 +9353,10 @@ inline fapi2::ReturnCode cal_step_enable(const fapi2::Target<fapi2::TARGET_TYPE_ return fapi2::FAPI2_RC_INVALID_PARAMETER; } - uint16_t l_value[2]; + uint32_t l_value[2]; FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, i_target, l_value) ); - memcpy(o_array, &l_value, 4); + memcpy(o_array, &l_value, 8); return fapi2::current_err; fapi_try_exit: diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H index c1a465fc9..c4b583c6a 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H @@ -194,7 +194,7 @@ uint64_t coarse_rd_cycles(const fapi2::Target<T>& i_target ) template<fapi2::TargetType T> inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target, poll_parameters& i_poll, - const fapi2::buffer<uint16_t>& i_cal_steps_enabled) + const fapi2::buffer<uint32_t>& 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 240b3a259..c4b1c3292 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<fapi2::TARGET_TYPE_MCA>& i_target, - const std::vector<uint64_t> i_rank_pairs, - fapi2::buffer<uint16_t> i_cal_steps_enabled) + const std::vector<uint64_t>& i_rank_pairs, + const fapi2::buffer<uint32_t>& i_cal_steps_enabled) { fapi2::buffer<uint64_t> 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<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ABORT_ON_ERROR>(cal_abort_on_error); + l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ABORT_ON_ERROR>(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<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_WR_LEVEL>( i_cal_steps_enabled.getBit<WR_LEVEL>()); @@ -834,7 +833,8 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& // 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<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_INITIAL_PAT_WR>(); + l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_INITIAL_PAT_WR>( + i_cal_steps_enabled.getBit<INITIAL_PAT_WR>()); } } @@ -903,11 +903,14 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& 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<WR_VREF_LATCH>()) + { + 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<fapi2::TARGET_TYPE_MCA>& // 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<uint16_t> 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<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rank, - const fapi2::buffer<uint16_t> i_cal_steps_enabled) + const fapi2::buffer<uint32_t>& 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<fapi2::TARGET_TYPE_MCA>& /// 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<uint16_t> 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<fapi2::TARGET_TYPE_MCA>& template<> fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp, - const fapi2::buffer<uint16_t> i_cal_steps_enabled, + const fapi2::buffer<uint32_t>& i_cal_steps_enabled, const uint8_t i_abort_on_error) { const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target); @@ -967,9 +970,11 @@ fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<fapi2::TARGET_TY // Sanity check due to WR_LEVEL termination requirement if ((i_cal_steps_enabled.getBit<mss::cal_steps::WR_LEVEL>()) && - (mss::bit_count(static_cast<uint16_t>(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<uint16_t> 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<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp, - const fapi2::buffer<uint16_t> i_cal_steps_enabled, + const fapi2::buffer<uint32_t>& i_cal_steps_enabled, const uint8_t i_abort_on_error) { const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(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<mss::cal_steps::EXT_ZQCAL>()) - { - FAPI_DBG("%s Running EXT_ZQCAL step on RP%d", mss::c_str(i_target), i_rp); - fapi2::buffer<uint16_t> l_steps_to_execute; - l_steps_to_execute.setBit<mss::cal_steps::EXT_ZQCAL>(); - 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<mss::cal_steps::WR_LEVEL>()) { @@ -1041,7 +1038,7 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_ std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> > l_rtt_inst; FAPI_DBG("%s Running WR_LEVEL step on RP%d", mss::c_str(i_target), i_rp); - fapi2::buffer<uint16_t> l_steps_to_execute; + fapi2::buffer<uint32_t> l_steps_to_execute; l_steps_to_execute.setBit<mss::cal_steps::WR_LEVEL>(); // Setup WR_LEVEL specific terminations @@ -1070,14 +1067,15 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_ } // Lets run DQS - if (i_cal_steps_enabled.getBit< mss::cal_steps::DQS_ALIGN > ()) + if(i_cal_steps_enabled.getBit<mss::cal_steps::DQS_ALIGN>()) { // Sets up the cal steps in the buffer - fapi2::buffer<uint16_t> l_steps_to_execute; + fapi2::buffer<uint32_t> l_steps_to_execute; l_steps_to_execute.setBit<mss::cal_steps::DQS_ALIGN>(); + l_steps_to_execute.writeBit<mss::cal_steps::INITIAL_PAT_WR>(i_cal_steps_enabled.getBit<mss::cal_steps::WR_LEVEL>()); - 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<fapi2::TARGET_TYPE_ "%s Failed to run dqs align workaround on rp %d", mss::c_str(i_target), i_rp); } - // Run cal steps between RDCLK_ALIGN and RD_CTR_VREF if any are selected - note RDCLK_ALIGN takes place after WR_LEVEL - if (i_cal_steps_enabled.getBit - < mss::cal_steps::RDCLK_ALIGN, mss::cal_steps::STEPS_FROM_RDCLK_ALIGN_TO_AFTER_RD_CTR_VREF_LEN > ()) + // 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<mss::cal_steps::RDCLK_ALIGN, mss::cal_steps::RDCLK_ALIGN_TO_RD_CTR_LEN>()) { // Sets up the cal steps in the buffer - fapi2::buffer<uint16_t> l_steps_to_execute; - i_cal_steps_enabled.extract<mss::cal_steps::RDCLK_ALIGN, mss::cal_steps::STEPS_FROM_RDCLK_ALIGN_TO_AFTER_RD_CTR_VREF_LEN, mss::cal_steps::RDCLK_ALIGN> - (l_steps_to_execute); + fapi2::buffer<uint32_t> l_steps_to_execute; + + i_cal_steps_enabled.extract<mss::cal_steps::RDCLK_ALIGN, + mss::cal_steps::RDCLK_ALIGN_TO_RD_CTR_LEN, + mss::cal_steps::RDCLK_ALIGN>(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<fapi2::TARGET_TYPE_ } // Run cal steps after RD_CTR if any are selected - note: WRITE_CTR takes place after RD_CTR - if (i_cal_steps_enabled.getBit<mss::cal_steps::WRITE_CTR, mss::cal_steps::STEPS_FROM_WR_CTR_TO_COARSE_RD_LEN>()) + if (i_cal_steps_enabled.getBit<mss::cal_steps::WRITE_CTR, mss::cal_steps::WR_VREF_TO_COARSE_RD_LEN>()) { - fapi2::buffer<uint16_t> 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<uint32_t> l_steps_to_execute = i_cal_steps_enabled; - // Clear until we hit write centering - l_steps_to_execute.clearBit<mss::cal_steps::EXT_ZQCAL, mss::cal_steps::WRITE_CTR>(); + // Clear all steps we've run previously + l_steps_to_execute.clearBit<mss::cal_steps::DRAM_ZQCAL>() + .clearBit<mss::cal_steps::WR_LEVEL>() + .clearBit<mss::cal_steps::INITIAL_PAT_WR>() + .clearBit<mss::cal_steps::RDCLK_ALIGN, mss::cal_steps::RDCLK_ALIGN_TO_RD_CTR_LEN>(); - 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 f3a4cd89d..195c540ce 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<T>& 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<uint16_t> representing the cal steps to enable +/// @param[in] i_cal_steps_enabled fapi2::buffer<uint32_t> 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<T>& i_target, - const std::vector<uint64_t> i_rank_pairs, - const fapi2::buffer<uint16_t> i_cal_steps_enabled); + const std::vector<uint64_t>& i_rank_pairs, + const fapi2::buffer<uint32_t>& 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<uint16_t> 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<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rank, - const fapi2::buffer<uint16_t> i_cal_steps_enabled); + const fapi2::buffer<uint32_t>& 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<uint16_t> 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<fapi2::TARGET_TYPE_MCA>& template< fapi2::TargetType T > fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<T>& i_target, const uint64_t i_rp, - const fapi2::buffer<uint16_t> i_cal_steps_enabled, + const fapi2::buffer<uint32_t>& i_cal_steps_enabled, const uint8_t i_abort_on_error); /// @@ -171,14 +171,14 @@ fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<T>& 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<uint16_t> 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<T>& i_target, const uint64_t i_rp, - const fapi2::buffer<uint16_t> i_cal_steps_enabled, + const fapi2::buffer<uint32_t>& 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 bce9f0de6..601fe19f2 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<TARGET_TYPE_MCA>& i .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; + fapi2::buffer<uint32_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>()); + l_config0_data.writeBit<TT::WR_VREF_CONFIG0_1D_ONLY_SWITCH>(!l_cal_steps_enabled.getBit<WRITE_CTR_2D_VREF>()); //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 fe9ef2680..99cd8bae4 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 <cstdint> +#include <generic/memory/lib/utils/mss_math.H> 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 c15b5bb03..f9f1ec552 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<fapi2::TARGET_TY /// @note This function is called after training - it will only be run after coarse wr/rd /// fapi2::ReturnCode post_training_workarounds( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, - const fapi2::buffer<uint16_t>& i_cal_steps_enabled ) + const fapi2::buffer<uint32_t>& i_cal_steps_enabled ) { // Only runs on the last cal steps (coarse wr/rd) if (i_cal_steps_enabled.getBit<mss::cal_steps::COARSE_RD>() || @@ -439,7 +439,7 @@ fapi2::ReturnCode dqs_align_workaround(const fapi2::Target<fapi2::TARGET_TYPE_MC auto l_skip = mss::states::ON; std::map<uint64_t, uint64_t> 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<fapi2::TARGET_TYPE_MC // Hit calibration one more time { - const auto l_dqs_align_cal = fapi2::buffer<uint16_t>().setBit<mss::cal_steps::DQS_ALIGN>(); + const auto l_dqs_align_cal = fapi2::buffer<uint32_t>().setBit<mss::cal_steps::DQS_ALIGN>(); 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 aa0aba569..ff41fc8d6 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<fapi2::TARGET_TY /// @note This function is called after training - it will only be run after coarse wr/rd /// fapi2::ReturnCode post_training_workarounds( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, - const fapi2::buffer<uint16_t>& i_cal_steps_enabled ); + const fapi2::buffer<uint32_t>& 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 eb14c0c25..59791b9b6 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<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp, - const fapi2::buffer<uint16_t>& i_cal_steps_enabled, + const fapi2::buffer<uint32_t>& 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 aef4b2342..eb80bf52a 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<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp, - const fapi2::buffer<uint16_t>& i_cal_steps_enabled, + const fapi2::buffer<uint32_t>& 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 bb184b347..4dc0ba7a4 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 <lib/shared/mss_const.H> #include <lib/workarounds/dp16_workarounds.H> #include <lib/fir/unmask.H> +#include <lib/dimm/ddr4/zqcal.H> 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<TARGET_TYPE_MCBIST>& 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<uint16_t> l_cal_steps_enabled = i_special_training; + fapi2::buffer<uint32_t> 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<TARGET_TYPE_MCA>(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<uint64_t> 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 2ee19ad40..62dc6a4c1 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 <fapi2.H> typedef fapi2::ReturnCode (*p9_mss_draminit_training_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&, - 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<fapi2::TARGET_TYPE_MCBIST>& 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 cfb4d0f59..6d96875fa 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<fapi2::TARGET_TYPE_MCS> 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() ); |