From f71bc6d259e8953b313b89f236f94dadd098179c Mon Sep 17 00:00:00 2001 From: Brian Silver Date: Fri, 19 Aug 2016 15:04:20 -0500 Subject: Add ZQCL instruction after MRS have completed Change default cal steps to include ZQCL Change-Id: Ib99bfade301d064c70f1a6380bf81c1c20acea96 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28553 Reviewed-by: ANDRE A. MARIN Reviewed-by: STEPHEN GLANCY Tested-by: Jenkins Server Reviewed-by: Louis Stermole Tested-by: Hostboot CI Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28556 Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell --- .../chips/p9/procedures/hwp/memory/lib/ccs/ccs.H | 95 ++++++++++++++++------ .../hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C | 44 +++++++++- .../p9/procedures/hwp/memory/p9_mss_eff_config.C | 2 +- 3 files changed, 113 insertions(+), 28 deletions(-) diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H index e242dd426..501c50031 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H @@ -116,6 +116,7 @@ class ccsTraits // ARR0 ARR0_DDR_ADDRESS_0_13 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13, ARR0_DDR_ADDRESS_0_13_LEN = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13_LEN, + ARR0_DDR_ADDRESS_10 = 10, // ADR10 is the 10th bit from the left in Nimbus ARR0 ARR0_DDR_ADDRESS_17 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17, ARR0_DDR_BANK_GROUP_1 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_1, ARR0_DDR_RESETN = MCBIST_CCS_INST_ARR0_00_DDR_RESETN, @@ -305,6 +306,8 @@ class program /// /// @brief Common setup for all MRS/RCD instructions +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in,out] i_arr0 fapi2::buffer representing the ARR0 of the instruction /// @return void /// @@ -328,7 +331,8 @@ static void mrs_rcd_helper( fapi2::buffer& i_arr0 ) /// /// @brief Create, initialize an RCD (RCW - JEDEC) CCS command -/// @tparam T the fapi2 type of the unit which contains the CCS engine +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target the DIMM this instruction is headed for /// @return the RCD CCS instruction /// @note THIS IS DDR4 ONLY RIGHT NOW. We can (and possibly should) specialize this @@ -360,7 +364,8 @@ inline instruction_t rcd_command( const fapi2::Target mrs_command( const fapi2::Target des_command() /// /// @brief Create, initialize an instruction which indicates an initial cal +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_rp the rank-pair (rank) to cal /// @return the initial cal instruction /// @@ -450,6 +458,40 @@ inline instruction_t initial_cal_command(const uint64_t i_rp) return l_inst; } +/// +/// @brief Setup ZQ Long instruction +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction +/// @param[in] i_target the DIMM this instruction is headed for +/// @param[in] i_rank the rank on this dimm +/// @return the MRS CCS instruction +/// @note THIS IS DDR4 ONLY RIGHT NOW. We can (and possibly should) specialize this +/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included +/// in this template definition) +/// +template< fapi2::TargetType T, typename TT = ccsTraits > +inline instruction_t zqcl_command( const fapi2::Target& i_target, const uint64_t i_rank ) +{ + fapi2::buffer l_boilerplate_arr0; + fapi2::buffer l_boilerplate_arr1; + + // CKE is high Note: P8 set all 4 of these high - not sure if that's correct. BRS + l_boilerplate_arr0.insertFromRight(0b1111); + + // ACT is high + l_boilerplate_arr0.setBit(); + + // RAS/CAS high, WE low + l_boilerplate_arr0.setBit(); + l_boilerplate_arr0.setBit(); + l_boilerplate_arr0.clearBit(); + + // ADDR10/AP is high + l_boilerplate_arr0.setBit(); + + return instruction_t(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1); +} + // // These functions are a little sugar to keep callers from doing the traits-dance to get the // appropriate bit field @@ -457,8 +499,8 @@ inline instruction_t initial_cal_command(const uint64_t i_rp) /// /// @brief Select the port(s) to be used by the CCS -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target the target to effect /// @param[in] i_ports the buffer representing the ports /// @return void @@ -483,8 +525,8 @@ fapi_try_exit: /// /// @brief User sets to a '1'b to tell the Hdw to stop CCS whenever failure occurs. When a /// '0'b, Hdw will continue CCS even if a failure occurs. -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] the target to effect /// @param[in] i_buffer the buffer representing the mode register /// @param[in] i_value true iff stop whenever failure occurs. @@ -498,8 +540,8 @@ inline void stop_on_err( const fapi2::Target&, fapi2::buffer& i_buf /// /// @brief Disable ECC checking on the CCS arrays -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] the target to effect /// @param[in] i_buffer the buffer representing the mode register /// @return void @@ -514,8 +556,8 @@ inline void disable_ecc( const fapi2::Target&, fapi2::buffer& i_buf /// /// @brief User sets to a '1'b to force the Hdw to ignore any array ue or sue errors /// during CCS command fetching. -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] the target to effect /// @param[in] i_buffer the buffer representing the mode register /// @param[in] i_value true iff ignore any array ue or sue errors. @@ -529,8 +571,8 @@ inline void ue_disable( const fapi2::Target&, fapi2::buffer& i_buff /// /// @brief DDr calibration counter -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] the target to effect /// @param[in] i_buffer the buffer representing the mode register /// @param[in] i_count the count to wait for DDR cal to complete. @@ -564,8 +606,8 @@ void copy_cke_to_spare_cke( const fapi2::Target&, fapi2::buffer& i_ /// /// @brief Read the modeq register appropriate for this target -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target the target to effect /// @param[in] i_buffer the buffer representing the mode register /// @return FAPI2_RC_SUCCSS iff ok @@ -579,8 +621,8 @@ inline fapi2::ReturnCode read_mode( const fapi2::Target& i_target, fapi2::buf /// /// @brief Write the modeq register appropriate for this target -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target the target to effect /// @param[in] i_buffer the buffer representing the mode register /// @return FAPI2_RC_SUCCSS iff ok @@ -593,9 +635,8 @@ inline fapi2::ReturnCode write_mode( const fapi2::Target& i_target, const fap /// /// @brief Execute a set of CCS instructions - multiple ports -/// @tparam T the fapi2::TargetType - derived -/// @tparam P the fapi2::TargetType of the ports - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target the target to effect /// @param[in] i_program the vector of instructions /// @param[in] i_ports the vector of ports @@ -608,9 +649,8 @@ fapi2::ReturnCode execute( const fapi2::Target& i_target, /// /// @brief Execute a set of CCS instructions - single port -/// @tparam T the fapi2::TargetType - derived -/// @tparam P the fapi2::TargetType of the ports - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target the target to effect /// @param[in] i_program the vector of instructions /// @param[in] i_port the port @@ -628,16 +668,19 @@ fapi2::ReturnCode execute( const fapi2::Target& i_target, /// /// @brief Execute a CCS array already loaded in to the engine -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the ccsTraits associated with T - derived +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target the target to effect /// @param[in] i_program the MCBIST ccs program - to get the polling parameters /// @return FAPI2_RC_SUCCSS iff ok /// template< fapi2::TargetType T, typename TT = ccsTraits > fapi2::ReturnCode execute_inst_array(const fapi2::Target& i_target, ccs::program& i_program); + /// /// @brief Start or stop the CCS engine +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target The MCBIST containing the CCS engine /// @param[in] i_start_stop bool MSS_CCS_START for starting MSS_CCS_STOP otherwise /// @return FAPI2_RC_SUCCESS iff success @@ -647,6 +690,8 @@ fapi2::ReturnCode start_stop( const fapi2::Target& i_target, bool i_start_sto /// /// @brief Query the status of the CCS engine +/// @tparam T the target type of the chiplet which executes the CCS instruction +/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction /// @param[in] i_target The MCBIST containing the CCS engine /// @param[out] io_status The query result first being the result, second the type /// @return FAPI2_RC_SUCCESS iff success 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 166246dde..3b55a0fc6 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 @@ -60,8 +60,12 @@ fapi2::ReturnCode mrs_load( const fapi2::Target& i_target, { FAPI_INF("ddr4::mrs_load %s", mss::c_str(i_target)); - // Per DDR4MRS02 table 104 - timing requirements - static const uint64_t tMRD = 8; + // Per DDR4 Full spec update (79-4A) - timing requirements + constexpr uint64_t tMRD = 8; + constexpr uint64_t tZQinit = 1024; + uint64_t l_freq = 0; + uint64_t tDLLK = 0; + fapi2::buffer l_cal_steps; static std::vector< mrs_data > l_mrs_data = { @@ -75,6 +79,11 @@ fapi2::ReturnCode mrs_load( const fapi2::Target& i_target, std::vector< uint64_t > l_ranks; FAPI_TRY( mss::ranks(i_target, l_ranks) ); + // Calculate tDLLK from our frequency. Magic numbers (in clocks) from the DDR4 spec + FAPI_TRY( mss::freq(mss::find_target(i_target), l_freq) ); + tDLLK = (l_freq < fapi2::ENUM_ATTR_MSS_FREQ_MT2133) ? 597 : 768; + + // Load MRS for (const auto& d : l_mrs_data) { for (const auto& r : l_ranks) @@ -117,6 +126,37 @@ 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 + tZQinit); + l_inst_b_side.arr1.insertFromRight(tDLLK + 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); + } + } + fapi_try_exit: return fapi2::current_err; } 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 40ddaa572..729f3b438 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 @@ -240,7 +240,7 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target } { - uint16_t l_cal_step[mss::PORTS_PER_MCS] = {0x7AC0, 0x7AC0}; + uint16_t l_cal_step[mss::PORTS_PER_MCS] = {0xFAC0, 0xFAC0}; FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, i_target, l_cal_step) ); } -- cgit v1.2.1