summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/dimm
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/dimm')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H93
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H72
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C97
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H25
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H4
5 files changed, 223 insertions, 68 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
index 746b1621e..89f9539ae 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -830,6 +830,9 @@ struct mrs00_data
///
mrs00_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+ // Delete MRS00 default constructor
+ mrs00_data() = delete;
+
///
/// @brief Less than operator
/// @param[in] i_rhs right hand comparison operator
@@ -873,6 +876,16 @@ struct mrs00_data
return iv_burst_length < i_rhs.iv_burst_length;
}
+ ///
+ /// @brief Equal to operator
+ /// @param[in] i_rhs right hand comparison operator
+ /// @bool true if this object is equal to i_rhs
+ ///
+ bool operator==(const mss::ddr4::mrs00_data& i_rhs) const
+ {
+ return !((*this < i_rhs) || (i_rhs < *this));
+ }
+
uint8_t iv_burst_length;
uint8_t iv_read_burst_type;
uint8_t iv_dll_reset;
@@ -905,6 +918,9 @@ struct mrs01_data
///
mrs01_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+ // Delete MRS01 default constructor
+ mrs01_data() = delete;
+
///
/// @brief Less than operator
/// @param[in] i_rhs right hand comparison operator
@@ -958,6 +974,16 @@ struct mrs01_data
return iv_dll_enable < i_rhs.iv_dll_enable;
}
+ ///
+ /// @brief Equal to operator
+ /// @param[in] i_rhs right hand comparison operator
+ /// @bool true if this object is equal to i_rhs
+ ///
+ bool operator==(const mss::ddr4::mrs01_data& i_rhs) const
+ {
+ return !((*this < i_rhs) || (i_rhs < *this));
+ }
+
uint8_t iv_dll_enable;
uint8_t iv_odic[MAX_RANK_PER_DIMM];
uint8_t iv_additive_latency;
@@ -991,6 +1017,9 @@ struct mrs02_data
///
mrs02_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+ // Delete MRS02 default constructor
+ mrs02_data() = delete;
+
///
/// @brief Less than operator
/// @param[in] i_rhs right hand comparison operator
@@ -1024,6 +1053,16 @@ struct mrs02_data
return iv_cwl < i_rhs.iv_cwl;
}
+ ///
+ /// @brief Equal to operator
+ /// @param[in] i_rhs right hand comparison operator
+ /// @bool true if this object is equal to i_rhs
+ ///
+ bool operator==(const mss::ddr4::mrs02_data& i_rhs) const
+ {
+ return !((*this < i_rhs) || (i_rhs < *this));
+ }
+
uint8_t iv_lpasr;
uint8_t iv_cwl;
uint8_t iv_write_crc;
@@ -1055,6 +1094,9 @@ struct mrs03_data
///
mrs03_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+ // Delete MRS03 default constructor
+ mrs03_data() = delete;
+
///
/// @brief Less than operator
/// @param[in] i_rhs right hand comparison operator
@@ -1110,6 +1152,16 @@ struct mrs03_data
return iv_mpr_page < i_rhs.iv_mpr_page;
}
+ ///
+ /// @brief Equal to operator
+ /// @param[in] i_rhs right hand comparison operator
+ /// @bool true if this object is equal to i_rhs
+ ///
+ bool operator==(const mss::ddr4::mrs03_data& i_rhs) const
+ {
+ return !((*this < i_rhs) || (i_rhs < *this));
+ }
+
uint8_t iv_mpr_mode;
uint8_t iv_mpr_page;
uint8_t iv_geardown;
@@ -1144,6 +1196,9 @@ struct mrs04_data
///
mrs04_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+ // Delete MRS04 default constructor
+ mrs04_data() = delete;
+
///
/// @brief Less than operator
/// @param[in] i_rhs right hand comparison operator
@@ -1217,6 +1272,16 @@ struct mrs04_data
return iv_max_pd_mode < i_rhs.iv_max_pd_mode;
}
+ ///
+ /// @brief Equal to operator
+ /// @param[in] i_rhs right hand comparison operator
+ /// @bool true if this object is equal to i_rhs
+ ///
+ bool operator==(const mss::ddr4::mrs04_data& i_rhs) const
+ {
+ return !((*this < i_rhs) || (i_rhs < *this));
+ }
+
uint8_t iv_max_pd_mode;
uint8_t iv_temp_refresh_range;
uint8_t iv_temp_ref_mode;
@@ -1254,6 +1319,9 @@ struct mrs05_data
///
mrs05_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+ // Delete MRS05 default constructor
+ mrs05_data() = delete;
+
///
/// @brief Less than operator
/// @param[in] i_rhs right hand comparison operator
@@ -1317,6 +1385,16 @@ struct mrs05_data
return iv_ca_parity_latency < i_rhs.iv_ca_parity_latency;
}
+ ///
+ /// @brief Equal to operator
+ /// @param[in] i_rhs right hand comparison operator
+ /// @bool true if this object is equal to i_rhs
+ ///
+ bool operator==(const mss::ddr4::mrs05_data& i_rhs) const
+ {
+ return !((*this < i_rhs) || (i_rhs < *this));
+ }
+
uint8_t iv_ca_parity_latency;
uint8_t iv_crc_error_clear;
uint8_t iv_ca_parity_error_status;
@@ -1352,6 +1430,9 @@ struct mrs06_data
///
mrs06_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+ // Delete MRS06 default constructor
+ mrs06_data() = delete;
+
///
/// @brief Less than operator
/// @param[in] i_rhs right hand comparison operator
@@ -1388,6 +1469,16 @@ struct mrs06_data
return memcmp(iv_vrefdq_train_value, i_rhs.iv_vrefdq_train_value, sizeof(i_rhs.iv_vrefdq_train_value)) < MEMCMP_EQUAL;
}
+ ///
+ /// @brief Equal to operator
+ /// @param[in] i_rhs right hand comparison operator
+ /// @bool true if this object is equal to i_rhs
+ ///
+ bool operator==(const mss::ddr4::mrs06_data& i_rhs) const
+ {
+ return !((*this < i_rhs) || (i_rhs < *this));
+ }
+
uint8_t iv_vrefdq_train_value[MAX_RANK_PER_DIMM];
uint8_t iv_vrefdq_train_range[MAX_RANK_PER_DIMM];
uint8_t iv_vrefdq_train_enable[MAX_RANK_PER_DIMM];
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H
index 271e90368..748907d44 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -208,7 +208,8 @@ class commands
public:
// Typdefs to make the code more readable
typedef std::pair<fapi2::Target<fapi2::TARGET_TYPE_DIMM>, uint64_t> rank_target;
- typedef std::map<D, std::vector<uint64_t> > mrs_drams;
+ typedef std::pair<D, std::vector<uint64_t> > mrs_dram;
+ typedef std::vector<mrs_dram> mrs_drams_vect;
///
/// @brief Base constructor
@@ -267,7 +268,57 @@ class commands
set_FUNCTION(mss::ffdc_function_codes::PDA_ADD_COMMAND),
"%s does not have rank %lu", mss::c_str(i_target), i_rank);
- iv_commands[ {i_target, i_rank}][i_mrs].push_back(i_dram);
+ // Does the compression
+ {
+ // If the rank/target pair does not exist simply insert a new pair
+ const rank_target RANK_TARGET = {i_target, i_rank};
+ // Note: technically this should be const auto to keep the iterator at the found position
+ // However, HB asumes that the const in front of the auto makes this a const_iterator
+ // Note: Find value from key prints an error if the key could not be found. We don't want that
+ // Rolling our own below
+ // TODO:RTC184689 Create find_iterator_from_value and find_iterator_from_key
+ auto l_it = std::find_if(iv_commands.begin(),
+ iv_commands.end(), [&RANK_TARGET](const std::pair<rank_target, mrs_drams_vect>& i_rhs)
+ {
+ return RANK_TARGET == i_rhs.first;
+ });
+
+ if( l_it == iv_commands.end() )
+ {
+ FAPI_INF("%s rank%lu NEW target rank info DRAM%lu", mss::c_str(i_target), i_rank, i_dram);
+ mrs_drams_vect l_mrs_dram = {{ i_mrs, { i_dram } }};
+ iv_commands.push_back( { RANK_TARGET, l_mrs_dram } );
+ }
+ // The rank/target exist
+ else
+ {
+ // Does the MRS exist?
+ auto& l_mrs_vect = l_it->second;
+ // Note: technically this should be const auto to keep the iterator at the found position
+ // However, HB asumes that the const in front of the auto makes this a const_iterator
+ // Note: Find value from key prints an error if the key could not be found. We don't want that
+ // Rolling our own below
+ // TODO:RTC184689 Create find_iterator_from_value and find_iterator_from_key
+ auto l_mrs_it = std::find_if(l_mrs_vect.begin(), l_mrs_vect.end(), [&i_mrs](const mrs_dram & i_rhs)
+ {
+ return i_mrs == i_rhs.first;
+ });
+
+ // No, add a new DRAM mapping
+ if( l_mrs_it == l_mrs_vect.end() )
+ {
+ FAPI_INF("%s rank%lu inserting new DRAM + MRS info DRAM%lu", mss::c_str(i_target), i_rank, i_dram);
+ const mrs_dram MRS_DRAM = { i_mrs, { i_dram } };
+ l_mrs_vect.push_back( MRS_DRAM );
+ }
+ // Yes, add a DRAM onto the vector
+ else
+ {
+ l_mrs_it->second.push_back( i_dram );
+ FAPI_INF("%s rank%lu pushing back DRAM%lu size %lu", mss::c_str(i_target), i_rank, i_dram, l_mrs_it->second.size());
+ }
+ }
+ }
fapi_try_exit:
return fapi2::current_err;
@@ -294,23 +345,24 @@ class commands
/// @brief Returns the command information
/// @return iv_commands
///
- inline const typename std::map<rank_target, mrs_drams>& get() const
+ inline const typename std::vector<std::pair<rank_target, mrs_drams_vect>>& get() const
{
return iv_commands;
}
private:
- // The following is a map of targets/DIMM as the key to a map of
+ // The following is a vector of target/DIMM pairs as the key to a vector of
// the MRS command as the key to the DRAM's to toggle. An explanation as to the data structure is included below
+ // Note: due to HB compile, a vector is used instead of a map
// PDA compression is a little complex, but is organized to allow us to minimize the number of commands run
- // Each individual map is designed to further minimize the number of commands run
- // The compressed commands consist of a map within a map
- // The outside map, maps the DIMM/rank to the MRS command and DRAM's that need to be run
+ // Each individual vector is designed to further minimize the number of commands run
+ // The compressed commands consist of a vector of pairs within a vector of pairs
+ // The outside vector, maps the DIMM/rank to the MRS command and DRAM's that need to be run
// Basically, it's a list of a specific rank target with all the commands that need to be run
// The rank-specific target information allows us to just issue the enter/exit commands for PDA for each rank once
// The MRS commands to the DRAM are then looped over in the inside loop
- // The inside map has a key of the MRS and a value of a vector of DRAM's to issue the MRS to
+ // The inside vector has a key of the MRS and a value of a vector of DRAM's to issue the MRS to
// CCS does not allow the user to toggle the DQ during an MRS command
// The DQ information is stored in separate registers in the PHY
// What this means for issuing the commands is that we have to issue an invocation of CCS for each different MRS command we issue
@@ -318,7 +370,7 @@ class commands
// Each invocation of CCS creates a noticable increase in time, as the registers need to be configured, CCS needs to be started, and we need to poll for done
// By only entering into PDA on a DIMM-rank once and by issuing the PDA MRS's to multiple DRAM's at a time, we can save a lot of runtime
// Note: in shmoo, adding the compression reduced runtime from about 13 minutes down to 3 minutes
- typename std::map<rank_target, mrs_drams> iv_commands;
+ typename std::vector<std::pair<rank_target, mrs_drams_vect>> iv_commands;
};
///
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 6e9c4398e..f6e77862b 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
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -49,6 +49,8 @@
#include <lib/dimm/mrs_load.H>
#include <lib/shared/mss_kind.H>
#include <generic/memory/lib/spd/common/dimm_module_decoder.H>
+#include <lib/phy/dp16.H>
+#include <lib/mss_attribute_accessors_manual.H>
namespace mss
{
@@ -223,6 +225,35 @@ enum invalid_timing_function_encoding
/////////////////////////
///
+/// @brief Gets the JEDEC train and range values from the encoded VPD value
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[out] o_range - the JEDEC VREFDQ range
+/// @param[out] o_value - the JEDEC VREFDQ value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode get_vpd_wr_vref_range_and_value( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_range,
+ uint8_t& o_value )
+{
+ fapi2::buffer<uint8_t> l_vpd_value;
+ constexpr uint64_t VPD_TRAIN_RANGE_START = 1;
+ constexpr uint64_t VPD_TRAIN_VALUE_START = 2;
+ constexpr uint64_t VPD_TRAIN_VALUE_LEN = 6;
+
+ FAPI_TRY(mss::vpd_mt_vref_dram_wr(i_target, l_vpd_value));
+
+ o_range = l_vpd_value.getBit<VPD_TRAIN_RANGE_START>() ?
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE2 :
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE1;
+ l_vpd_value.extractToRight<VPD_TRAIN_VALUE_START, VPD_TRAIN_VALUE_LEN>(o_value);
+
+ FAPI_INF("%s JEDEC range 0x%02x JEDEC value 0x%02x", mss::c_str(i_target), o_range, o_value);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief IBT helper - maps from VPD definition of IBT to the RCD control word bit fields
/// @param[in] i_ibt the IBT from VPD (e.g., 10, 15, ...), stored as 10% of original val (10 in VPD == 100 Ohms)
/// @return the IBT bit field e.g., 00, 01 ... (right aligned)
@@ -2449,25 +2480,24 @@ fapi_try_exit:
}
///
-/// @brief Determines & sets effective config for Vref DQ Train Value
+/// @brief Determines & sets effective config for Vref DQ Train Value and Range
/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note The value and range attributes are combined as offsetting the WR VREF percentage can cause both the value and range to shift
+/// The calculations would have to be done twice if the calculations were done separately. As such, they are combined below
///
-fapi2::ReturnCode eff_dimm::vref_dq_train_value()
+fapi2::ReturnCode eff_dimm::vref_dq_train_value_and_range()
{
+ // Taken from DDR4 (this attribute is DDR4 only) spec MRS6 section VrefDQ training: values table
+ constexpr uint8_t JEDEC_MAX_TRAIN_VALUE = 0b00110010;
uint8_t l_attrs_vref_dq_train_val[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+ uint8_t l_attrs_vref_dq_train_range[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
std::vector< uint64_t > l_ranks;
- // value to set.
- fapi2::buffer<uint8_t> l_vpd_value;
+ // Gets the JEDEC VREFDQ range and value
fapi2::buffer<uint8_t> l_train_value;
- constexpr uint64_t VPD_TRAIN_VALUE_START = 2;
- constexpr uint64_t VPD_TRAIN_VALUE_LEN = 6;
- // Taken from DDR4 (this attribute is DDR4 only) spec MRS6 section VrefDQ training: values table
- constexpr uint8_t JEDEC_MAX_TRAIN_VALUE = 0b00110010;
-
- FAPI_TRY(mss::vpd_mt_vref_dram_wr(iv_dimm, l_vpd_value));
- l_vpd_value.extractToRight<VPD_TRAIN_VALUE_START, VPD_TRAIN_VALUE_LEN>(l_train_value);
+ fapi2::buffer<uint8_t> l_train_range;
+ FAPI_TRY(mss::get_vpd_wr_vref_range_and_value(iv_dimm, l_train_range, l_train_value));
FAPI_ASSERT(l_train_value <= JEDEC_MAX_TRAIN_VALUE,
fapi2::MSS_INVALID_VPD_VREF_DRAM_WR_RANGE()
@@ -2477,6 +2507,11 @@ fapi2::ReturnCode eff_dimm::vref_dq_train_value()
"%s VPD DRAM VREF value out of range max 0x%02x value 0x%02x", mss::c_str(iv_dimm),
JEDEC_MAX_TRAIN_VALUE, l_train_value );
+ // Updates the training values and ranges
+ FAPI_TRY(mss::dp16::wr_vref::offset_values(iv_mca, l_train_range, l_train_value),
+ "Failed to offset VPD WR VREF values %s", mss::c_str(iv_mca));
+
+
// Attribute to set num dimm ranks is a pre-requisite
FAPI_TRY( eff_vref_dq_train_value(iv_mcs, &l_attrs_vref_dq_train_val[0][0][0]) );
FAPI_TRY( mss::rank::ranks(iv_dimm, l_ranks) );
@@ -2484,11 +2519,15 @@ fapi2::ReturnCode eff_dimm::vref_dq_train_value()
for(const auto& l_rank : l_ranks)
{
l_attrs_vref_dq_train_val[iv_port_index][iv_dimm_index][index(l_rank)] = l_train_value;
+ l_attrs_vref_dq_train_range[iv_port_index][iv_dimm_index][index(l_rank)] = l_train_range;
}
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_VALUE, iv_mcs, l_attrs_vref_dq_train_val),
"Failed setting attribute for ATTR_EFF_VREF_DQ_TRAIN_VALUE");
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_RANGE, iv_mcs, l_attrs_vref_dq_train_range),
+ "Failed setting attribute for ATTR_EFF_VREF_DQ_TRAIN_RANGE");
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -2521,40 +2560,6 @@ fapi_try_exit:
}
///
-/// @brief Determines & sets effective config for Vref DQ Train Range
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_dimm::vref_dq_train_range()
-{
-
- // Attribute to set num dimm ranks is a pre-requisite
- uint8_t l_attrs_vref_dq_train_range[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
- std::vector< uint64_t > l_ranks;
-
- // value to set.
- fapi2::buffer<uint8_t> l_vpd_value;
- fapi2::buffer<uint8_t> l_train_range;
- constexpr uint64_t VPD_TRAIN_RANGE_START = 1;
- FAPI_TRY(mss::vpd_mt_vref_dram_wr(iv_dimm, l_vpd_value));
- l_train_range = l_vpd_value.getBit<VPD_TRAIN_RANGE_START>();
-
- // gets the current value of train_range
- FAPI_TRY( eff_vref_dq_train_range(iv_mcs, &l_attrs_vref_dq_train_range[0][0][0]) );
- FAPI_TRY( mss::rank::ranks(iv_dimm, l_ranks) );
-
- for(const auto& l_rank : l_ranks)
- {
- l_attrs_vref_dq_train_range[iv_port_index][iv_dimm_index][index(l_rank)] = l_train_range;
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_RANGE, iv_mcs, l_attrs_vref_dq_train_range),
- "Failed setting attribute for ATTR_EFF_VREF_DQ_TRAIN_RANGE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Determines & sets effective config for CA Parity Latency
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
index b0de045ed..9b8b1780d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,6 +40,17 @@ namespace mss
{
///
+/// @brief Gets the JEDEC train and range values from the encoded VPD value
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[out] o_range - the JEDEC VREFDQ range
+/// @param[out] o_value - the JEDEC VREFDQ value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode get_vpd_wr_vref_range_and_value( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_range,
+ uint8_t& o_value );
+
+///
/// @class mss::dimm::eff_dimm
/// @brief A class made to perform eff_config functions based on the different dimm kinds (gen, type, buffer type)
/// @note this is a base class
@@ -484,15 +495,17 @@ class eff_dimm
///
/// @brief Determines & sets effective config for Output Buffer
/// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note The value and range attributes are combined as offsetting the WR VREF percentage can cause both the value and range to shift
+ /// The calculations would have to be done twice if the calculations were done separately. As such, they are combined below
///
fapi2::ReturnCode output_buffer();
///
- /// @brief Determines & sets effective config for Vref DQ Train Value
+ /// @brief Determines & sets effective config for Vref DQ Train Value and Range
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode vref_dq_train_value();
+ fapi2::ReturnCode vref_dq_train_value_and_range();
///
/// @brief Determines & sets effective config for Vref DQ Train Enable
@@ -501,12 +514,6 @@ class eff_dimm
fapi2::ReturnCode vref_dq_train_enable();
///
- /// @brief Determines & sets effective config for Vref DQ Train Range
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode vref_dq_train_range();
-
- ///
/// @brief Determines & sets effective config for CA Parity Latency
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
index e5b3b9041..7cc82c5e5 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -708,7 +708,7 @@ fapi2::ReturnCode get_dimm_target_from_rank(const fapi2::Target<T>& i_target,
/// @brief Given a target, get the rank pair assignments, based on DIMMs
/// @tparam T the fapi2::TargetType
/// @param[in] i_target the target (MCA or MBA?)
-/// @param[out] o_registers the regiter settings for the appropriate rank pairs
+/// @param[out] o_registers the register settings for the appropriate rank pairs
/// @return FAPI2_RC_SUCCESS if and only if ok
///
template< fapi2::TargetType T>
OpenPOWER on IntegriCloud