diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C | 131 |
1 files changed, 131 insertions, 0 deletions
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 |