diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C | 469 |
1 files changed, 186 insertions, 283 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C b/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C index 4c88f60d8..b81796771 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -41,10 +41,8 @@ #include <fapi2.H> // mss lib -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> #include <lib/freq/cas_latency.H> -#include <lib/freq/sync.H> -#include <lib/utils/conversions.H> +#include <lib/spd/spd_factory.H> #include <lib/eff_config/timing.H> #include <generic/memory/lib/utils/find.H> #include <lib/utils/checker.H> @@ -56,34 +54,27 @@ using fapi2::TARGET_TYPE_MCA; namespace mss { -/// -/// @brief encoding for MSS_INVALID_TIMING so we can look up functions based on encoding -/// -enum invalid_timing_function_encoding -{ - TAAMIN = 10, - TCKMIN = 11, - TCKMAX = 12, -}; - ///////////////////////// // Member method implementation ///////////////////////// /// -/// @brief Class constructor that retrieves required SPD data held by internal state -/// @param[in] i_target the controller target -/// @param[in] i_caches decoder caches +/// @brief Class constructor that retrieves required SPD data held by internal state +/// @param[in] i_target the controller target +/// @param[in] i_caches decoder caches +/// @param[in] i_supported_freqs vector of supported freqs /// @param[out] o_rc returns FAPI2_RC_SUCCESS if constructor initialzed successfully /// cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const std::vector< std::shared_ptr<spd::decoder> >& i_caches, - fapi2::ReturnCode& o_rc ): + const std::vector<uint32_t>& i_supported_freqs, + fapi2::ReturnCode& o_rc): iv_dimm_list_empty(false), iv_target(i_target), iv_largest_taamin(0), iv_proposed_tck(0), - iv_common_cl(UINT64_MAX) // Masks out supported CLs + iv_common_cl_bitmap(UINT64_MAX), + iv_supported_freqs(i_supported_freqs) { o_rc = fapi2::FAPI2_RC_SUCCESS; @@ -97,16 +88,17 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, for ( const auto& l_cache : i_caches ) { // Retrieve timing values from the SPD + const auto l_target = l_cache->iv_target; uint64_t l_taa_min_in_ps = 0; uint64_t l_tckmax_in_ps = 0; uint64_t l_tck_min_in_ps = 0; FAPI_TRY( get_taamin(l_cache, l_taa_min_in_ps), - "%s. Failed to get tAAmin", mss::c_str(iv_target) ); + "%s. Failed to get tAAmin", mss::c_str(l_target) ); FAPI_TRY( get_tckmax(l_cache, l_tckmax_in_ps), - "%s. Failed to get tCKmax", mss::c_str(iv_target) ); + "%s. Failed to get tCKmax", mss::c_str(l_target) ); FAPI_TRY( get_tckmin(l_cache, l_tck_min_in_ps), - "%s. Failed to get tCKmin", mss::c_str(iv_target) ); + "%s. Failed to get tCKmin", mss::c_str(l_target) ); // Determine largest tAAmin value iv_largest_taamin = std::max(iv_largest_taamin, l_taa_min_in_ps); @@ -133,56 +125,28 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, // Retrieve dimm supported cas latencies from SPD uint64_t l_dimm_supported_cl = 0; FAPI_TRY( l_cache->supported_cas_latencies(l_dimm_supported_cl), - "%s. Failed to get supported CAS latency", mss::c_str(iv_target) ); + "%s. Failed to get supported CAS latency", mss::c_str(l_target) ); // Bitwise ANDING the bitmap from all modules creates a bitmap w/a common CL - iv_common_cl &= l_dimm_supported_cl; + iv_common_cl_bitmap &= l_dimm_supported_cl; } }// caches - // Limit tCK from the max supported dimm speed in the system - // So that this is taken into account when calculating CL - { - // Defaulting to non-zero speed - uint64_t l_freq_override = fapi2::ENUM_ATTR_MSS_FREQ_MT2666; - uint64_t l_tck_override_in_ps = 0; - - FAPI_TRY( select_supported_freq(iv_target, l_freq_override), - "%s. Failed select_supported_freq()", mss::c_str(iv_target) ); - FAPI_TRY( freq_to_ps(l_freq_override, l_tck_override_in_ps), - "%s. Failed freq_to_ps()", mss::c_str(iv_target) ); - - FAPI_INF("%s. Selected supported dimm speed %d MT/s (Clock period %d in ps)", - mss::c_str(iv_target), l_freq_override, l_tck_override_in_ps); - - iv_proposed_tck = std::max( l_tck_override_in_ps, iv_proposed_tck ); - FAPI_INF("%s. Initial proposed tCK in ps: %d", mss::c_str(iv_target), iv_proposed_tck); - - - // Sanity check - FAPI_ASSERT(iv_proposed_tck > 0, - fapi2::MSS_INVALID_CALCULATED_TCK(). - set_TAAMIN(iv_largest_taamin). - set_PROPOSED_TCK(iv_proposed_tck). - set_IS_3DS(iv_is_3ds). - set_FREQUENCY(l_freq_override). - set_MCA_TARGET(iv_target), - "%s. Invalid calculated clock period(<= 0) : %d", - mss::c_str(iv_target), - iv_proposed_tck); - } - // Why didn't I encapsulate common CL operations and checking in a function // like the timing params? Well, I want to check the "final" common CL and // the creation of common CLs (bitwise ANDING) is at the dimm level operation - FAPI_ASSERT(iv_common_cl != 0, + FAPI_ASSERT(iv_common_cl_bitmap != 0, fapi2::MSS_NO_COMMON_SUPPORTED_CL(). - set_CL_SUPPORTED(iv_common_cl). + set_CL_SUPPORTED(iv_common_cl_bitmap). set_MCA_TARGET(iv_target), "%s. No common CAS latencies (CL bitmap = 0)", mss::c_str(iv_target) ); - FAPI_INF("%s. Supported CL bitmap 0x%llX", mss::c_str(iv_target), iv_common_cl); + FAPI_INF("Largest tAAmin (ps): %d, tCKmin (ps): %d, and supported CL bitmap 0x%llX for all modules across %s", + iv_largest_taamin, iv_proposed_tck, iv_common_cl_bitmap, mss::c_str(iv_target)); + + iv_common_cl = integral_bitmap_to_vector(iv_common_cl_bitmap); + FAPI_TRY( mss::required_synch_mode(iv_req_sync_mode) ); fapi_try_exit: o_rc = fapi2::current_err; @@ -191,24 +155,30 @@ fapi_try_exit: /// -/// @brief Constructor that allows the user to set desired data in lieu of SPD -/// @param[in] i_target the controller target -/// @param[in] i_taa_min largest tAAmin we want to set in picoseconds -/// @param[in] i_tck_min proposed tCKmin in picoseconds -/// @param[in] i_common_cl_mask common CAS latency mask we want to force (bitmap) -/// @param[in] i_is_3ds loading::IS_3DS if this is for 3DS, loading::NOT_3DS otherwise +/// @brief Constructor that allows the user to set desired data in lieu of SPD - helpful for testing +/// @param[in] i_target the controller target +/// @param[in] i_taa_min largest tAAmin we want to set in picoseconds +/// @param[in] i_tck_min proposed tCKmin in picoseconds +/// @param[in] i_common_cl_mask common CAS latency mask we want to force (bitmap) +/// @param[in] i_is_3ds loading::IS_3DS if this is for 3DS, loading::NOT_3DS otherwise +/// @param[in] i_req_sync_mode required synchronous mode -- defaulted to SYNCH_MODE_UNDETERMINED, +/// @param[in] i_supported_freqs vector of supported freqs -- defaulted to NIMBUS_SUPPORTED_FREQS /// cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_taa_min, const uint64_t i_tck_min, const uint64_t i_common_cl_mask, - const loading i_is_3ds): + const loading i_is_3ds, + const uint8_t i_req_sync_mode, + const std::vector<uint32_t>& i_supported_freqs): iv_dimm_list_empty(false), iv_target(i_target), iv_largest_taamin(i_taa_min), iv_proposed_tck(i_tck_min), - iv_common_cl(i_common_cl_mask), - iv_is_3ds(i_is_3ds) + iv_is_3ds(i_is_3ds), + iv_common_cl_bitmap(i_common_cl_mask), + iv_req_sync_mode(i_req_sync_mode), + iv_supported_freqs(i_supported_freqs) { const auto l_dimm_list = find_targets<TARGET_TYPE_DIMM>(iv_target); @@ -217,52 +187,122 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, FAPI_INF("cas latency ctor seeing no DIMM on %s", mss::c_str(iv_target)); iv_dimm_list_empty = true; } + + iv_common_cl = integral_bitmap_to_vector(iv_common_cl_bitmap); } /// -/// @brief Calculates CAS latency and checks if it is supported and within JEDEC spec. +/// @brief Calculates CAS latency and checks if it is supported and within JEDEC spec. /// @param[out] o_cas_latency selected CAS latency /// @param[out] o_tck cycle time corresponding to selected CAS latency -/// @return fapi2::FAPI2_RC_SUCCESS if ok +/// @return fapi2::FAPI2_RC_SUCCESS if ok /// fapi2::ReturnCode cas_latency::find_cl(uint64_t& o_cas_latency, uint64_t& o_tck) { - uint64_t l_desired_cas_latency = 0; - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - if(!iv_dimm_list_empty) + // note: iv_common_cl is sorted in increasing order + const uint64_t l_max_cl = iv_common_cl.back(); + const uint64_t l_min_cl = *iv_common_cl.begin(); + + bool l_is_cl_in_common = false; + bool l_is_cl_exceeding_taa = true; + uint64_t l_desired_cas_latency = 0; + bool l_is_1st_iteration = true; + + if(iv_dimm_list_empty) { - // Create a vector filled with common CLs from buffer - std::vector<uint64_t> l_supported_cls = integral_bitmap_to_vector(iv_common_cl); + // If the MCA has no dimm configured then both + // CAS latency and tCK are safe as 0's + o_cas_latency = 0; + o_tck = 0; + return fapi2::FAPI2_RC_SUCCESS; + } - // Make sure we have at least one entry. We should since iv_common_cl is checked in ctor - FAPI_ASSERT( !l_supported_cls.empty(), - fapi2::MSS_NO_COMMON_SUPPORTED_CL(). - set_CL_SUPPORTED(iv_common_cl). - set_MCA_TARGET(iv_target), - "%s. Error making support cas latency vector. No common CAS latencies", - mss::c_str(iv_target) ); + while(!l_is_cl_in_common && l_is_cl_exceeding_taa) + { + if( l_is_1st_iteration ) + { + // Our first run should try to run the highest common supported freq. + // If we don't meet JEDEC requirements then every iteration afterwards + // will bin down + l_is_1st_iteration = false; + FAPI_TRY( apply_freq_constraints<HIGHEST_COMMON>(iv_proposed_tck) ); + } + else + { + // Limit tCK from system constraints such as supported VPD for the system + // as well as MRW frequency overrides, if enabled. This guy will bin freq down until + // we can't and then we fail out, prevents infinite loop when raising tCK + FAPI_TRY( apply_freq_constraints<BIN_DOWN>(iv_proposed_tck) ); + } // For a proposed tCK value between tCKmin(all) and tCKmax, determine the desired CAS Latency. FAPI_TRY( calc_cas_latency(iv_largest_taamin, iv_proposed_tck, l_desired_cas_latency), "%s. Failed to calculate CAS latency", mss::c_str(iv_target) ); - // Chose an actual CAS Latency (CLactual) that is greater than or equal to CLdesired + // Choose an actual CAS Latency (CLactual) that is greater than or equal to CLdesired // and is supported by all modules on the memory channel - FAPI_TRY( is_cl_supported_in_common(l_supported_cls, l_desired_cas_latency), - "%s. Failed to find a common CAS latency supported among all modules", mss::c_str(iv_target) ); + l_is_cl_in_common = is_cl_supported_in_common(iv_common_cl, l_desired_cas_latency); + + while( !l_is_cl_in_common && (l_desired_cas_latency < l_max_cl) ) + { + ++l_desired_cas_latency; + l_is_cl_in_common = is_cl_supported_in_common(iv_common_cl, l_desired_cas_latency); + + } + + // If no such value exists, choose a higher tCKproposed value and repeat until a solution is found. + if(!l_is_cl_in_common) + { + FAPI_INF("Desired CL isn't supported by all DIMMs, choosing a higher tCK"); + continue; + } // Once the calculation of CLactual is completed // verify that this CAS Latency value does not exceed tAAmax. - FAPI_TRY( is_cl_exceeding_taa_max (l_desired_cas_latency, iv_proposed_tck), - "%s. Failed to find a CL value that doesn't exceed tAAmax", mss::c_str(iv_target) ); - } + l_is_cl_exceeding_taa = is_cl_exceeding_taa_max (l_desired_cas_latency, iv_proposed_tck); + + // If not, choose a lower CL value and repeat until a solution is found. + while( l_is_cl_exceeding_taa && (l_desired_cas_latency > l_min_cl) ) + { + --l_desired_cas_latency; + l_is_cl_exceeding_taa = is_cl_exceeding_taa_max (l_desired_cas_latency, iv_proposed_tck); + } + + l_is_cl_in_common = is_cl_supported_in_common(iv_common_cl, l_desired_cas_latency); + + }// end while + + FAPI_ASSERT( !l_is_cl_exceeding_taa, + fapi2::MSS_CL_EXCEEDS_TAA_MAX() + .set_CAS_LATENCY(l_desired_cas_latency) + .set_TCK(iv_proposed_tck) + .set_COMPARE(l_desired_cas_latency * iv_proposed_tck) + .set_TAA_MAX(iv_largest_taamin) + .set_IS_3DS(iv_is_3ds), + "%s: Calculated Cas Latency (CL %d * tCK %d) exceeds JEDEC value of tAAmax %d", + mss::c_str(iv_target), + l_desired_cas_latency, iv_proposed_tck, iv_largest_taamin); + + // If the cas_latency wasn't found, we return an error + // Passing in timing values which were used to calculated i_cas_latency for extra info + // iv_common_cl contains all of the valid cas latencies that populate the input vector + FAPI_ASSERT( l_is_cl_in_common, + fapi2::MSS_FAILED_TO_FIND_SUPPORTED_CL() + .set_DESIRED_CAS_LATENCY(l_desired_cas_latency) + .set_TAA(iv_largest_taamin) + .set_TCK(iv_proposed_tck) + .set_COMMON_CLS(iv_common_cl_bitmap) + .set_MCA_TARGET(iv_target), + "%s. Failed to find a common CAS latency supported among all modules" + "Desired %d, common CL's %016lx", + mss::c_str(iv_target), + l_desired_cas_latency, + iv_common_cl_bitmap); // Update output values after all criteria is met - // If the MCA has no dimm configured than both - // l_desired_latency & iv_proposed_tck is 0 by initialization o_cas_latency = l_desired_cas_latency; o_tck = iv_proposed_tck; @@ -271,10 +311,10 @@ fapi_try_exit: } /// -/// @brief Retrieves SDRAM Minimum CAS Latency Time (tAAmin) from SPD -/// @param[in] i_pDecoder the SPD decoder +/// @brief Retrieves SDRAM Minimum CAS Latency Time (tAAmin) from SPD +/// @param[in] i_pDecoder the SPD decoder /// @param[out] o_value tCKmin value in ps -/// @return FAPI2_RC_SUCCESS iff ok +/// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode cas_latency::get_taamin( const std::shared_ptr<mss::spd::decoder>& i_pDecoder, uint64_t& o_value ) @@ -284,15 +324,18 @@ fapi2::ReturnCode cas_latency::get_taamin( const std::shared_ptr<mss::spd::decod 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( i_pDecoder->medium_timebase(l_medium_timebase), - "%s. Failed medium_timebase()", mss::c_str(iv_target) ); + "%s. Failed medium_timebase()", mss::c_str(l_target) ); FAPI_TRY( i_pDecoder->fine_timebase(l_fine_timebase), - "%s. Failed fine_timebase()", mss::c_str(iv_target) ); + "%s. Failed fine_timebase()", mss::c_str(l_target) ); FAPI_TRY( i_pDecoder->min_taa(l_timing_mtb), - "%s. Failed min_taa()", mss::c_str(iv_target) ); + "%s. Failed min_taa()", mss::c_str(l_target) ); FAPI_TRY( i_pDecoder->fine_offset_min_taa(l_timing_ftb), - "%s. Failed fine_offset_min_taa()", mss::c_str(iv_target) ); + "%s. Failed fine_offset_min_taa()", mss::c_str(l_target) ); // Calculate timing value l_temp = spd::calc_timing_from_timebase(l_timing_mtb, @@ -304,127 +347,28 @@ fapi2::ReturnCode cas_latency::get_taamin( const std::shared_ptr<mss::spd::decod FAPI_ASSERT(l_temp > 0, fapi2::MSS_INVALID_TIMING_VALUE(). set_VALUE(o_value). - set_FUNCTION(TAAMIN). - set_DIMM_TARGET(iv_target), + set_FUNCTION(GET_TAAMIN). + set_DIMM_TARGET(l_target), "%s. tAAmin invalid (<= 0) : %d", - mss::c_str(iv_target), + mss::c_str(l_target), l_temp); o_value = l_temp; FAPI_INF( "%s. tAAmin (ps): %d", - mss::c_str(iv_target), + mss::c_str(l_target), o_value); -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 cas_latency::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 - FAPI_TRY( i_pDecoder->medium_timebase(l_medium_timebase), - "%s. Failed medium_timebase()", mss::c_str(iv_target) ); - FAPI_TRY( i_pDecoder->fine_timebase(l_fine_timebase), - "%s. Failed fine_timebase()", mss::c_str(iv_target) ); - FAPI_TRY( i_pDecoder->min_tck(l_timing_mtb), - "%s. Failed min_tck()", mss::c_str(iv_target) ); - FAPI_TRY( i_pDecoder->fine_offset_min_tck(l_timing_ftb), - "%s. Failed fine_offset_min_tck()", mss::c_str(iv_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(TCKMIN). - set_DIMM_TARGET(iv_target), - "%s. tCKmin invalid (<= 0) : %d", - mss::c_str(iv_target), - l_temp); - - o_value = l_temp; - - FAPI_INF("%s. tCKmin (ps): %d", - mss::c_str(iv_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 cas_latency::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 - FAPI_TRY( i_pDecoder->medium_timebase(l_medium_timebase), - "%s. Failed medium_timebase()", mss::c_str(iv_target) ); - FAPI_TRY( i_pDecoder->fine_timebase(l_fine_timebase), - "%s. Failed fine_timebase()", mss::c_str(iv_target) ); - FAPI_TRY( i_pDecoder->max_tck(l_timing_mtb), - "%s. Failed max_tck()", mss::c_str(iv_target) ); - FAPI_TRY( i_pDecoder->fine_offset_max_tck(l_timing_ftb), - "%s. Failed fine_offset_max_tck()", mss::c_str(iv_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(TCKMAX). - set_DIMM_TARGET(iv_target), - "%s. tCKmax invalid (<= 0) : %d", - mss::c_str(iv_target), - l_temp); - - o_value = l_temp; - - FAPI_INF( "%s. tCKmax (ps): %d", - mss::c_str(iv_target), - o_value); + return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: return fapi2::current_err; } /// -/// @brief Gets max CAS latency (CL) for the appropriate High/Low Range -/// @param[in] i_supported_cl -/// @return the maximum supported CL -/// @note Depends on bit 7 of byte 23 from the DDR4 SPD +/// @brief Gets max CAS latency (CL) for the appropriate High/Low Range +/// @param[in] i_supported_cl +/// @return the maximum supported CL +/// @note Depends on bit 7 of byte 23 from the DDR4 SPD /// inline uint64_t cas_latency::get_max_cl(const fapi2::buffer<uint64_t> i_supported_cl) const { @@ -438,10 +382,10 @@ inline uint64_t cas_latency::get_max_cl(const fapi2::buffer<uint64_t> i_supporte } /// -/// @brief Gets min CAS latency (CL) for the appropriate High/Low Range -/// @param[in] i_supported_cl -/// @return the minimum supported CL -/// @note Depends on bit 7 of byte 23 from the DDR4 SPD +/// @brief Gets min CAS latency (CL) for the appropriate High/Low Range +/// @param[in] i_supported_cl +/// @return the minimum supported CL +/// @note Depends on bit 7 of byte 23 from the DDR4 SPD /// inline uint64_t cas_latency::get_min_cl(const fapi2::buffer<uint64_t>& i_supported_cl) const { @@ -456,10 +400,10 @@ inline uint64_t cas_latency::get_min_cl(const fapi2::buffer<uint64_t>& i_support /// /// @brief Calculates CAS latency time from tCK and tAA -/// @param[in] i_taa cas latency time -/// @param[in] i_tck min cycle time +/// @param[in] i_taa cas latency time +/// @param[in] i_tck min cycle time /// @param[out] o_cas_latency calculated CAS latency -/// @return FAPI2_RC_SUCCESS iff okay +/// @return FAPI2_RC_SUCCESS iff okay /// inline fapi2::ReturnCode cas_latency::calc_cas_latency(const uint64_t i_taa, const uint64_t i_tck, @@ -478,26 +422,26 @@ fapi_try_exit: } /// -/// @brief Helper function to create a vector of supported CAS latencies from a bitmap -/// @param[in] i_common_cl common CAS latency bitmap -/// @return vector of supported CAS latencies +/// @brief Helper function to create a vector of supported CAS latencies from a bitmap +/// @param[in] i_common_cl common CAS latency bitmap +/// @return vector of supported CAS latencies /// std::vector<uint64_t> cas_latency::integral_bitmap_to_vector(const uint64_t i_common_cl) const { std::vector<uint64_t> l_vector; fapi2::buffer<uint64_t> l_cl_mask(i_common_cl); - uint64_t min_cl = get_min_cl(l_cl_mask); - uint64_t max_cl = get_max_cl(l_cl_mask); + const uint64_t l_min_cl = get_min_cl(l_cl_mask); + const uint64_t l_max_cl = get_max_cl(l_cl_mask); - FAPI_INF("%s. min CL %lu", mss::c_str(iv_target), min_cl); - FAPI_INF("%s. max CL %lu", mss::c_str(iv_target), max_cl); + FAPI_INF("%s. min CL %lu", mss::c_str(iv_target), l_min_cl); + FAPI_INF("%s. max CL %lu", mss::c_str(iv_target), l_max_cl); - for(uint64_t l_cas_latency = min_cl; l_cas_latency <= max_cl; ++l_cas_latency) + for(uint64_t l_cas_latency = l_min_cl; l_cas_latency <= l_max_cl; ++l_cas_latency) { // 64 bit is buffer length - indexed at 0 - 63 constexpr uint64_t l_buffer_length = 64 - 1; - uint64_t l_bit_pos = l_buffer_length - (l_cas_latency - min_cl); + uint64_t l_bit_pos = l_buffer_length - (l_cas_latency - l_min_cl); // Traversing through buffer one bit at a time // 0 means unsupported CAS latency @@ -506,8 +450,8 @@ std::vector<uint64_t> cas_latency::integral_bitmap_to_vector(const uint64_t i_co if( l_cl_mask.getBit(l_bit_pos) ) { // I want don't this to print all the time, DBG is fine - FAPI_DBG( "%s. Supported CL (%d) from common CL mask", - mss::c_str(iv_target), l_cas_latency ); + FAPI_DBG( "%s. Supported CL (%d) from common CL mask (0x%llX)", + mss::c_str(iv_target), l_cas_latency, i_common_cl ); l_vector.push_back(l_cas_latency); } @@ -517,85 +461,44 @@ std::vector<uint64_t> cas_latency::integral_bitmap_to_vector(const uint64_t i_co } /// -/// @brief Determines if a requested CAS latency (CL) is supported in the bin of common CLs -/// @param[in] i_common_cls vector of common CAS latencies -/// @param[in] i_cas_latency CAS latency we are comparing against -/// @return FAPI2_RC_SUCCESS iff ok +/// @brief Determines if a requested CAS latency (CL) is supported in the bin of common CLs +/// @param[in] i_common_cls vector of common CAS latencies (must be sorted) +/// @param[in] i_cas_latency CL we are comparing against +/// @return true iff desired CL was found in the bitmap of common CLs, false otherwise /// -inline fapi2::ReturnCode cas_latency::is_cl_supported_in_common(const std::vector<uint64_t>& i_common_cls, +inline bool cas_latency::is_cl_supported_in_common(const std::vector<uint64_t>& i_common_cls, const uint64_t i_cas_latency) const { - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; + const bool l_found = std::binary_search(i_common_cls.begin(), i_common_cls.end(), i_cas_latency); - // Grabbing freq info for ffdc - std::vector<uint32_t> l_mrw_freqs(NUM_MRW_FREQS, 0); - std::vector<uint32_t> l_max_freqs(NUM_MAX_FREQS, 0); + FAPI_INF("Found CL: %d in common CL mask: 0x%llX ? %s for %s", + i_cas_latency, iv_common_cl_bitmap, l_found ? "yes" : "no", mss::c_str(iv_target)); - FAPI_TRY( mss::mrw_supported_freq(l_mrw_freqs.data()) ); - FAPI_TRY( mss::max_allowed_dimm_freq(l_max_freqs.data()) ); - - // If the cas_latency wasn't found, we return an error - // Passing in timing values which were used to calculated i_cas_latency for extra info - // iv_common_cl contains all of the valid cas latencies that populate the input vector - FAPI_ASSERT( std::binary_search(i_common_cls.begin(), i_common_cls.end(), i_cas_latency), - fapi2::MSS_FAILED_TO_FIND_SUPPORTED_CL() - .set_DESIRED_CAS_LATENCY(i_cas_latency) - .set_TAA(iv_largest_taamin) - .set_TCK(iv_proposed_tck) - .set_COMMON_CLS(iv_common_cl) - .set_MSS_MRW_FREQ_0(l_mrw_freqs[0]) - .set_MSS_MRW_FREQ_1(l_mrw_freqs[1]) - .set_MSS_MRW_FREQ_2(l_mrw_freqs[2]) - .set_MSS_MRW_FREQ_3(l_mrw_freqs[3]) - .set_MSS_MAX_FREQ_0(l_max_freqs[0]) - .set_MSS_MAX_FREQ_1(l_max_freqs[1]) - .set_MSS_MAX_FREQ_2(l_max_freqs[2]) - .set_MSS_MAX_FREQ_3(l_max_freqs[3]) - .set_MSS_MAX_FREQ_4(l_max_freqs[4]) - .set_MCA_TARGET(iv_target), - "%s. Failed to find a common CAS latency supported among all modules" - "Desired %d, common CL's %016lx", - mss::c_str(iv_target), - i_cas_latency, - iv_common_cl); -fapi_try_exit: - return fapi2::current_err; + return l_found; } /// -/// @brief Checks that CAS latency doesn't exceed largest CAS latency time -/// @param[in] i_cas_latency cas latency -/// @param[in] i_tck cycle time -/// @return FAPI2_RC_SUCCESS iff ok +/// @brief Checks that CAS latency doesn't exceed largest CAS latency time +/// @param[in] i_cas_latency cas latency +/// @param[in] i_tck cycle time +/// @return true iff CL exceeds tAAmax, false otherwise /// -inline fapi2::ReturnCode cas_latency::is_cl_exceeding_taa_max(const uint64_t i_cas_latency, +inline bool cas_latency::is_cl_exceeding_taa_max(const uint64_t i_cas_latency, const uint64_t i_tck) const { - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; // JEDEC SPD spec requirement const size_t l_taa_max = (iv_is_3ds == loading::NOT_3DS) ? TAA_MAX_DDR4 : TAA_MAX_DDR4_3DS; + const bool l_is_cl_exceeding_taa = (i_cas_latency * i_tck) > l_taa_max; - FAPI_INF("%s. CL (%d) * tCK (%d) = %d > %d", + FAPI_INF("%s. CL (%d) * tCK (%d) = %d > %d ? %s", mss::c_str(iv_target), i_cas_latency, i_tck, i_cas_latency * i_tck, - l_taa_max); + l_taa_max, + l_is_cl_exceeding_taa ? "yes" : "no"); - FAPI_ASSERT( ((i_cas_latency * i_tck) <= l_taa_max), - fapi2::MSS_CL_EXCEEDS_TAA_MAX() - .set_CAS_LATENCY(i_cas_latency) - .set_TCK(i_tck) - .set_COMPARE(i_cas_latency * i_tck) - .set_TAA_MAX(l_taa_max) - .set_IS_3DS(iv_is_3ds), - "%s: Calculated Cas Latency (i_cas_latency %d * i_tck %d) exceeds JEDEC value of TAA MAX %d", - mss::c_str(iv_target), - i_cas_latency, - i_tck, - l_taa_max); -fapi_try_exit: - return fapi2::current_err; + return l_is_cl_exceeding_taa; } }// mss |