summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2017-12-14 13:48:31 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-01-13 14:14:15 -0500
commit21407ef5012141424473c7df5839dc4ab9ab662a (patch)
tree35e098cb79a6cc20f7d6e060c2e1730933a12855 /src/import/chips/p9/procedures
parent01c730dd41576de25c422070d89e5117ed6975dc (diff)
downloadtalos-hostboot-21407ef5012141424473c7df5839dc4ab9ab662a.tar.gz
talos-hostboot-21407ef5012141424473c7df5839dc4ab9ab662a.zip
Fixes WR LVL terminations
Disables Qoff (DQ outputs) during write leveling for ranks that are not being calibrated and puts those ranks into WR LVL mode. This solves SI issues related to DQ termination, by only terminating the DQS. Change-Id: I0214554c7e11b4268f5ca92c476363a861f1b842 CQ:SW412938 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50960 Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50968 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H13
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C17
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C198
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H79
5 files changed, 310 insertions, 9 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 fe7e62806..49da3db73 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
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -300,6 +300,17 @@ class instruction_t
TT::ARR0_DDR_CSN_2_3_LEN>(CS_N[l_effective_rank].first);
}
}
+
+ ///
+ /// @brief Equals comparison operator
+ /// @param[in] i_rhs - the instruction to compare to
+ /// @return True if both instructions are equal
+ ///
+ inline bool operator==( const instruction_t<T>& i_rhs ) const
+ {
+ return arr0 == i_rhs.arr0 &&
+ arr1 == i_rhs.arr1;
+ }
};
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
index 06131bd61..6f0ba4e72 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
@@ -48,6 +48,7 @@
#include <lib/dimm/ddr4/latch_wr_vref.H>
#include <lib/workarounds/seq_workarounds.H>
#include <lib/workarounds/dqs_align_workarounds.H>
+#include <lib/workarounds/ccs_workarounds.H>
#include <generic/memory/lib/utils/scom.H>
#include <lib/utils/count_dimm.H>
@@ -201,6 +202,13 @@ fapi2::ReturnCode wr_lvl::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE
l_program.iv_instructions.clear();
}
+ FAPI_INF("%s RP%lu %s WR_LVL workaround setup", mss::c_str(i_target), i_rp, iv_sim ? "skipping" : "running");
+
+ if(!iv_sim)
+ {
+ FAPI_TRY( mss::ccs::workarounds::wr_lvl::configure_non_calibrating_ranks(i_target, i_rp, mss::states::OFF_N) );
+ }
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -256,6 +264,13 @@ fapi2::ReturnCode wr_lvl::post_workaround( const fapi2::Target<fapi2::TARGET_TYP
FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
}
+ FAPI_INF("%s RP%lu %s WR_LVL workaround cleanup", mss::c_str(i_target), i_rp, iv_sim ? "skipping" : "running");
+
+ if(!iv_sim)
+ {
+ FAPI_TRY( mss::ccs::workarounds::wr_lvl::configure_non_calibrating_ranks(i_target, i_rp, mss::states::ON_N) );
+ }
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -893,7 +908,7 @@ std::vector<std::shared_ptr<step>> steps_factory(const fapi2::buffer<uint32_t>&
if(i_cal_steps.getBit<mss::cal_steps::WR_LEVEL>())
{
FAPI_INF("Write leveling is enabled");
- l_steps.push_back(std::make_shared<wr_lvl>());
+ l_steps.push_back(std::make_shared<wr_lvl>(i_sim));
}
// INITIAL_PAT_WR
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H
index 69372ef85..3ae5e3365 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H
@@ -301,11 +301,16 @@ class wr_lvl : public phy_step
public:
///
/// @brief Base constructor
+ /// @param[in] i_sim - true if in simulation mode
///
- wr_lvl() :
- phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_WR_LEVEL>(), "WR_LVL")
+ wr_lvl(const bool i_sim) :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_WR_LEVEL>(), "WR_LVL"),
+ iv_sim(i_sim)
{}
+ // Delete the default constructor
+ wr_lvl() = delete;
+
///
/// @brief Default destructor
///
@@ -339,6 +344,9 @@ class wr_lvl : public phy_step
/// @return l_cycles - the number of cycles a given calibration step wil take
///
uint64_t calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const;
+
+ private:
+ bool iv_sim;
};
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C
index bc4b791b7..e7ceb2b0b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,7 @@
#include <lib/dimm/rank.H>
#include <p9_mc_scom_addresses.H>
#include <generic/memory/lib/utils/scom.H>
+#include <lib/eff_config/timing.H>
namespace mss
{
@@ -75,13 +76,13 @@ fapi2::ReturnCode enable_pda_shadow_reg( const fapi2::Target<fapi2::TARGET_TYPE_
fapi2::buffer<uint64_t> l_data;
// Read
- FAPI_TRY(mss::getScom(i_target, RP_TO_REG[l_rp], l_data));
+ FAPI_TRY( mss::getScom(i_target, RP_TO_REG[l_rp], l_data) );
// Modify
l_data.setBit<PDA_BIT>();
// Write
- FAPI_TRY(mss::putScom(i_target, RP_TO_REG[l_rp], l_data));
+ FAPI_TRY( mss::putScom(i_target, RP_TO_REG[l_rp], l_data) );
}
fapi_try_exit:
@@ -119,7 +120,7 @@ fapi2::ReturnCode exit( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
// Re-enable PDA mode in the PHY
{
- FAPI_TRY(enable_pda_shadow_reg(l_mca, i_rank));
+ FAPI_TRY( enable_pda_shadow_reg(l_mca, i_rank) );
}
// Sets up the B-side MRS - the outside code will issue it
@@ -135,6 +136,195 @@ fapi_try_exit:
return fapi2::current_err;
}
+namespace wr_lvl
+{
+
+///
+/// @brief Updates an MRS to have the desired Qoff value
+/// @param[in,out] io_mrs - the MRS to update
+/// @param[in] i_state - the state for the qoff in the MRS
+///
+void update_mrs(mss::ddr4::mrs01_data& io_mrs, const mss::states i_state)
+{
+ io_mrs.iv_qoff = i_state;
+ io_mrs.iv_wl_enable = i_state;
+}
+
+///
+/// @brief Adds in an MRS on a per-rank basis based upon qoff
+/// @param[in] i_target - the target on which to operate
+/// @param[in] i_rank - the rank on which to operate
+/// @param[in] i_state - the state of qoff
+/// @param[in,out] io_inst the instruction to fixup
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode add_mrs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rank,
+ const mss::states& i_state,
+ std::vector<ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>>& io_inst)
+{
+ // First, get the DIMM target
+ // Note: the target is setup below based upon the rank
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm(0);
+ FAPI_TRY( mss::rank::get_dimm_target_from_rank(i_target, i_rank, l_dimm) );
+
+ // Updates and adds in the MRS information
+ {
+ // Get the MRS data
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ mss::ddr4::mrs01_data l_mrs(l_dimm, l_rc);
+ FAPI_TRY( l_rc, "%s failed to create MRS for rank %lu", mss::c_str(l_dimm), i_rank);
+
+ // Update the MRS data for qoff
+ update_mrs(l_mrs, i_state);
+
+ // Add the MRS data to the ccs instructions
+ FAPI_TRY( mrs_engine(l_dimm, l_mrs, i_rank, mss::tmod(i_target), io_inst) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Gets a vector of ranks that are not going to be calibrated in the given rank pair
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[out] o_ranks - the vector of ranks that are not being calibrated
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode get_non_calibrating_ranks(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ std::vector<uint64_t>& o_ranks)
+{
+ o_ranks.clear();
+ std::vector<uint64_t> l_pairs;
+
+ // Get our rank pairs
+ FAPI_TRY( mss::rank::get_rank_pairs(i_target, l_pairs) );
+
+ // Loops through all of the rank pairs
+ for(const auto l_rp : l_pairs)
+ {
+ // If this is our current rank pair, add in all non-primary ranks
+ if(l_rp == i_rp)
+ {
+ FAPI_TRY( add_non_primary_ranks(i_target, l_rp, o_ranks) );
+ }
+ else
+ {
+ FAPI_TRY( add_ranks_from_pair(i_target, l_rp, o_ranks) );
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Adds the non-primary ranks from a rank pair to a ranks vector
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[in,out] io_ranks - the vector of ranks that are not being calibrated
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode add_non_primary_ranks(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ std::vector<uint64_t>& io_ranks)
+{
+ std::vector<uint64_t> l_ranks_in_pair;
+ FAPI_TRY( mss::rank::get_ranks_in_pair(i_target, i_rp, l_ranks_in_pair) );
+
+ // Loops through the ranks and adds them as need be
+ {
+ // Primary rank is first, so we skip that one
+ const auto l_begin = l_ranks_in_pair.begin() + 1;
+ const auto l_end = l_ranks_in_pair.end();
+
+ // Loops through the ranks
+ for(auto l_it = l_begin; l_it < l_end; ++l_it)
+ {
+ const auto l_rank = *l_it;
+ add_rank_to_vector(l_rank, io_ranks);
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Adds all ranks from a rank pair to a ranks vector
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[in,out] io_ranks - the vector of ranks that are not being calibrated
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode add_ranks_from_pair(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ std::vector<uint64_t>& io_ranks)
+{
+ std::vector<uint64_t> l_ranks_in_pair;
+ FAPI_TRY( mss::rank::get_ranks_in_pair(i_target, i_rp, l_ranks_in_pair) );
+
+ // Loops through the ranks
+ for(const auto l_rank : l_ranks_in_pair)
+ {
+ add_rank_to_vector(l_rank, io_ranks);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Adds a rank to the ranks vector if it is valid
+/// @param[in] i_rank - the rank to add to the vector
+/// @param[in,out] io_ranks - the vector of ranks that are not being calibrated
+///
+void add_rank_to_vector(const uint64_t i_rank, std::vector<uint64_t>& io_ranks)
+{
+ if(i_rank != mss::NO_RANK)
+ {
+ io_ranks.push_back(i_rank);
+ }
+}
+
+///
+/// @brief Enables or disables the DQ outputs on all non-calibrating ranks
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[in] i_state - the state of qoff
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode configure_non_calibrating_ranks(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const mss::states& i_state)
+{
+ // Declares variables
+ mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
+ std::vector<uint64_t> l_ranks;
+ const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
+
+ // Gets the ranks to configure
+ FAPI_TRY( get_non_calibrating_ranks(i_target, i_rp, l_ranks) );
+
+ // Adds in the MRS instructions to configure qoff
+ for(const auto l_rank : l_ranks)
+ {
+ FAPI_TRY( add_mrs(i_target, l_rank, i_state, l_program.iv_instructions) );
+ }
+
+ // Executes the CCS instructions
+ FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns wr_lvl
+
} // ns workarounds
} // ns ccs
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H
index c39187b37..ded4f9891 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,6 +42,7 @@
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/ccs/ccs.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
namespace mss
{
@@ -76,6 +77,82 @@ fapi2::ReturnCode exit( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
fapi2::ReturnCode enable_pda_shadow_reg( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rank );
+namespace wr_lvl
+{
+
+///
+/// @brief Updates an MRS to have the desired Qoff value
+/// @param[in,out] io_mrs - the MRS to update
+/// @param[in] i_state - the state for the qoff in the MRS
+///
+void update_mrs(mss::ddr4::mrs01_data& io_mrs, const mss::states i_state);
+
+///
+/// @brief Adds in an MRS on a per-rank basis based upon qoff
+/// @param[in] i_target - the target on which to operate
+/// @param[in] i_rank - the rank on which to operate
+/// @param[in] i_state - the state of qoff
+/// @param[in,out] io_inst the instruction to fixup
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode add_mrs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rank,
+ const mss::states& i_state,
+ std::vector<ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>>& io_inst);
+
+///
+/// @brief Gets a vector of ranks that are not going to be calibrated in the given rank pair
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[out] o_ranks - the vector of ranks that are not being calibrated
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode get_non_calibrating_ranks(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ std::vector<uint64_t>& o_ranks);
+
+///
+/// @brief Adds the non-primary ranks from a rank pair to a ranks vector
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[in,out] io_ranks - the vector of ranks that are not being calibrated
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode add_non_primary_ranks(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ std::vector<uint64_t>& io_ranks);
+
+///
+/// @brief Adds all ranks from a rank pair to a ranks vector
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[in,out] io_ranks - the vector of ranks that are not being calibrated
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode add_ranks_from_pair(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ std::vector<uint64_t>& io_ranks);
+
+///
+/// @brief Adds a rank to the ranks vector if it is valid
+/// @param[in] i_rank - the rank to add to the vector
+/// @param[in,out] io_ranks - the vector of ranks that are not being calibrated
+///
+void add_rank_to_vector(const uint64_t i_rank, std::vector<uint64_t>& io_ranks);
+
+///
+/// @brief Enables or disables the DQ outputs on all non-calibrating ranks
+/// @param[in] i_target - the MCA target on which to oparate
+/// @param[in] i_rp - the rank pair that is currently being calibrated
+/// @param[in] i_state - the state of qoff
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode configure_non_calibrating_ranks(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const mss::states& i_state);
+
+} // ns wr_lvl
+
} // ns workarounds
} // ns ccs
OpenPOWER on IntegriCloud