summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
diff options
context:
space:
mode:
authorJacob Harvey <jlharvey@us.ibm.com>2017-02-28 12:59:13 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-06-11 14:39:59 -0400
commitb79fd9671a34ff842b4c1d5beb6695feb5dc5b62 (patch)
tree5cce1cc047dd54903e82ca51c68741a367b59e55 /src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
parent987752d8494c4ac2f0dac41b72c21b5cbb0d0488 (diff)
downloadtalos-hostboot-b79fd9671a34ff842b4c1d5beb6695feb5dc5b62.tar.gz
talos-hostboot-b79fd9671a34ff842b4c1d5beb6695feb5dc5b62.zip
Cleaning up error handling for mss_freq L3
Change-Id: I799ed61062720822e8225efa8d0381a4c73a879c Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37283 Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Reviewed-by: Thi N. Tran <thi@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37313 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H77
1 files changed, 72 insertions, 5 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
index a5d8dfaff..3c3b89d7e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
@@ -27,7 +27,7 @@
/// @brief Synchronous function implementations
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP
@@ -50,6 +50,24 @@ enum class speed_equality : uint8_t
};
///
+/// @brief Checks to see if a passed in value could be a valid nest frequency
+/// @param[in] i_proposed_freq a frequency value that is to be checked
+/// @return boolean true, false whether the value is a valid nest frequency
+///
+inline bool is_nest_freq_valid (const uint64_t i_proposed_freq)
+{
+ std::vector<uint64_t> l_nest_freqs_supported = { fapi2::ENUM_ATTR_FREQ_PB_MHZ_1600,
+ fapi2::ENUM_ATTR_FREQ_PB_MHZ_1866,
+ fapi2::ENUM_ATTR_FREQ_PB_MHZ_2000,
+ fapi2::ENUM_ATTR_FREQ_PB_MHZ_2133,
+ fapi2::ENUM_ATTR_FREQ_PB_MHZ_2400
+ };
+ std::sort(l_nest_freqs_supported.begin(), l_nest_freqs_supported.end());
+
+ return ( std::binary_search(l_nest_freqs_supported.begin(), l_nest_freqs_supported.end(), i_proposed_freq) );
+}
+
+///
/// @brief Retrieves a mapping of MSS frequency values per mcbist target
/// @param[in] i_targets vector of controller targets
/// @param[out] o_freq_map dimm speed map <key, value> = (mcbist target, frequency)
@@ -94,7 +112,7 @@ fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_T
/// @param[in] vector of MVPD freqs
/// @param[in] vector of max allowed freqs
/// @param[in] bool whether or not we're forced into sync mode
-/// @param[in,out] reference to a std::vector<uint32_t> space to put the sorted vector
+/// @param[out] reference to a std::vector<uint32_t> space to put the sorted vector
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Taken from ATTR_MSS_MRW_SUPPORTED_FREQ. The result is sorted so such that the min
/// supported freq is std::vector<>.begin and the max is std::vector<>.end - 1. You can
@@ -104,19 +122,19 @@ fapi2::ReturnCode supported_freqs_helper(const fapi2::Target<fapi2::TARGET_TYPE_
const std::vector<uint32_t>& i_freqs,
const std::vector<uint32_t>& i_max_freqs,
const bool i_req_sync_mode,
- std::vector<uint32_t>& io_freqs);
+ std::vector<uint32_t>& o_freqs);
///
/// @brief Create and sort a vector of supported MT/s (freq)
/// @param[in] MCA target for which to get the DIMM configs
-/// @param[in,out] reference to a std::vector<uint32_t> space to put the sorted vector
+/// @param[out] reference to a std::vector<uint32_t> space to put the sorted vector
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Taken from ATTR_MSS_MRW_SUPPORTED_FREQ. The result is sorted so such that the min
/// supported freq is std::vector<>.begin and the max is std::vector<>.end - 1. You can
/// search the resulting vector for valid frequencies as it is sorted.
///
fapi2::ReturnCode supported_freqs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- std::vector<uint32_t>& io_freqs);
+ std::vector<uint32_t>& o_freqs);
///
/// @brief Return whether a given freq is supported
@@ -126,6 +144,55 @@ fapi2::ReturnCode supported_freqs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i
///
bool is_freq_supported(const uint32_t i_freq, const std::vector<uint32_t>& i_freqs);
+///
+/// @brief Selects DIMM frequency to run based on supported system frequencies
+/// @tparam T the fapi2::TargetType for which the DIMM information exists.
+/// @param[in] target from which to get the dimm information
+/// @param[in,out] io_dimm_freq input is current dimm freq & output is next
+/// lowest dimm freq between 1866 MT/s (-5% margin) - 2666 MT/s (+5% margin)
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note Frequency values obtained from:
+/// @note From P9 User's Manual Version 0.8 - June 08, 2015
+/// @note Memory Controller Unit - page 199 of 456
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode select_supported_freq(const fapi2::Target<T>& i_target, uint64_t& io_dimm_freq)
+{
+ std::vector<uint32_t> l_freqs;
+
+ FAPI_TRY( mss::supported_freqs(i_target, l_freqs) );
+
+ {
+ // supported_freqs sorts so upper_bound is valid.
+ auto iterator = std::upper_bound(l_freqs.begin(), l_freqs.end(), io_dimm_freq);
+
+ auto l_supported = l_freqs.begin();
+
+ // Doing this because the HB compiler freaks out if we have it within the FAPI_ASSERT.
+ // Outputting the value and then incrementing the iterator, that's why it's a post increment
+ const auto l_0 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0;
+ const auto l_1 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0;
+ const auto l_2 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0;
+ const auto l_3 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0;
+
+ FAPI_ASSERT( (iterator != l_freqs.begin() && l_freqs.size() != 0),
+ fapi2::MSS_SELECTED_FREQ_NOT_SUPPORTED()
+ .set_FREQ(io_dimm_freq)
+ .set_SUPPORTED_FREQ_0( l_0 )
+ .set_SUPPORTED_FREQ_1( l_1 )
+ .set_SUPPORTED_FREQ_2( l_2 )
+ .set_SUPPORTED_FREQ_3( l_3 )
+ .set_TARGET(i_target),
+ "%s Error finding selected freq (%d) from list",
+ mss::c_str(i_target),
+ io_dimm_freq );
+ // Upper bound checks just greater than, not equals. Return one up
+ io_dimm_freq = *(--iterator);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
}// mss
OpenPOWER on IntegriCloud