summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-09-21 13:55:25 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-09-25 13:25:06 -0400
commit97de3f088e7509bd8ff05712f4936716d732a3bd (patch)
treeab92e12c64091602f3cad4224ac921ae952879ab /src/import/chips/p9/procedures
parentac77052e578c98e32754d6f9120890c29ea023da (diff)
downloadtalos-hostboot-97de3f088e7509bd8ff05712f4936716d732a3bd.tar.gz
talos-hostboot-97de3f088e7509bd8ff05712f4936716d732a3bd.zip
Change WR_CNTR_FW values
Add unit test for cal timers Change-Id: I4b5283fda50677c9935dff0e1f499a008ed2c5ca Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30092 Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30093 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H40
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H43
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H6
4 files changed, 73 insertions, 21 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
index f9d8c1f60..6dfb94227 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
@@ -425,5 +425,45 @@ inline fapi2::ReturnCode max_dodt_off( const fapi2::Target<fapi2::TARGET_TYPE_MC
// the max DODTon/off so it would really never be used anyway there anyway. We can implement it if
// we find another need for it.
+///
+/// @brief Number of memory clock cycles to wait between the write and
+/// read command pairs during Write Centering.
+/// @return constexpr value of 0 clocks
+///
+constexpr uint64_t fw_wr_rd()
+{
+ // Per PHY spec, defaults to 0. Would need an attribute to drive differently
+ return 0;
+}
+
+///
+/// @brief This value sets the delay between a read and write command in memory clock cycles.
+/// This delay value is used in two places in the write centering algorithm.
+/// @param[in] i_target the MCA
+/// @param[out] o_fw_rd_wr *in clocks*
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+inline fapi2::ReturnCode fw_rd_wr( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint8_t& o_fw_rd_wr )
+{
+ // From the PHY spec. Also confirmed with S. Wyatt as this is different than the calculation used in Centaur.
+ // This field must be set to the larger of the two values in number of memory clock cycles.
+ // FW_RD_WR = max(tWTR + 11, AL + tRTP + 3)
+ // Note from J. Bialas: The difference between tWTR_S and tWTR_L is that _S is write to read
+ // time to different bank groups, while _L is to the same. The algorithm should be switching
+ // bank groups so tWTR_S can be used
+ uint8_t l_trtp = 0;
+ uint8_t l_twtr_s = 0;
+ uint8_t l_al = 0;
+ FAPI_TRY( mss::eff_dram_trtp(i_target, l_trtp) );
+ FAPI_TRY( mss::eff_dram_twtr_s(i_target, l_twtr_s) );
+ FAPI_TRY( mss::eff_dram_al(i_target, l_al) );
+
+ o_fw_rd_wr = std::max(l_twtr_s + 11, l_al + l_trtp + 3);
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // mss
#endif
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 898154c93..66a53e42b 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
@@ -122,23 +122,32 @@ uint64_t read_ctr_cycles(const fapi2::Target<T>& i_target )
/// @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
-/// @return uint64_t, the cycles taken for write centering on a single rank
+/// @param[out] o_cycles the cycles taken for write centering on a single rank
+/// @return FAPI2_RC_SUCCESS iff ok
///
template<fapi2::TargetType T>
-uint64_t write_ctr_cycles(const fapi2::Target<T>& i_target )
+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.
- uint64_t l_write_ctr_cycles = 1000 + (WR_LVL_NUM_VALID_SAMPLES * (WR_CNTR_FW_WR_RD + WR_CNTR_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;
+ 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("write_ctr_cycles: %lu(%luns) (%u, %u, %u, %u, %u)",
- l_write_ctr_cycles, mss::cycles_to_ns(i_target, l_write_ctr_cycles),
- WR_LVL_NUM_VALID_SAMPLES, WR_CNTR_FW_WR_RD, WR_CNTR_FW_RD_WR, WR_LVL_BIG_STEP, WR_LVL_SMALL_STEP);
+ 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;
- return l_write_ctr_cycles;
+fapi_try_exit:
+ return fapi2::current_err;
}
///
@@ -186,13 +195,18 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
poll_parameters& i_poll,
const fapi2::buffer<uint16_t>& i_cal_steps_enabled)
{
+ uint64_t l_write_cntr_cycles = 0;
+ uint64_t l_total_cycles = 0;
+ int64_t l_ns_left = 0;
+ FAPI_TRY( mss::write_ctr_cycles(i_target, l_write_cntr_cycles) );
+
// First, calculate the total number of cycles this cal should take if everything
// runs to completion
- uint64_t l_total_cycles = i_cal_steps_enabled.getBit<WR_LEVEL>() ? wr_lvl_cycles(i_target) : 0;
+ 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;
l_total_cycles += i_cal_steps_enabled.getBit<READ_CTR>() ? read_ctr_cycles(i_target) : 0;
- l_total_cycles += i_cal_steps_enabled.getBit<WRITE_CTR>() ? write_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;
@@ -211,8 +225,7 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
i_poll.iv_sim_delay = mss::cycles_to_simcycles(mss::ns_to_cycles(i_target, DELAY_1US));
// Round up to the cycles left after the initial delay
- int64_t l_ns_left = std::max(0L,
- (int64_t(mss::cycles_to_ns(i_target, l_total_cycles)) - int64_t(i_poll.iv_initial_delay)));
+ l_ns_left = std::max(0L, (int64_t(mss::cycles_to_ns(i_target, l_total_cycles)) - int64_t(i_poll.iv_initial_delay)));
i_poll.iv_poll_count = l_ns_left / i_poll.iv_delay;
i_poll.iv_poll_count += l_ns_left % i_poll.iv_delay ? 0 : 1;
@@ -232,8 +245,7 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
i_poll.iv_sim_delay = mss::cycles_to_simcycles(mss::ns_to_cycles(i_target, DELAY_1US));
// Round up to the cycles left after the initial delay
- int64_t l_ns_left = std::max(0L,
- (int64_t(mss::cycles_to_ns(i_target, l_total_cycles)) - int64_t(i_poll.iv_initial_delay)));
+ l_ns_left = std::max(0L, (int64_t(mss::cycles_to_ns(i_target, l_total_cycles)) - int64_t(i_poll.iv_initial_delay)));
i_poll.iv_poll_count = l_ns_left / i_poll.iv_delay;
i_poll.iv_poll_count += l_ns_left % i_poll.iv_delay ? 0 : 1;
@@ -253,6 +265,9 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
i_poll.iv_initial_sim_delay, i_poll.iv_delay, i_poll.iv_sim_delay, i_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/write_cntrl.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H
index 26cc5e564..bf42eb207 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H
@@ -382,9 +382,12 @@ template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = wcTraits<T
inline fapi2::ReturnCode reset_config2( const fapi2::Target<T>& i_target )
{
fapi2::buffer<uint64_t> l_data;
+ uint8_t l_fw_rd_wr = 0;
+
+ FAPI_TRY( mss::fw_rd_wr(i_target, l_fw_rd_wr) );
l_data.insertFromRight<TT::NUM_VALID_SAMPLES, TT::NUM_VALID_SAMPLES_LEN>(WR_LVL_NUM_VALID_SAMPLES);
- l_data.insertFromRight<TT::FW_RD_WR, TT::FW_RD_WR_LEN>(WR_CNTR_FW_RD_WR);
+ l_data.insertFromRight<TT::FW_RD_WR, TT::FW_RD_WR_LEN>(l_fw_rd_wr);
FAPI_DBG("wc_config2 reset 0x%llx", l_data);
FAPI_TRY( write_config2(i_target, l_data) );
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
index 7477f683d..15b71222c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
@@ -68,12 +68,6 @@ enum sizes
WR_LVL_PRE_DLY = 0b101010,
WR_LVL_NUM_VALID_SAMPLES = 0x5,
- // THIS IS LIKELY INCORRECT - Should be defined in the DDR4 write centering protocol BRS
- // This field must be set to the larger of the two values in number of memory clock cycles.
- // FW_RD_WR = max(tWTR + 11, AL + tRTP + 3)
- WR_CNTR_FW_RD_WR = 0x11 + 4,
- WR_CNTR_FW_WR_RD = 0x0,
-
// Attribute? BRS
COARSE_CAL_STEP_SIZE = 0x4,
CONSEQ_PASS = 0x8,
OpenPOWER on IntegriCloud