diff options
Diffstat (limited to 'src/import')
5 files changed, 93 insertions, 33 deletions
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 c6ac6db5a..ae55f78e0 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 @@ -48,6 +48,7 @@ #include <lib/shared/mss_kind.H> #include <lib/phy/dp16.H> #include <lib/mss_attribute_accessors_manual.H> +#include <generic/memory/lib/utils/freq/gen_mss_freq.H> namespace mss { @@ -4496,8 +4497,10 @@ fapi2::ReturnCode eff_lrdimm::dram_rtt_park() FAPI_TRY( eff_dram_rtt_park(iv_mcs, &l_mcs_attrs[0][0][0]) ); // Get the value from the LRDIMM SPD - FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks0_1(iv_freq, l_decoder_val_01) ); - FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks2_3(iv_freq, l_decoder_val_23) ); + FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks0_1(iv_freq, l_decoder_val_01), + "%s failed to decode RTT_PARK for ranks 0/1", mss::c_str(iv_mcs) ); + FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks2_3(iv_freq, l_decoder_val_23), + "%s failed to decode RTT_PARK for ranks 2/3", mss::c_str(iv_mcs) ); // Setting the four rank values for this dimm // Rank 0 and 1 have the same value, l_decoder_val_01 @@ -5249,21 +5252,10 @@ fapi2::ReturnCode eff_dimm::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_t // Find our blob in the vector of blob pointers uint8_t* l_mt_blob = l_mt_blobs[mss::index(p)]; - uint64_t l_rank_count_dimm[MAX_DIMM_PER_PORT] = {}; - // If we don't have any DIMM, don't worry about it. This will just drop the blob full of 0's into our index. - // This will fill the VPD attributes with 0's which is perfectly ok. - for (const auto& d : mss::find_targets<TARGET_TYPE_DIMM>(p)) - { - uint8_t l_num_master_ranks = 0; - FAPI_TRY( mss::eff_num_master_ranks_per_dimm(d, l_num_master_ranks) ); - l_rank_count_dimm[mss::index(d)] = l_num_master_ranks; - } - - // This value will, of course, be 0 if there is no DIMM in the port. - // Which shouldn't happen w/the DIMM check above. - l_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0]; - l_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1]; + // Sets up the number of ranks for this port + FAPI_TRY(configure_vpd_ranks<mss::proc_type::NIMBUS>(p, l_vpd_info), "%s failed to configure the ranks on the VPD", + mss::c_str(p)); FAPI_INF("%s. VPD info - rank count for dimm_0: %d, dimm_1: %d", mss::c_str(i_target), l_vpd_info.iv_rank_count_dimm_0, l_vpd_info.iv_rank_count_dimm_1); diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C index 688875f34..0a1f6b8b7 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C @@ -131,8 +131,8 @@ fapi2::ReturnCode set_freq<mss::proc_type::NIMBUS>( /// /// @brief Gets the number of master ranks per DIMM - specialization for NIMBUS and MCA -/// @param[in] i_target the target on which to set the frequency values -/// @param[out] o_master_ranks number of master ranks per DIMM +/// @param[in] i_target the target on which to get the number of master ranks per DIMM +/// @param[out] o_master_ranks number of master ranks per DIMM /// @return FAPI2_RC_SUCCESS iff ok /// template<> @@ -155,6 +155,20 @@ fapi2::ReturnCode max_allowed_dimm_freq<mss::proc_type::NIMBUS>(uint32_t* o_allo } /// +/// @brief Gets the DIMM type - specialization for NIMBUS and MCA +/// @param[in] i_target the target on which to get the DIMM types +/// @param[out] o_dimm_type DIMM types +/// @return FAPI2_RC_SUCCESS iff ok +/// +template<> +fapi2::ReturnCode get_dimm_type<mss::proc_type::NIMBUS>( + const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + uint8_t* o_dimm_type) +{ + return mss::eff_dimm_type(i_target, o_dimm_type); +} + +/// /// @brief Update supported frequency scoreboard according to processor limits - specialization for NIMBUS and MCBIST /// @param[in] i_target processor frequency domain /// @param[in,out] io_scoreboard scoreboard of port targets supporting each frequency diff --git a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H index 3670a8f89..59ea61fab 100644 --- a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H +++ b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H @@ -3368,7 +3368,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_1866 { public: - static constexpr size_t COMPARISON_VAL = 0b01; + static constexpr size_t COMPARISON_VAL = 0b111; static constexpr const char* FIELD_STR = "DRAM ODT RTT_PARK, package rank 0, 1 for data rates <= 1866"; template <typename T> @@ -3387,7 +3387,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_2400 { public: - static constexpr size_t COMPARISON_VAL = 0b01; + static constexpr size_t COMPARISON_VAL = 0b111; static constexpr const char* FIELD_STR = "DRAM ODT RTT_PARK, package rank 0, 1 for 1866 < data rates <= 2400"; template <typename T> @@ -3406,7 +3406,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_3200 { public: - static constexpr size_t COMPARISON_VAL = 0b01; + static constexpr size_t COMPARISON_VAL = 0b111; static constexpr const char* FIELD_STR = "DRAM ODT RTT_PARK, package rank 0, 1 for 2400 < data rates <= 3200"; template <typename T> @@ -3425,7 +3425,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_1866 { public: - static constexpr size_t COMPARISON_VAL = 0b01; + static constexpr size_t COMPARISON_VAL = 0b111; static constexpr const char* FIELD_STR = "DRAM ODT RTT_PARK, package rank 2, 3 for data rates <= 1866"; template <typename T> @@ -3444,7 +3444,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_2400 { public: - static constexpr size_t COMPARISON_VAL = 0b01; + static constexpr size_t COMPARISON_VAL = 0b111; static constexpr const char* FIELD_STR = "DRAM ODT RTT_PARK, package rank 2, 3 for 1866 < data rates <= 2400"; template <typename T> @@ -3463,7 +3463,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_3200 { public: - static constexpr size_t COMPARISON_VAL = 0b01; + static constexpr size_t COMPARISON_VAL = 0b111; static constexpr const char* FIELD_STR = "DRAM ODT RTT_PARK, package rank 2, 3 for 2400 < data rates <= 3200"; template <typename T> diff --git a/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H b/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H index 655146f87..5abfbfc00 100644 --- a/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H +++ b/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H @@ -43,6 +43,7 @@ #include <generic/memory/lib/utils/freq/cas_latency.H> #include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H> #include <generic/memory/lib/data_engine/pre_data_init.H> +#include <generic/memory/lib/utils/count_dimm.H> #include <vpd_access.H> namespace mss @@ -75,8 +76,8 @@ fapi2::ReturnCode set_freq(const fapi2::Target<T>& i_target, /// @brief Gets the number of master ranks per DIMM /// @tparam P mss::proc_type on which to operate /// @tparam T fapi2::TargetType on which to set the frequency -/// @param[in] i_target the target on which to set the frequency values -/// @param[out] o_master_ranks number of master ranks per DIMM +/// @param[in] i_target the target on which to get the number of master ranks per DIMM +/// @param[out] o_master_ranks number of master ranks per DIMM /// @return FAPI2_RC_SUCCESS iff ok /// template<mss::proc_type P, fapi2::TargetType T> @@ -84,6 +85,63 @@ fapi2::ReturnCode get_master_rank_per_dimm(const fapi2::Target<T>& i_target, uint8_t* o_master_ranks); /// +/// @brief Gets the number of master ranks per DIMM +/// @tparam P mss::proc_type on which to operate +/// @tparam T fapi2::TargetType on which to get the DIMM types +/// @param[in] i_target the target on which to get the DIMM types +/// @param[out] o_dimm_type DIMM types +/// @return FAPI2_RC_SUCCESS iff ok +/// +template<mss::proc_type P, fapi2::TargetType T> +fapi2::ReturnCode get_dimm_type(const fapi2::Target<T>& i_target, + uint8_t* o_dimm_type); + +/// +/// @brief Configures the number of ranks in the VPD accessor dependent upon DIMM type +/// @tparam P mss::proc_type on which to operate +/// @tparam TT Traits associated with the processor type +/// @param[in] i_target the target on which to set the frequency values +/// @param[in,out] io_vpd_info VPD information that needs to be configured +/// @return FAPI2_RC_SUCCESS iff ok +/// +template<mss::proc_type P, typename TT = mss::frequency_traits<P>> +fapi2::ReturnCode configure_vpd_ranks(const fapi2::Target<TT::PORT_TARGET_TYPE>& i_target, + fapi2::VPDInfo<TT::VPD_TARGET_TYPE>& io_vpd_info) +{ + uint8_t l_rank_count_dimm[TT::MAX_DIMM_PER_PORT] = {}; + uint8_t l_dimm_type[TT::MAX_DIMM_PER_PORT] = {}; + + // ATTR to update + // Note: this flat out assumes that we have two DIMM per port max. This goes against the directive to have arrays be dynamic in length and derived from ATTR's + FAPI_TRY( get_master_rank_per_dimm<P>(i_target, &(l_rank_count_dimm[0])) ); + FAPI_TRY( get_dimm_type<P>(i_target, &(l_dimm_type[0])) ); + + // So for LRDIMM, our SI works a bit differently than for non-LRDIMM + // LRDIMM's have buffers that operate on a per-DIMM basis across multiple ranks + // As such, they act as a single load, similar to a 1R DIMM would + // per the IBM signal integrity team, the 1R DIMM settings should be used for LRDIMM's + // So, if we are LRDIMM's and have ranks, we want to only note it as a 1R DIMM for purposes of querying the VPD + FAPI_DBG("%s for DIMM 0 rank count %u dimm type %u %s", + mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM"); + FAPI_DBG("%s for DIMM 1 rank count %u dimm type %u %s", + mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM"); + + l_rank_count_dimm[0] = ((l_dimm_type[0] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[0] > 0)) ? 1 : l_rank_count_dimm[0]; + l_rank_count_dimm[1] = ((l_dimm_type[1] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[1] > 0)) ? 1 : l_rank_count_dimm[1]; + + FAPI_DBG("after LR modification %s for DIMM 0 rank count %u dimm type %u %s", + mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM"); + FAPI_DBG("after LR modification %s for DIMM 1 rank count %u dimm type %u %s", + mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM"); + + io_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0]; + io_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1]; + +fapi_try_exit: + return fapi2::current_err; +} + +/// /// @brief Sets frequency attributes /// @tparam P mss::proc_type on which to operate /// @tparam TT Traits associated with the processor type @@ -208,7 +266,6 @@ template<mss::proc_type P, typename TT = mss::frequency_traits<P>> fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target, std::vector<std::vector<uint32_t>>& o_vpd_supported_freqs) { - uint8_t l_rank_count_dimm[TT::MAX_DIMM_PER_PORT] = {}; uint8_t l_vpd_blob[TT::VPD_KEYWORD_MAX] = {}; // This bitmap will keep track of the ports we visit. @@ -244,12 +301,8 @@ fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE> continue; } - // ATTR to update - // Note: this flat out assumes that we have two DIMM per port max. This goes against the directive to have arrays be dynamic in length and derived from ATTR's - FAPI_TRY( get_master_rank_per_dimm<P>(p, &(l_rank_count_dimm[0])) ); - - l_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0]; - l_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1]; + // Configures the number of ranks for the VPD configuration + FAPI_TRY( configure_vpd_ranks<P>(p, l_vpd_info), "%s failed to configure VPD ranks", mss::c_str(p)); l_vpd_info.iv_is_config_ffdc_enabled = false; // Iterate through all supported memory freqs diff --git a/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H b/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H index ba63170ed..791fa5b97 100644 --- a/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H +++ b/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H @@ -83,6 +83,7 @@ class frequency_traits<mss::proc_type::NIMBUS> static constexpr uint64_t VPD_KEYWORD_MAX = 255; static constexpr const char* VPD_BLOB_NAME = "MR"; static constexpr auto VPD_BLOB = fapi2::MemVpdData::MR; + static constexpr auto LRDIMM_TYPE = fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM; // Coding minion, why have these explicitly defined frequency values? // Isn't the supported frequency vector used for this purpose? |