summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H733
1 files changed, 1 insertions, 732 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 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,104 +40,13 @@
#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/dimm/mss_timing.H>
#include <lib/utils/mss_nimbus_conversions.H>
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<fapi2::TargetType T, typename OT>
-inline OT ps_to_nck( const fapi2::Target<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<fapi2::TargetType T, typename OT>
-inline OT ns_to_nck( const fapi2::Target<T>& 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
/// @tparam OT output type
@@ -159,30 +68,6 @@ fapi_try_exit:
}
///
-/// @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<fapi2::TARGET_TYPE_DIMM>& 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
/// @tparam OT the type of the output location
@@ -582,602 +467,6 @@ fapi_try_exit:
}
///
-/// @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<fapi2::TARGET_TYPE_DIMM>& i_target)
-{
- uint64_t l_freq = 0;
- uint64_t l_tras = 0;
-
- // Frequency is used to determine tRAS
- FAPI_TRY( freq(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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<fapi2::TARGET_TYPE_MCBIST>(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<T>& 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
/// @param[in] i_target a target for attributes
@@ -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<T>& 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
OpenPOWER on IntegriCloud