From d9bbcfabbc2f041ba85095ac70dc27c37cb87755 Mon Sep 17 00:00:00 2001 From: Louis Stermole Date: Fri, 7 Jun 2019 15:44:22 -0400 Subject: Add missing timing attrs to p9a_eff_config Change-Id: I0270bec76fa1146c3c74cc125f838f5602b8a5b8 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/78564 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Tested-by: Hostboot CI Tested-by: HWSV CI Reviewed-by: STEPHEN GLANCY Reviewed-by: Mark Pizzutillo Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/78576 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Christian R. Geddes --- .../p9/procedures/hwp/memory/lib/dimm/eff_dimm.C | 24 +- .../procedures/hwp/memory/lib/eff_config/timing.C | 165 +---- .../procedures/hwp/memory/lib/eff_config/timing.H | 733 +-------------------- .../xml/error_info/p9_memory_mss_eff_config.xml | 45 -- 4 files changed, 11 insertions(+), 956 deletions(-) (limited to 'src/import/chips') diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C index baac38c30..74e3182ee 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C @@ -366,16 +366,6 @@ enum invalid_freq_function_encoding : uint8_t F0BC6X = 0x60, }; -/// -/// @brief encoding for MSS_INVALID_TIMING so we can look up functions based on encoding -/// -enum invalid_timing_function_encoding : uint8_t -{ - TRRD_S = 0, - TRRD_L = 1, - TFAW = 2, -}; - ///////////////////////// // Non-member function implementations ///////////////////////// @@ -4098,7 +4088,7 @@ fapi2::ReturnCode eff_dimm::dram_trrd_s() l_trrd_s_in_nck); } - FAPI_TRY( trrd_s( iv_dimm, iv_dram_width, l_jedec_trrd) ); + FAPI_TRY( trrd_s( iv_dimm, iv_dram_width, iv_freq, l_jedec_trrd) ); // Taking the worst case between the required minimum JEDEC value and the proposed value from SPD if (l_jedec_trrd != l_trrd_s_in_nck) @@ -4174,7 +4164,7 @@ fapi2::ReturnCode eff_dimm::dram_trrd_l() l_trrd_l_in_nck); } - FAPI_TRY( trrd_l( iv_dimm, iv_dram_width, l_jedec_trrd) ); + FAPI_TRY( trrd_l( iv_dimm, iv_dram_width, iv_freq, l_jedec_trrd) ); // Taking the worst case between the required minimum JEDEC value and the proposed value from SPD if (l_jedec_trrd != l_trrd_l_in_nck) @@ -4273,7 +4263,7 @@ fapi2::ReturnCode eff_dimm::dram_tfaw() l_tfaw_in_nck); } - FAPI_TRY( mss::tfaw(iv_dimm, iv_dram_width, l_jedec_tfaw_in_nck), "Failed tfaw()" ); + FAPI_TRY( mss::tfaw(iv_dimm, iv_dram_width, iv_freq, l_jedec_tfaw_in_nck), "Failed tfaw()" ); // Taking the worst case between the required minimum JEDEC value and the proposed value from SPD if (l_jedec_tfaw_in_nck != l_tfaw_in_nck) @@ -4342,11 +4332,15 @@ fapi2::ReturnCode eff_dimm::dram_tras() // which will give the best timing value for the dimm // (like 2400 MT/s) which may be different than the system // speed (if we were being limited by VPD or MRW restrictions) - const uint64_t l_tras_in_ps = mss::tras(iv_dimm); + uint64_t l_tras_in_ps; + uint64_t l_freq = 0; + uint8_t l_tras_in_nck = 0; // Calculate nck std::vector l_attrs_dram_tras(PORTS_PER_MCS, 0); - uint8_t l_tras_in_nck = 0; + + FAPI_TRY( freq(mss::find_target(iv_dimm), l_freq) ); + l_tras_in_ps = mss::tras(iv_dimm, l_freq); // Cast needed for calculations to be done on the same integral type // as required by template deduction. We have iv_tCK_in_ps as a signed diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C index ebc203f2e..1f2920c7b 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -37,167 +37,4 @@ namespace mss { -enum temp_mode : uint8_t -{ - NORMAL = 1, - EXTENDED = 2, -}; - -// Proposed DDR4 Full spec update(79-4B) -// Item No. 1716.78C -// pg.46 -// Table 24 - tREFI and tRFC parameters (in ps) -constexpr uint64_t TREFI_BASE = 7800000; - -// Proposed DDR4 3DS Addendum -// Item No. 1727.58A -// pg. 69 - 71 -// Table 42 - Refresh parameters by logical rank density -static const std::vector > TRFC_DLR1 = -{ - // { density in GBs, tRFC4(min) in picoseconds } - {4, 90000}, - {8, 120000}, - {16, 185000}, -}; - -// Proposed DDR4 3DS Addendum -// Item No. 1727.58A -// pg. 69 - 71 -// Table 42 - Refresh parameters by logical rank density -static const std::vector > TRFC_DLR2 = -{ - // { density in GBs, tRFC4(min) in picoseconds } - {4, 55000}, - {8, 90000}, - {16, 120000}, -}; - -// Proposed DDR4 3DS Addendum -// Item No. 1727.58A -// pg. 69 - 71 -// Table 42 - Refresh parameters by logical rank density -static const std::vector > TRFC_DLR4 = -{ - // { density in GBs, tRFC4(min) in picoseconds } - {4, 40000}, - {8, 55000}, - {16, 90000}, -}; - -/// -/// @brief Calculates refresh interval time -/// @param[in] i_mode fine refresh rate mode -/// @param[in] i_refresh_request_rate refresh rate -/// @param[out] o_value timing val in ps -/// @return fapi2::ReturnCode -/// -fapi2::ReturnCode calc_trefi( const refresh_rate i_mode, - const uint8_t i_refresh_request_rate, - uint64_t& o_timing ) -{ - uint64_t l_refresh_request = 0; - constexpr double TEN_PERCENT_FASTER = 0.90; - - switch(i_refresh_request_rate) - { - case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE: - l_refresh_request = TREFI_BASE; - break; - - case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE: - // We are truncating but there is no remainder with TREFI_BASE, so we are okay - l_refresh_request = TREFI_BASE / 2; - break; - - case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE_10_PERCENT_FASTER: - // We are truncating but there is no remainder with TREFI_BASE, so we are okay - // 10% faster so 100% - 10% = 90% - l_refresh_request = TREFI_BASE * TEN_PERCENT_FASTER; - break; - - case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE_10_PERCENT_FASTER: - // We are truncating but there is no remainder with TREFI_BASE, so we are okay - // 10% faster so 100% - 10% = 90% - l_refresh_request = (TREFI_BASE / 2) * TEN_PERCENT_FASTER; - break; - - default: - // Will catch incorrect MRW value set - FAPI_ASSERT(false, - fapi2::MSS_INVALID_REFRESH_RATE_REQUEST().set_REFRESH_RATE_REQUEST(i_refresh_request_rate), - "Incorrect refresh request rate received: %d ", i_refresh_request_rate); - break; - } - - o_timing = (l_refresh_request / i_mode); - - FAPI_INF( "tREFI (ps): %d, refresh request (ps): %d, tREFI_base (ps): %d, REF%dX", - o_timing, l_refresh_request, TREFI_BASE, i_mode ); - - // FAPI_ASSERT doesn't set current_err as good - return fapi2::FAPI2_RC_SUCCESS; - -fapi_try_exit: - return fapi2::current_err; -} - -/// @brief Calculates Minimum Refresh Recovery Delay Time (different logical rank) -/// @param[in] i_mode fine refresh rate mode -/// @param[in] i_density SDRAM density -/// @param[out] o_trfc_in_ps timing val in ps -/// @return fapi2::FAPI2_RC_SUCCESS iff okay -/// -fapi2::ReturnCode calc_trfc_dlr(const fapi2::Target& i_target, - const uint8_t i_refresh_mode, - const uint8_t i_density, - uint64_t& o_trfc_in_ps) -{ - bool l_is_val_found = 0; - - // Selects appropriate tRFC based on fine refresh mode - switch(i_refresh_mode) - { - case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL: - l_is_val_found = find_value_from_key(TRFC_DLR1, i_density, o_trfc_in_ps); - break; - - case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X: - case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X: - l_is_val_found = find_value_from_key(TRFC_DLR2, i_density, o_trfc_in_ps); - break; - - case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X: - case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X: - l_is_val_found = find_value_from_key(TRFC_DLR4, i_density, o_trfc_in_ps); - break; - - default: - // Fine Refresh Mode will be a platform attribute set by the MRW, - // which they "shouldn't" mess up as long as use "attribute" enums. - // if openpower messes this up we can at least catch it - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FINE_REFRESH() - .set_REFRESH_MODE(i_refresh_mode), - "Incorrect Fine Refresh Mode received: %d ", - i_refresh_mode); - break; - }// switch - - FAPI_ASSERT( l_is_val_found, - fapi2::MSS_FAILED_TO_FIND_TRFC() - .set_SDRAM_DENSITY(i_density) - .set_REFRESH_MODE(i_refresh_mode) - .set_DIMM_TARGET(i_target), - "%s: Unable to find tRFC (ps) from map with SDRAM density key %d with %d refresh mode", - mss::c_str(i_target), - i_density, - i_refresh_mode); - - // Again, FAPI_ASSERT doesn't set current_err to good, only to bad - return fapi2::FAPI2_RC_SUCCESS; -fapi_try_exit: - return fapi2::current_err; -} - }// mss 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 8b8215b96..d748400cb 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 @@ -40,103 +40,12 @@ #include #include #include +#include #include namespace mss { -/// -/// @brief Enums for ffdc error callout so we know which function had the error -/// -enum functions -{ - TRAS = 0, - TFAW_HALF_KB_PAGE_HELPER = 1, - TFAW_ONE_KB_PAGE_HELPER = 2, - TFAW_TW_KB_PAGE_HELPER = 3, - TFAW_SLR_X4_HELPER = 4, - TFAW_SLR_X8_HELPER = 5, - TRRD_S_SLR = 6, - TRRD_L_SLR = 7, - TRRD_L_HALF_AND_1KB_PAGE_HELPER = 8, - TRRD_S_HALF_AND_1KB_PAGE_HELPER = 9, - TRRD_S_2KB_PAGE_HELPER = 10, - TDLLK = 11, -}; - -enum refresh_rate : uint8_t -{ - REF1X = 1, ///< Refresh rate 1X - REF2X = 2, ///< Refresh rate 2X - REF4X = 4, ///< Refresh rate 4X -}; - -namespace spd -{ - -/// -/// @brief Returns clock cycles form picoseconds based on speed bin -/// Uses SPD rounding algorithm for DDR4 -/// @tparam T the target type from which to get the mt/s -/// @tparam OT the output type, derrived from the parameters -/// @param[in] i_target target for the frequency attribute -/// @param[in] timing_in_ps timing parameter in ps -/// @return the clock cycles of timing parameter (provided in ps) -/// @note Uses DDR4 SPD Contents Rounding Algorithm -/// @note Item 2220.46 -/// -template -inline OT ps_to_nck( const fapi2::Target& i_target, const OT& i_timing_in_ps) -{ - uint64_t l_freq = 0; - OT l_tck_in_ps = 0; - OT l_temp_nck = 0; - - FAPI_TRY( mss::freq( find_target(i_target), l_freq) ); - - // No time if MT/s is 0 (well, infinite really but shut up) - if (l_freq == 0) - { - return 0; - } - - FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps), - "Failed freq() accessor" ); - FAPI_TRY( calc_nck(i_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_temp_nck), - "Failed calc_nck()" ); - - return l_temp_nck; - -fapi_try_exit: - // We simply can't work if we can't get the frequency or - // if we get an unsupported value that can't be converted to a valid tCK (clock period) - // ...so this should be ok - FAPI_ERR("Can't get MSS_FREQ, obtained an invalid MSS_FREQ (%d), or overflow occurred - stopping", l_freq); - fapi2::Assert(false); - - // Keeps compiler happy - return 0; -} - -/// -/// @brief Returns clock cycles from nanoseconds -/// Uses SPD rounding algorithm for DDR4 -/// @tparam T the target type from which to get the mt/s -/// @tparam OT the output type, derrived from the parameters -/// @param[in] timing_in_ps timing parameter in ps -/// @param[out] o_value_nck the end calculation in nck -/// @return the clock cycles of timing parameter (provided in ps)F -/// @note Uses DDR4 SPD Contents Rounding Algorithm -/// @note Item 2220.46 -/// -template -inline OT ns_to_nck( const fapi2::Target& i_target, const OT& i_timing_in_ns) -{ - return ps_to_nck(i_target, i_timing_in_ns * CONVERT_PS_IN_A_NS); -} - -}// spd - /// /// @brief Returns application clock period (tCK) based on dimm transfer rate /// @tparam T the fapi2 target @@ -158,30 +67,6 @@ fapi_try_exit: return fapi2::current_err; } -/// -/// @brief Calculates refresh interval time -/// @param[in] i_mode fine refresh rate mode -/// @param[in] i_temp_refresh_range temperature refresh range -/// @param[out] o_value timing val in ps -/// @return fapi2::ReturnCode -/// -fapi2::ReturnCode calc_trefi( const refresh_rate i_mode, - const uint8_t i_temp_refresh_range, - uint64_t& o_timing ); - -/// -/// @brief Calculates Minimum Refresh Recovery Delay Time (different logical rank) -/// @param[in] i_target a target for attributes -/// @param[in] i_mode fine refresh rate mode -/// @param[in] i_density SDRAM density -/// @param[out] o_trfc_in_ps timing val in ps -/// @return fapi2::FAPI2_RC_SUCCESS iff okay -/// -fapi2::ReturnCode calc_trfc_dlr( const fapi2::Target& i_target, - const uint8_t i_refresh_mode, - const uint8_t i_density, - uint64_t& o_trfc_in_ps ); - /// /// @brief DLL locking time *in clocks* /// @tparam T the fapi2::TargetType of i_target @@ -581,602 +466,6 @@ fapi_try_exit: return fapi2::current_err; } -/// -/// @brief tRTP *in ps* -/// @return constexpr value of RTP = 7500 ps -/// -constexpr uint64_t trtp() -{ - // Per JEDEC spec, defaults to 7500 ps for all frequencies. - // (technically max of 7.5 ns or 4 nclk, which is always 7.5ns for DDR4) - return 7500; -} - -/// -/// @brief Return the minimum allowable tRAS in picoseconds -/// @param[in] i_target the fapi2 target -/// @return value in picoseconds -/// -inline uint64_t tras(const fapi2::Target& i_target) -{ - uint64_t l_freq = 0; - uint64_t l_tras = 0; - - // Frequency is used to determine tRAS - FAPI_TRY( freq(mss::find_target(i_target), l_freq) ); - - switch(l_freq) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - l_tras = 34000; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - l_tras = 33000; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - l_tras = 32000; - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FREQ_PASSED_IN() - .set_FREQ(l_freq) - .set_FUNCTION(TRAS) - .set_DIMM_TARGET(i_target), - "%s Invalid frequency %lu", - mss::c_str(i_target), - l_freq); - } - - return l_tras; - -fapi_try_exit: - - // We simply can't work if we can't get the frequency or - // if we get an unsupported value that can't be converted to a valid tCK (clock period) - // ...so this should be ok - FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq); - fapi2::Assert(false); - - // Keeps compiler happy - return 0; -} - -/// -/// @brief Helper function to find tFAW based speed (MT/s) for 1/2 KB page -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -static fapi2::ReturnCode tfaw_half_kb_page_helper(const fapi2::Target& i_target, - uint64_t& o_output) -{ - // Values derived from DDR4 Spec (79-4A) - // 13.3 Timing Parameters by Speed Grade - // Table 132. Pg 240 - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - - uint64_t l_freq = 0; - FAPI_TRY( freq(find_target(i_target), l_freq), - "Failed to invoke freq accessor" ); - - // It could have been more "efficient" to hand-calculate the answer and - // use compile time constants to return the answer. To avoid magic - // numbers and to align (more closely) with the DDR4 JEDEC spec, - // we let the std library do the work for us for maintainability. - // Could have used compile-time constants to denote the numbers below - // but they are "random" and vary. - switch(l_freq) - { - // static_cast is needed for template deduction of std::max API - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - o_output = std::max( 16, spd::ns_to_nck(i_target, 17) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - o_output = std::max( 16, spd::ns_to_nck(i_target, 15) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - o_output = std::max( 16, spd::ns_to_nck(i_target, 13) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_output = std::max( 16, spd::ns_to_nck(i_target, 12) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FREQ_PASSED_IN() - .set_FREQ(l_freq) - .set_FUNCTION(TFAW_HALF_KB_PAGE_HELPER) - .set_DIMM_TARGET(i_target), - "%s Invalid frequency %lu", - mss::c_str(i_target), - l_freq); - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Helper function to find tFAW based speed (MT/s) for 1KB page -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -static fapi2::ReturnCode tfaw_1kb_page_helper(const fapi2::Target& i_target, - uint64_t& o_output) -{ - // Values derived from DDR4 Spec (79-4A) - // 13.3 Timing Parameters by Speed Grade - // Table 132. Pg 240 - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - - uint64_t l_freq = 0; - FAPI_TRY( freq(find_target(i_target), l_freq), - "Failed to invoke freq accessor" ); - - // It could have been more "efficient" to hand-calculate the answer and - // use compile time constants to return the answer. To avoid magic - // numbers and to align (more closely) with the DDR4 JEDEC spec, - // we let the std library do the work for us for maintainability (and ease of debug?). - // Could have used compile-time constants to denote the numbers below - // but they are "random" and vary. - switch(l_freq) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - o_output = std::max( 20, spd::ns_to_nck(i_target, 23) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_output = std::max( 20, spd::ns_to_nck(i_target, 21) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FREQ_PASSED_IN() - .set_FREQ(l_freq) - .set_FUNCTION(TFAW_ONE_KB_PAGE_HELPER) - .set_DIMM_TARGET(i_target), - "%s Invalid frequency %lu", - mss::c_str(i_target), - l_freq); - break; - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Helper function to find tFAW based speed (MT/s) for 2KB page -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -static fapi2::ReturnCode tfaw_2kb_page_helper(const fapi2::Target& i_target, - uint64_t& o_output) -{ - - // Values derived from DDR4 Spec (79-4A) - // 13.3 Timing Parameters by Speed Grade - // Table 132. Pg 240 - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - - // It could have been more "efficient" to hand-calculate the answer and - // use compile time constants to return the answer. To avoid magic - // numbers and to align (more closely) with the DDR4 JEDEC spec, - // we let the std library do the work for us for maintainability. - // Could have used compile-time constants to denote the numbers below - // but they are "random" and vary. - uint64_t l_freq = 0; - FAPI_TRY( freq(find_target(i_target), l_freq), - "Failed to invoke freq accessor" ); - - switch(l_freq) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_output = std::max( 28, spd::ns_to_nck(i_target, 30) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FREQ_PASSED_IN() - .set_FREQ(l_freq) - .set_FUNCTION(TFAW_TW_KB_PAGE_HELPER) - .set_DIMM_TARGET(i_target), - "%s Invalid frequency %lu", - mss::c_str(i_target), - l_freq); - break; - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Return the minimum allowable tFAW in nck -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[in] i_dram_width the page size -/// @param[out] o_tFAW timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -// -template< fapi2::TargetType T > -fapi2::ReturnCode tfaw( const fapi2::Target& i_target, - const uint8_t i_dram_width, - uint64_t& o_tFAW ) -{ - switch(i_dram_width) - { - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4: - FAPI_TRY( tfaw_half_kb_page_helper(i_target, o_tFAW) ); - break; - - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8: - FAPI_TRY( tfaw_1kb_page_helper(i_target, o_tFAW) ); - break; - - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16: - FAPI_TRY( tfaw_2kb_page_helper(i_target, o_tFAW) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_DRAM_WIDTH() - .set_DRAM_WIDTH(i_dram_width) - .set_DIMM_TARGET(i_target), - "Invalid DRAM width with %d for target %s", - i_dram_width, - mss::c_str(i_target)); - break; - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief tFAW_dlr *in nck* -/// @return 16nck -/// @note From DDR4 3DS Spec -/// 12.2 Timing Parameters by Speed Grade -/// -constexpr uint64_t tfaw_dlr() -{ - return 16; -} - -/// -/// @brief tRRD_dlr *in nck* -/// @return 4nck -/// @note From DDR4 3DS Spec -/// 12.2 Timing Parameters by Speed Grade -/// -constexpr uint64_t trrd_dlr() -{ - return 4; -} - -/// -/// @brief Helper function to find tRRD_L based speed (MT/s) for 1KB page -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -static fapi2::ReturnCode trrd_l_half_and_1kb_page_helper(const fapi2::Target& i_target, - uint64_t& o_output) -{ - // Values derived from DDR4 Spec (79-4A) - // 13.3 Timing Parameters by Speed Grade - // Table 132. Pg 240 - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - - uint64_t l_freq = 0; - FAPI_TRY( freq(find_target(i_target), l_freq), - "Failed to invoke freq accessor" ); - - // It could have been more "efficient" to hand-calculate the answer and - // use compile time constants to return the answer. To avoid magic - // numbers and to align (more closely) with the DDR4 JEDEC spec, - // we let the std library do the work for us for maintainability (and ease of debug?). - // Could have used compile-time constants to denote the numbers below - // but they are "random" and vary. - switch(l_freq) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - // From the spec: Max(4nCK,5.3ns) - o_output = std::max( 4, spd::ps_to_nck(i_target, 5300) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - // Max(4nCK,4.9ns) - o_output = std::max( 4, spd::ps_to_nck(i_target, 4900) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FREQ_PASSED_IN() - .set_FREQ(l_freq) - .set_FUNCTION(TRRD_L_HALF_AND_1KB_PAGE_HELPER) - .set_DIMM_TARGET(i_target), - "%s Invalid frequency %lu", - mss::c_str(i_target), - l_freq); - } - - return fapi2::FAPI2_RC_SUCCESS; -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Helper function to find tRRD_L based speed (MT/s) for 2KB page -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -static fapi2::ReturnCode trrd_l_2kb_page_helper(const fapi2::Target& i_target, - uint64_t& o_output) -{ - - // Values derived from DDR4 Spec (79-4A) - // 13.3 Timing Parameters by Speed Grade - // Table 132. Pg 240 - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - - uint64_t l_freq = 0; - FAPI_TRY( freq(find_target(i_target), l_freq), - "Failed to invoke freq accessor" ); - - // It could have been more "efficient" to hand-calculate the answer and - // use compile time constants to return the answer. To avoid magic - // numbers and to align (more closely) with the DDR4 JEDEC spec, - // we let the std library do the work for us for maintainability (and ease of debug?). - // Could have used compile-time constants to denote the numbers below - // but they are "random" and vary. - switch(l_freq) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_output = std::max( 4, spd::ps_to_nck(i_target, 6400) ); - break; - - default: - FAPI_TRY(fapi2::FAPI2_RC_INVALID_PARAMETER, "%s Invalid frequency %lu", mss::c_str(i_target), l_freq); - break; - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Return the minimum allowable tRRD_L in nck -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[in] i_dram_width the page size -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -fapi2::ReturnCode trrd_l( const fapi2::Target& i_target, - const uint8_t i_dram_width, - uint64_t& o_tRRD_L ) -{ - switch(i_dram_width) - { - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4: - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8: - FAPI_TRY( trrd_l_half_and_1kb_page_helper(i_target, o_tRRD_L), "Error calculating trrd l for half and 1kb page" ); - break; - - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16: - FAPI_TRY( trrd_l_2kb_page_helper(i_target, o_tRRD_L) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_PAGE_SIZE() - .set_DRAM_WIDTH(i_dram_width) - .set_DIMM_TARGET(i_target), - "%s Recieved an invalid page size: %lu", - mss::c_str(i_target), - i_dram_width); - break; - } - - return fapi2::FAPI2_RC_SUCCESS; -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Helper function to find tRRD_S based speed (MT/s) for 1KB page -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -static fapi2::ReturnCode trrd_s_half_and_1kb_page_helper(const fapi2::Target& i_target, - uint64_t& o_output) -{ - // Values derived from DDR4 Spec (79-4A) - // 13.3 Timing Parameters by Speed Grade - // Table 132. Pg 240 - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - - uint64_t l_freq = 0; - FAPI_TRY( freq(find_target(i_target), l_freq), - "Failed to invoke freq accessor" ); - - // It could have been more "efficient" to hand-calculate the answer and - // use compile time constants to return the answer. To avoid magic - // numbers and to align (more closely) with the DDR4 JEDEC spec, - // we let the std library do the work for us for maintainability (and ease of debug?). - // Could have used compile-time constants to denote the numbers below - // but they are "random" and vary. - switch(l_freq) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - o_output = std::max( 4, spd::ps_to_nck(i_target, 4200) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - o_output = std::max( 4, spd::ps_to_nck(i_target, 3700) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - o_output = std::max( 4, spd::ps_to_nck(i_target, 3300) ); - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_output = std::max( 4, spd::ps_to_nck(i_target, 3000) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FREQ_PASSED_IN() - .set_FREQ(l_freq) - .set_FUNCTION(TRRD_S_HALF_AND_1KB_PAGE_HELPER) - .set_DIMM_TARGET(i_target), - "%s Invalid frequency %lu", - mss::c_str(i_target), - l_freq); - } - - return fapi2::FAPI2_RC_SUCCESS; -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Helper function to find tRRD_S based speed (MT/s) for 2KB page -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[out] o_output timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -static fapi2::ReturnCode trrd_s_2kb_page_helper(const fapi2::Target& i_target, - uint64_t& o_output) -{ - // Values derived from DDR4 Spec (79-4A) - // 13.3 Timing Parameters by Speed Grade - // Table 132. Pg 240 - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - - uint64_t l_freq = 0; - FAPI_TRY( freq(find_target(i_target), l_freq), - "Failed to invoke freq accessor" ); - - // It could have been more "efficient" to hand-calculate the answer and - // use compile time constants to return the answer. To avoid magic - // numbers and to align (more closely) with the DDR4 JEDEC spec, - // we let the std library do the work for us for maintainability (and ease of debug?). - // Could have used compile-time constants to denote the numbers below - // but they are "random" and vary. - switch(l_freq) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_output = std::max( 4, spd::ps_to_nck(i_target, 5300) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_FREQ_PASSED_IN() - .set_FREQ(l_freq) - .set_FUNCTION(TRRD_S_2KB_PAGE_HELPER) - .set_DIMM_TARGET(i_target), - "%s Invalid frequency %lu", - mss::c_str(i_target), - l_freq); - break; - } - - return fapi2::FAPI2_RC_SUCCESS; -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Return the minimum allowable tRRD_S in nck -/// @tparam T the fapi2::TargetType of a type from which we can get MT/s -/// @param[in] i_target the fapi2 target -/// @param[in] i_dram_width the page size -/// @param[out] o_tRRD_S timing in clocks (nck) -/// @return FAPI2_RC_SUCCESS iff okay -/// @note this is only for non-3DS DIMM -/// -template< fapi2::TargetType T > -fapi2::ReturnCode trrd_s( const fapi2::Target& i_target, - const uint8_t i_dram_width, - uint64_t& o_tRRD_S ) -{ - switch(i_dram_width) - { - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4: - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8: - FAPI_TRY( trrd_s_half_and_1kb_page_helper(i_target, o_tRRD_S), "Error calculating trrd_s for half and 1kb page" ); - break; - - case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16: - FAPI_TRY( trrd_s_2kb_page_helper(i_target, o_tRRD_S) ); - break; - - default: - FAPI_ASSERT( false, - fapi2::MSS_INVALID_PAGE_SIZE() - .set_DRAM_WIDTH(i_dram_width) - .set_DIMM_TARGET(i_target), - "%s Recieved an invalid page size: %lu", - mss::c_str(i_target), - i_dram_width); - break; - } - - return fapi2::FAPI2_RC_SUCCESS; -fapi_try_exit: - return fapi2::current_err; -} - /// /// @brief VREF DQ Enter time *in clocks* /// @tparam T the fapi2::TargetType of i_target @@ -1215,25 +504,5 @@ constexpr uint64_t tccd_s() return 4; } -namespace lrdimm -{ - -/// -/// @brief Return the VREF to VREF change time long -/// @tparam fapi2::TargetType T - type of the target on which to operate -/// @param[in] i_target the fapi2 target -/// @return value in clocks -/// @note VREF time change long is used for changing by more than one VREF tick -/// -template< fapi2::TargetType T > -inline uint64_t vref_time_long(const fapi2::Target& i_target) -{ - // Taken from the LRDIMM spec - constexpr uint64_t VREF_TIME_LONG_NS = 500; - return mss::spd::ns_to_nck(i_target, VREF_TIME_LONG_NS); -} - -} // ns lrdimm - } // mss #endif diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml index 56fb232dc..4bd96d9f7 100644 --- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml @@ -36,18 +36,6 @@ - - RC_MSS_INVALID_FINE_REFRESH_MODE - - Invalid fine refresh mode received from the mrw - - FINE_REF_MODE - - CODE - HIGH - - - RC_MSS_INVALID_FINE_REFRESH_MODE_WITH_TEMP_REFRESH_MODE_ENABLED @@ -382,19 +370,6 @@ - - RC_MSS_INVALID_REFRESH_RATE_REQUEST - - Invalid refresh request rate received. - Possibly due to bad MRW setting for ATTR_MSS_MRW_REFRESH_RATE_REQUEST. - - REFRESH_RATE_REQUEST - - CODE - HIGH - - - RC_MSS_INVALID_FINE_REFRESH @@ -407,26 +382,6 @@ - - RC_MSS_FAILED_TO_FIND_TRFC - - Unable to find tRFC (ps) from map with SDRAM density key - - SDRAM_DENSITY - REFRESH_MODE - - DIMM_TARGET - MEDIUM - - - DIMM_TARGET - - - CODE - HIGH - - - RC_MSS_INVALID_PAGE_SIZE -- cgit v1.2.1