diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C | 132 |
1 files changed, 131 insertions, 1 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C index 92a3402cf..f57d414c0 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -52,6 +52,7 @@ #include <generic/memory/lib/utils/c_str.H> #include <lib/utils/conversions.H> #include <generic/memory/lib/utils/find.H> +#include <lib/eff_config/timing.H> using fapi2::TARGET_TYPE_MCA; using fapi2::TARGET_TYPE_MCS; @@ -60,6 +61,135 @@ using fapi2::FAPI2_RC_SUCCESS; namespace mss { + + +/// +/// @brief Helper function to retrieves medium and fine timebase values +/// @param[in] i_pDecoder the SPD decoder +/// @param[out] o_mtb the medium timebase (MTB) from SPD +/// @param[out] o_ftb the fine timebase (FTB) from SPD +/// @return FAPI2_RC_SUCCESS iff ok +/// +static fapi2::ReturnCode get_timebases( const std::shared_ptr<mss::spd::decoder>& i_pDecoder, + int64_t& o_mtb, + int64_t& o_ftb ) +{ + // Retrieve timing parameters + const auto l_target = i_pDecoder->iv_target; + + FAPI_TRY( i_pDecoder->medium_timebase(o_mtb), + "%s. Failed medium_timebase()", mss::c_str(l_target) ); + FAPI_TRY( i_pDecoder->fine_timebase(o_ftb), + "%s. Failed fine_timebase()", mss::c_str(l_target) ); + + FAPI_INF("MTB: %d, FTB: %d for %s", o_mtb, o_ftb, mss::c_str(l_target)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD +/// @param[in] i_pDecoder the SPD decoder +/// @param[out] o_value tCKmin value in ps +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_tckmin( const std::shared_ptr<mss::spd::decoder>& i_pDecoder, + uint64_t& o_value ) +{ + int64_t l_timing_ftb = 0; + int64_t l_timing_mtb = 0; + int64_t l_medium_timebase = 0; + int64_t l_fine_timebase = 0; + int64_t l_temp = 0; + + // Retrieve timing parameters + const auto l_target = i_pDecoder->iv_target; + + FAPI_TRY( get_timebases(i_pDecoder, l_medium_timebase, l_fine_timebase), + "%s. Failed get_timebases", mss::c_str(l_target) ); + FAPI_TRY( i_pDecoder->min_tck(l_timing_mtb), + "%s. Failed min_tck()", mss::c_str(l_target) ); + FAPI_TRY( i_pDecoder->fine_offset_min_tck(l_timing_ftb), + "%s. Failed fine_offset_min_tck()", mss::c_str(l_target) ); + + // Calculate timing value + l_temp = spd::calc_timing_from_timebase(l_timing_mtb, + l_medium_timebase, + l_timing_ftb, + l_fine_timebase); + + // Sanity check + FAPI_ASSERT(l_temp > 0, + fapi2::MSS_INVALID_TIMING_VALUE(). + set_VALUE(l_temp). + set_FUNCTION(GET_TCKMIN). + set_DIMM_TARGET(l_target), + "%s. tCKmin invalid (<= 0) : %d", + mss::c_str(l_target), + l_temp); + + o_value = l_temp; + + FAPI_INF("%s. tCKmin (ps): %d", + mss::c_str(l_target), + o_value ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD +/// @param[in] i_pDecoder SPD decoder +/// @param[out] o_value tCKmax value in ps +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_tckmax( const std::shared_ptr<mss::spd::decoder>& i_pDecoder, + uint64_t& o_value ) +{ + int64_t l_timing_ftb = 0; + int64_t l_timing_mtb = 0; + int64_t l_medium_timebase = 0; + int64_t l_fine_timebase = 0; + int64_t l_temp = 0; + + // Retrieve timing parameters + const auto l_target = i_pDecoder->iv_target; + + FAPI_TRY( get_timebases(i_pDecoder, l_medium_timebase, l_fine_timebase), + "%s. Failed get_timebases", mss::c_str(l_target) ); + FAPI_TRY( i_pDecoder->max_tck(l_timing_mtb), + "%s. Failed max_tck()", mss::c_str(l_target) ); + FAPI_TRY( i_pDecoder->fine_offset_max_tck(l_timing_ftb), + "%s. Failed fine_offset_max_tck()", mss::c_str(l_target) ); + + // Calculate timing value + l_temp = spd::calc_timing_from_timebase(l_timing_mtb, + l_medium_timebase, + l_timing_ftb, + l_fine_timebase); + + // Sanity check + FAPI_ASSERT(l_temp > 0, + fapi2::MSS_INVALID_TIMING_VALUE(). + set_VALUE(l_temp). + set_FUNCTION(GET_TCKMAX). + set_DIMM_TARGET(l_target), + "%s. tCKmax invalid (<= 0) : %d", + mss::c_str(l_target), + l_temp); + + o_value = l_temp; + + FAPI_INF( "%s. tCKmax (ps): %d", + mss::c_str(l_target), + o_value); + +fapi_try_exit: + return fapi2::current_err; +} + namespace spd { |