summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H')
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
index 7b8cb4fe9..06345713c 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
@@ -22,3 +22,183 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file axone_sync.H
+/// @brief Synchronous function implementations for Axone
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_SYNC_H_
+#define _MSS_SYNC_H_
+
+#include <map>
+#include <vector>
+
+#include <fapi2.H>
+#include <mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <lib/shared/axone_consts.H>
+#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/mss_math.H>
+
+namespace mss
+{
+
+// List of the OMI frequencies for Axone
+// Note: these need to be sorted so binary search works
+static const std::vector<uint64_t> AXONE_OMI_FREQS =
+{
+ 21330, // fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_21_33GBPS,
+ 23460, // fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_23_46GBPS,
+ 25600, // fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_25_60GBPS,
+};
+
+///
+/// @brief Converts an OMI frequency attribute enum to the corresponding OMI frequency
+/// @param[in] i_omi_enum a frequency enum value that is to be converted
+/// @return the corresponding OMI frequency
+///
+inline uint64_t convert_omi_freq_attr_to_freq(const fapi2::ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_Type
+ i_omi_enum)
+{
+ switch (i_omi_enum)
+ {
+ case fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_21_33GBPS:
+ return 21330;
+
+ case fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_23_46GBPS:
+ return 23460;
+
+ case fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_25_60GBPS:
+ return 25600;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::P9A_MSS_UNSUPPORTED_OMI_FREQ()
+ .set_OMI_FREQ_ENUM(i_omi_enum),
+ "freq system saw an unsupported OMI frequency with enum value: %d",
+ i_omi_enum );
+ }
+
+fapi_try_exit:
+ return 0;
+}
+
+///
+/// @brief Converts a DDR frequency to the corresponding OMI frequency
+/// @param[in] i_target the port target
+/// @param[in] i_ddr_freq a frequency value that is to be converted
+/// @param[out] o_omi_freq the corresponding OMI frequency
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+inline fapi2::ReturnCode convert_ddr_freq_to_omi_freq(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_ddr_freq,
+ uint64_t& o_omi_freq)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+ constexpr uint64_t ROUND_UNITS = 10;
+
+ // Get the OMI to DDR freq ratio
+ uint8_t l_ratio[TT::MAX_DIMM_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_host_to_ddr_speed_ratio(i_target, l_ratio));
+
+ // Multiply by the ratio and round to the nearest 10GBPS
+ FAPI_TRY(mss::divide_and_round((i_ddr_freq * l_ratio[0]), ROUND_UNITS, o_omi_freq));
+ o_omi_freq *= ROUND_UNITS;
+ FAPI_DBG("For ratio %d and DDR freq %d, corresponding OMI freq is %d", l_ratio[0], i_ddr_freq, o_omi_freq);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Converts an OMI frequency to the corresponding DDR frequency
+/// @param[in] i_target the port target
+/// @param[in] i_omi_freq a frequency value that is to be converted
+/// @param[out] o_ddr_freq the corresponding DDR frequency
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+inline fapi2::ReturnCode convert_omi_freq_to_ddr_freq(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_omi_freq,
+ uint64_t& o_ddr_freq)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+
+ // Get the OMI to DDR freq ratio
+ uint8_t l_ratio[TT::MAX_DIMM_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_host_to_ddr_speed_ratio(i_target, l_ratio));
+
+ FAPI_TRY(mss::divide_and_round(i_omi_freq, static_cast<uint64_t>(l_ratio[0]), o_ddr_freq),
+ "%s freq system saw a zero Host (OMI) to DDR frequency ratio", mss::c_str(i_target));
+ FAPI_DBG( "For ratio %d and OMI freq %d, corresponding DDR freq is %d", l_ratio[0], i_omi_freq, o_ddr_freq);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Checks to see if a passed in value could be a valid OMI frequency
+/// @param[in] i_target the port target
+/// @param[in] i_proposed_freq a frequency value that is to be checked
+/// @param[out] o_valid boolean whether the value is a valid OMI frequency
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+inline fapi2::ReturnCode is_omi_freq_valid (const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_proposed_freq,
+ uint64_t& o_valid)
+{
+ uint64_t l_proposed_omi_freq = 0;
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(i_target, i_proposed_freq, l_proposed_omi_freq));
+
+ o_valid = std::binary_search(AXONE_OMI_FREQS.begin(), AXONE_OMI_FREQS.end(), l_proposed_omi_freq);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Retrieves a mapping of MSS frequency values per port target
+/// @param[in] i_targets vector of port targets
+/// @param[out] o_freq_map dimm speed map <key, value> = (port target, frequency)
+/// @param[out] o_is_speed_equal holds whether map dimm speed is equal
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode dimm_speed_map(const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >& i_targets,
+ std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& o_freq_map,
+ speed_equality& o_is_speed_equal);
+
+///
+/// @brief Helper function to deconfigure MEM_PORT target
+/// @param[in] i_target the port target
+/// @param[in] i_dimm_speed dimm speed in MT/s
+/// @param[in] i_omi_freq OMI freq in MHz
+/// @return true if hardware was deconfigured
+///
+bool deconfigure(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_dimm_speed,
+ const uint32_t i_omi_freq);
+
+///
+/// @brief Selects synchronous mode and performs requirements enforced by selected port frequency
+/// @param[in] i_freq_map dimm speed mapping
+/// @param[in] i_equal_dimm_speed tracks whether map has equal dimm speeds
+/// @param[in] i_omi_freq OMI frequency
+/// @param[out] o_selected_sync_mode final synchronous mode
+/// @param[out] o_selected_omi_freq final freq selected, only valid if final sync mode is in-sync
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& i_freq_map,
+ const speed_equality i_equal_dimm_speed,
+ const uint32_t i_omi_freq,
+ uint8_t& o_selected_sync_mode,
+ uint64_t& o_selected_omi_freq);
+
+}// mss
+
+#endif
OpenPOWER on IntegriCloud