summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2017-10-03 14:03:46 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-11-10 10:57:07 -0500
commit0f5f2625adad6e82f56abe7a5a4db0930dcb4f93 (patch)
tree822376a7992817ea8e50a06a2ebb12595f50af4b /src/import/chips/p9/procedures/hwp/memory
parentc0d7d47a554fb9187b0411ca6eca47a40e6daf84 (diff)
downloadtalos-hostboot-0f5f2625adad6e82f56abe7a5a4db0930dcb4f93.tar.gz
talos-hostboot-0f5f2625adad6e82f56abe7a5a4db0930dcb4f93.zip
Updates dramint training structure
Creates a class to contain workaround and cal steps to execute Change-Id: Ife1a3a451dbc92b46eec15131a6ad3f68968c1f7 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/47092 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/47096 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: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H216
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C384
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H53
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C722
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H677
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H15
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C13
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.C9
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/wr_vref_workarounds.H6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C20
20 files changed, 1526 insertions, 615 deletions
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 e901055e8..1f52142f7 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
@@ -41,218 +41,28 @@
#include <lib/eff_config/timing.H>
#include <lib/utils/poll.H>
#include <lib/phy/read_cntrl.H>
+#include <lib/phy/mss_training.H>
namespace mss
{
///
-/// @brief Return the cycles taken for write leveling on a single rank
-/// @tparam T the target type used to get attributes
-/// @param[in] i_target used to get attributes
-/// @return uint64_t, the cycles taken for write leveling on a single rank
-///
-template<fapi2::TargetType T>
-uint64_t wr_lvl_cycles(const fapi2::Target<T>& i_target )
-{
- const uint64_t TWLO_TWLOE = mss::twlo_twloe(i_target);
-
- // This step runs for approximately (80 + TWLO_TWLOE) x NUM_VALID_SAMPLES x (384/(BIG_STEP + 1) +
- // (2 x (BIG_STEP + 1))/(SMALL_STEP + 1)) + 20 memory clock cycles per rank.
-
- const uint64_t l_wr_lvl_cycles = (80 + TWLO_TWLOE) * WR_LVL_NUM_VALID_SAMPLES * (384 / (WR_LVL_BIG_STEP + 1) +
- (2 * (WR_LVL_BIG_STEP + 1)) / (WR_LVL_SMALL_STEP + 1)) + 20;
- FAPI_DBG("%s wr_lvl_cycles: %llu(%lluns) (%llu, %llu, %llu, %llu)",
- mss::c_str(i_target),
- l_wr_lvl_cycles,
- mss::cycles_to_ns(i_target,
- l_wr_lvl_cycles),
- TWLO_TWLOE, WR_LVL_NUM_VALID_SAMPLES, WR_LVL_BIG_STEP, WR_LVL_SMALL_STEP);
-
- return l_wr_lvl_cycles;
-}
-
-///
-/// @brief Return the cycles taken for DQS align on a single rank
-/// @tparam T the target type used to get attributes
-/// @param[in] i_target used to get attributes
-/// @return uint64_t, the cycles taken for DQS align on a single rank
-///
-template<fapi2::TargetType T>
-uint64_t dqs_align_cycles(const fapi2::Target<T>& i_target )
-{
- // This step runs for approximately 6 x 600 x 4 DRAM clocks per rank pair.
- const uint64_t l_dqs_align_cycles = 6 * 600 * 4;
-
- FAPI_DBG("%s dqs_align_cycles: %llu(%lluns)", mss::c_str(i_target), l_dqs_align_cycles, mss::cycles_to_ns(i_target,
- l_dqs_align_cycles));
- return l_dqs_align_cycles;
-}
-
-///
-/// @brief Return the cycles taken for RD clock align on a single rank
-/// @tparam T the target type used to get attributes
-/// @param[in] i_target used to get attributes
-/// @return uint64_t, the cycles taken for RD clock align on a single rank
-///
-template<fapi2::TargetType T>
-uint64_t rdclk_align_cycles(const fapi2::Target<T>& i_target )
-{
- // This step runs for approximately 24 x ((1024/COARSE_CAL_STEP_SIZE + 4 x COARSE_CAL_STEP_SIZE) x 4 + 32) DRAM
- // clocks per rank pair
- const uint64_t l_rdclk_align_cycles = 24 * ((1024 / COARSE_CAL_STEP_SIZE + 4 * COARSE_CAL_STEP_SIZE) * 4 + 32);
- FAPI_DBG("%s rdclk_align_cycles: %llu(%lluns) (%llu)", mss::c_str(i_target), l_rdclk_align_cycles,
- mss::cycles_to_ns(i_target, l_rdclk_align_cycles), COARSE_CAL_STEP_SIZE);
- return l_rdclk_align_cycles;
-}
-
-///
-/// @brief Return the cycles taken for read centering on a single rank
-/// @tparam T the target type used to get attributes
-/// @param[in] i_target used to get attributes
-/// @return uint64_t, the cycles taken for read centering on a single rank
-///
-template<fapi2::TargetType T>
-uint64_t read_ctr_cycles(const fapi2::Target<T>& i_target )
-{
- // This step runs for approximately 6 x (512/COARSE_CAL_STEP_SIZE + 4 x (COARSE_CAL_STEP_SIZE +
- // 4 x CONSEQ_PASS)) x 24 DRAM clocks per rank pair.
-
- const uint64_t l_read_ctr_cycles = 6 * (512 / COARSE_CAL_STEP_SIZE + 4 * (COARSE_CAL_STEP_SIZE + 4 * CONSEQ_PASS)) * 24;
- FAPI_DBG("%s read_ctr_cycles %llu(%lluns) (%llu, %llu)",
- mss::c_str(i_target),
- l_read_ctr_cycles,
- mss::cycles_to_ns(i_target, l_read_ctr_cycles),
- COARSE_CAL_STEP_SIZE,
- CONSEQ_PASS);
- return l_read_ctr_cycles;
-}
-
-///
-/// @brief Return the cycles taken for write centering on a single rank
-/// @tparam T the target type used to get attributes
-/// @param[in] i_target used to get attributes
-/// @param[out] o_cycles the cycles taken for write centering on a single rank
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template<fapi2::TargetType T>
-fapi2::ReturnCode write_ctr_cycles(const fapi2::Target<T>& i_target, uint64_t& o_cycles)
-{
- // 1000 + (NUM_VALID_SAMPLES * (FW_WR_RD + FW_RD_WR + 16) *
- // (1024/(SMALL_STEP +1) + 128/(BIG_STEP +1)) + 2 * (BIG_STEP+1)/(SMALL_STEP+1)) x 24 DRAM
- // clocks per rank pair.
- constexpr uint64_t WR_CNTR_FW_WR_RD = mss::fw_wr_rd();
- uint8_t l_fw_rd_wr = 0;
-
- FAPI_TRY( mss::fw_rd_wr(i_target, l_fw_rd_wr) );
-
- o_cycles = 1000 + (WR_LVL_NUM_VALID_SAMPLES * (WR_CNTR_FW_WR_RD + l_fw_rd_wr + 16) *
- (1024 / (WR_LVL_SMALL_STEP + 1) + 128 / (WR_LVL_BIG_STEP + 1)) + 2 *
- (WR_LVL_BIG_STEP + 1) / (WR_LVL_SMALL_STEP + 1)) * 24;
-
- FAPI_DBG("%s write_ctr_cycles: %lu(%luns) (%u, %u, %u, %u, %u)",
- mss::c_str(i_target),
- o_cycles,
- mss::cycles_to_ns(i_target, o_cycles),
- WR_LVL_NUM_VALID_SAMPLES,
- WR_CNTR_FW_WR_RD,
- l_fw_rd_wr,
- WR_LVL_BIG_STEP,
- WR_LVL_SMALL_STEP);
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return the cycles taken for coarse write on a single rank
-/// @tparam T the target type used to get attributes
-/// @param[in] i_target used to get attributes
-/// @return uint64_t, the cycles taken for coarse write on a single rank
-///
-template<fapi2::TargetType T>
-uint64_t coarse_wr_cycles(const fapi2::Target<T>& i_target )
-{
- // The run length given here is the maximum run length for this calibration algorithm.
- // This step runs for approximately 40 DRAM clocks per rank pair.
- static const uint64_t l_coarse_wr_cycles = 40;
- FAPI_DBG("%s coarse_wr_cycles: %llu(%lluns)",
- mss::c_str(i_target),
- l_coarse_wr_cycles,
- mss::cycles_to_ns(i_target, l_coarse_wr_cycles));
- return l_coarse_wr_cycles;
-}
-
-///
-/// @brief Return the cycles taken for coarse read on a single rank
-/// @tparam T the target type used to get attributes
-/// @param[in] i_target used to get attributes
-/// @return uint64_t, the cycles taken for coarse rd on a single rank
-///
-template<fapi2::TargetType T>
-uint64_t coarse_rd_cycles(const fapi2::Target<T>& i_target )
-{
- // The run length given here is the maximum run length for this calibration algorithm.
- // This step runs for approximately 32 DRAM clocks per rank pair.
- static const uint64_t l_coarse_rd_cycles = 32;
- FAPI_DBG("%s coarse_rd_cycles: %llu(%lluns)",
- mss::c_str(i_target),
- l_coarse_rd_cycles,
- mss::cycles_to_ns(i_target, l_coarse_rd_cycles));
- return l_coarse_rd_cycles;
-}
-
-///
/// @brief Configure the polling intervals with the proper timeings based on the cal steps enabled
/// @tparam T the fapi2::TargetType of the port
/// @param[in] i_target the port target
+/// @param[in] i_total_cycles the number of cycles a cal step takes
/// @param[in,out] io_poll the poll_parameters to update
-/// @param[in] i_cal_steps_enabled a fapi2::buffer<uint8_t> representing the cal steps enabled
/// @return FAPI2_RC_SUCCESS iff everything is OK
///
template<fapi2::TargetType T>
inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
- poll_parameters& io_poll,
- const fapi2::buffer<uint32_t>& i_cal_steps_enabled)
+ const uint64_t i_total_cycles,
+ poll_parameters& io_poll)
{
// This should equal half of the minimum poll count of the quickest cal segment when in sim
// i.e. DQS_ALIGN + INITIAL_PAT_WR = 3 polls, so this should be 2
constexpr uint64_t MINIMUM_POLL_COUNT = 2;
- uint64_t l_write_cntr_cycles = 0;
- uint64_t l_total_cycles = 0;
- int64_t l_ns_left = 0;
- uint8_t cal_abort_on_error = 0;
- uint16_t l_vref_cal_enable = 0;
-
- FAPI_TRY( mss::write_ctr_cycles(i_target, l_write_cntr_cycles), "%s Failed calling write_ctr_cycles",
- mss::c_str(i_target) );
- FAPI_TRY( mss::cal_abort_on_error(cal_abort_on_error), "%s Failed calling cal_abort_on_errorp", mss::c_str(i_target) );
- FAPI_TRY( mss::rdvref_cal_enable(i_target, l_vref_cal_enable), "%s Failed calling rdvref_cal_enable",
- mss::c_str(i_target) );
-
- // First, calculate the total number of cycles this cal should take if everything
- // runs to completion
- l_total_cycles = i_cal_steps_enabled.getBit<WR_LEVEL>() ? wr_lvl_cycles(i_target) : 0;
- l_total_cycles += i_cal_steps_enabled.getBit<DQS_ALIGN>() ? dqs_align_cycles(i_target) : 0;
- l_total_cycles += i_cal_steps_enabled.getBit<RDCLK_ALIGN>() ? rdclk_align_cycles(i_target) : 0;
-
- // We run either read centering during normal draminit_training and also during draminit_training_advance,
- // can't be run twice in one cal though
- l_total_cycles += ( i_cal_steps_enabled.getBit<READ_CTR>() || i_cal_steps_enabled.getBit<TRAINING_ADV>())
- ? read_ctr_cycles(i_target) : 0;
- l_total_cycles += i_cal_steps_enabled.getBit<WRITE_CTR>() ? l_write_cntr_cycles : 0;
- l_total_cycles += i_cal_steps_enabled.getBit<COARSE_WR>() ? coarse_wr_cycles(i_target) : 0;
- l_total_cycles += i_cal_steps_enabled.getBit<COARSE_RD>() ? coarse_rd_cycles(i_target) : 0;
- l_total_cycles += ((l_vref_cal_enable != 0)
- && i_cal_steps_enabled.getBit<READ_CTR_2D_VREF>()) ? rc::vref_guess_time(i_target) : 0;
-
- // Now we have to decide if we're going to abort on an error or keep going. If we keep going,
- // then we want our initial delay to be the expected time to completion - we don't have much
- // of a choice. If we abort on error then we want to have a small initial delay, and poll more
- // times with longer durations between the polling.
-
// Sometimes when running in sim, particularly Mesa, it is helpful to not delay a bunch
// when training starts - makes it simpler to get an AET for, say, write leveling. So
// this is here to allow the simple removal of the initial delay for those situations.
@@ -261,18 +71,18 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
io_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(1);
#else
// We don't want to wait too long for the initial check, just some hueristics here
- io_poll.iv_initial_delay = mss::cycles_to_ns(i_target, l_total_cycles / 8);
- io_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(l_total_cycles / 8);
+ io_poll.iv_initial_delay = mss::cycles_to_ns(i_target, i_total_cycles / 8);
+ io_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(i_total_cycles / 8);
#endif
// Delay 10us between polls, and setup the poll count so
- // iv_initial_delay + (iv_delay * iv_poll_count) == l_total_cycles + some fudge;
+ // iv_initial_delay + (iv_delay * iv_poll_count) == i_total_cycles + some fudge;
io_poll.iv_delay = DELAY_10US;
io_poll.iv_sim_delay = mss::cycles_to_simcycles(mss::ns_to_cycles(i_target, io_poll.iv_delay));
// Round up to the cycles left after the initial delay
- l_ns_left = std::max(int64_t(0), (int64_t(mss::cycles_to_ns(i_target,
- l_total_cycles)) - int64_t(io_poll.iv_initial_delay)));
+ const uint64_t l_ns_left = std::max(int64_t(0), (int64_t(mss::cycles_to_ns(i_target,
+ i_total_cycles)) - int64_t(io_poll.iv_initial_delay)));
io_poll.iv_poll_count = l_ns_left / io_poll.iv_delay;
io_poll.iv_poll_count += l_ns_left % io_poll.iv_delay ? 0 : 1;
@@ -285,10 +95,9 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
// HB is failing, bump it out 4x for the polling
io_poll.iv_poll_count *= 4;
- FAPI_INF("%s cal abort on error? %s. tc: %luc, id: %luns(%lusc), d: %lu(%lusc), pc: %lu",
+ FAPI_INF("%s tc: %luc, id: %luns(%lusc), d: %lu(%lusc), pc: %lu",
mss::c_str(i_target),
- (cal_abort_on_error ? "yup" : "nope"),
- l_total_cycles,
+ i_total_cycles,
io_poll.iv_initial_delay,
io_poll.iv_initial_sim_delay,
io_poll.iv_delay,
@@ -296,9 +105,6 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
io_poll.iv_poll_count);
return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
}
}
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 45e36dd95..da960bac9 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
@@ -38,6 +38,7 @@
#include <fapi2.H>
#include <mss.H>
+#include <lib/mss_attribute_accessors.H>
#include <lib/phy/ddr_phy.H>
#include <lib/phy/read_cntrl.H>
@@ -52,6 +53,7 @@
#include <lib/dimm/ddr4/latch_wr_vref.H>
#include <lib/workarounds/seq_workarounds.H>
#include <lib/workarounds/dqs_align_workarounds.H>
+#include <lib/phy/mss_training.H>
#include <lib/utils/bit_count.H>
#include <generic/memory/lib/utils/find.H>
@@ -937,11 +939,13 @@ fapi_try_exit:
///
/// @brief Write the READ_VREF register to enable and or to skip the read centering cal
/// @param[in] i_target the MCA target associated with this cal setup
-/// @param[in] i_cal_steps_enabled fapi2::buffer<uint8_t> representing the cal steps to enable
+/// @param[in] i_rd_ctr - run RD CTR if set to true
+/// @param[in] i_rd_vref - run RD VREF is set to true
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
fapi2::ReturnCode setup_read_vref_config1( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const fapi2::buffer<uint32_t>& i_cal_steps_enabled)
+ const bool i_rd_ctr,
+ const bool i_rd_vref)
{
fapi2::buffer<uint64_t> l_data;
typedef rcTraits<fapi2::TARGET_TYPE_MCA> TT;
@@ -951,16 +955,15 @@ fapi2::ReturnCode setup_read_vref_config1( const fapi2::Target<fapi2::TARGET_TYP
FAPI_TRY( mss::rc::read_vref_config1(i_target, l_data), "%s Failed read_vref_config1", mss::c_str(i_target) );
// Enable is based off of the RDVREF attribute
- l_data.writeBit<TT::RDVREF_CALIBRATION_ENABLE>( i_cal_steps_enabled.getBit<READ_CTR_2D_VREF>() );
+ l_data.writeBit<TT::RDVREF_CALIBRATION_ENABLE>( i_rd_vref );
// Check to see if READ_CENTERING is disabled, if so, set the bit
- l_data.writeBit<TT::SKIP_RDCENTERING>( !(i_cal_steps_enabled.getBit<READ_CTR>()
- || i_cal_steps_enabled.getBit<TRAINING_ADV>()) );
+ l_data.writeBit<TT::SKIP_RDCENTERING>( !i_rd_ctr );
FAPI_INF("%s %s read VREF cal, read centering is %s",
mss::c_str(i_target),
- i_cal_steps_enabled.getBit<READ_CTR_2D_VREF>() ? "Enabling" : "Disabling",
- i_cal_steps_enabled.getBit<READ_CTR>() ? "yup" : "nope");
+ i_rd_vref ? "Enabling" : "Disabling",
+ i_rd_ctr ? "yup" : "nope");
FAPI_TRY( mss::rc::write_vref_config1(i_target, l_data), "%s Failed write_vref_config1", mss::c_str(i_target) );
fapi_try_exit:
@@ -969,199 +972,61 @@ fapi_try_exit:
///
/// @brief Setup all the cal config register
-/// @param[in] i_target the MCA 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<uint8_t> representing the cal steps to enable
+/// @param[in] i_target the target associated with this cal setup
+/// @param[in] i_rank_pair the rank pair to calibrate
+/// @param[in] i_cal_config the calibration config register
+/// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-template<>
fapi2::ReturnCode setup_cal_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<uint64_t>& i_rank_pairs,
- const fapi2::buffer<uint32_t>& i_cal_steps_enabled)
+ const uint64_t i_rank_pair,
+ const fapi2::buffer<uint64_t>& i_cal_config,
+ const uint8_t i_abort_on_error)
{
- fapi2::buffer<uint64_t> l_cal_config;
- uint8_t l_sim = 0;
- uint8_t l_cal_abort_on_error = 0;
-
- 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
-
-
- // 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 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>());
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_DQS_ALIGN>(
- i_cal_steps_enabled.getBit<DQS_ALIGN>());
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_RDCLK_ALIGN>(
- i_cal_steps_enabled.getBit<RDCLK_ALIGN>());
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_READ_CTR>(
- i_cal_steps_enabled.getBit<READ_CTR>() || i_cal_steps_enabled.getBit<READ_CTR_2D_VREF>());
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_WRITE_CTR>(
- i_cal_steps_enabled.getBit<WRITE_CTR>() || i_cal_steps_enabled.getBit<WRITE_CTR_2D_VREF>());
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_INITIAL_COARSE_WR>(
- i_cal_steps_enabled.getBit<COARSE_WR>());
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_COARSE_RD>(
- i_cal_steps_enabled.getBit<COARSE_RD>());
-
- // Turn on initial pattern write only in h/w, never for sim (makes the DIMM behavioral lose it's mind)
- if (!l_sim)
- {
- // If we are running training advance, none of the steps above can be enabled.
- // If they are, we have a code bug and should fapi2:Assert.
- // This isn't dependent on system or attributes but code structure
- if ( l_cal_config != 0 && i_cal_steps_enabled.getBit<TRAINING_ADV>())
- {
- FAPI_ERR("Error setting up draminit training advance. Set CUSTOM_RD with other cal steps");
- fapi2::Assert( false );
- }
-
- // Enable CUSTOM_RD for training ADV. If this bit is set, only TRAINING_ADV and INIT_PAT_WR can be set
- // We assert this above.
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_CUSTOM_RD>(
- i_cal_steps_enabled.getBit<TRAINING_ADV>());
-
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_INITIAL_PAT_WR>(
- i_cal_steps_enabled.getBit<INITIAL_PAT_WR>());
- }
-
- // Moved this down here so we can make the training advance check above
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ABORT_ON_ERROR>(l_cal_abort_on_error);
- }
-
- // Blast the VREF config with the proper setting for these cal bits if there were any enable bits set
- if (i_cal_steps_enabled.getBit<READ_CTR_2D_VREF>())
- {
- uint16_t l_vref_cal_enable = 0;
-
- // Blast the VREF_CAL_ENABLE to the registers that control which dp16's to use for rdvref
- FAPI_TRY( mss::rdvref_cal_enable(i_target, l_vref_cal_enable) );
- FAPI_TRY( mss::scom_blastah(i_target, dp16Traits<TARGET_TYPE_MCA>::RD_VREF_CAL_ENABLE_REG, l_vref_cal_enable) );
- }
-
- // Now lets set the actual read_vref_config. We want to write/ clear this every time we run so seperate function
- FAPI_TRY( setup_read_vref_config1(i_target, i_cal_steps_enabled),
- "%s Failed setting the read_vref_config1", mss::c_str(i_target) );
-
- {
- typedef mss::dp16Traits<fapi2::TARGET_TYPE_MCA> TT;
- std::vector<fapi2::buffer<uint64_t>> l_wr_vref_config;
- FAPI_TRY( mss::scom_suckah(i_target, TT::WR_VREF_CONFIG0_REG, l_wr_vref_config) );
-
- // Loops and sets or clears the 2D VREF bit on all DPs
- for(auto& l_data : l_wr_vref_config)
- {
- // 0: Run only the VREF (2D) write centering algorithm
- // 1: Run only the 1D
- l_data.writeBit<TT::WR_VREF_CONFIG0_1D_ONLY_SWITCH>(!i_cal_steps_enabled.getBit<WRITE_CTR_2D_VREF>());
- }
-
- FAPI_TRY(mss::scom_blastah(i_target, TT::WR_VREF_CONFIG0_REG, l_wr_vref_config));
- }
+ auto l_cal_config = i_cal_config;
- // loops through all RP's running workarounds and latching the VREF's as need be
- for(const auto& l_rp : i_rank_pairs)
- {
- // Latches in the WR VREF values
- // Overrides will be set by mss::workarounds::wr_vref::execute.
- // If the execute code is skipped, then it will read from the attributes
- uint8_t l_vrefdq_train_range_override = mss::ddr4::USE_DEFAULT_WR_VREF_SETTINGS;
- uint8_t l_vrefdq_train_value_override = mss::ddr4::USE_DEFAULT_WR_VREF_SETTINGS;
-
- // Runs WR VREF workarounds if needed
- // it will check and see if it needs to run, if not it will return success
- FAPI_TRY( mss::workarounds::wr_vref::execute(i_target,
- l_rp,
- i_cal_steps_enabled,
- 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) );
- }
- }
+ // Sets up abort on error
+ l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ABORT_ON_ERROR>(i_abort_on_error);
// Note: This rank encoding isn't used if the cal is initiated from the CCS engine
- // as they use the recal inteface.
+ // as they use the recal interface.
// Configure the rank pairs
- for (const auto& rp : i_rank_pairs)
- {
- FAPI_TRY( 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 + i_rank_pair) );
- FAPI_INF("cal_config for %s: 0x%04lx (steps: 0x%08x)",
- mss::c_str(i_target), uint16_t(l_cal_config), i_cal_steps_enabled);
+ FAPI_INF("cal_config for %s: 0x%016lx", mss::c_str(i_target), l_cal_config);
FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0, l_cal_config) );
- // Sets up the workarounds
- FAPI_TRY( mss::workarounds::dp16::rd_vref_vref_sense_setup(i_target) );
-
fapi_try_exit:
return fapi2::current_err;
}
///
-/// @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
-/// @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<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);
-}
-
-///
/// @brief Execute a set of PHY cal steps
-/// Specializaton for TARGET_TYPE_MCA
-/// @param[in] i_target the target associated with this cal
+/// @param[in] i_target the target associated with this cal - MCA specialization
/// @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_config fapi2::buffer representing the calibration configuration register
/// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override
+/// @param[in] i_total_cycles how long the calibration will take in cycles
/// @return FAPI2_RC_SUCCESS iff setup was successful
/// @note This is a helper function. Library users are required to call setup_and_execute_cal
///
-template<>
-fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+template< >
+fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
- const fapi2::buffer<uint32_t>& i_cal_steps_enabled,
- const uint8_t i_abort_on_error)
+ const fapi2::buffer<uint64_t>& i_cal_config,
+ const uint8_t i_abort_on_error,
+ const uint64_t i_total_cycles)
{
const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
auto l_cal_inst = mss::ccs::initial_cal_command<TARGET_TYPE_MCBIST>(i_rp);
mss::ccs::program<TARGET_TYPE_MCBIST, TARGET_TYPE_MCA> l_program;
- // Sanity check due to WR_LEVEL termination requirement
- if ((i_cal_steps_enabled.getBit<mss::cal_steps::WR_LEVEL>()) &&
- (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 (0x%08llx)",
- i_cal_steps_enabled );
-
- fapi2::Assert(false);
- }
-
- FAPI_DBG("%s executing training CCS instruction: 0x%llx, 0x%llx for cal steps 0x%08x",
+ FAPI_DBG("%s executing training CCS instruction: 0x%016llx, 0x%016llx for cal config 0x%16x",
mss::c_str(i_target),
l_cal_inst.arr0,
l_cal_inst.arr1,
- i_cal_steps_enabled);
+ i_cal_config);
// Delays in the CCS instruction ARR1 for training are supposed to be 0xFFFF,
// and we're supposed to poll for the done or timeout bit. But we don't want
@@ -1176,196 +1041,23 @@ fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<fapi2::TARGET_TY
// We need to figure out how long to wait before we start polling. Each cal step has an expected
// duration, so for each cal step which was enabled, we update the CCS program.
- FAPI_TRY( mss::cal_timer_setup(i_target, l_program.iv_poll, i_cal_steps_enabled) );
- FAPI_TRY( mss::setup_cal_config(i_target, i_rp, i_cal_steps_enabled) );
+ FAPI_TRY( mss::cal_timer_setup(i_target, i_total_cycles, l_program.iv_poll) );
+ FAPI_TRY( mss::setup_cal_config( i_target, i_rp, i_cal_config, i_abort_on_error) );
- // In the event of an init cal hang, CCS_STATQ(2) will assert and CCS_STATQ(3:5) = “001” to indicate a
+ // In the event of an init cal hang, CCS_STATQ(2) will assert and CCS_STATQ(3:5) = "001" to indicate a
// timeout. Otherwise, if calibration completes, FW should inspect DDRPHY_FIR_REG bits (50) and (58)
// for signs of a calibration error. If either bit is on, then the DDRPHY_PC_INIT_CAL_ERROR register
// should be polled to determine which calibration step failed.
// If we got a cal timeout, or another CCS error just leave now. If we got success, check the error
// bits for a cal failure. We'll return the proper ReturnCode so all we need to do is FAPI_TRY.
- FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target), "%s failed to execute CCS program for cal steps 0x%08x",
- mss::c_str(i_target), i_cal_steps_enabled );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Perform necessary termination setup and execute a set of PHY cal steps
-/// 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_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<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 WR_LEVEL step (with overridden termination values) if selected
- if (i_cal_steps_enabled.getBit<mss::cal_steps::WR_LEVEL>())
- {
- mss::ccs::program<TARGET_TYPE_MCBIST, TARGET_TYPE_MCA> l_program;
- 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<uint32_t> l_steps_to_execute;
- l_steps_to_execute.setBit<mss::cal_steps::WR_LEVEL>();
-
- // Setup WR_LEVEL specific terminations
- // JEDEC spec requires disabling RTT_WR during WR_LEVEL, and enabling equivalent terminations
- FAPI_TRY( setup_wr_level_terminations(i_target, i_rp, l_rtt_inst) );
-
- if (!l_rtt_inst.empty())
- {
- l_program.iv_instructions.insert(l_program.iv_instructions.end(), l_rtt_inst.begin(), l_rtt_inst.end() );
- FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
- l_program.iv_instructions.clear();
- }
-
- // Execute WR_LEVEL
- FAPI_TRY( execute_cal_steps_helper(i_target,
- i_rp,
- l_steps_to_execute,
- i_abort_on_error) );
-
- // Restore normal terminations
- l_rtt_inst.clear();
- FAPI_TRY( restore_mainline_terminations(i_target, i_rp, l_rtt_inst) );
-
- if (!l_rtt_inst.empty())
- {
- l_program.iv_instructions.insert(l_program.iv_instructions.end(),
- l_rtt_inst.begin(),
- l_rtt_inst.end() );
- FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
- }
- }
-
- // run Initial Pattern Write and custom read centering if enabled
- if(i_cal_steps_enabled.getBit<mss::cal_steps::INITIAL_PAT_WR>())
- {
- // Sets up the cal steps in the buffer
- fapi2::buffer<uint32_t> l_steps_to_execute;
- l_steps_to_execute.writeBit<mss::cal_steps::INITIAL_PAT_WR>
- (i_cal_steps_enabled.getBit<mss::cal_steps::INITIAL_PAT_WR>());
- l_steps_to_execute.writeBit<mss::cal_steps::TRAINING_ADV>
- (i_cal_steps_enabled.getBit<mss::cal_steps::TRAINING_ADV>());
-
- FAPI_INF("%s Running Initial Pattern Write and TRAINING_ADV(%s) on RP%d 0x%08x",
- mss::c_str(i_target),
- (i_cal_steps_enabled.getBit<mss::cal_steps::TRAINING_ADV>() ? "yes" : "no"),
- 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) );
- }
-
- // Lets run DQS
- if(i_cal_steps_enabled.getBit<mss::cal_steps::DQS_ALIGN>())
- {
- // Sets up the cal steps in the buffer
- fapi2::buffer<uint32_t> l_steps_to_execute;
- l_steps_to_execute.setBit<mss::cal_steps::DQS_ALIGN>();
-
- FAPI_INF("%s Running DQS align on RP%d 0x%08x",
- 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) );
-
- // Now run the DQS align workaround
- FAPI_TRY(mss::workarounds::dp16::dqs_align::dqs_align_workaround(i_target, i_rp, i_abort_on_error),
- "%s Failed to run dqs align workaround on rp %d", mss::c_str(i_target), i_rp);
- }
-
- // Run cal step READ CLOCK ALIGN
- if (i_cal_steps_enabled.getBit<mss::cal_steps::RDCLK_ALIGN>())
- {
- // Turn off refresh
- FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
-
- // Sets up the cal steps in the buffer
- fapi2::buffer<uint32_t> l_steps_to_execute;
-
- l_steps_to_execute.setBit<mss::cal_steps::RDCLK_ALIGN>();
-
- FAPI_INF("%s Running rd_clk align on RP%d 0x%08x", 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) );
-
- // Run the red_waterfall workaround for low VDN sensitivity
- // Increments the waterfall forward by one
- FAPI_TRY( mss::workarounds::dp16::fix_red_waterfall_gate( i_target, i_rp) );
-
- // Turn refresh back on
- FAPI_TRY( mss::workarounds::dqs_align::turn_on_refresh(i_target) );
- }
-
- if(i_cal_steps_enabled.getBit<mss::cal_steps::READ_CTR_2D_VREF, mss::cal_steps::READ_VREF_TO_READ_CTR_LEN>())
- {
- // Turn off refresh
- FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
-
- // Sets up the cal steps in the buffer
- fapi2::buffer<uint32_t> l_steps_to_execute;
-
- l_steps_to_execute.writeBit<mss::cal_steps::READ_CTR_2D_VREF>
- (i_cal_steps_enabled.getBit<mss::cal_steps::READ_CTR_2D_VREF>());
- l_steps_to_execute.writeBit<mss::cal_steps::READ_CTR>(i_cal_steps_enabled.getBit<mss::cal_steps::READ_CTR>());
-
- FAPI_INF("%s Running read centering vref through read centering on RP%d 0x%08x", 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) );
-
- // Now run the read centering workaround
- if(l_steps_to_execute.getBit<READ_CTR>())
- {
- FAPI_TRY(mss::workarounds::dp16::rd_dq::fix_delay_values(i_target, i_rp),
- "%s Failed to run read centering workaround on rp %d", mss::c_str(i_target), i_rp);
- }
-
- // Turn refresh back on
- FAPI_TRY( mss::workarounds::dqs_align::turn_on_refresh(i_target) );
- }
-
- // 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_2D_VREF, mss::cal_steps::WR_VREF_TO_COARSE_RD_LEN>())
- {
- fapi2::buffer<uint32_t> l_steps_to_execute( i_cal_steps_enabled );
- l_steps_to_execute.clearBit<mss::cal_steps::DRAM_ZQCAL, mss::cal_steps::DRAM_ZQCAL_UP_TO_WRITE_CTR_2D_VREF>();
-
- // Setting the WR_VREF_LATCH bit to run the WR_VREF workaround after wr_vref runs
- // Gets set iff the bit is set in i_steps_to_execute
- l_steps_to_execute.writeBit<WR_VREF_LATCH>( i_cal_steps_enabled.getBit<WR_VREF_LATCH>() );
-
- FAPI_DBG("%s Running remaining cal steps on RP%d 0x%08x", mss::c_str(i_target), i_rp, l_steps_to_execute);
-
- FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) );
- }
+ FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target), "%s failed to execute CCS program for calibration",
+ mss::c_str(i_target) );
fapi_try_exit:
return fapi2::current_err;
}
-
// TODO RTC:167929 Can ODT VPD processing be shared between RD and WR?
///
/// @brief Setup odt_rd_config
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 37f763846..d56af96cd 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
@@ -37,7 +37,6 @@
#define _MSS_DDR_PHY_H_
#include <fapi2.H>
-#include <lib/mss_attribute_accessors.H>
#include <lib/ccs/ccs.H>
namespace mss
@@ -107,11 +106,13 @@ fapi2::ReturnCode check_bang_bang_lock( const fapi2::Target<fapi2::TARGET_TYPE_M
///
/// @brief Write the READ_VREF register to enable and or to skip the read centering cal
/// @param[in] i_target the MCA target associated with this cal setup
-/// @param[in] i_cal_steps_enabled fapi2::buffer<uint8_t> representing the cal steps to enable
+/// @param[in] i_rd_ctr - run RD CTR if set to true
+/// @param[in] i_rd_vref - run RD VREF is set to true
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
fapi2::ReturnCode setup_read_vref_config1( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const fapi2::buffer<uint32_t>& i_cal_steps_enabled);
+ const bool i_rd_ctr,
+ const bool i_rd_vref);
///
/// @brief Configure the DP16 sysclk
@@ -140,58 +141,34 @@ fapi2::ReturnCode clear_initial_cal_errors( const fapi2::Target<T>& i_target );
///
/// @brief Setup all the cal config register
-/// @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<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<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 representing the cal steps to enable
+/// @param[in] i_rank_pair the rank pair to calibrate
+/// @param[in] i_cal_config the calibration config register
+/// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override
/// @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<uint32_t>& i_cal_steps_enabled);
+ const uint64_t i_rank_pair,
+ const fapi2::buffer<uint64_t>& i_cal_config,
+ const uint8_t i_abort_on_error);
///
/// @brief Execute a set of PHY cal steps
/// @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_config fapi2::buffer representing the calibration configuration register
/// @param[in] i_abort_on_error CAL_ABORT_ON_ERROR override
+/// @param[in] i_total_cycles how long the calibration will take in cycles
/// @return FAPI2_RC_SUCCESS iff setup was successful
/// @note This is a helper function. Library users are required to call setup_and_execute_cal
///
template< fapi2::TargetType T >
fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<T>& i_target,
const uint64_t i_rp,
- const fapi2::buffer<uint32_t>& i_cal_steps_enabled,
- const uint8_t i_abort_on_error);
-
-///
-/// @brief Perform necessary termination setup and execute a set of PHY cal steps
-/// @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_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<uint32_t>& i_cal_steps_enabled,
- const uint8_t i_abort_on_error);
+ const fapi2::buffer<uint64_t>& i_cal_config,
+ const uint8_t i_abort_on_error,
+ const uint64_t i_total_cycles);
// TODO RTC:167929 Can ODT VPD processing be shared between RD and WR?
// TODO RTC:157753 tparams P and R can be pulled from an MCA trait once we have it
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 4c191f105..9c7060c26 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
@@ -22,3 +22,725 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file workarounds/mss_training_workarounds.C
+/// @brief High level workarounds for training
+/// Workarounds are very device specific, so there is no attempt to generalize
+/// this code in any way.
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <vector>
+#include <initializer_list>
+
+#include <fapi2.H>
+#include <mss.H>
+#include <lib/phy/ddr_phy.H>
+#include <lib/phy/mss_training.H>
+
+#include <lib/workarounds/dp16_workarounds.H>
+#include <lib/workarounds/wr_vref_workarounds.H>
+#include <lib/dimm/ddr4/latch_wr_vref.H>
+#include <lib/workarounds/seq_workarounds.H>
+#include <lib/workarounds/dqs_align_workarounds.H>
+
+#include <generic/memory/lib/utils/scom.H>
+#include <lib/utils/count_dimm.H>
+#include <lib/dimm/rank.H>
+#include <lib/shared/mss_const.H>
+
+namespace mss
+{
+
+namespace training
+{
+
+///
+/// @brief Executes a cal step with workarounds
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode step::execute( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ // First, pre-workaround
+ FAPI_TRY(pre_workaround(i_target, i_rp, i_abort_on_error));
+
+ // Second, setup/run
+ FAPI_TRY(run(i_target, i_rp, i_abort_on_error));
+
+ // Finally, post workaround
+ FAPI_TRY(post_workaround(i_target, i_rp, i_abort_on_error));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Executes the pre-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode wr_vref_latch::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ FAPI_INF("%s RP%d WR VREF latch workaround", mss::c_str(i_target), i_rp);
+
+ // DD1 chip bugs require the WR VREF workarounds below
+ // This DD1 chip bug might override the VREF values, as such
+ // Runs WR VREF workarounds if needed
+ // it will check and see if it needs to run, if not it will return success
+ // Overrides will be set by mss::workarounds::wr_vref::execute.
+ // If the execute code is skipped, then it will read from the attributes
+ FAPI_TRY( mss::workarounds::wr_vref::execute(i_target,
+ i_rp,
+ iv_wr_vref,
+ iv_vrefdq_train_range_override,
+ iv_vrefdq_train_value_override) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets up and runs the calibration step
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode wr_vref_latch::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ // Latches the WR VREF's on this rank pair, if required
+ // Note: the VREF latching should be done before write centering
+ // The latching is not a workaround (but is required by JEDEC), so we do not execute it in the workarounds steps
+ // It's not a training step per-se but is part of the setup and is included in the cal step enable
+ FAPI_INF("%s RP%d latching WR VREF values below", mss::c_str(i_target), i_rp);
+
+ // Latches the VREF's
+ FAPI_TRY( mss::ddr4::latch_wr_vref_commands_by_rank_pair(i_target,
+ i_rp,
+ iv_vrefdq_train_range_override,
+ iv_vrefdq_train_value_override) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t wr_vref_latch::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // The latch code figures out it's own cycles, so just return 1
+ return 1;
+}
+
+///
+/// @brief Sets up and runs the calibration step
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode phy_step::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ // Execute this cal step
+ FAPI_INF("%s RP%d running cal step '%s'", mss::c_str(i_target), i_rp, get_name());
+ FAPI_TRY(mss::execute_cal_steps_helper( i_target,
+ i_rp,
+ iv_init_cal_config,
+ i_abort_on_error,
+ calculate_cycles(i_target)));
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Executes the pre-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode wr_lvl::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> > l_rtt_inst;
+
+ FAPI_DBG("%s Running Pre-WR_LEVEL workaround steps on RP%d", mss::c_str(i_target), i_rp);
+ // Setup WR_LEVEL specific terminations
+ // JEDEC spec requires disabling RTT_WR during WR_LEVEL, and enabling equivalent terminations
+ FAPI_TRY( setup_wr_level_terminations(i_target, i_rp, l_rtt_inst) );
+
+ if (!l_rtt_inst.empty())
+ {
+ const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
+ mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
+ l_program.iv_instructions.insert(l_program.iv_instructions.end(), l_rtt_inst.begin(), l_rtt_inst.end() );
+ FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
+ l_program.iv_instructions.clear();
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t wr_lvl::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ const uint64_t TWLO_TWLOE = mss::twlo_twloe(i_target);
+
+ // This step runs for approximately (80 + TWLO_TWLOE) x NUM_VALID_SAMPLES x (384/(BIG_STEP + 1) +
+ // (2 x (BIG_STEP + 1))/(SMALL_STEP + 1)) + 20 memory clock cycles per rank.
+
+ const uint64_t l_wr_lvl_cycles = (80 + TWLO_TWLOE) * WR_LVL_NUM_VALID_SAMPLES * (384 / (WR_LVL_BIG_STEP + 1) +
+ (2 * (WR_LVL_BIG_STEP + 1)) / (WR_LVL_SMALL_STEP + 1)) + 20;
+ FAPI_DBG("%s wr_lvl_cycles: %llu(%lluns) (%llu, %llu, %llu, %llu)",
+ mss::c_str(i_target),
+ l_wr_lvl_cycles,
+ mss::cycles_to_ns(i_target,
+ l_wr_lvl_cycles),
+ TWLO_TWLOE, WR_LVL_NUM_VALID_SAMPLES, WR_LVL_BIG_STEP, WR_LVL_SMALL_STEP);
+
+ return l_wr_lvl_cycles;
+}
+
+///
+/// @brief Executes the post-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode wr_lvl::post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> > l_rtt_inst;
+
+ FAPI_DBG("%s Running Post-WR_LEVEL workaround steps on RP%d", mss::c_str(i_target), i_rp);
+
+ FAPI_TRY( restore_mainline_terminations(i_target, i_rp, l_rtt_inst) );
+
+ if (!l_rtt_inst.empty())
+ {
+ const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
+ mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
+ l_program.iv_instructions.insert(l_program.iv_instructions.end(),
+ l_rtt_inst.begin(),
+ l_rtt_inst.end() );
+ FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t initial_pattern_write::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // Not sure how long this should take, so we're gonna use 1 to make sure we get at least one polling loop
+ return 1;
+}
+
+///
+/// @brief Executes the post-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode dqs_align::post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+
+ FAPI_DBG("%s Running Post-DQS_ALIGN workaround steps on RP%d", mss::c_str(i_target), i_rp);
+
+ FAPI_TRY(mss::workarounds::dp16::dqs_align::dqs_align_workaround(i_target, i_rp, i_abort_on_error),
+ "%s Failed to run dqs align workaround on rp %d", mss::c_str(i_target), i_rp);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t dqs_align::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // This step runs for approximately 6 x 600 x 4 DRAM clocks per rank pair.
+ const uint64_t l_dqs_align_cycles = 6 * 600 * 4;
+
+ FAPI_DBG("%s dqs_align_cycles: %llu(%lluns)", mss::c_str(i_target), l_dqs_align_cycles, mss::cycles_to_ns(i_target,
+ l_dqs_align_cycles));
+ return l_dqs_align_cycles;
+}
+
+///
+/// @brief Executes the pre-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode rdclk_align::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ FAPI_DBG("%s Running Pre-RDCLK_ALIGN workaround steps on RP%d", mss::c_str(i_target), i_rp);
+ // Turn off refresh
+ FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Executes the post-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode rdclk_align::post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ FAPI_DBG("%s Running Post-RDCLK_ALIGN workaround steps on RP%d", mss::c_str(i_target), i_rp);
+
+ // Run the red_waterfall workaround for low VDN sensitivity
+ // Increments the waterfall forward by one
+ FAPI_TRY( mss::workarounds::dp16::fix_red_waterfall_gate( i_target, i_rp) );
+
+ // Turn refresh back on
+ FAPI_TRY( mss::workarounds::dqs_align::turn_on_refresh(i_target) );
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t rdclk_align::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // This step runs for approximately 24 x ((1024/COARSE_CAL_STEP_SIZE + 4 x COARSE_CAL_STEP_SIZE) x 4 + 32) DRAM
+ // clocks per rank pair
+ const uint64_t l_rdclk_align_cycles = 24 * ((1024 / COARSE_CAL_STEP_SIZE + 4 * COARSE_CAL_STEP_SIZE) * 4 + 32);
+ FAPI_DBG("%s rdclk_align_cycles: %llu(%lluns) (%llu)", mss::c_str(i_target), l_rdclk_align_cycles,
+ mss::cycles_to_ns(i_target, l_rdclk_align_cycles), COARSE_CAL_STEP_SIZE);
+ return l_rdclk_align_cycles;
+}
+
+///
+/// @brief Executes the pre-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode read_ctr::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ FAPI_DBG("%s Running Pre-RD_CTR workaround steps on RP%d", mss::c_str(i_target), i_rp);
+ // Turn off refresh
+ FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
+
+ // Sets up the RD VREF sense workaround
+ FAPI_TRY( mss::workarounds::dp16::rd_vref_vref_sense_setup(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Sets up and runs the calibration step
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode read_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ // Blast the VREF config with the proper setting for these cal bits if there were any enable bits set
+ if (iv_rd_vref)
+ {
+ uint16_t l_vref_cal_enable = 0;
+
+ // Blast the VREF_CAL_ENABLE to the registers that control which dp16's to use for rdvref
+ FAPI_TRY( mss::rdvref_cal_enable(i_target, l_vref_cal_enable) );
+ FAPI_TRY( mss::scom_blastah(i_target, dp16Traits<fapi2::TARGET_TYPE_MCA>::RD_VREF_CAL_ENABLE_REG, l_vref_cal_enable) );
+ }
+
+ // Now lets set the actual read_vref_config. We want to write/ clear this every time we run so seperate function
+ FAPI_TRY( setup_read_vref_config1(i_target, iv_rd_ctr, iv_rd_vref),
+ "%s Failed setting the read_vref_config1", mss::c_str(i_target) );
+
+ // Now run the actual calibration
+ FAPI_TRY(phy_step::run(i_target, i_rp, i_abort_on_error));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Executes the post-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode read_ctr::post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ FAPI_DBG("%s Running Post-RD_CTR workaround steps on RP%d", mss::c_str(i_target), i_rp);
+
+ // Now run the read centering workaround
+ if(iv_rd_ctr)
+ {
+ FAPI_TRY(mss::workarounds::dp16::rd_dq::fix_delay_values(i_target, i_rp),
+ "%s Failed to run read centering workaround on rp %d", mss::c_str(i_target), i_rp);
+ }
+
+ // Turn refresh back on
+ FAPI_TRY( mss::workarounds::dqs_align::turn_on_refresh(i_target) );
+
+ // Sets up the RD VREF sense workaround
+ FAPI_TRY( mss::workarounds::dp16::rd_vref_vref_sense_cleanup( i_target ) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t read_ctr::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // This step runs for approximately 6 x (512/COARSE_CAL_STEP_SIZE + 4 x (COARSE_CAL_STEP_SIZE +
+ // 4 x CONSEQ_PASS)) x 24 DRAM clocks per rank pair.
+
+ const uint64_t l_read_ctr_cycles = 6 * (512 / COARSE_CAL_STEP_SIZE + 4 * (COARSE_CAL_STEP_SIZE + 4 * CONSEQ_PASS)) * 24;
+ FAPI_DBG("%s read_ctr_cycles %llu(%lluns) (%llu, %llu)",
+ mss::c_str(i_target),
+ l_read_ctr_cycles,
+ mss::cycles_to_ns(i_target, l_read_ctr_cycles),
+ COARSE_CAL_STEP_SIZE,
+ CONSEQ_PASS);
+
+ // This calibration step could take up to read centering + RD VREF time, so let's just output that to make the math simpler
+ return l_read_ctr_cycles + rc::vref_guess_time(i_target);
+}
+
+
+///
+/// @brief Sets up and runs the calibration step
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode write_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ typedef mss::dp16Traits<fapi2::TARGET_TYPE_MCA> TT;
+ std::vector<fapi2::buffer<uint64_t>> l_wr_vref_config;
+ FAPI_TRY( mss::scom_suckah(i_target, TT::WR_VREF_CONFIG0_REG, l_wr_vref_config) );
+
+ // Loops and sets or clears the 2D VREF bit on all DPs
+ for(auto& l_data : l_wr_vref_config)
+ {
+ // 0: Run only the VREF (2D) write centering algorithm
+ // 1: Run only the 1D
+ l_data.writeBit<TT::WR_VREF_CONFIG0_1D_ONLY_SWITCH>(!iv_wr_vref);
+ }
+
+ FAPI_TRY(mss::scom_blastah(i_target, TT::WR_VREF_CONFIG0_REG, l_wr_vref_config));
+
+ FAPI_TRY(phy_step::run(i_target, i_rp, i_abort_on_error));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t write_ctr::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // 1000 + (NUM_VALID_SAMPLES * (FW_WR_RD + FW_RD_WR + 16) *
+ // (1024/(SMALL_STEP +1) + 128/(BIG_STEP +1)) + 2 * (BIG_STEP+1)/(SMALL_STEP+1)) x 24 DRAM
+ // clocks per rank pair.
+ constexpr uint64_t WR_CNTR_FW_WR_RD = mss::fw_wr_rd();
+ uint8_t l_fw_rd_wr = 0;
+ uint64_t l_cycles = 1;
+
+ FAPI_TRY( mss::fw_rd_wr(i_target, l_fw_rd_wr) );
+
+ l_cycles = 1000 + (WR_LVL_NUM_VALID_SAMPLES * (WR_CNTR_FW_WR_RD + l_fw_rd_wr + 16) *
+ (1024 / (WR_LVL_SMALL_STEP + 1) + 128 / (WR_LVL_BIG_STEP + 1)) + 2 *
+ (WR_LVL_BIG_STEP + 1) / (WR_LVL_SMALL_STEP + 1)) * 24;
+
+ FAPI_DBG("%s write_ctr_cycles: %lu(%luns) (%u, %u, %u, %u, %u)",
+ mss::c_str(i_target),
+ l_cycles,
+ mss::cycles_to_ns(i_target, l_cycles),
+ WR_LVL_NUM_VALID_SAMPLES,
+ WR_CNTR_FW_WR_RD,
+ l_fw_rd_wr,
+ WR_LVL_BIG_STEP,
+ WR_LVL_SMALL_STEP);
+
+ return l_cycles;
+
+fapi_try_exit:
+ // We had an error, let's exit
+ FAPI_ERR("%s had an error and is going to exit", mss::c_str(i_target));
+ fapi2::Assert(false);
+
+ // Error case, the return is to make the compiler happy
+ return l_cycles;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t coarse_wr_rd::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // The run length given here is the maximum run length for this calibration algorithm.
+ // This step runs for approximately 40 DRAM clocks per rank pair.
+ constexpr uint64_t COARSE_WR_CYCLES = 40;
+
+ // The run length given here is the maximum run length for this calibration algorithm.
+ // This step runs for approximately 32 DRAM clocks per rank pair.
+ constexpr uint64_t COARSE_RD_CYCLES = 32;
+
+ // Total coarse cycles
+ constexpr uint64_t COARSE_WR_RD_CYCLES = COARSE_WR_CYCLES + COARSE_RD_CYCLES;
+
+ FAPI_DBG("%s coarse_wr_cycles: %llu(%lluns) coarse_rd_cycles %llu(%lluns) coarse wr/rd cycles %llu(%lluns)",
+ mss::c_str(i_target),
+ COARSE_WR_CYCLES,
+ mss::cycles_to_ns(i_target, COARSE_WR_CYCLES),
+ COARSE_RD_CYCLES,
+ mss::cycles_to_ns(i_target, COARSE_RD_CYCLES),
+ COARSE_WR_RD_CYCLES,
+ mss::cycles_to_ns(i_target, COARSE_WR_RD_CYCLES));
+ return COARSE_WR_RD_CYCLES;
+}
+
+///
+/// @brief Executes the pre-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode custom_read_ctr::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ FAPI_DBG("%s Running Pre-Custom RD CTR workaround steps on RP%d", mss::c_str(i_target), i_rp);
+ // Turn off refresh
+ FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Executes a cal step with workarounds
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode custom_read_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ constexpr bool RUN_RD_CTR = true;
+ constexpr bool SKIP_RD_VREF = false;
+ // Now lets set the actual read_vref_config. We want to write/ clear this every time we run so seperate function
+ FAPI_TRY( setup_read_vref_config1(i_target, RUN_RD_CTR, SKIP_RD_VREF),
+ "%s Failed setting the read_vref_config1", mss::c_str(i_target) );
+
+ FAPI_TRY(phy_step::run(i_target, i_rp, i_abort_on_error));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Executes the post-cal step workaround
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode custom_read_ctr::post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ FAPI_DBG("%s Running Post-Custom RD CTR workaround steps on RP%d", mss::c_str(i_target), i_rp);
+ // Turn refresh back on
+ FAPI_TRY( mss::workarounds::dqs_align::turn_on_refresh(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the number of cycles a given calibration step will take
+/// @param[in] i_target - the MCA target on which to operate
+/// @return l_cycles - the number of cycles a given calibration step wil take
+///
+uint64_t custom_read_ctr::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const
+{
+ // This step runs for approximately 6 x (512/COARSE_CAL_STEP_SIZE + 4 x (COARSE_CAL_STEP_SIZE +
+ // 4 x CONSEQ_PASS)) x 24 DRAM clocks per rank pair.
+
+ const uint64_t l_read_ctr_cycles = 6 * (512 / COARSE_CAL_STEP_SIZE + 4 * (COARSE_CAL_STEP_SIZE + 4 * CONSEQ_PASS)) * 24;
+ FAPI_DBG("%s read_ctr_cycles %llu(%lluns) (%llu, %llu)",
+ mss::c_str(i_target),
+ l_read_ctr_cycles,
+ mss::cycles_to_ns(i_target, l_read_ctr_cycles),
+ COARSE_CAL_STEP_SIZE,
+ CONSEQ_PASS);
+
+ // This calibration step could take up to read centering + RD VREF time, so let's just output that to make the math simpler
+ return l_read_ctr_cycles;
+}
+
+///
+/// @brief Creates the vector of training steps to loop over
+/// @param[in] i_cal_steps - the bit mask of calibration steps
+/// @return a vector of the calibration steps to run
+///
+std::vector<std::shared_ptr<step>> steps_factory(const fapi2::buffer<uint32_t>& i_cal_steps)
+{
+ std::vector<std::shared_ptr<step>> l_steps;
+
+ // WR LVL
+ 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>());
+ }
+
+ // INITIAL_PAT_WR
+ if(i_cal_steps.getBit<mss::cal_steps::INITIAL_PAT_WR>())
+ {
+ FAPI_INF("Initial pattern write is enabled");
+ l_steps.push_back(std::make_shared<initial_pattern_write>());
+ }
+
+ // DQS_ALIGN
+ if(i_cal_steps.getBit<mss::cal_steps::DQS_ALIGN>())
+ {
+ FAPI_INF("DQS align is enabled");
+ l_steps.push_back(std::make_shared<dqs_align>());
+ }
+
+ // RDCLK_ALIGN
+ if(i_cal_steps.getBit<mss::cal_steps::RDCLK_ALIGN>())
+ {
+ FAPI_INF("RDCLK align is enabled");
+ l_steps.push_back(std::make_shared<rdclk_align>());
+ }
+
+ // READ_CTR_2D_VREF or READ_CTR
+ const bool RD_VREF = i_cal_steps.getBit<mss::cal_steps::READ_CTR_2D_VREF>();
+ const bool RD_CTR = i_cal_steps.getBit<mss::cal_steps::READ_CTR>();
+
+ if(RD_VREF || RD_CTR)
+ {
+ FAPI_INF("Read centering %s enabled read VREF %s enabled",
+ RD_CTR ? "is" : "isn't",
+ RD_VREF ? "is" : "isn't");
+ l_steps.push_back(std::make_shared<read_ctr>(RD_VREF, RD_CTR));
+ }
+
+ // WR_VREF_LATCH additionally WRITE_CTR_2D_VREF is needed
+ const bool WR_LATCH = i_cal_steps.getBit<mss::cal_steps::WR_VREF_LATCH>();
+ const bool WR_VREF = i_cal_steps.getBit<mss::cal_steps::WRITE_CTR_2D_VREF>();
+ const bool WRITE_CTR = i_cal_steps.getBit<mss::cal_steps::WRITE_CTR>();
+
+ if(WR_LATCH)
+ {
+ FAPI_INF("Write VREF latching is enabled %s WR VREF",
+ WR_VREF ? "with" : "without");
+
+ l_steps.push_back(std::make_shared<wr_vref_latch>( WR_VREF ));
+ }
+
+
+ // WRITE_CTR_2D_VREF or WRITE_CTR
+ if(WR_VREF || WRITE_CTR)
+ {
+ FAPI_INF("Write centering is enabled %s WR VREF",
+ WR_VREF ? "with" : "without");
+
+ l_steps.push_back(std::make_shared<write_ctr>( WR_VREF ));
+ }
+
+ // COARSE WR/RD
+ if(i_cal_steps.getBit<mss::cal_steps::COARSE_WR>() || i_cal_steps.getBit<mss::cal_steps::COARSE_RD>())
+ {
+ FAPI_INF("Coarse WR/RD is enabled");
+ l_steps.push_back(std::make_shared<coarse_wr_rd>());
+ }
+
+ // Training Advanced - aka custom pattern RD CTR
+ if(i_cal_steps.getBit<mss::cal_steps::TRAINING_ADV>())
+ {
+ FAPI_INF("Custom RD_CTR is enabled");
+ l_steps.push_back(std::make_shared<custom_read_ctr>());
+ }
+
+ return l_steps;
+}
+
+} // ns training
+
+} // ns mss
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 ba82528db..24ebc0e71 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
@@ -22,3 +22,680 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file workarounds/mss_training_workarounds.H
+/// @brief High level workarounds for training
+/// Workarounds are very device specific, so there is no attempt to generalize
+/// this code in any way.
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef MSS_WORKAROUNDS_TRAINING_H
+#define MSS_WORKAROUNDS_TRAINING_H
+
+#include <fapi2.H>
+#include <lib/eff_config/timing.H>
+#include <lib/phy/read_cntrl.H>
+#include <lib/dimm/ddr4/latch_wr_vref.H>
+
+namespace mss
+{
+
+namespace training
+{
+
+///
+/// @brief Training step class - contains all information to run a calibration step
+/// @note step is an abstract class
+///
+class step
+{
+ public:
+ // Delete base constructor
+ step() = delete;
+
+ ///
+ /// @brief Default virtual destructor
+ ///
+ virtual ~step() = default;
+
+ ///
+ /// @brief Constructor for step class
+ /// @param[in] i_name - calibration step name
+ ///
+ step( const char* i_name) :
+ iv_name(i_name)
+ {}
+
+ ///
+ /// @brief Executes the pre-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ virtual fapi2::ReturnCode pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+ {
+ FAPI_INF("%s RP%d cal step '%s' has no pre-cal step workaround.", mss::c_str(i_target), i_rp, iv_name);
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Sets up and runs the calibration step
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ virtual fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const = 0;
+
+ ///
+ /// @brief Executes the post-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ virtual fapi2::ReturnCode post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+ {
+ FAPI_INF("%s RP%d cal step '%s' has no post-cal step workaround.", mss::c_str(i_target), i_rp, iv_name);
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Executes a cal step with workarounds
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode execute( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @return l_cycles - the number of cycles a given calibration step wil take
+ ///
+ virtual uint64_t calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const = 0;
+
+ ///
+ /// @brief Gets the name of this calibration step
+ /// @return name of this calibration step
+ ///
+ const char* get_name() const
+ {
+ return iv_name;
+ }
+
+ private:
+ // Contains the human readable name for this calibration step
+ const char* iv_name;
+};
+
+///
+/// @brief Latches the WR VREF data into the hardware
+///
+class wr_vref_latch : public step
+{
+ public:
+ // Delete base constructor
+ wr_vref_latch() = delete;
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~wr_vref_latch() override = default;
+
+ ///
+ /// @brief Constructor for step class
+ /// @param[in] i_wr_vref - true if WR VREF will be run during the calibration
+ ///
+ wr_vref_latch( const bool i_wr_vref ) :
+ step("WR_VREF_LATCH"),
+ iv_wr_vref(i_wr_vref),
+ iv_vrefdq_train_range_override(mss::ddr4::USE_DEFAULT_WR_VREF_SETTINGS),
+ iv_vrefdq_train_value_override(mss::ddr4::USE_DEFAULT_WR_VREF_SETTINGS)
+ {}
+
+ ///
+ /// @brief Executes the pre-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Sets up and runs the calibration step
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+
+ ///
+ /// @brief Getter for WR VREF
+ /// @return bool iv_wr_vref
+ ///
+ bool get_wr_vref() const
+ {
+ return iv_wr_vref;
+ }
+
+ ///
+ /// @brief Getter for WR VREF
+ /// @return uint64_t iv_vrefdq_train_range_override
+ ///
+ uint64_t get_vrefdq_range() const
+ {
+ return iv_vrefdq_train_range_override;
+ }
+
+ ///
+ /// @brief Getter for WR VREF
+ /// @return uint64_t iv_vrefdq_train_value_override
+ ///
+ uint64_t get_vrefdq_value() const
+ {
+ return iv_vrefdq_train_value_override;
+ }
+
+ private:
+ // Notes whether the WR VREF calibration workaround needs to be run or not
+ bool iv_wr_vref;
+
+ // WR VREF values to latch
+ // Note: these are mutable as they might need to be modified for a workaround related to Nimbus DD1 WR VREF HW calibration
+ mutable uint8_t iv_vrefdq_train_range_override;
+ mutable uint8_t iv_vrefdq_train_value_override;
+};
+
+///
+/// @brief A PHY hardware accelerated calibration step
+/// @note phy_step is an abstract class
+///
+class phy_step : public step
+{
+ public:
+ // Delete base constructor
+ phy_step() = delete;
+
+ ///
+ /// @brief Default destructor
+ ///
+ virtual ~phy_step() = default;
+
+ ///
+ /// @brief Constructor for step class
+ /// @param[in] i_init_cal_config - calibration step name
+ /// @param[in] i_name - calibration step name
+ ///
+ phy_step( const fapi2::buffer<uint64_t> i_init_cal_config, const char* i_name) :
+ step(i_name),
+ iv_init_cal_config(i_init_cal_config)
+ {}
+
+ ///
+ /// @brief Sets up and runs the calibration step
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ virtual fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @return l_cycles - the number of cycles a given calibration step wil take
+ ///
+ virtual uint64_t calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const = 0;
+
+ ///
+ /// @brief Gets the init cal config register's starting
+ /// @return fapi2::buffer<uint64_t> iv_init_cal_config - init cal config's starting value
+ ///
+ const fapi2::buffer<uint64_t> get_init_cal_config() const
+ {
+ return iv_init_cal_config;
+ }
+
+ private:
+ // Contains all of the base information for the init cal configuration register
+ fapi2::buffer<uint64_t> iv_init_cal_config;
+};
+
+///
+/// @brief Write leveling calibration step class
+///
+class wr_lvl : public phy_step
+{
+ public:
+ ///
+ /// @brief Base constructor
+ ///
+ wr_lvl() :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_WR_LEVEL>(), "WR_LVL")
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~wr_lvl() override = default;
+
+ ///
+ /// @brief Executes the pre-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Executes the post-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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;
+};
+
+///
+/// @brief Initial pattern write
+///
+class initial_pattern_write : public phy_step
+{
+ public:
+ ///
+ /// @brief Base constructor
+ ///
+ initial_pattern_write() :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_INITIAL_PAT_WR>(),
+ "INITIAL_PATTERN_WRITE")
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~initial_pattern_write() override = default;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+};
+
+///
+/// @brief DQS align
+///
+class dqs_align : public phy_step
+{
+ public:
+ ///
+ /// @brief Base constructor
+ ///
+ dqs_align() :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_DQS_ALIGN>(),
+ "DQS_ALIGN")
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~dqs_align() override = default;
+
+ ///
+ /// @brief Executes the post-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+};
+
+///
+/// @brief Read clock align
+///
+class rdclk_align : public phy_step
+{
+ public:
+ ///
+ /// @brief Base constructor
+ ///
+ rdclk_align() :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_RDCLK_ALIGN>(),
+ "RDCLK_ALIGN")
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~rdclk_align() override = default;
+
+ ///
+ /// @brief Executes the pre-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Executes the post-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+};
+
+///
+/// @brief Read centering (and potentially RD VREF)
+///
+class read_ctr : public phy_step
+{
+ public:
+ // No default constructor
+ read_ctr() = delete;
+
+ ///
+ /// @brief Base constructor
+ /// @param[in] i_rd_vref - true IFF RD VREF is enabled
+ /// @param[in] i_rd_ctr - true IFF RD CTR is enabled
+ ///
+ read_ctr(const bool i_rd_vref, const bool i_rd_ctr) :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_READ_CTR>(),
+ "READ_CTR"),
+ iv_rd_vref(i_rd_vref),
+ iv_rd_ctr(i_rd_ctr)
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~read_ctr() override = default;
+
+ ///
+ /// @brief Executes the pre-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Sets up and runs the calibration step
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Executes the post-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+
+ ///
+ /// @brief Getter for RD VREF
+ /// @return bool iv_rd_vref
+ ///
+ bool get_rd_vref() const
+ {
+ return iv_rd_vref;
+ }
+
+ ///
+ /// @brief Getter for RD centering
+ /// @return bool iv_rd_ctr
+ ///
+ bool get_rd_ctr() const
+ {
+ return iv_rd_ctr;
+ }
+
+ private:
+ bool iv_rd_vref;
+ bool iv_rd_ctr;
+};
+
+///
+/// @brief Write centering (and potentially WR VREF)
+///
+class write_ctr : public phy_step
+{
+ public:
+ // No default constructor
+ write_ctr() = delete;
+
+ ///
+ /// @brief Base constructor
+ /// @param[in] i_wr_vref - true IFF WR VREF is enabled
+ ///
+ write_ctr(const bool i_wr_vref) :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_WRITE_CTR>(),
+ "write_ctr"),
+ iv_wr_vref(i_wr_vref)
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~write_ctr() override = default;
+
+ ///
+ /// @brief Sets up and runs the calibration step
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+
+ ///
+ /// @brief Getter for WR VREF
+ /// @return bool iv_wr_vref
+ ///
+ bool get_wr_vref() const
+ {
+ return iv_wr_vref;
+ }
+
+ private:
+ bool iv_wr_vref;
+};
+
+///
+/// @brief Coarse WR/RD calibration
+///
+class coarse_wr_rd : public phy_step
+{
+ public:
+ ///
+ /// @brief Base constructor
+ ///
+ static constexpr uint64_t COARSE_WR_RD_LEN = 2;
+ coarse_wr_rd() :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_INITIAL_COARSE_WR, COARSE_WR_RD_LEN>(),
+ "COARSE_WR/RD")
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~coarse_wr_rd() override = default;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+};
+
+///
+/// @brief Custom read centering - can include initial pattern write
+///
+class custom_read_ctr : public phy_step
+{
+ public:
+ ///
+ /// @brief Base constructor
+ ///
+ custom_read_ctr() :
+ phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_CUSTOM_RD>(),
+ "CUSTOM_READ_CTR")
+ {}
+
+ ///
+ /// @brief Default destructor
+ ///
+ ~custom_read_ctr() override = default;
+
+ ///
+ /// @brief Sets up and runs the calibration step
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Executes the pre-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Executes the post-cal step workaround
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @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 override;
+};
+
+///
+/// @brief Creates the vector of training steps to loop over
+/// @param[in] i_cal_steps - the bit mask of calibration steps
+/// @return a vector of the calibration steps to run
+///
+std::vector<std::shared_ptr<step>> steps_factory(const fapi2::buffer<uint32_t>& i_cal_steps);
+
+} // ns training
+
+} // ns mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H
index 797588274..9f71d1655 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H
@@ -283,6 +283,21 @@ inline void set_trfc_cycles( fapi2::buffer<uint64_t>& io_data, const uint64_t i_
}
///
+/// @brief Get SEQ_MEM_TIMING_PARAM0_TRFC_CYCLES
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to seqTraits<T>
+/// @param[in] i_data the value of the register
+/// @param[out] o_value value representing trfc value in cycles
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = seqTraits<T> >
+inline void get_trfc_cycles( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::TRFC_CYCLES, TT::TRFC_CYCLES_LEN>(o_value);
+ FAPI_DBG("seq_timing0 trfc_cycles: 0x%llx", o_value);
+}
+
+///
/// @brief Read SEQ_MEM_TIMING_PARAM1
/// @tparam T fapi2 Target Type - derived
/// @tparam TT traits type defaults to seqTraits<T>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
index 7e2f52ae9..4b877b47f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
@@ -26,7 +26,7 @@
///
/// @file workarounds/adr32s_workarounds.C
/// @brief Workarounds for the ADR32s logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.H
index 713a9505f..a4e02cafe 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.H
@@ -26,7 +26,7 @@
///
/// @file workarounds/adr32s_workarounds.H
/// @brief Workarounds for the ADR32s logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
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 98e6a4479..1ed664574 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
@@ -26,7 +26,7 @@
///
/// @file workarounds/dp16.C
/// @brief Workarounds for the DP16 logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
@@ -45,6 +45,7 @@
#include <lib/phy/dp16.H>
#include <lib/phy/ddr_phy.H>
#include <lib/phy/phy_cntrl.H>
+#include <lib/phy/mss_training.H>
#include <lib/dimm/rank.H>
#include <lib/utils/bit_count.H>
#include <lib/fir/check.H>
@@ -190,7 +191,6 @@ fapi2::ReturnCode post_training_workarounds( const fapi2::Target<fapi2::TARGET_T
i_cal_steps_enabled.getBit<mss::cal_steps::COARSE_WR>())
{
FAPI_TRY( mss::workarounds::dp16::modify_calibration_results( i_target ) );
- FAPI_TRY( mss::workarounds::dp16::rd_vref_vref_sense_cleanup( i_target ) );
}
// Returns success, as we might not have run these workarounds, depending upon cal step enable
@@ -555,6 +555,9 @@ fapi2::ReturnCode dqs_align_workaround(const fapi2::Target<fapi2::TARGET_TYPE_MC
// Boolean to keep track of if a fail was calibration related, or scom related
bool l_cal_fail = false;
+ // Create a DQS align calibration step, as it might need to be used in the loop below
+ const auto l_dqs_align_step = mss::training::dqs_align();
+
FAPI_TRY( eff_dram_width( i_target, l_dram_width) );
l_is_x8 = ((l_dram_width[0] == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ||
@@ -590,11 +593,7 @@ fapi2::ReturnCode dqs_align_workaround(const fapi2::Target<fapi2::TARGET_TYPE_MC
FAPI_TRY(mss::workarounds::dp16::dqs_align::reset_disables(i_target, i_rp));
// Hit calibration one more time
- {
- 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));
- }
+ FAPI_TRY(l_dqs_align_step.execute(i_target, i_rp, i_abort_on_error));
// Get the current passing states
// We override any states that were passing previously and are still passing
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 586d5419d..fd5cdb7e6 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
@@ -26,7 +26,7 @@
///
/// @file workarounds/dp16.H
/// @brief Workarounds for the DP16 logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C
index 3a1c039a4..27202d57a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C
@@ -26,7 +26,7 @@
///
/// @file workarounds/mca_workarounds.C
/// @brief Workarounds for the MCA logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.H
index 82ab4db42..56e98e72c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.H
@@ -26,7 +26,7 @@
///
/// @file workarounds/mca_workarounds.H
/// @brief Workarounds for the MCA logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
index de06e36a4..3b6009f42 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
@@ -26,7 +26,7 @@
///
/// @file mcbist_workarounds.C
/// @brief Workarounds for the MCBISt engine
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
index e9d978be3..1f1aa5dbe 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
@@ -26,7 +26,7 @@
///
/// @file mcbist_workarounds.H
/// @brief Workarounds for the MCBISt engine
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.C
index 383dc5114..8ec8165e1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.C
@@ -26,7 +26,7 @@
///
/// @file workarounds/seq_workarounds.C
/// @brief Workarounds for the SEQ logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.H
index 6ff7fc925..08ef94879 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/seq_workarounds.H
@@ -26,7 +26,7 @@
///
/// @file workarounds/seq_workarounds.H
/// @brief Workarounds for the SEQ logic blocks
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
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 e14ef0964..b9426fe94 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
@@ -26,7 +26,7 @@
///
/// @file wr_vref_workarounds.C
/// @brief Workarounds for the WR VREF calibration logic
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
@@ -52,21 +52,22 @@ namespace wr_vref
/// @brief Executes WR VREF workarounds
/// @param[in] i_target the fapi2 target of the port
/// @param[in] i_rp - the rank pair to execute the override on
-/// @param[in] i_cal_steps_enabled - cal steps to exectue, used to see if WR VREF needs to be exectued
+/// @param[in] i_wr_vref_enabled - true if WR VREF is enabled
/// @param[out] o_vrefdq_train_range - training range value
/// @param[out] o_vrefdq_train_value - training value value
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
+// 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<uint32_t>& i_cal_steps_enabled,
+ const bool i_wr_vref_enabled,
uint8_t& o_vrefdq_train_range,
uint8_t& o_vrefdq_train_value )
{
// Skip running WR VREF workarounds if:
// 1) the chip does not need to have the workaround run
// 2) WR VREF has not been requested in the calibration steps
- if ((! mss::chip_ec_feature_mss_wr_vref(i_target)) || (!i_cal_steps_enabled.getBit<WRITE_CTR_2D_VREF>()))
+ if ((! mss::chip_ec_feature_mss_wr_vref(i_target)) || (!i_wr_vref_enabled))
{
return fapi2::FAPI2_RC_SUCCESS;
}
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 4350a8da7..82761e08d 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
@@ -26,7 +26,7 @@
///
/// @file wr_vref_workarounds.H
/// @brief Workarounds for the WR VREF calibration logic
-/// Workarounds are very deivce specific, so there is no attempt to generalize
+/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
@@ -53,7 +53,7 @@ namespace wr_vref
/// @brief Executes WR VREF workarounds
/// @param[in] i_target the fapi2 target of the port
/// @param[in] i_rp - the rank pair to execute the override on
-/// @param[in] i_cal_steps_enabled - cal steps to exectue, used to see if WR VREF needs to be exectued
+/// @param[in] i_wr_vref_enabled - true if WR VREF is enabled
/// @param[out] o_vrefdq_train_range - training range value
/// @param[out] o_vrefdq_train_value - training value value
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
@@ -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<uint32_t>& i_cal_steps_enabled,
+ const bool i_wr_vref_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 fdd8b7ce0..c354bc86b 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
@@ -42,6 +42,7 @@
#include <lib/shared/mss_const.H>
#include <lib/workarounds/dp16_workarounds.H>
#include <lib/workarounds/dqs_align_workarounds.H>
+#include <lib/phy/mss_training.H>
#include <lib/fir/unmask.H>
#include <lib/dimm/ddr4/zqcal.H>
@@ -61,6 +62,7 @@ extern "C"
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 );
@@ -177,7 +179,11 @@ extern "C"
bool l_cal_fail = false;
FAPI_INF("Execute cal on rp %d %s", rp, mss::c_str(p));
- FAPI_TRY( mss::setup_and_execute_cal(p, rp, l_cal_steps_enabled, l_cal_abort_on_error) );
+ for(const auto& l_step : mss::training::steps_factory(l_cal_steps_enabled))
+ {
+ FAPI_TRY( l_step->execute( p, rp, l_cal_abort_on_error) );
+ }
+
FAPI_TRY( mss::find_and_log_cal_errors(p, rp, l_cal_abort_on_error, l_cal_fail, l_fails) );
}// rank pairs
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
index 35ccf81fb..0a33fe947 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
@@ -42,6 +42,7 @@
#include <lib/phy/dp16.H>
#include <lib/phy/seq.H>
#include <lib/phy/ddr_phy.H>
+#include <lib/phy/mss_training.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
@@ -88,6 +89,7 @@ extern "C"
for( const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
{
fapi2::buffer<uint32_t> l_cal_steps_enabled;
+ std::vector<std::shared_ptr<mss::training::step>> l_steps;
FAPI_TRY( mss::cal_step_enable(p, l_cal_steps_enabled), "Error in p9_mss_draminit_training %s", mss::c_str(i_target) );
if (!l_cal_steps_enabled.getBit<mss::TRAINING_ADV>())
@@ -103,6 +105,9 @@ extern "C"
l_cal_steps_enabled = 0;
l_cal_steps_enabled.setBit<mss::INITIAL_PAT_WR>().setBit<mss::TRAINING_ADV>();
+ // Gets the training steps to calibrate
+ l_steps = mss::training::steps_factory(l_cal_steps_enabled);
+
// Keep track of the last error seen by a rank pair
fapi2::ReturnCode l_rank_pair_error(fapi2::FAPI2_RC_SUCCESS);
@@ -138,7 +143,13 @@ extern "C"
FAPI_TRY( l_original_settings.save() );
std::vector<fapi2::ReturnCode> l_fails_on_rp;
- FAPI_TRY( mss::setup_and_execute_cal(p, rp, l_cal_steps_enabled, l_cal_abort_on_error) );
+
+ // Loop through all of the steps (should just be initial pattern write and custom read centering)
+ for(const auto l_step : l_steps)
+ {
+ FAPI_TRY( l_step->execute(p, rp, l_cal_abort_on_error) );
+ }
+
FAPI_TRY( mss::find_and_log_cal_errors(p, rp, l_cal_abort_on_error, l_cal_fail, l_fails_on_rp) );
// If we got a fail, let's ignore the previous fails and run backup pattern
@@ -164,7 +175,12 @@ extern "C"
FAPI_TRY( mss::seq::setup_rd_wr_data( p, l_backup) );
// Rerun the training for this rp
- FAPI_TRY( mss::setup_and_execute_cal(p, rp, l_cal_steps_enabled, l_cal_abort_on_error) );
+ // Loop through all of the steps (should just be initial pattern write and custom read centering)
+ for(const auto l_step : l_steps)
+ {
+ FAPI_TRY( l_step->execute(p, rp, l_cal_abort_on_error) );
+ }
+
FAPI_TRY( mss::find_and_log_cal_errors(p, rp, l_cal_abort_on_error, l_cal_fail, l_fails_on_rp) );
// If we got fails from the backup pattern, restore the pre-adv training settings for this rank pair
OpenPOWER on IntegriCloud