diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-09-21 13:55:25 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-09-25 13:25:06 -0400 |
commit | 97de3f088e7509bd8ff05712f4936716d732a3bd (patch) | |
tree | ab92e12c64091602f3cad4224ac921ae952879ab /src/import/chips/p9/procedures | |
parent | ac77052e578c98e32754d6f9120890c29ea023da (diff) | |
download | talos-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')
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, |