summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9
diff options
context:
space:
mode:
authorJacob Harvey <jlharvey@us.ibm.com>2016-12-15 11:26:18 -0600
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-01-25 08:57:27 -0500
commit9fe6f884d176a13b432baaa986179ef6fa654f94 (patch)
tree396e232199ca328577c2ea15515964e99dddc7b3 /src/import/chips/p9
parent95409452c0f81f41d720e95e8ebcd66d49202019 (diff)
downloadtalos-hostboot-9fe6f884d176a13b432baaa986179ef6fa654f94.tar.gz
talos-hostboot-9fe6f884d176a13b432baaa986179ef6fa654f94.zip
Implement BC attributes and make eff_dimm class
Implementing the BC# attributes in eff_config Also implementing an eff_dimm object and factory Move functions from eff_config.C to eff_dimm.C Added MRW attribute for write_crc option Eff_config is no more Change-Id: I16607510454f61410711cbcb5c6715e6f80241dd Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34253 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Brian R. Silver <bsilver@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34254 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C4194
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H1238
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C4100
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H825
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H17
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H20
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C263
-rwxr-xr-xsrc/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml13
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml2
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml86
12 files changed, 5689 insertions, 5081 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 da0bc9e10..3488fad50 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 2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,4195 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+#include <math.h>
+
+// fapi2
+#include <fapi2.H>
+#include <vpd_access.H>
+#include <utility>
+
+// mss lib
+#include <lib/utils/fake_vpd.H>
+#include <lib/mss_vpd_decoder.H>
+#include <lib/spd/spd_factory.H>
+#include <lib/spd/common/spd_decoder.H>
+#include <lib/spd/common/rcw_settings.H>
+#include <lib/eff_config/timing.H>
+#include <lib/dimm/rank.H>
+#include <lib/utils/conversions.H>
+#include <lib/utils/find.H>
+#include <lib/dimm/eff_dimm.H>
+#include <lib/dimm/mrs_load.H>
+#include <lib/shared/mss_kind.H>
+#include <lib/spd/common/dimm_module_decoder.H>
+
+namespace mss
+{
+
+using fapi2::TARGET_TYPE_DIMM;
+using fapi2::TARGET_TYPE_MCS;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_MCBIST;
+
+///
+/// @brief bit encodings for Frequencies RC0A (RC10)
+/// @note valid frequency values for Nimbus systems
+/// From DDR4 Register v1.0
+/// More encodings available but they won't be used due to system constrains
+///
+// TODO: RTC 167542
+//Do we need to implement v2.0? It would be easy with the new structure - JLH
+enum rc10_encode : uint8_t
+{
+ DDR4_1866 = 0b001,
+ DDR4_2133 = 0b010,
+ DDR4_2400 = 0b011,
+ DDR4_2666 = 0b100,
+};
+
+///
+/// @brief bit encodings for RC0D (RC10 here) - DIMM Configuration Control Word RC0D (RC10 here)
+/// From DDR4 Register v1.0
+///
+enum rc13_encode : uint8_t
+{
+ DIRECT_CS_MODE = 0, ///< Direct DualCS mode: Register uses two DCS_n inputes
+ LRDIMM = 0,
+ RDIMM = 1,
+};
+
+///
+/// @brief bit encodings for RC3x - Fine Granularity RDIMM Operating Speed
+/// @note Only limited encodings here, more available
+/// From DDR4 Register v1.0
+///
+enum rc3x_encode : uint8_t
+{
+ MT1860_TO_MT1880 = 0x1F,
+ MT2120_TO_MT2140 = 0x2C,
+ MT2380_TO_MT2400 = 0x39,
+ MT2660_TO_MT2680 = 0x47,
+};
+
+///
+/// @brief bc03_encode enums for Host Interface DQ Driver Control Word
+/// From DDR4 Databuffer 01 rev 1.0 and same for DDR4 DataBuffer 02 rev 0.95
+///
+enum bc03_encode : uint8_t
+{
+ // Bit position of the BC03 bit to enable/ disable DQ/ DQS drivers
+ BC03_DQ_DISABLE_POS = 4,
+ BC03_DQ_DISABLE = 1,
+ BC03_DQ_ENABLE = 0,
+};
+
+
+///
+/// @brief bc09_encode enums Power Saving Settings Control Word
+///
+//Used for hard coding currently
+enum bc09_encode : uint8_t
+{
+ BC09_CKE_POWER_DOWN_DISABLE = 0,
+ BC09_CKE_POWER_DOWN_ENABLE = 1,
+ BC09_CKE_POWER_DOWN_ENABLE_POS = 4,
+ BC09_CKE_POWER_ODT_OFF = 1,
+ BC09_CKE_POWER_ODT_ON = 0,
+};
+
+///
+/// @brief encoding for DB01 and DB02 as seen from SPD
+///
+enum lrdimm_databuffers
+{
+ LRDIMM_DB01 = 0b0000,
+ LRDIMM_DB02 = 0b0001
+};
+
+/////////////////////////
+// Non-member function implementations
+/////////////////////////
+
+///
+/// @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)
+/// @note Unrecognized IBT values will force an assertion.
+///
+static uint64_t ibt_helper(const uint8_t i_ibt)
+{
+ switch(i_ibt)
+ {
+ // Off
+ case 0:
+ return 0b11;
+ break;
+
+ // 100 Ohm
+ case 10:
+ return 0b00;
+ break;
+
+ // 150 Ohm
+ case 15:
+ return 0b01;
+ break;
+
+ // 300 Ohm
+ case 30:
+ return 0b10;
+ break;
+
+ default:
+ FAPI_ERR("unknown IBT value %d", i_ibt);
+ fapi2::Assert(false);
+ };
+
+ // Not reached, but 'return' off ...
+ return 0b11;
+}
+
+///
+/// @brief factory to make an eff_config DIMM object based on dimm kind (type, gen, and revision number)
+/// @param[in] i_target dimm target
+/// @param[in] i_pDecoder the spd::decoder for the dimm target
+/// @param[out] o_fact_obj a shared pointer of the eff_dimm type
+///
+fapi2::ReturnCode eff_dimm::eff_dimm_factory (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder,
+ std::shared_ptr<eff_dimm>& o_fact_obj)
+{
+ uint8_t l_type = 0;
+ uint8_t l_gen = 0;
+ uint8_t l_buffer_type = 0;
+ kind_t l_dimm_kind = DEFAULT_KIND;
+
+ fapi2::ReturnCode l_rc;
+
+ // Now time to get the three attributes to tell which dimm we're working with.
+ // Dram_gen and dimm_type are set in the SPD factory and we'll call the SPD decoder to get the reg and buff type
+ FAPI_TRY( eff_dram_gen(i_target, l_gen), "Failed accessing the ATTR_MSS_EFF_DRAM_GEN" );
+ FAPI_TRY( eff_dimm_type(i_target, l_type), "Failed accessing the ATTR_MSS_EFF_DIMM_TYPE" );
+ FAPI_TRY( i_pDecoder->iv_module_decoder->register_and_buffer_type(l_buffer_type),
+ "Failed decoding register and buffer type" );
+
+ l_dimm_kind = mss::dimm_kind(l_type, l_gen);
+
+ switch (l_dimm_kind)
+ {
+ case KIND_LRDIMM_DDR4:
+ switch (l_buffer_type)
+ {
+ case LRDIMM_DB01:
+ o_fact_obj = std::make_shared<eff_lrdimm_db01> (i_target, i_pDecoder, l_rc );
+
+ // Assert that l_rc is good and o_fact_object isn't null
+ FAPI_ASSERT( ((l_rc == fapi2::FAPI2_RC_SUCCESS) && (o_fact_obj != nullptr)),
+ fapi2::MSS_ERROR_CREATING_EFF_CONFIG_DIMM_OBJECT().
+ set_DIMM_TYPE(l_type).
+ set_DRAM_GEN(l_gen).
+ set_REG_AND_BUFF_TYPE(l_buffer_type).
+ set_DIMM_TARGET(i_target),
+ "Failure creating an eff_dimm object for an LRDIMM DB01 for target %s buff_type %d",
+ mss::c_str(i_target),
+ l_buffer_type);
+ break;
+
+ case LRDIMM_DB02:
+ o_fact_obj = std::make_shared<eff_lrdimm_db02> (i_target, i_pDecoder, l_rc);
+
+ // Assert that l_rc is good and o_fact_object isn't null
+ FAPI_ASSERT( ((l_rc == fapi2::FAPI2_RC_SUCCESS) && (o_fact_obj != nullptr)),
+ fapi2::MSS_ERROR_CREATING_EFF_CONFIG_DIMM_OBJECT().
+ set_DIMM_TYPE(l_type).
+ set_DRAM_GEN(l_gen).
+ set_REG_AND_BUFF_TYPE(l_buffer_type).
+ set_DIMM_TARGET(i_target),
+ "Failure creating an eff_dimm object for an LRDIMM DB02 for target %s buff_type %d",
+ mss::c_str(i_target),
+ l_buffer_type);
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_LRDIMM_DB().
+ set_DATA_BUFFER_GEN(l_buffer_type).
+ set_DIMM_TARGET(i_target),
+ "Error when creating a LRDIMM dimm object due to invalid databuffer type (%d) for target %s",
+ l_buffer_type,
+ mss::c_str(i_target));
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ break;
+
+ case KIND_RDIMM_DDR4:
+ o_fact_obj = std::make_shared<eff_rdimm> (i_target, i_pDecoder, l_rc);
+ // Assert that l_rc is good and o_fact_object isn't null
+ FAPI_ASSERT( ((l_rc == fapi2::FAPI2_RC_SUCCESS) && (o_fact_obj != nullptr)),
+ fapi2::MSS_ERROR_CREATING_EFF_CONFIG_DIMM_OBJECT().
+ set_DIMM_TYPE(l_type).
+ set_DRAM_GEN(l_gen).
+ set_REG_AND_BUFF_TYPE(l_buffer_type).
+ set_DIMM_TARGET(i_target),
+ "Failure creating an eff_dimm object for an RDIMM for target %s register type %d",
+ mss::c_str(i_target),
+ l_buffer_type);
+ break;
+
+ default:
+ FAPI_ERR("Wrong kind of DIMM plugged in (not DDR4 LRDIMM or RDIMM for target %s", mss::c_str(i_target));
+ FAPI_ASSERT(false,
+ fapi2::MSS_UNSUPPORTED_DIMM_KIND().
+ set_DIMM_KIND(l_dimm_kind).
+ set_DIMM_TYPE(l_type).
+ set_DRAM_GEN(l_gen).
+ set_DIMM_TARGET(i_target),
+ "Invalid dimm target when passed into eff_config: kind %d, type %d, gen %d for target %s",
+ l_dimm_kind,
+ l_type,
+ l_gen,
+ mss::c_str(i_target));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+/////////////////////////
+// Member Method implementation
+/////////////////////////
+
+///
+/// @brief Determines & sets effective config for eff_dram_mfg_id type from SPD
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_mfg_id()
+{
+ uint16_t l_decoder_val = 0;
+ uint16_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_mfg_id(iv_mcs, &l_mcs_attrs[0][0]), "Failed accessing ATTR_MSS_EFF_DRAM_MFG_ID" );
+ FAPI_TRY( iv_pDecoder->dram_manufacturer_id_code(iv_dimm, l_decoder_val), "Failed getting dram id code from SPD" );
+
+ l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_MFG_ID, iv_mcs, l_mcs_attrs), "Failed to set ATTR_EFF_DRAM_MFG_ID" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}// dimm_type
+
+///
+/// @brief Determines & sets effective config for dram width
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_width()
+{
+ uint8_t l_decoder_val = 0;
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Get & update MCS attribute
+ FAPI_TRY( iv_pDecoder->device_width(iv_dimm, l_decoder_val), "Failed accessing device width from SPD" );
+ FAPI_TRY( eff_dram_width(iv_mcs, &l_mcs_attrs[0][0]), "Failed getting EFF_DRAM_WIDTH" );
+
+ l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_WIDTH, iv_mcs, l_mcs_attrs), "Failed setting ATTR_EFF_DRAM_WIDTH" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Determines & sets effective config for dram density
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_density()
+{
+
+ uint8_t l_decoder_val = 0;
+ FAPI_TRY( iv_pDecoder->sdram_density(iv_dimm, l_decoder_val), "Failed to get dram_density from SPD" );
+
+ // Get & update MCS attribute
+ {
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dram_density(iv_mcs, &l_mcs_attrs[0][0]), "Failed to get ATTR_MSS_EFF_DRAM_DENSITY" );
+
+ l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DENSITY, iv_mcs, l_mcs_attrs), "Failed to set ATTR_EFF_DRAM_DENSITY" );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for number of ranks per dimm
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::ranks_per_dimm()
+{
+ uint8_t l_ranks_per_dimm = 0;
+ uint8_t l_attrs_ranks_per_dimm[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_num_ranks_per_dimm(iv_mcs, &l_attrs_ranks_per_dimm[0][0]), "Failed to get EFF_NUM_RANKS_PER_DIMM" );
+ FAPI_TRY( iv_pDecoder->logical_ranks_per_dimm(iv_dimm, l_ranks_per_dimm),
+ "Failed to get logical_ranks_per_dimm from SPD" );
+
+ l_attrs_ranks_per_dimm[iv_port_index][iv_dimm_index] = l_ranks_per_dimm;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_NUM_RANKS_PER_DIMM, iv_mcs, l_attrs_ranks_per_dimm),
+ "Failed to set ATTR_EFF_NUM_RANKS_PER_DIMM" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for stack type
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::primary_stack_type()
+{
+ uint8_t l_decoder_val = 0;
+ FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(iv_dimm, l_decoder_val),
+ "Failed to get dram_signal_loading from SPD" );
+
+ // Get & update MCS attribute
+ {
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_prim_stack_type(iv_mcs, &l_mcs_attrs[0][0]), "Failed to get ATTR_MSS_EFF_PRIM_STACK_TYPE" );
+
+ l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_PRIM_STACK_TYPE, iv_mcs, l_mcs_attrs), "Failed to set EFF_PRIM_STACK_TYPE" );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for dimm size
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @warn Dependent on the following attributes already set:
+/// @warn eff_dram_density, eff_sdram_width, eff_ranks_per_dimm
+///
+fapi2::ReturnCode eff_dimm::dimm_size()
+{
+ // Retrieve values needed to calculate dimm size
+ uint8_t l_bus_width = 0;
+ uint8_t l_sdram_width = 0;
+ uint8_t l_sdram_density = 0;
+ uint8_t l_logical_rank_per_dimm = 0;
+
+ FAPI_TRY( iv_pDecoder->device_width(iv_dimm, l_sdram_width), "Failed to get device width from SPD" );
+ FAPI_TRY( iv_pDecoder->prim_bus_width(iv_dimm, l_bus_width), "Failed to get prim bus width from SPD" );
+ FAPI_TRY( iv_pDecoder->sdram_density(iv_dimm, l_sdram_density), "Failed to get dram density from SPD" );
+ FAPI_TRY( iv_pDecoder->logical_ranks_per_dimm(iv_dimm, l_logical_rank_per_dimm),
+ "Failed to get logical ranks from SPD" );
+
+ {
+ // Calculate dimm size
+ // Formula from SPD Spec
+ // Total = SDRAM Capacity 8 * Primary Bus Width SDRAM Width * Logical Ranks per DIMM
+ uint32_t l_dimm_size = 0;
+ l_dimm_size = (l_sdram_density * l_bus_width * l_logical_rank_per_dimm) / (8 * l_sdram_width);
+
+ // Get & update MCS attribute
+ uint32_t l_attrs_dimm_size[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_size(iv_mcs, &l_attrs_dimm_size[0][0]), "Failed to get ATTR_MSS_EFF_DIMM_SIZE" );
+
+ l_attrs_dimm_size[iv_port_index][iv_dimm_index] = l_dimm_size;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_SIZE, iv_mcs, l_attrs_dimm_size), "Failed to get ATTR_MSS_EFF_DIMM_SIZE" );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for Hybrid memory type from SPD
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::hybrid_memory_type()
+{
+ uint8_t l_decoder_val = 0;
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_hybrid_memory_type(iv_mcs, &l_mcs_attrs[0][0]), "Failed to get ATTR_MSS_HYBRID_MEMORY_TYPE" );
+ FAPI_TRY(iv_pDecoder->hybrid_media(iv_dimm, l_decoder_val), "Failed to get Hybrid_media from SPD");
+
+ l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, iv_mcs, l_mcs_attrs),
+ "Failed to set ATTR_EFF_HYBRID_MEMORY_TYPE" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for temperature controlled refresh mode
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note from DDR4 Spec (79-4B) 4.9.4 page 48
+///
+fapi2::ReturnCode eff_dimm::temp_refresh_mode()
+{
+ uint8_t l_mcs_attrs [mss::PORTS_PER_MCS] = {};
+
+ FAPI_TRY(mss::eff_temp_refresh_mode (iv_mcs, &l_mcs_attrs[0]));
+
+ // If fine refresh mode is normal, enable temperature control refresh mode
+ // Otherwise disable the temperature control refresh
+ l_mcs_attrs[iv_port_index] = (iv_refresh_mode == fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL) ?
+ fapi2::ENUM_ATTR_EFF_TEMP_REFRESH_MODE_ENABLE :
+ fapi2::ENUM_ATTR_EFF_TEMP_REFRESH_MODE_DISABLE;
+ FAPI_INF("%s: temperature control refresh mode is %d", mss::c_str(iv_dimm), l_mcs_attrs[iv_port_index]);
+ FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_EFF_TEMP_REFRESH_MODE, iv_mcs, l_mcs_attrs ) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+};
+
+
+
+///
+/// @brief Determines & sets effective config for refresh interval time (tREFI)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trefi()
+{
+ uint64_t l_trefi_in_ps = 0;
+
+ // Calculates appropriate tREFI based on fine refresh mode
+ switch(iv_refresh_mode)
+ {
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
+
+ FAPI_TRY( calc_trefi( mss::refresh_rate::REF1X,
+ iv_temp_refresh_range,
+ l_trefi_in_ps),
+ "Failed to calculate tREF1 for target %s", mss::c_str(iv_dimm) );
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
+
+ FAPI_TRY( calc_trefi( mss::refresh_rate::REF2X,
+ iv_temp_refresh_range,
+ l_trefi_in_ps),
+ "Failed to calculate tREF2 for target %s", mss::c_str(iv_dimm) );
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
+
+ FAPI_TRY( calc_trefi( mss::refresh_rate::REF4X,
+ iv_temp_refresh_range,
+ l_trefi_in_ps),
+ "Failed to calculate tREF4 for target %s", mss::c_str(iv_dimm) );
+ break;
+
+ default:
+ // Fine Refresh Mode will be a platform attribute set by the MRW,
+ // which they "shouldn't" mess up as long as use "attribute" enums.
+ // if openpower messes this up we can at least catch it
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_FINE_REFRESH_MODE().
+ set_FINE_REF_MODE(iv_refresh_mode),
+ "%s Incorrect Fine Refresh Mode received: %d ",
+ mss::c_str(iv_dimm),
+ iv_refresh_mode);
+ break;
+ }
+
+ {
+ // Calculate refresh cycle time in nCK & set attribute
+
+ std::vector<uint16_t> l_mcs_attrs_trefi(PORTS_PER_MCS, 0);
+ uint64_t l_trefi_in_nck = 0;
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dram_trefi(iv_mcs, l_mcs_attrs_trefi.data()) );
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck( l_trefi_in_ps,
+ static_cast<uint64_t>(iv_tCK_in_ps),
+ INVERSE_DDR4_CORRECTION_FACTOR,
+ l_trefi_in_nck),
+ "Error in calculating tREFI for target %s, with value of l_trefi_in_ps: %d", mss::c_str(iv_dimm), l_trefi_in_ps);
+
+ FAPI_INF("tCK (ps): %d, tREFI (ps): %d, tREFI (nck): %d",
+ iv_tCK_in_ps, l_trefi_in_ps, l_trefi_in_nck);
+
+ // Update MCS attribute
+ l_mcs_attrs_trefi[iv_port_index] = l_trefi_in_nck;
+
+ // casts vector into the type FAPI_ATTR_SET is expecting by deduction
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TREFI,
+ iv_mcs,
+ UINT16_VECTOR_TO_1D_ARRAY(l_mcs_attrs_trefi, PORTS_PER_MCS)),
+ "Failed to set tREFI attribute");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}// refresh_interval
+
+///
+/// @brief Determines & sets effective config for refresh cycle time (tRFC)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trfc()
+{
+ int64_t l_trfc_mtb = 0;
+ int64_t l_trfc_in_ps = 0;
+
+ // Selects appropriate tRFC based on fine refresh mode
+ switch(iv_refresh_mode)
+ {
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
+ FAPI_TRY( iv_pDecoder->min_refresh_recovery_delay_time_1(iv_dimm, l_trfc_mtb),
+ "Failed to decode SPD for tRFC1" );
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
+ FAPI_TRY( iv_pDecoder->min_refresh_recovery_delay_time_2(iv_dimm, l_trfc_mtb),
+ "Failed to decode SPD for tRFC2" );
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
+ FAPI_TRY( iv_pDecoder->min_refresh_recovery_delay_time_4(iv_dimm, l_trfc_mtb),
+ "Failed to decode SPD for tRFC4" );
+ break;
+
+ default:
+ // Fine Refresh Mode will be a platform attribute set by the MRW,
+ // which they "shouldn't" mess up as long as use "attribute" enums.
+ // if openpower messes this up we can at least catch it
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_FINE_REFRESH_MODE().
+ set_FINE_REF_MODE(iv_refresh_mode),
+ "%s Incorrect Fine Refresh Mode received: %d ",
+ mss::c_str(iv_dimm),
+ iv_refresh_mode);
+ break;
+
+ }// switch
+
+ // Calculate trfc (in ps)
+ {
+ constexpr int64_t l_trfc_ftb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb) );
+
+ FAPI_INF( "medium timebase (ps): %ld, fine timebase (ps): %ld, tRFC (MTB): %ld, tRFC(FTB): %ld",
+ l_mtb, l_ftb, l_trfc_mtb, l_trfc_ftb );
+
+ l_trfc_in_ps = spd::calc_timing_from_timebase(l_trfc_mtb, l_mtb, l_trfc_ftb, l_ftb);
+ }
+
+ {
+ // Calculate refresh cycle time in nCK & set attribute
+
+ uint16_t l_trfc_in_nck = 0;
+ std::vector<uint16_t> l_mcs_attrs_trfc(PORTS_PER_MCS, 0);
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dram_trfc(iv_mcs, l_mcs_attrs_trfc.data()),
+ "Failed to retrieve tRFC attribute" );
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_trfc_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_in_nck),
+ "Error in calculating l_tRFC for target %s, with value of l_trfc_in_ps: %d", mss::c_str(iv_dimm), l_trfc_in_ps);
+
+ FAPI_INF("tCK (ps): %d, tRFC (ps): %d, tRFC (nck): %d",
+ iv_tCK_in_ps, l_trfc_in_ps, l_trfc_in_nck);
+
+ // Update MCS attribute
+ l_mcs_attrs_trfc[iv_port_index] = l_trfc_in_nck;
+
+ // casts vector into the type FAPI_ATTR_SET is expecting by deduction
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRFC,
+ iv_mcs,
+ UINT16_VECTOR_TO_1D_ARRAY(l_mcs_attrs_trfc, PORTS_PER_MCS) ),
+ "Failed to set tRFC attribute" );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for refresh cycle time (different logical ranks - tRFC_DLR)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trfc_dlr()
+{
+
+ uint8_t l_density = 0;
+ uint64_t l_tCK_in_ps = 0;
+ uint64_t l_trfc_dlr_in_ps = 0;
+ uint8_t l_trfc_dlr_in_nck = 0;
+ std::vector<uint8_t> l_mcs_attrs_trfc_dlr(PORTS_PER_MCS, 0);
+
+ // Retrieve map params
+ FAPI_TRY( iv_pDecoder->sdram_density(iv_dimm, l_density), "Failed to get sdram density");
+ FAPI_TRY( mss::mrw_fine_refresh_mode(iv_refresh_mode), "Failed to get MRW attribute for fine refresh mode" );
+
+ FAPI_INF("Retrieved SDRAM density: %d, fine refresh mode: %d",
+ l_density, iv_refresh_mode);
+
+ // Calculate refresh cycle time in ps
+ FAPI_TRY( calc_trfc_dlr(iv_refresh_mode, l_density, l_trfc_dlr_in_ps), "Failed calc_trfc_dlr()" );
+
+ // Calculate clock period (tCK) from selected freq from mss_freq
+ FAPI_TRY( clock_period(iv_dimm, l_tCK_in_ps), "Failed to calculate clock period (tCK)");
+
+ // Calculate refresh cycle time in nck
+ FAPI_TRY( spd::calc_nck(l_trfc_dlr_in_ps, l_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_dlr_in_nck));
+
+ FAPI_INF("tCK (ps): %d, tRFC_DLR (ps): %d, tRFC_DLR (nck): %d",
+ l_tCK_in_ps, l_trfc_dlr_in_ps, l_trfc_dlr_in_nck);
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dram_trfc_dlr(iv_mcs, l_mcs_attrs_trfc_dlr.data()), "Failed to retrieve tRFC_DLR attribute" );
+
+ // Update MCS attribute
+ l_mcs_attrs_trfc_dlr[iv_port_index] = l_trfc_dlr_in_nck;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRFC_DLR,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_mcs_attrs_trfc_dlr, PORTS_PER_MCS) ),
+ "Failed to set tRFC_DLR attribute" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for dimm rcd mirror mode
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::rcd_mirror_mode()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_mirror_mode = 0;
+ uint8_t l_attrs_mirror_mode[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dimm_rcd_mirror_mode(iv_mcs, &l_attrs_mirror_mode[0][0]) );
+
+ // Update MCS attribute
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->register_to_dram_addr_mapping(l_mirror_mode) );
+ l_attrs_mirror_mode[iv_port_index][iv_dimm_index] = l_mirror_mode;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RCD_MIRROR_MODE, iv_mcs, l_attrs_mirror_mode) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for dram bank bits
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_bank_bits()
+{
+ uint8_t l_bank_bits = 0;
+ uint8_t l_attrs_bank_bits[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_bank_bits(iv_mcs, &l_attrs_bank_bits[0][0]) );
+ FAPI_TRY( iv_pDecoder->bank_bits(iv_dimm, l_bank_bits) );
+
+ l_attrs_bank_bits[iv_port_index][iv_dimm_index] = l_bank_bits;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_BANK_BITS, iv_mcs, l_attrs_bank_bits) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for dram row bits
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_row_bits()
+{
+ uint8_t l_row_bits = 0;
+ uint8_t l_attrs_row_bits[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_row_bits(iv_mcs, &l_attrs_row_bits[0][0]) );
+ FAPI_TRY( iv_pDecoder->row_address_bits(iv_dimm, l_row_bits) );
+
+ l_attrs_row_bits[iv_port_index][iv_dimm_index] = l_row_bits;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_ROW_BITS, iv_mcs, l_attrs_row_bits) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tDQS
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Sets TDQS to off for x4, sets to on for x8
+///
+fapi2::ReturnCode eff_dimm::dram_dqs_time()
+{
+ uint8_t l_attrs_dqs_time[PORTS_PER_MCS] = {};
+ uint8_t l_dram_width = 0;
+
+ // Get the DRAM width
+ FAPI_TRY( iv_pDecoder->device_width(iv_dimm, l_dram_width) );
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_tdqs(iv_mcs, &l_attrs_dqs_time[0]) );
+ FAPI_INF("SDRAM width: %d for target %s", l_dram_width, mss::c_str(iv_dimm));
+
+ // Only possible dram width are x4, x8. If x8, tdqs is available, else not available
+ l_attrs_dqs_time[iv_port_index] = (l_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ?
+ fapi2::ENUM_ATTR_EFF_DRAM_TDQS_ENABLE : fapi2::ENUM_ATTR_EFF_DRAM_TDQS_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TDQS, iv_mcs, l_attrs_dqs_time) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tCCD_L
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_tccd_l()
+{
+ int64_t l_tccd_in_ps = 0;
+
+ // Get the tCCD_L timing values
+ // tCCD_L is speed bin independent and is
+ // the same for all bins within a speed grade.
+ // It is safe to read this from SPD because the correct nck
+ // value will be calulated based on our dimm speed.
+
+ // TODO: RTC 163150 Clean up eff_config timing boilerplate
+ {
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+ int64_t l_tccd_mtb = 0;
+ int64_t l_tccd_ftb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb),
+ "Failed medium_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb),
+ "Failed fine_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->min_tccd_l(iv_dimm, l_tccd_mtb),
+ "Failed min_tccd_l() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_offset_min_tccd_l(iv_dimm, l_tccd_ftb),
+ "Failed fine_offset_min_tccd_l() for %s", mss::c_str(iv_dimm) );
+
+ FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tCCD_L (MTB): %ld, tCCD_L(FTB): %ld",
+ l_mtb, l_ftb, l_tccd_mtb, l_tccd_ftb );
+
+ l_tccd_in_ps = spd::calc_timing_from_timebase(l_tccd_mtb, l_mtb, l_tccd_ftb, l_ftb);
+ }
+
+ {
+ // Calculate refresh cycle time in nCK & set attribute
+ uint8_t l_tccd_in_nck = 0;
+ std::vector<uint8_t> l_mcs_attrs_tccd(PORTS_PER_MCS, 0);
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dram_tccd_l(iv_mcs, l_mcs_attrs_tccd.data()),
+ "Failed to retrieve tCCD attribute" );
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_tccd_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_tccd_in_nck),
+ "Error in calculating tccd for target %s, with value of l_tccd_in_ps: %d", mss::c_str(iv_dimm), l_tccd_in_ps);
+
+ FAPI_INF("tCK (ps): %d, tCCD_L (ps): %d, tCCD_L (nck): %d",
+ iv_tCK_in_ps, l_tccd_in_ps, l_tccd_in_nck);
+
+ // Update MCS attribute
+ l_mcs_attrs_tccd[iv_port_index] = l_tccd_in_nck;
+
+ // casts vector into the type FAPI_ATTR_SET is expecting by deduction
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TCCD_L,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_mcs_attrs_tccd, PORTS_PER_MCS) ),
+ "Failed to set tCCD_L attribute" );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC00
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc00()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc00[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc00(iv_mcs, &l_attrs_dimm_rc00[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc00[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc00;
+
+ FAPI_INF("%s: RC00 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc00[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC00, iv_mcs, l_attrs_dimm_rc00) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC01
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc01()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc01[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc01(iv_mcs, &l_attrs_dimm_rc01[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc01[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc01;
+
+ FAPI_INF("%s: RC01 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc01[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC01, iv_mcs, l_attrs_dimm_rc01) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC02
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc02()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc02[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc02(iv_mcs, &l_attrs_dimm_rc02[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc02[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc02;
+
+ FAPI_INF("%s: RC02 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc02[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC02, iv_mcs, l_attrs_dimm_rc02) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC03
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc03()
+{
+ fapi2::buffer<uint8_t> l_buffer;
+
+ uint8_t l_attrs_dimm_rc03[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ uint8_t l_cs_output_drive = 0;
+ uint8_t l_ca_output_drive = 0;
+
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->cs_signal_output_driver(l_cs_output_drive) );
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->ca_signal_output_driver(l_ca_output_drive) );
+
+ FAPI_INF( "%s: Retrieved register output drive, for CA: %d, CS: %d",
+ mss::c_str(iv_dimm), l_ca_output_drive, l_cs_output_drive );
+
+ // Lets construct encoding byte for RCD setting
+ {
+ // Buffer insert constants for CS and CA output drive
+ constexpr size_t CS_START = 4;
+ constexpr size_t CA_START = 6;
+ constexpr size_t LEN = 2;
+
+ l_buffer.insertFromRight<CA_START, LEN>(l_ca_output_drive)
+ .insertFromRight<CS_START, LEN>(l_cs_output_drive);
+ }
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dimm_ddr4_rc03(iv_mcs, &l_attrs_dimm_rc03[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc03[iv_port_index][iv_dimm_index] = l_buffer;
+
+ FAPI_INF("%s: RC03 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc03[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC03, iv_mcs, l_attrs_dimm_rc03) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC04
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc04()
+{
+ uint8_t l_attrs_dimm_rc04[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ uint8_t l_odt_output_drive = 0;
+ uint8_t l_cke_output_drive = 0;
+
+ fapi2::buffer<uint8_t> l_buffer;
+
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->odt_signal_output_driver(l_odt_output_drive) );
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->cke_signal_output_driver(l_cke_output_drive) );
+
+ FAPI_INF( "%s: Retrieved signal driver output, for CKE: %d, ODT: %d",
+ mss::c_str(iv_dimm), l_cke_output_drive, l_odt_output_drive );
+
+ // Lets construct encoding byte for RCD setting
+ {
+ // Buffer insert constants for ODT and CKE output drive
+ constexpr size_t CKE_START = 6;
+ constexpr size_t ODT_START = 4;
+ constexpr size_t LEN = 2;
+
+ l_buffer.insertFromRight<CKE_START, LEN>(l_cke_output_drive)
+ .insertFromRight<ODT_START, LEN>(l_odt_output_drive);
+ }
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dimm_ddr4_rc04(iv_mcs, &l_attrs_dimm_rc04[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc04[iv_port_index][iv_dimm_index] = l_buffer;
+
+ FAPI_INF("%s: RC04 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc04[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC04, iv_mcs, l_attrs_dimm_rc04) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC05
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc05()
+{
+ uint8_t l_attrs_dimm_rc05[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ uint8_t l_a_side_output_drive = 0;
+ uint8_t l_b_side_output_drive = 0;
+
+ fapi2::buffer<uint8_t> l_buffer;
+
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->a_side_clk_output_driver(l_a_side_output_drive) );
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->b_side_clk_output_driver(l_b_side_output_drive) );
+
+ FAPI_INF( "%s: Retrieved register output drive for clock, b-side (Y0,Y2): %d, a-side (Y1,Y3): %d",
+ mss::c_str(iv_dimm), l_b_side_output_drive, l_a_side_output_drive );
+
+ {
+ // Buffer insert constants for ODT and CKE output drive
+ constexpr size_t B_START = 6;
+ constexpr size_t A_START = 4;
+ constexpr size_t LEN = 2;
+
+ // Lets construct encoding byte for RCD setting
+ l_buffer.insertFromRight<B_START, LEN>(l_b_side_output_drive)
+ .insertFromRight<A_START, LEN>(l_a_side_output_drive);
+ }
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dimm_ddr4_rc05(iv_mcs, &l_attrs_dimm_rc05[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc05[iv_port_index][iv_dimm_index] = l_buffer;
+
+ FAPI_INF( "%s: RC05 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc05[iv_port_index][iv_dimm_index] )
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC05, iv_mcs, l_attrs_dimm_rc05) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC06_07
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc06_07()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc06_07[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc06_07(iv_mcs, &l_attrs_dimm_rc06_07[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc06_07[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc06_07;
+
+ FAPI_INF( "%s: RC06_07 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc06_07[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC06_07, iv_mcs, l_attrs_dimm_rc06_07) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC08
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc08()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc08[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc08(iv_mcs, &l_attrs_dimm_rc08[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc08[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc08;
+
+ FAPI_INF( "%s: RC08 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc08[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC08, iv_mcs, l_attrs_dimm_rc08) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC09
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc09()
+{
+ // TODO - RTC 160118: Clean up eff_config boiler plate that can moved into helper functions
+
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc09[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc09(iv_mcs, &l_attrs_dimm_rc09[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc09[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc09;
+
+ FAPI_INF( "%s: RC09 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc09[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC09, iv_mcs, l_attrs_dimm_rc09) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC10
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc10()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc10[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc10(iv_mcs, &l_attrs_dimm_rc10[0][0]) );
+
+
+ switch(iv_freq)
+ {
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
+ l_attrs_dimm_rc10[iv_port_index][iv_dimm_index] = rc10_encode::DDR4_1866;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
+ l_attrs_dimm_rc10[iv_port_index][iv_dimm_index] = rc10_encode::DDR4_2133;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
+ l_attrs_dimm_rc10[iv_port_index][iv_dimm_index] = rc10_encode::DDR4_2400;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
+ l_attrs_dimm_rc10[iv_port_index][iv_dimm_index] = rc10_encode::DDR4_2666;
+ break;
+
+ default:
+ FAPI_ERR("Invalid frequency for rc10 encoding received: %d", iv_freq);
+ return fapi2::FAPI2_RC_FALSE;
+ break;
+ }
+
+ FAPI_INF( "%s: RC10 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc10[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC10, iv_mcs, l_attrs_dimm_rc10) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC11
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc11()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc11[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc11(iv_mcs, &l_attrs_dimm_rc11[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc11[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc0b;
+
+ FAPI_INF( "%s: RC11 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc11[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC11, iv_mcs, l_attrs_dimm_rc11) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC12
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc12()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc12[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc12(iv_mcs, &l_attrs_dimm_rc12[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc12[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc0c;
+
+ FAPI_INF( "%s: R12 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc12[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC12, iv_mcs, l_attrs_dimm_rc12) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC13
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc13()
+{
+ uint8_t l_attrs_dimm_rc13[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ fapi2::buffer<uint8_t> l_buffer;
+
+ // TODO - RTC 160116: Fix RC0D chip select setting for LRDIMMs
+ constexpr uint8_t l_cs_mode = rc13_encode::DIRECT_CS_MODE;
+ uint8_t l_mirror_mode = 0;
+ uint8_t l_dimm_type = 0;
+ uint8_t l_module_type = 0;
+
+ FAPI_TRY( spd::base_module_type(iv_dimm, iv_pDecoder->iv_spd_data, l_module_type) );
+
+ l_dimm_type = (l_module_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) ?
+ rc13_encode::RDIMM :
+ rc13_encode::LRDIMM;
+
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->register_to_dram_addr_mapping(l_mirror_mode) );
+
+ // Lets construct encoding byte for RCD setting
+ {
+ // CS
+ constexpr size_t CS_START = 6;
+ constexpr size_t CS_LEN = 2;
+
+ // DIMM TYPE
+ constexpr size_t DIMM_TYPE_START = 5;
+ constexpr size_t DIMM_TYPE_LEN = 1;
+
+ // MIRROR mode
+ constexpr size_t MIRROR_START = 4;
+ constexpr size_t MIRROR_LEN = 1;
+
+ l_buffer.insertFromRight<CS_START, CS_LEN>(l_cs_mode)
+ .insertFromRight<DIMM_TYPE_START, DIMM_TYPE_LEN>(l_dimm_type)
+ .insertFromRight<MIRROR_START, MIRROR_LEN>(l_mirror_mode);
+ }
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dimm_ddr4_rc13(iv_mcs, &l_attrs_dimm_rc13[0][0]) );
+
+ // Update MCS attribute
+ FAPI_TRY( spd::base_module_type(iv_dimm, iv_pDecoder->iv_spd_data, l_dimm_type) );
+ l_attrs_dimm_rc13[iv_port_index][iv_dimm_index] = l_buffer;
+
+ FAPI_INF( "%s: RC13 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc13[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC13, iv_mcs, l_attrs_dimm_rc13) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC14
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc14()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc14[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc14(iv_mcs, &l_attrs_dimm_rc14[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc14[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc0e;
+
+ FAPI_INF( "%s: RC14 setting: 0x%0x", mss::c_str(iv_dimm), l_attrs_dimm_rc14[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC14, iv_mcs, l_attrs_dimm_rc14) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC15
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc15()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc15[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc15(iv_mcs, &l_attrs_dimm_rc15[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc15[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc0f;
+
+ FAPI_INF( "%s: RC15 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc15[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC15, iv_mcs, l_attrs_dimm_rc15) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_1x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc1x()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_1x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_1x(iv_mcs, &l_attrs_dimm_rc_1x[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_1x[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc1x;
+
+ FAPI_INF( "%s: RC1X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_1x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_1x, iv_mcs, l_attrs_dimm_rc_1x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_2x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc2x()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_2x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_2x(iv_mcs, &l_attrs_dimm_rc_2x[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_2x[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc2x;
+
+ FAPI_INF( "%s: RC2X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_2x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_2x, iv_mcs, l_attrs_dimm_rc_2x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_3x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc3x()
+{
+ uint8_t l_attrs_dimm_rc_3x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dimm_ddr4_rc_3x(iv_mcs, &l_attrs_dimm_rc_3x[0][0]) );
+
+ switch(iv_freq)
+ {
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
+ l_attrs_dimm_rc_3x[iv_port_index][iv_dimm_index] = rc3x_encode::MT1860_TO_MT1880;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
+ l_attrs_dimm_rc_3x[iv_port_index][iv_dimm_index] = rc3x_encode::MT2120_TO_MT2140;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
+ l_attrs_dimm_rc_3x[iv_port_index][iv_dimm_index] = rc3x_encode::MT2380_TO_MT2400;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
+ l_attrs_dimm_rc_3x[iv_port_index][iv_dimm_index] = rc3x_encode::MT2660_TO_MT2680;
+ break;
+
+ default:
+ FAPI_ERR("Invalid frequency for rc_3x encoding received: %d", iv_freq);
+ return fapi2::FAPI2_RC_FALSE;
+ break;
+ }
+
+ FAPI_INF( "%s: RC3X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_3x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_3x, iv_mcs, l_attrs_dimm_rc_3x) );
+
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_4x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc4x()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_4x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_4x(iv_mcs, &l_attrs_dimm_rc_4x[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_4x[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc4x;
+
+ FAPI_INF( "%s: RC4X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_4x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_4x, iv_mcs, l_attrs_dimm_rc_4x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_5x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc5x()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_5x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_5x(iv_mcs, &l_attrs_dimm_rc_5x[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_5x[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc5x;
+
+ FAPI_INF( "%s: RC5X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_5x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_5x, iv_mcs, l_attrs_dimm_rc_5x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_6x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc6x()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_6x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_6x(iv_mcs, &l_attrs_dimm_rc_6x[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_6x[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc6x;
+
+ FAPI_INF( "%s: RC6X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_6x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_6x, iv_mcs, l_attrs_dimm_rc_6x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_7x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc7x()
+{
+ uint8_t l_attrs_dimm_rc_7x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ fapi2::buffer<uint8_t> l_rcd7x = 0;
+
+ // All the IBT bit fields in the RCD control word are 2 bits long.
+ constexpr uint64_t LEN = 2;
+
+ // CA starts at bit 6, others are the same. So the field runs from START for LEN bits,
+ // for example CA field is bits 6:7
+ constexpr uint64_t CA_START = 6;
+ uint8_t l_ibt_ca = 0;
+
+ constexpr uint64_t CKE_START = 2;
+ uint8_t l_ibt_cke = 0;
+
+ constexpr uint64_t CS_START = 4;
+ uint8_t l_ibt_cs = 0;
+
+ constexpr uint64_t ODT_START = 0;
+ uint8_t l_ibt_odt = 0;
+
+ // Pull the individual settings from VPD, and shuffle them into RCD7x
+ FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_ca(iv_dimm, l_ibt_ca) );
+ FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_cke(iv_dimm, l_ibt_cke) );
+ FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_cs(iv_dimm, l_ibt_cs) );
+ FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_odt(iv_dimm, l_ibt_odt) );
+
+ l_rcd7x.insertFromRight<CA_START, LEN>( ibt_helper(l_ibt_ca) );
+ l_rcd7x.insertFromRight<CKE_START, LEN>( ibt_helper(l_ibt_cke) );
+ l_rcd7x.insertFromRight<CS_START, LEN>( ibt_helper(l_ibt_cs) );
+ l_rcd7x.insertFromRight<ODT_START, LEN>( ibt_helper(l_ibt_odt) );
+
+ // Now write RCD7x out to the effective attribute
+ FAPI_TRY( eff_dimm_ddr4_rc_7x(iv_mcs, &l_attrs_dimm_rc_7x[0][0]) );
+ l_attrs_dimm_rc_7x[iv_port_index][iv_dimm_index] = l_rcd7x;
+
+ FAPI_INF( "%s: RC7X setting is 0x%x", mss::c_str(iv_dimm), l_attrs_dimm_rc_7x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_7x, iv_mcs, l_attrs_dimm_rc_7x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_8x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc8x()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_8x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_8x(iv_mcs, &l_attrs_dimm_rc_8x[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_8x[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc8x;
+
+ FAPI_INF( "%s: RC8X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_8x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_8x, iv_mcs, l_attrs_dimm_rc_8x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_9x
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rc9x()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_9x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_9x(iv_mcs, &l_attrs_dimm_rc_9x[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_9x[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc9x;
+
+ FAPI_INF( "%s: RC9X setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_9x[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_9x, iv_mcs, l_attrs_dimm_rc_9x) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_AX
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rcax()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_ax[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_ax(iv_mcs, &l_attrs_dimm_rc_ax[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_ax[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rcax;
+
+ FAPI_INF( "%s: RCAX setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_ax[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_Ax, iv_mcs, l_attrs_dimm_rc_ax) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM RC_BX
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dimm_rcbx()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_rc_bx[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_rc_bx(iv_mcs, &l_attrs_dimm_rc_bx[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_rc_bx[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rcbx;
+
+ FAPI_INF( "%s: RCBX setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc_bx[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_Bx, iv_mcs, l_attrs_dimm_rc_bx) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tWR
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_twr()
+{
+ int64_t l_twr_in_ps = 0;
+
+ // Get the tWR timing values
+ // tWR is speed bin independent and is
+ // the same for all bins within a speed grade.
+ // It is safe to read this from SPD because the correct nck
+ // value will be calulated based on our dimm speed.
+ {
+ constexpr int64_t l_twr_ftb = 0;
+ int64_t l_twr_mtb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb),
+ "Failed medium_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb),
+ "Failed fine_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->min_write_recovery_time(iv_dimm, l_twr_mtb),
+ "Failed min_write_recovery_time() for %s", mss::c_str(iv_dimm) );
+
+ FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tWR (MTB): %ld, tWR(FTB): %ld",
+ l_mtb, l_ftb, l_twr_mtb, l_twr_ftb);
+
+ // Calculate twr (in ps)
+ l_twr_in_ps = spd::calc_timing_from_timebase(l_twr_mtb, l_mtb, l_twr_ftb, l_ftb);
+ }
+
+ {
+ std::vector<uint8_t> l_attrs_dram_twr(PORTS_PER_MCS, 0);
+ uint8_t l_twr_in_nck = 0;
+
+ // Calculate tNCK
+ FAPI_TRY( spd::calc_nck(l_twr_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twr_in_nck),
+ "Error in calculating l_twr_in_nck for target %s, with value of l_twr_in_ps: %d", mss::c_str(iv_dimm), l_twr_in_ps);
+
+ FAPI_INF( "tCK (ps): %d, tWR (ps): %d, tWR (nck): %d for target: %s",
+ iv_tCK_in_ps, l_twr_in_ps, l_twr_in_nck, mss::c_str(iv_dimm) );
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_twr(iv_mcs, l_attrs_dram_twr.data()) );
+
+ l_attrs_dram_twr[iv_port_index] = l_twr_in_nck;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TWR,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_twr, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TWR");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for RBT
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::read_burst_type()
+{
+ uint8_t l_attrs_rbt[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_rbt(iv_mcs, &l_attrs_rbt[0][0]) );
+
+ l_attrs_rbt[iv_port_index][iv_dimm_index] = fapi2::ENUM_ATTR_EFF_DRAM_RBT_SEQUENTIAL;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RBT, iv_mcs, l_attrs_rbt),
+ "Failed setting attribute for RTB");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for TM
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note dram testing mode
+/// @note always disabled
+///
+fapi2::ReturnCode eff_dimm::dram_tm()
+{
+ uint8_t l_attrs_tm[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_tm(iv_mcs, &l_attrs_tm[0][0]) );
+
+ l_attrs_tm[iv_port_index][iv_dimm_index] = fapi2::ENUM_ATTR_EFF_DRAM_TM_NORMAL;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TM, iv_mcs, l_attrs_tm),
+ "Failed setting attribute for BL");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for cwl
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Sets CAS Write Latency, depending on frequency and ATTR_MSS_MT_PREAMBLE
+///
+fapi2::ReturnCode eff_dimm::dram_cwl()
+{
+
+ // Taken from DDR4 JEDEC spec 1716.78C
+ // Proposed DDR4 Full spec update(79-4A)
+ // Page 26, Table 7
+ static std::pair<uint64_t, uint8_t> CWL_TABLE_1 [6] =
+ {
+ {1600, 9},
+ {1866, 10},
+ {2133, 11},
+ {2400, 12},
+ {2666, 14},
+ {3200, 16},
+ };
+ static std::pair<uint64_t, uint8_t> CWL_TABLE_2 [3] =
+ {
+ {2400, 14},
+ {2666, 16},
+ {3200, 18},
+ };
+
+ std::vector<uint8_t> l_attrs_cwl(PORTS_PER_MCS, 0);
+ uint8_t l_cwl = 0;
+ uint8_t l_preamble = 0;
+
+ FAPI_TRY( vpd_mt_preamble (iv_mca, l_preamble) );
+
+ // get the first nibble as according to vpd. 4-7 is read, 0-3 for write
+ l_preamble = l_preamble & 0x0F;
+
+ FAPI_ASSERT( ((l_preamble == 0) || (l_preamble == 1)),
+ fapi2::MSS_INVALID_VPD_MT_PREAMBLE()
+ .set_VALUE(l_preamble)
+ .set_DIMM_TARGET(iv_dimm),
+ "Target %s VPD_MT_PREAMBLE is invalid (not 1 or 0), value is %d",
+ mss::c_str(iv_dimm),
+ l_preamble );
+
+ // Using an if branch because a ternary conditional wasn't working with params for find_value_from_key
+ if (l_preamble == 0)
+ {
+ FAPI_TRY( mss::find_value_from_key( CWL_TABLE_1,
+ iv_freq, l_cwl),
+ "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
+ iv_freq,
+ l_preamble);
+ }
+ else
+ {
+ FAPI_TRY( mss::find_value_from_key( CWL_TABLE_2,
+ iv_freq, l_cwl),
+ "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
+ iv_freq,
+ l_preamble);
+
+ }
+
+ FAPI_TRY( eff_dram_cwl(iv_mcs, l_attrs_cwl.data()) );
+ l_attrs_cwl[iv_port_index] = l_cwl;
+
+ FAPI_INF("Calculated CAS Write Latency is %d", l_cwl);
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_CWL,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_cwl, PORTS_PER_MCS)),
+ "Failed setting attribute for cwl");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for lpasr
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note from JEDEC DDR4 DRAM MR2 page 26
+/// @note All DDR4 supports auto refresh, setting to default
+///
+fapi2::ReturnCode eff_dimm::dram_lpasr()
+{
+ std::vector<uint8_t> l_attrs_lpasr(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_dram_lpasr(iv_mcs, l_attrs_lpasr.data()) );
+
+ l_attrs_lpasr[iv_port_index] = fapi2::ENUM_ATTR_EFF_DRAM_LPASR_MANUAL_EXTENDED;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_LPASR,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_lpasr, PORTS_PER_MCS)),
+ "Failed setting attribute for LPASR");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for additive latency
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::additive_latency()
+{
+ std::vector<uint8_t> l_attrs_dram_al(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_dram_al(iv_mcs, l_attrs_dram_al.data()) );
+
+ l_attrs_dram_al[iv_port_index] = fapi2::ENUM_ATTR_EFF_DRAM_AL_DISABLE;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_AL,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_al, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_AL");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DLL Reset
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dll_reset()
+{
+ uint8_t l_attrs_dll_reset[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_dll_reset(iv_mcs, &l_attrs_dll_reset[0][0]) );
+
+ // Default is to reset DLLs during IPL.
+ l_attrs_dll_reset[iv_port_index][iv_dimm_index] = fapi2::ENUM_ATTR_EFF_DRAM_DLL_RESET_YES;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DLL_RESET, iv_mcs, l_attrs_dll_reset),
+ "Failed setting attribute for BL");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DLL Enable
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dll_enable()
+{
+ uint8_t l_attrs_dll_enable[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_dll_enable(iv_mcs, &l_attrs_dll_enable[0][0]) );
+
+ // Enable DLLs by default.
+ l_attrs_dll_enable[iv_port_index][iv_dimm_index] = fapi2::ENUM_ATTR_EFF_DRAM_DLL_ENABLE_YES;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DLL_ENABLE, iv_mcs, l_attrs_dll_enable),
+ "Failed setting attribute for BL");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for Write Level Enable
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::write_level_enable()
+{
+ std::vector<uint8_t> l_attrs_wr_lvl_enable(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_dram_wr_lvl_enable(iv_mcs, l_attrs_wr_lvl_enable.data()) );
+
+ l_attrs_wr_lvl_enable[iv_port_index] = fapi2::ENUM_ATTR_EFF_DRAM_WR_LVL_ENABLE_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_WR_LVL_ENABLE,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_wr_lvl_enable, PORTS_PER_MCS)),
+ "Failed setting attribute for WR_LVL_ENABLE");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for Output Buffer
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::output_buffer()
+{
+ std::vector<uint8_t> l_attrs_output_buffer(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_dram_output_buffer(iv_mcs, l_attrs_output_buffer.data()) );
+
+ l_attrs_output_buffer[iv_port_index] = fapi2::ENUM_ATTR_EFF_DRAM_OUTPUT_BUFFER_ENABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_OUTPUT_BUFFER,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_output_buffer, PORTS_PER_MCS)),
+ "Failed setting attribute for OUTPUT_BUFFER");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for Vref DQ Train Value
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::vref_dq_train_value()
+{
+
+ uint8_t l_attrs_vref_dq_train_val[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_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);
+
+ FAPI_ASSERT(l_train_value <= JEDEC_MAX_TRAIN_VALUE,
+ fapi2::MSS_INVALID_VPD_VREF_DRAM_WR_RANGE()
+ .set_MAX(JEDEC_MAX_TRAIN_VALUE)
+ .set_VALUE(l_train_value)
+ .set_DIMM_TARGET(iv_dimm),
+ "%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 );
+
+ // 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) );
+
+ 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;
+ }
+
+ 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_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for Vref DQ Train Enable
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::vref_dq_train_enable()
+{
+ // Default mode for train enable should be normal operation mode - 0x00
+
+ uint8_t l_attrs_vref_dq_train_enable[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+ std::vector< uint64_t > l_ranks;
+
+ // Attribute to set num dimm ranks is a pre-requisite
+ FAPI_TRY( eff_vref_dq_train_enable(iv_mcs, &l_attrs_vref_dq_train_enable[0][0][0]) );
+ FAPI_TRY( mss::rank::ranks(iv_dimm, l_ranks) );
+
+ for(const auto& l_rank : l_ranks)
+ {
+ l_attrs_vref_dq_train_enable[iv_port_index][iv_dimm_index][index(l_rank)] = 0x00;
+ }
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_ENABLE, iv_mcs, l_attrs_vref_dq_train_enable),
+ "Failed setting attribute for ATTR_EFF_VREF_DQ_TRAIN_ENABLE");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @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
+///
+fapi2::ReturnCode eff_dimm::ca_parity_latency()
+{
+ // TODO: RTC 159554 Update RAS related attributes
+ std::vector<uint8_t> l_attrs_ca_parity_latency(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_ca_parity_latency(iv_mcs, l_attrs_ca_parity_latency.data()) );
+ l_attrs_ca_parity_latency[iv_port_index] = fapi2::ENUM_ATTR_EFF_CA_PARITY_LATENCY_DISABLE;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CA_PARITY_LATENCY,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_ca_parity_latency, PORTS_PER_MCS)),
+ "Failed setting attribute for CA_PARITY_LATENCY");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for CRC Error Clear
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::crc_error_clear()
+{
+ // TODO: RTC 159554 Update RAS related attributes
+ std::vector<uint8_t> l_attrs_crc_error_clear(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_crc_error_clear(iv_mcs, l_attrs_crc_error_clear.data()) );
+
+ l_attrs_crc_error_clear[iv_port_index] = fapi2::ENUM_ATTR_EFF_CRC_ERROR_CLEAR_CLEAR;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CRC_ERROR_CLEAR,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_crc_error_clear, PORTS_PER_MCS)),
+ "Failed setting attribute for CRC_ERROR_CLEAR");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for CA Parity Error Status
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::ca_parity_error_status()
+{
+ // TODO: RTC 159554 Update RAS related attributes
+ std::vector<uint8_t> l_attrs_ca_parity_error_status(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_ca_parity_error_status(iv_mcs, l_attrs_ca_parity_error_status.data()) );
+
+ l_attrs_ca_parity_error_status[iv_port_index] = fapi2::ENUM_ATTR_EFF_CA_PARITY_ERROR_STATUS_CLEAR;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CA_PARITY_ERROR_STATUS,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_ca_parity_error_status, PORTS_PER_MCS)),
+ "Failed setting attribute for CA_PARITY_ERROR_STATUS");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for CA Parity
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::ca_parity()
+{
+ // TODO: RTC 159554 Update RAS related attributes
+ std::vector<uint8_t> l_attrs_ca_parity(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_ca_parity(iv_mcs, l_attrs_ca_parity.data()) );
+
+ l_attrs_ca_parity[iv_port_index] = fapi2::ENUM_ATTR_EFF_CA_PARITY_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CA_PARITY,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_ca_parity, PORTS_PER_MCS)),
+ "Failed setting attribute for CA_PARITY");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for ODT Input Buffer
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::odt_input_buffer()
+{
+ // keeping this value as 0x01, given that we know that that works in sim
+ constexpr uint8_t SIM_VALUE = 0x01;
+ std::vector<uint8_t> l_attrs_odt_input_buffer(PORTS_PER_MCS, 0);
+
+ // Targets
+
+ // keep simulation to values we know work
+ uint8_t is_sim = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), is_sim) );
+
+
+ FAPI_TRY( eff_odt_input_buff(iv_mcs, l_attrs_odt_input_buffer.data()) );
+
+ // sim vs actual hardware value
+ l_attrs_odt_input_buffer[iv_port_index] = is_sim ? SIM_VALUE : fapi2::ENUM_ATTR_EFF_ODT_INPUT_BUFF_ACTIVATED;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_ODT_INPUT_BUFF,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_odt_input_buffer, PORTS_PER_MCS)),
+ "Failed setting attribute for ODT_INPUT_BUFF");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for data_mask
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Datamask is unnused and not needed because no DBI.
+/// @note Defaulted to 0
+///
+fapi2::ReturnCode eff_dimm::data_mask()
+{
+ std::vector<uint8_t> l_attrs_data_mask(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_data_mask(iv_mcs, l_attrs_data_mask.data()) );
+
+ l_attrs_data_mask[iv_port_index] = fapi2::ENUM_ATTR_EFF_DATA_MASK_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DATA_MASK,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_data_mask, PORTS_PER_MCS)),
+ "Failed setting attribute for DATA_MASK");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for write_dbi
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note DBI is not supported
+///
+fapi2::ReturnCode eff_dimm::write_dbi()
+{
+ std::vector<uint8_t> l_attrs_write_dbi(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_write_dbi(iv_mcs, l_attrs_write_dbi.data()) );
+
+ l_attrs_write_dbi[iv_port_index] = fapi2::ENUM_ATTR_EFF_WRITE_DBI_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_WRITE_DBI,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_write_dbi, PORTS_PER_MCS)),
+ "Failed setting attribute for WRITE_DBI");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for read_dbi
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note read_dbi is not supported, so set to DISABLED (0)
+/// @note No logic for DBI
+///
+fapi2::ReturnCode eff_dimm::read_dbi()
+{
+
+ std::vector<uint8_t> l_attrs_read_dbi(PORTS_PER_MCS, 0);
+ FAPI_TRY( eff_read_dbi(iv_mcs, l_attrs_read_dbi.data()) );
+
+ l_attrs_read_dbi[iv_port_index] = fapi2::ENUM_ATTR_EFF_READ_DBI_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_READ_DBI,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_read_dbi, PORTS_PER_MCS)),
+ "Failed setting attribute for READ_DBI");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for Post Package Repair
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note write_dbi is not supported, so set to DISABLED (0)
+/// @note no logic for DBI
+///
+fapi2::ReturnCode eff_dimm::post_package_repair()
+{
+
+ uint8_t l_decoder_val = 0;
+ uint8_t l_attrs_dram_ppr[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_ppr(iv_mcs, &l_attrs_dram_ppr[0][0]) );
+ FAPI_TRY( iv_pDecoder->post_package_repair(iv_dimm, l_decoder_val) );
+
+ l_attrs_dram_ppr[iv_port_index][iv_dimm_index] = l_decoder_val;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_PPR, iv_mcs, l_attrs_dram_ppr),
+ "Failed setting attribute for DRAM_PPR");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for rd_preamble_train
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::read_preamble_train()
+{
+ std::vector<uint8_t> l_attrs_rd_preamble_train(PORTS_PER_MCS, 0);
+ FAPI_TRY( eff_rd_preamble_train(iv_mcs, l_attrs_rd_preamble_train.data()) );
+
+ l_attrs_rd_preamble_train[iv_port_index] = fapi2::ENUM_ATTR_EFF_RD_PREAMBLE_TRAIN_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_RD_PREAMBLE_TRAIN,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_rd_preamble_train, PORTS_PER_MCS)),
+ "Failed setting attribute for RD_PREAMBLE_TRAIN");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for rd_preamble
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::read_preamble()
+{
+ std::vector<uint8_t> l_attrs_rd_preamble(PORTS_PER_MCS, 0);
+ uint8_t l_preamble = 0;
+
+ FAPI_TRY( vpd_mt_preamble (iv_mca, l_preamble) ) ;
+ l_preamble = l_preamble & 0xF0;
+ l_preamble = l_preamble >> 4;
+
+
+ FAPI_ASSERT( ((l_preamble == 0) || (l_preamble == 1)),
+ fapi2::MSS_INVALID_VPD_MT_PREAMBLE()
+ .set_VALUE(l_preamble)
+ .set_DIMM_TARGET(iv_dimm),
+ "Target %s VPD_MT_PREAMBLE is invalid (not 1 or 0), value is %d",
+ mss::c_str(iv_dimm),
+ l_preamble );
+
+ FAPI_TRY( eff_rd_preamble(iv_mcs, l_attrs_rd_preamble.data()) );
+
+ l_attrs_rd_preamble[iv_port_index] = l_preamble;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_RD_PREAMBLE,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_rd_preamble, PORTS_PER_MCS)),
+ "Failed setting attribute for RD_PREAMBLE");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for wr_preamble
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::write_preamble()
+{
+ std::vector<uint8_t> l_attrs_wr_preamble(PORTS_PER_MCS, 0);
+ uint8_t l_preamble = 0;
+
+ FAPI_TRY( vpd_mt_preamble (iv_mca, l_preamble) ) ;
+ l_preamble = l_preamble & 0x0F;
+ FAPI_INF("WR preamble is %d", l_preamble);
+
+ FAPI_ASSERT( ((l_preamble == 0) || (l_preamble == 1)),
+ fapi2::MSS_INVALID_VPD_MT_PREAMBLE()
+ .set_VALUE(l_preamble)
+ .set_DIMM_TARGET(iv_dimm),
+ "Target %s VPD_MT_PREAMBLE is invalid (not 1 or 0), value is %d",
+ mss::c_str(iv_dimm),
+ l_preamble );
+
+ FAPI_TRY( eff_wr_preamble(iv_mcs, l_attrs_wr_preamble.data()) );
+
+ l_attrs_wr_preamble[iv_port_index] = l_preamble;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_WR_PREAMBLE,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_wr_preamble, PORTS_PER_MCS)),
+ "Failed setting attribute for RD_PREAMBLE");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for self_ref_abort
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::self_refresh_abort()
+{
+ std::vector<uint8_t> l_attrs_self_ref_abort(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_self_ref_abort(iv_mcs, l_attrs_self_ref_abort.data()) );
+
+ l_attrs_self_ref_abort[iv_port_index] = fapi2::ENUM_ATTR_EFF_SELF_REF_ABORT_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_SELF_REF_ABORT,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_self_ref_abort, PORTS_PER_MCS)),
+ "Failed setting attribute for SELF_REF_ABORT");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for cs_cmd_latency
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::cs_to_cmd_addr_latency()
+{
+ std::vector<uint8_t> l_attrs_cs_cmd_latency(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_cs_cmd_latency(iv_mcs, l_attrs_cs_cmd_latency.data()) );
+
+ l_attrs_cs_cmd_latency[iv_port_index] = fapi2::ENUM_ATTR_EFF_CS_CMD_LATENCY_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CS_CMD_LATENCY,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_cs_cmd_latency, PORTS_PER_MCS)),
+ "Failed setting attribute for CS_CMD_LATENCY");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for int_vref_mon
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::internal_vref_monitor()
+{
+ std::vector<uint8_t> l_attrs_int_vref_mon(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_internal_vref_monitor(iv_mcs, l_attrs_int_vref_mon.data()) );
+
+ l_attrs_int_vref_mon[iv_port_index] = fapi2::ENUM_ATTR_EFF_INTERNAL_VREF_MONITOR_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_INTERNAL_VREF_MONITOR,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_int_vref_mon, PORTS_PER_MCS)),
+ "Failed setting attribute for INT_VREF_MON");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for powerdown_mode
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::max_powerdown_mode()
+{
+ std::vector<uint8_t> l_attrs_powerdown_mode(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_max_powerdown_mode(iv_mcs, l_attrs_powerdown_mode.data()) );
+
+ l_attrs_powerdown_mode[iv_port_index] = fapi2::ENUM_ATTR_EFF_MAX_POWERDOWN_MODE_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MAX_POWERDOWN_MODE,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_powerdown_mode, PORTS_PER_MCS)),
+ "Failed setting attribute for POWERDOWN_MODE");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for mpr_rd_format
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::mpr_read_format()
+{
+ std::vector<uint8_t> l_attrs_mpr_rd_format(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_mpr_rd_format(iv_mcs, l_attrs_mpr_rd_format.data()) );
+
+ // Serial format is standard for Nimbus and needed for PHY calibration (draminit_training)
+ l_attrs_mpr_rd_format[iv_port_index] = fapi2::ENUM_ATTR_EFF_MPR_RD_FORMAT_SERIAL;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MPR_RD_FORMAT,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_mpr_rd_format, PORTS_PER_MCS)),
+ "Failed setting attribute for MPR_RD_FORMAT");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for CRC write latency
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::crc_wr_latency()
+{
+ std::vector<uint8_t> l_attrs_crc_wr_latency(PORTS_PER_MCS, 0);
+
+ // keep simulation to values we know work
+ uint8_t is_sim = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), is_sim) );
+
+ FAPI_TRY( eff_crc_wr_latency(iv_mcs, l_attrs_crc_wr_latency.data()) );
+
+ // keep simulation to values we know work
+ if(is_sim)
+ {
+ l_attrs_crc_wr_latency[iv_port_index] = 0x05;
+ }
+ // set the attribute according to frequency
+ else
+ {
+ // TODO RTC:159481 - update CRC write latency to include 2667
+ // currently, JEDEC defines the following
+ // crc wr latency - freq
+ // 4 - 1600
+ // 5 - 1866, 2133, 2400
+ // 6 - TBD
+ // Nimbus only supports 1866->2400 on the current list
+ // 2667 is not noted. We will set crc_wr_latency to 0x05 until JEDEC value is updated
+ // When JEDEC defines the 2667 value we can change this, but leave the sim value as 0x05
+ l_attrs_crc_wr_latency[iv_port_index] = 0x05;
+ }
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CRC_WR_LATENCY,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_crc_wr_latency, PORTS_PER_MCS)),
+ "Failed setting attribute for CRC WRITE LATENCY");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for temperature readout
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::temp_readout()
+{
+ std::vector<uint8_t> l_attrs_temp_readout(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_temp_readout(iv_mcs, l_attrs_temp_readout.data()) );
+
+ // Disabled for mainline mode
+ l_attrs_temp_readout[iv_port_index] = fapi2::ENUM_ATTR_EFF_TEMP_READOUT_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_TEMP_READOUT,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_temp_readout, PORTS_PER_MCS)),
+ "Failed setting attribute for TEMP_READOUT");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for per DRAM addressability
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::per_dram_addressability()
+{
+ std::vector<uint8_t> l_attrs_per_dram_access(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_per_dram_access(iv_mcs, l_attrs_per_dram_access.data()) );
+
+ // PDA is disabled in mainline functionality
+ l_attrs_per_dram_access[iv_port_index] = fapi2::ENUM_ATTR_EFF_PER_DRAM_ACCESS_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_PER_DRAM_ACCESS,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_per_dram_access, PORTS_PER_MCS)),
+ "Failed setting attribute for PER_DRAM_ACCESS");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for geardown mode
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::geardown_mode()
+{
+ std::vector<uint8_t> l_attrs_geardown_mode(PORTS_PER_MCS, 0);
+
+ // Geardown maps directly to autoset = 0 gets 1/2 rate, 1 get 1/4 rate.
+ FAPI_TRY( eff_geardown_mode(iv_mcs, l_attrs_geardown_mode.data()) );
+
+ // If the MRW states 'auto' we use what's in VPD, otherwise we use what's in the MRW.
+ // We remove 1 from the value as that matches the expectations in the MR perfectly.
+ l_attrs_geardown_mode[iv_port_index] = mss::two_n_mode_helper(iv_dimm);
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_GEARDOWN_MODE,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_geardown_mode, PORTS_PER_MCS)),
+ "Failed setting attribute for GEARDOWN_MODE");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for MPR page
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::mpr_page()
+{
+ std::vector<uint8_t> l_attrs_mpr_page(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_mpr_page(iv_mcs, l_attrs_mpr_page.data()) );
+
+ // page0 is needed for PHY calibration algorithm (run in draminit_training)
+ l_attrs_mpr_page[iv_port_index] = fapi2::ENUM_ATTR_EFF_MPR_PAGE_PG0;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MPR_PAGE,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_mpr_page, PORTS_PER_MCS)),
+ "Failed setting attribute for MPR_PAGE");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for MPR mode
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::mpr_mode()
+{
+ std::vector<uint8_t> l_attrs_mpr_mode(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_mpr_mode(iv_mcs, l_attrs_mpr_mode.data()) );
+
+ // MPR mode is disabled for mainline functionality
+ l_attrs_mpr_mode[iv_port_index] = fapi2::ENUM_ATTR_EFF_MPR_MODE_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MPR_MODE,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_mpr_mode, PORTS_PER_MCS)),
+ "Failed setting attribute for MPR_MODE");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for write CRC
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::write_crc()
+{
+ // TODO: RTC 159554 Update RAS related attributes
+ std::vector<uint8_t> l_attrs_write_crc(PORTS_PER_MCS, 0);
+
+ uint8_t l_mrw = 0;
+
+ FAPI_TRY( eff_write_crc(iv_mcs, l_attrs_write_crc.data()) );
+ FAPI_TRY( mrw_dram_write_crc(l_mrw) );
+
+ l_attrs_write_crc[iv_port_index] = (l_mrw == fapi2::ENUM_ATTR_MSS_MRW_DRAM_WRITE_CRC_ENABLE) ?
+ fapi2::ENUM_ATTR_EFF_WRITE_CRC_ENABLE :
+ fapi2::ENUM_ATTR_EFF_WRITE_CRC_DISABLE;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_WRITE_CRC,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_write_crc, PORTS_PER_MCS)),
+ "Failed setting attribute for WRITE_CRC");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for ZQ Calibration
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::zqcal_interval()
+{
+ std::vector<uint32_t> l_attrs_zqcal_interval(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_zqcal_interval(iv_mcs, l_attrs_zqcal_interval.data()) );
+
+ // Calculate ZQCAL Interval based on the following equation from Ken:
+ // 0.5
+ // ------------------------------ = 13.333ms
+ // (1.5 * 10) + (0.15 * 150)
+ // (13333 * ATTR_MSS_FREQ) / 2
+
+ l_attrs_zqcal_interval[iv_port_index] = 13333 * iv_freq / 2;
+
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_ZQCAL_INTERVAL,
+ iv_mcs,
+ UINT32_VECTOR_TO_1D_ARRAY(l_attrs_zqcal_interval, PORTS_PER_MCS)),
+ "Failed setting attribute for ZQCAL_INTERVAL");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for MEMCAL Calibration
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::memcal_interval()
+{
+ std::vector<uint32_t> l_attrs_memcal_interval(PORTS_PER_MCS, 0);
+
+ FAPI_TRY( eff_memcal_interval(iv_mcs, l_attrs_memcal_interval.data()) );
+
+ // Calculate MEMCAL Interval based on 1sec interval across all bits per DP16
+ // (62500 * ATTR_MSS_FREQ) / 2
+ l_attrs_memcal_interval[iv_port_index] = 62500 * iv_freq / 2;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MEMCAL_INTERVAL,
+ iv_mcs,
+ UINT32_VECTOR_TO_1D_ARRAY(l_attrs_memcal_interval, PORTS_PER_MCS)),
+ "Failed setting attribute for MEMCAL_INTERVAL");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRP
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trp()
+{
+
+ int64_t l_trp_in_ps = 0;
+
+ // Calculate tRP (in ps)
+ {
+ int64_t l_trp_mtb = 0;
+ int64_t l_trp_ftb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb),
+ "Failed medium_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb),
+ "Failed fine_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->min_row_precharge_delay_time(iv_dimm, l_trp_mtb),
+ "Failed min_row_precharge_delay_time() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_offset_min_trp(iv_dimm, l_trp_ftb),
+ "Failed fine_offset_min_trp() for %s", mss::c_str(iv_dimm) );
+
+ FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tRP (MTB): %ld, tRP(FTB): %ld",
+ l_mtb, l_ftb, l_trp_mtb, l_trp_ftb);
+
+ l_trp_in_ps = spd::calc_timing_from_timebase(l_trp_mtb, l_mtb, l_trp_ftb, l_ftb);
+ }
+
+ // SPD spec gives us the minimum... compute our worstcase (maximum) from JEDEC
+ {
+ // Declaring as int64_t to fix std::max compile
+ const int64_t l_trp = mss::ps_to_cycles(iv_dimm, mss::trtp());
+ l_trp_in_ps = std::max( l_trp_in_ps , l_trp );
+ }
+
+ {
+ std::vector<uint8_t> l_attrs_dram_trp(PORTS_PER_MCS, 0);
+ uint8_t l_trp_in_nck = 0;
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_trp_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trp_in_nck),
+ "Error in calculating dram_tRP nck for target %s, with value of l_trp_in_ps: %d", mss::c_str(iv_dimm), l_trp_in_ps);
+
+ FAPI_INF( "tCK (ps): %d, tRP (ps): %d, tRP (nck): %d for target: %s",
+ iv_tCK_in_ps, l_trp_in_ps, l_trp_in_nck, mss::c_str(iv_dimm) );
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_trp(iv_mcs, l_attrs_dram_trp.data()) );
+
+ l_attrs_dram_trp[iv_port_index] = l_trp_in_nck ;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRP,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trp, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TRP");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRCD
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trcd()
+{
+ int64_t l_trcd_in_ps = 0;
+
+ // Calculate tRCD (in ps)
+ // Get the tRCD timing values
+ // tRCD is speed bin dependent and has a unique
+ // value for each speed bin so it is safe to
+ // read from SPD because the correct nck
+ // value will be calulated based on our dimm speed.
+ {
+ int64_t l_trcd_mtb = 0;
+ int64_t l_trcd_ftb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb),
+ "Failed medium_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb),
+ "Failed fine_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->min_ras_to_cas_delay_time(iv_dimm, l_trcd_mtb),
+ "Failed min_ras_to_cas_delay_time() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_offset_min_trcd(iv_dimm, l_trcd_ftb),
+ "Failed fine_offset_min_trcd() for %s", mss::c_str(iv_dimm) );
+
+ FAPI_INF("medium timebase MTB (ps): %ld, fine timebase FTB (ps): %ld, tRCD (MTB): %ld, tRCD (FTB): %ld",
+ l_mtb, l_ftb, l_trcd_mtb, l_trcd_ftb);
+
+ l_trcd_in_ps = spd::calc_timing_from_timebase(l_trcd_mtb, l_mtb, l_trcd_ftb, l_ftb);
+ }
+
+ {
+ std::vector<uint8_t> l_attrs_dram_trcd(PORTS_PER_MCS, 0);
+ uint8_t l_trcd_in_nck = 0;
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_trcd_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trcd_in_nck),
+ "Error in calculating trcd for target %s, with value of l_trcd_in_ps: %d", mss::c_str(iv_dimm), l_trcd_in_ps);
+
+ FAPI_INF("tCK (ps): %d, tRCD (ps): %d, tRCD (nck): %d for target: %s",
+ iv_tCK_in_ps, l_trcd_in_ps, l_trcd_in_nck, mss::c_str(iv_dimm));
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_trcd(iv_mcs, l_attrs_dram_trcd.data()) );
+
+ l_attrs_dram_trcd[iv_port_index] = l_trcd_in_nck;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRCD,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trcd, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TRCD");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRC
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trc()
+{
+ int64_t l_trc_in_ps = 0;
+
+ // Calculate trc (in ps)
+ {
+ int64_t l_trc_mtb = 0;
+ int64_t l_trc_ftb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb),
+ "Failed medium_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb),
+ "Failed fine_timebase() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->min_active_to_active_refresh_delay_time(iv_dimm, l_trc_mtb),
+ "Failed min_active_to_active_refresh_delay_time() for %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( iv_pDecoder->fine_offset_min_trc(iv_dimm, l_trc_ftb),
+ "Failed fine_offset_min_trc() for %s", mss::c_str(iv_dimm) );
+
+ FAPI_INF("medium timebase MTB (ps): %ld, fine timebase FTB (ps): %ld, tRCmin (MTB): %ld, tRCmin(FTB): %ld",
+ l_mtb, l_ftb, l_trc_mtb, l_trc_ftb);
+
+ l_trc_in_ps = spd::calc_timing_from_timebase(l_trc_mtb, l_mtb, l_trc_ftb, l_ftb);
+ }
+
+ {
+ std::vector<uint8_t> l_attrs_dram_trc(PORTS_PER_MCS, 0);
+ uint8_t l_trc_in_nck = 0;
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_trc_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trc_in_nck),
+ "Error in calculating trc for target %s, with value of l_trc_in_ps: %d",
+ mss::c_str(iv_dimm), l_trc_in_ps );
+
+ FAPI_INF( "tCK (ps): %d, tRC (ps): %d, tRC (nck): %d for target: %s",
+ iv_tCK_in_ps, l_trc_in_ps, l_trc_in_nck, mss::c_str(iv_dimm) );
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_trc(iv_mcs, l_attrs_dram_trc.data()) );
+
+ l_attrs_dram_trc[iv_port_index] = l_trc_in_nck;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRC,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trc, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TRC");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tWTR_L
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_twtr_l()
+{
+ int64_t l_twtr_l_in_ps = 0;
+
+ // Calculate twtr_l (in ps)
+ {
+ constexpr int64_t l_twtr_l_ftb = 0;
+ int64_t l_twtr_l_mtb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb) );
+ FAPI_TRY( iv_pDecoder->min_twtr_l(iv_dimm, l_twtr_l_mtb) );
+
+ FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tWTR_S (MTB): %ld, tWTR_S (FTB): %ld",
+ l_mtb, l_ftb, l_twtr_l_mtb, l_twtr_l_ftb );
+
+ l_twtr_l_in_ps = spd::calc_timing_from_timebase(l_twtr_l_mtb, l_mtb, l_twtr_l_ftb, l_ftb);
+ }
+
+
+ {
+ std::vector<uint8_t> l_attrs_dram_twtr_l(PORTS_PER_MCS, 0);
+ int8_t l_twtr_l_in_nck = 0;
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_twtr_l_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_l_in_nck),
+ "Error in calculating tWTR_L for target %s, with value of l_twtr_in_ps: %d", mss::c_str(iv_dimm), l_twtr_l_in_ps );
+
+ FAPI_INF( "tCK (ps): %d, tWTR_L (ps): %d, tWTR_L (nck): %d for target: %s",
+ iv_tCK_in_ps, l_twtr_l_in_ps, l_twtr_l_in_nck, mss::c_str(iv_dimm) );
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_twtr_l(iv_mcs, l_attrs_dram_twtr_l.data()) );
+
+ l_attrs_dram_twtr_l[iv_port_index] = l_twtr_l_in_nck;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TWTR_L,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_twtr_l, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TWTR_L");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tWTR_S
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_twtr_s()
+{
+ int64_t l_twtr_s_in_ps = 0;
+
+ // Calculate twtr_s (in ps)
+ {
+ constexpr int64_t l_twtr_s_ftb = 0;
+ int64_t l_twtr_s_mtb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( iv_pDecoder->medium_timebase(iv_dimm, l_mtb) );
+ FAPI_TRY( iv_pDecoder->fine_timebase(iv_dimm, l_ftb) );
+ FAPI_TRY( iv_pDecoder->min_twtr_s(iv_dimm, l_twtr_s_mtb) );
+
+ FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tWTR_S (MTB): %ld, tWTR_S (FTB): %ld",
+ l_mtb, l_ftb, l_twtr_s_mtb, l_twtr_s_ftb );
+
+ l_twtr_s_in_ps = spd::calc_timing_from_timebase(l_twtr_s_mtb, l_mtb, l_twtr_s_ftb, l_ftb);
+ }
+
+ {
+ std::vector<uint8_t> l_attrs_dram_twtr_s(PORTS_PER_MCS, 0);
+ uint8_t l_twtr_s_in_nck = 0;
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_twtr_s_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_s_in_nck),
+ "Error in calculating tWTR_S for target %s, with value of l_twtr_in_ps: %d", mss::c_str(iv_dimm), l_twtr_s_in_ps);
+
+ FAPI_INF("tCK (ps): %d, tWTR_S (ps): %d, tWTR_S (nck): %d for target: %s",
+ iv_tCK_in_ps, l_twtr_s_in_ps, l_twtr_s_in_nck, mss::c_str(iv_dimm) );
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_twtr_s(iv_mcs, l_attrs_dram_twtr_s.data()) );
+
+ l_attrs_dram_twtr_s[iv_port_index] = l_twtr_s_in_nck;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TWTR_S,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_twtr_s, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TWTR_S");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRRD_S
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trrd_s()
+{
+
+ std::vector<uint8_t> l_attrs_dram_trrd_s(PORTS_PER_MCS, 0);
+ uint64_t l_trrd_s_in_nck = 0;
+ uint8_t l_stack_type = 0;
+ uint8_t l_dram_width = 0;
+
+ FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(iv_dimm, l_stack_type) );
+ FAPI_TRY( iv_pDecoder->device_width(iv_dimm, l_dram_width),
+ "Failed to access device_width()");
+
+ // From the SPD Spec:
+ // At some frequencies, a minimum number of clocks may be required resulting
+ // in a larger tRRD_Smin value than indicated in the SPD.
+ // tRRD_S (3DS) is speed bin independent.
+ // So we won't read this from SPD and choose the correct value based on mss_freq
+
+ if( l_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS)
+ {
+ FAPI_TRY( trrd_s_slr(iv_dimm, l_trrd_s_in_nck) );
+ }
+ else
+ {
+ // Non-3DS
+ FAPI_TRY( mss::trrd_s(iv_dimm, l_dram_width, l_trrd_s_in_nck) );
+ }
+
+ FAPI_INF("SDRAM width: %d, tRRD_S (nck): %d for target: %s",
+ l_dram_width, l_trrd_s_in_nck, mss::c_str(iv_dimm));
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_trrd_s(iv_mcs, l_attrs_dram_trrd_s.data()) );
+
+ l_attrs_dram_trrd_s[iv_port_index] = l_trrd_s_in_nck;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRRD_S,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trrd_s, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TRRD_S");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRRD_L
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trrd_l()
+{
+
+ std::vector<uint8_t> l_attrs_dram_trrd_l(PORTS_PER_MCS, 0);
+ uint64_t l_trrd_l_in_nck = 0;
+ uint8_t l_stack_type = 0;
+ uint8_t l_dram_width = 0;
+
+ FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(iv_dimm, l_stack_type),
+ "Failed prim_sdram_signal_loading()" );
+ FAPI_TRY( iv_pDecoder->device_width(iv_dimm, l_dram_width),
+ "Failed to access device_width()");
+
+ // From the SPD Spec:
+ // At some frequencies, a minimum number of clocks may be required resulting
+ // in a larger tRRD_Smin value than indicated in the SPD.
+ // tRRD_S (3DS) is speed bin independent.
+ // So we won't read this from SPD and choose the correct value based on mss_freq
+
+ if( l_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS)
+ {
+ FAPI_TRY( trrd_l_slr(iv_dimm, l_trrd_l_in_nck) );
+ }
+ else
+ {
+ FAPI_TRY( mss::trrd_l(iv_dimm, l_dram_width, l_trrd_l_in_nck), "Failed trrd_l()" );
+ }
+
+ FAPI_INF("SDRAM width: %d, tRRD_L (nck): %d for target: %s",
+ l_dram_width, l_trrd_l_in_nck, mss::c_str(iv_dimm));
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_trrd_l(iv_mcs, l_attrs_dram_trrd_l.data()) );
+
+ l_attrs_dram_trrd_l[iv_port_index] = l_trrd_l_in_nck;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRRD_L,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trrd_l, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TRRD_L");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRRD_dlr
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trrd_dlr()
+{
+
+ std::vector<uint8_t> l_attrs_dram_trrd_dlr(PORTS_PER_MCS, 0);
+ constexpr uint64_t l_trrd_dlr_in_nck = trrd_dlr();
+
+ FAPI_INF("tRRD_dlr (nck): %d for target: %s", l_trrd_dlr_in_nck, mss::c_str(iv_dimm));
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_trrd_dlr(iv_mcs, l_attrs_dram_trrd_dlr.data()) );
+
+ l_attrs_dram_trrd_dlr[iv_port_index] = l_trrd_dlr_in_nck;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRRD_DLR,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trrd_dlr, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TRRD_DLR");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tfaw
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_tfaw()
+{
+
+ std::vector<uint8_t> l_attrs_dram_tfaw(PORTS_PER_MCS, 0);
+ uint64_t l_tfaw_in_nck = 0;
+ uint8_t l_stack_type = 0;
+ uint8_t l_dram_width = 0;
+
+ FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(iv_dimm, l_stack_type),
+ "Failed prim_sdram_signal_loading()");
+ FAPI_TRY( iv_pDecoder->device_width(iv_dimm, l_dram_width),
+ "Failed device_width()");
+
+ if( l_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS)
+ {
+ FAPI_TRY( tfaw_slr(iv_dimm, l_dram_width, l_tfaw_in_nck), "Failed tfaw_slr()");
+ }
+ else
+ {
+ FAPI_TRY( mss::tfaw(iv_dimm, l_dram_width, l_tfaw_in_nck), "Failed tfaw()" );
+ }
+
+ FAPI_INF("SDRAM width: %d, tFAW (nck): %d for target: %s",
+ l_dram_width, l_tfaw_in_nck, mss::c_str(iv_dimm));
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_tfaw(iv_mcs, l_attrs_dram_tfaw.data()) );
+
+ l_attrs_dram_tfaw[iv_port_index] = l_tfaw_in_nck;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TFAW,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_tfaw, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TFAW");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tFAW_DLR
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_tfaw_dlr()
+{
+
+ std::vector<uint8_t> l_attrs_dram_tfaw_dlr(PORTS_PER_MCS, 0);
+ constexpr uint64_t l_tfaw_dlr_in_nck = tfaw_dlr();
+
+ FAPI_INF("tFAW_dlr (nck): %d for target: %s", l_tfaw_dlr_in_nck, mss::c_str(iv_dimm));
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_tfaw_dlr(iv_mcs, l_attrs_dram_tfaw_dlr.data()) );
+
+ l_attrs_dram_tfaw_dlr[iv_port_index] = l_tfaw_dlr_in_nck;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TFAW_DLR,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_tfaw_dlr, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TFAW_DLR");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRAS
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_tras()
+{
+
+ // tRAS is bin independent so we don't read this from SPD
+ // which will give the best timing value for the dimm
+ // (like 2400 MT/s) which may be different than the system
+ // speed (if we were being limited by VPD or MRW restrictions)
+ const uint64_t l_tras_in_ps = mss::tras(iv_dimm);
+
+ // Calculate nck
+ std::vector<uint8_t> l_attrs_dram_tras(PORTS_PER_MCS, 0);
+ uint8_t l_tras_in_nck = 0;
+
+ // Cast needed for calculations to be done on the same integral type
+ // as required by template deduction. We have iv_tCK_in_ps as a signed
+ // integer because we have other timing values that calculations do
+ // addition with negative integers.
+ FAPI_TRY( spd::calc_nck(l_tras_in_ps,
+ static_cast<uint64_t>(iv_tCK_in_ps),
+ INVERSE_DDR4_CORRECTION_FACTOR,
+ l_tras_in_nck),
+ "Error in calculating tras_l for target %s, with value of l_twtr_in_ps: %d",
+ mss::c_str(iv_dimm), l_tras_in_ps);
+
+ FAPI_INF("tCK (ps): %d, tRAS (ps): %d, tRAS (nck): %d for target: %s",
+ iv_tCK_in_ps, l_tras_in_ps, l_tras_in_nck, mss::c_str(iv_dimm));
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_tras(iv_mcs, l_attrs_dram_tras.data()) );
+
+ l_attrs_dram_tras[iv_port_index] = l_tras_in_nck;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRAS,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_tras, PORTS_PER_MCS)),
+ "Failed setting attribute for tRAS");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for tRTP
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::dram_trtp()
+{
+ // Values from proposed DDR4 Full spec update(79-4A)
+ // Item No. 1716.78C
+ // Page 241 & 246
+ int64_t constexpr l_max_trtp_in_ps = trtp();
+
+ std::vector<uint8_t> l_attrs_dram_trtp(PORTS_PER_MCS, 0);
+ uint8_t l_calc_trtp_in_nck = 0;
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_max_trtp_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_calc_trtp_in_nck),
+ "Error in calculating trtp for target %s, with value of l_twtr_in_ps: %d",
+ mss::c_str(iv_dimm), l_max_trtp_in_ps);
+
+ FAPI_INF("tCK (ps): %d, tRTP (ps): %d, tRTP (nck): %d",
+ iv_tCK_in_ps, l_max_trtp_in_ps, l_calc_trtp_in_nck);
+
+ // Get & update MCS attribute
+ FAPI_TRY( eff_dram_trtp(iv_mcs, l_attrs_dram_trtp.data()) );
+
+ l_attrs_dram_trtp[iv_port_index] = l_calc_trtp_in_nck;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRTP,
+ iv_mcs,
+ UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trtp, PORTS_PER_MCS)),
+ "Failed setting attribute for DRAM_TRTP");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets the RTT_NOM value for the eff_dimm
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note used for MRS01
+///
+fapi2::ReturnCode eff_rdimm::dram_rtt_nom()
+{
+ constexpr size_t RTT_NOM_MAP_SIZE = 8;
+ uint8_t l_decoder_val = 0;
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+
+ // Temp holders to grab attributes to then parse into value for this dimm and rank
+ uint8_t l_rtt_nom[MAX_RANK_PER_DIMM] {};
+ // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
+ // for mss::index 1. So this doesn't correspond directly with the table in the JEDEC spec,
+ // as that's not in "denominator order."
+ // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
+ constexpr uint8_t rtt_nom_map[RTT_NOM_MAP_SIZE] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
+
+ size_t l_rtt_nom_index = 0;
+ std::vector< uint64_t > l_ranks;
+
+ FAPI_TRY( mss::vpd_mt_dram_rtt_nom(iv_dimm, &(l_rtt_nom[0])) );
+ FAPI_TRY( eff_dram_rtt_nom(iv_mcs, &l_mcs_attrs[0][0][0]) );
+
+ // Calculate the value for each rank and store in attribute
+
+ FAPI_TRY(mss::rank::ranks(iv_dimm, l_ranks));
+
+ for (const auto& l_rank : l_ranks)
+ {
+ // We have to be careful about 0
+ l_rtt_nom_index = (l_rtt_nom[mss::index(l_rank)] == 0) ?
+ 0 : fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_NOM_OHM240 / l_rtt_nom[mss::index(l_rank)];
+
+ // Make sure it's a valid mss::index
+ fapi2::Assert( l_rtt_nom_index < RTT_NOM_MAP_SIZE);
+
+ // Map from RTT_NOM array to the value in the map
+ l_decoder_val = rtt_nom_map[l_rtt_nom_index];
+
+ // Store value and move to next rank
+ l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = l_decoder_val;
+ }
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_NOM, iv_mcs, l_mcs_attrs) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for the RTT_NOM value
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note used for MRS01
+///
+fapi2::ReturnCode eff_lrdimm::dram_rtt_nom()
+{
+ std::vector< uint64_t > l_ranks;
+
+ uint8_t l_decoder_val = 0;
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+ FAPI_TRY( eff_dram_rtt_nom(iv_mcs, &l_mcs_attrs[0][0][0]) );
+
+ // Get the value from the LRDIMM SPD
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_nom( iv_freq, l_decoder_val));
+
+ // Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
+ // Same value for every rank for LRDIMMs
+ FAPI_TRY(mss::rank::ranks(iv_dimm, l_ranks));
+
+ for (const auto& l_rank : l_ranks)
+ {
+ l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = l_decoder_val;
+ }
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_NOM, iv_mcs, l_mcs_attrs) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for the RTT_WR value from SPD
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note used for MRS02
+///
+fapi2::ReturnCode eff_rdimm::dram_rtt_wr()
+{
+ std::vector< uint64_t > l_ranks;
+ uint8_t l_encoding = 0;
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+
+ FAPI_TRY( eff_dram_rtt_wr(iv_mcs, &l_mcs_attrs[0][0][0]) );
+
+ // Get RTT_WR from VPD
+ uint8_t l_dram_rtt_wr[MAX_RANK_PER_DIMM];
+ FAPI_TRY( mss::vpd_mt_dram_rtt_wr(iv_dimm, &(l_dram_rtt_wr[0])) );
+
+ // Calculate the value for each rank and store in attribute
+ FAPI_TRY(mss::rank::ranks(iv_dimm, l_ranks));
+ static const std::vector< std::pair<uint8_t, uint8_t> > l_rtt_wr_map =
+ {
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_DISABLE, 0b000},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_HIGHZ, 0b011},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM80, 0b100},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM120, 0b001},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM240, 0b010}
+ };
+
+ for (const auto& l_rank : l_ranks)
+ {
+ FAPI_ASSERT( mss::find_value_from_key(l_rtt_wr_map, l_dram_rtt_wr[mss::index(l_rank)], l_encoding),
+ fapi2::MSS_INVALID_RTT_WR()
+ .set_RTT_WR(l_dram_rtt_wr[l_rank])
+ .set_RANK(mss::index(l_rank))
+ .set_DIMM_TARGET(iv_dimm),
+ "unknown RTT_WR 0x%x (%s rank %d), dynamic odt off",
+ l_dram_rtt_wr[mss::index(l_rank)],
+ mss::c_str(iv_dimm),
+ mss::index(l_rank));
+
+ // Store value and move to next rank
+ l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = l_encoding;
+ }
+
+ // Set the attribute
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_WR, iv_mcs, l_mcs_attrs) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for the RTT_WR value from SPD
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note used for MRS02
+///
+fapi2::ReturnCode eff_lrdimm::dram_rtt_wr()
+{
+ std::vector< uint64_t > l_ranks;
+
+ uint8_t l_decoder_val = 0;
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+
+ // Get the value from the LRDIMM SPD
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_wr( iv_freq, l_decoder_val));
+
+ // Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
+ // Same value for every rank for LRDIMMs
+ FAPI_TRY(mss::rank::ranks(iv_dimm, l_ranks));
+
+ for (const auto& l_rank : l_ranks)
+ {
+ l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = l_decoder_val;
+ }
+
+ // Set the attribute
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_WR, iv_mcs, l_mcs_attrs) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for the RTT_PARK value from SPD
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note used for MRS05
+///
+fapi2::ReturnCode eff_rdimm::dram_rtt_park()
+{
+ std::vector< uint64_t > l_ranks;
+
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+
+ // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
+ // for mss::index 1. So this doesn't correspond directly with the table in the JEDEC spec,
+ // as that's not in "denominator order."
+ constexpr uint64_t RTT_PARK_COUNT = 8;
+ // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
+ constexpr uint8_t rtt_park_map[RTT_PARK_COUNT] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
+
+ uint8_t l_rtt_park[MAX_RANK_PER_DIMM];
+
+ FAPI_TRY( mss::vpd_mt_dram_rtt_park(iv_dimm, &(l_rtt_park[0])) );
+ FAPI_TRY( eff_dram_rtt_park(iv_mcs, &l_mcs_attrs[0][0][0]) );
+
+ // Calculate the value for each rank and store in attribute
+ FAPI_TRY(mss::rank::ranks(iv_dimm, l_ranks));
+
+ for (const auto& l_rank : l_ranks)
+ {
+ uint8_t l_rtt_park_index = 0;
+
+ // We have to be careful about 0
+ l_rtt_park_index = (l_rtt_park[mss::index(l_rank)] == 0) ?
+ 0 : fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_PARK_240OHM / l_rtt_park[mss::index(l_rank)];
+
+ // Map from RTT_PARK array to the value in the map
+ l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = rtt_park_map[l_rtt_park_index];
+ }
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_PARK, iv_mcs, l_mcs_attrs) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for the RTT_PARK value from SPD
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note used for MRS05
+///
+fapi2::ReturnCode eff_lrdimm::dram_rtt_park()
+{
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+ uint8_t l_decoder_val_01 = 0;
+ uint8_t l_decoder_val_23 = 0;
+
+ FAPI_TRY( eff_dram_rtt_park(iv_mcs, &l_mcs_attrs[0][0][0]) );
+
+ // Get the value from the LRDIMM SPD
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_park_ranks0_1( iv_freq, l_decoder_val_01));;
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_park_ranks2_3( iv_freq, l_decoder_val_23));;
+
+ // Setting the four rank values for this dimm
+ // Rank 0 and 1 have the same value, l_decoder_val_01
+ // Rank 2 and 3 have the same value, l_decoder_val_23
+ l_mcs_attrs[iv_port_index][iv_dimm_index][0] = l_decoder_val_01;
+ l_mcs_attrs[iv_port_index][iv_dimm_index][1] = l_decoder_val_01;
+ l_mcs_attrs[iv_port_index][iv_dimm_index][2] = l_decoder_val_23;
+ l_mcs_attrs[iv_port_index][iv_dimm_index][3] = l_decoder_val_23;
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_PARK, iv_mcs, l_mcs_attrs) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Determines & sets effective config for DIMM BC00
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Host Interface DQ RTT_NOM Control
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 56 table 23
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc00()
+{
+ uint8_t l_decoder_val;
+ constexpr size_t RTT_NOM_MAP_SIZE = 8;
+
+ // All LRDIMMS in the eyes of the MC are 1 rank, so say it's rank 0 for calculations
+ uint8_t l_rank = 0;
+ // value to mss::index into rtt_nom_map using rtt_nom attribute
+ size_t l_rtt_nom_index = 0;
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc00[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
+ // for mss::index 1. So this doesn't correspond directly with the table in the JEDEC spec,
+ // as that's not in "denominator order."
+ // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
+ constexpr uint8_t rtt_nom_map[RTT_NOM_MAP_SIZE] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
+
+ // Temp holders to grab attributes to then parse into value for this dimm and rank
+ uint8_t l_rtt_nom[MAX_RANK_PER_DIMM] = {};
+
+ FAPI_TRY( mss::vpd_mt_dram_rtt_nom(iv_dimm, &(l_rtt_nom[0])) );
+
+ // Calculate the value for each rank and store in attribute
+
+ // We have to be careful about 0
+ l_rtt_nom_index = (l_rtt_nom[l_rank] == 0) ?
+ 0 : fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_NOM_OHM240 / l_rtt_nom[l_rank];
+
+ // Make sure it's a valid mss::index
+ //
+ fapi2::Assert( l_rtt_nom_index < RTT_NOM_MAP_SIZE);
+
+ // Map from RTT_NOM array to the value in the map
+ l_decoder_val = rtt_nom_map[l_rtt_nom_index];
+ // Store value and move to next rank
+
+ // Read, modify, write
+ FAPI_TRY( eff_dimm_ddr4_bc00(iv_mcs, &l_attrs_dimm_bc00[0][0]) );
+ l_attrs_dimm_bc00[iv_port_index][iv_dimm_index] = l_decoder_val;
+
+ FAPI_INF("%s: BC00 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc00[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC00, iv_mcs, l_attrs_dimm_bc00) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC01
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Host Interface DQ RTT_WR Control
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 56 Table 24
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc01()
+{
+ // All LRDIMMS are treated as 1 rank DIMMS from the MC point of view
+ uint8_t l_rank = 0;
+ uint8_t l_encoding = 0;
+ uint8_t l_attrs_dimm_bc01[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Get RTT_WR from VPD
+ uint8_t l_dram_rtt_wr[MAX_RANK_PER_DIMM];
+ FAPI_TRY( mss::vpd_mt_dram_rtt_wr(iv_dimm, &(l_dram_rtt_wr[0])) );
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > l_rtt_wr_map =
+ {
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_DISABLE, 0b000},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_HIGHZ, 0b011},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM80, 0b100}, // RZQ/3
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM120, 0b001}, // RZQ/2
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM240, 0b010}
+ };
+
+ FAPI_ASSERT( mss::find_value_from_key(l_rtt_wr_map, l_dram_rtt_wr[l_rank], l_encoding),
+ fapi2::MSS_INVALID_RTT_WR()
+ .set_RTT_WR(l_dram_rtt_wr[l_rank])
+ .set_RANK(mss::index(l_rank))
+ .set_DIMM_TARGET(iv_dimm),
+ "unknown RTT_WR 0x%x (%s rank %d), dynamic odt off",
+ l_dram_rtt_wr[mss::index(l_rank)],
+ mss::c_str(iv_dimm),
+ l_rank);
+
+ // Read, modify, write
+ FAPI_TRY( eff_dimm_ddr4_bc01(iv_mcs, &l_attrs_dimm_bc01[0][0]) );
+
+ l_attrs_dimm_bc01[iv_port_index][iv_dimm_index] = l_encoding;
+
+ FAPI_INF("%s: BC01 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc01[iv_port_index][iv_dimm_index] );
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC01, iv_mcs, l_attrs_dimm_bc01) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC02
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Host Interface DQ RTT_PARK Control
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 56 Table 25
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc02()
+{
+ uint8_t l_decoder_val = 0;
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc02[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ {
+ uint8_t l_rank = 0;
+ // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
+ // for mss::index 1. So this doesn't correspond directly with the table in the JEDEC spec,
+ // as that's not in "denominator order."
+ constexpr uint64_t RTT_PARK_COUNT = 8;
+ // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
+ constexpr uint8_t rtt_park_map[RTT_PARK_COUNT] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
+
+ uint8_t l_rtt_park[MAX_RANK_PER_DIMM];
+
+ FAPI_TRY( mss::vpd_mt_dram_rtt_park(iv_dimm, &(l_rtt_park[0])) );
+
+ // Calculate the value for each rank and store in attribute
+ uint8_t l_rtt_park_index = 0;
+
+ // We have to be careful about 0
+ l_rtt_park_index = (l_rtt_park[l_rank] == 0) ?
+ 0 : fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_PARK_240OHM / l_rtt_park[l_rank];
+
+ // Map from RTT_PARK array to the value in the map
+ l_decoder_val = rtt_park_map[l_rtt_park_index];
+ }
+
+ FAPI_TRY( eff_dimm_ddr4_bc02(iv_mcs, &l_attrs_dimm_bc02[0][0]) );
+ l_attrs_dimm_bc02[iv_port_index][iv_dimm_index] = l_decoder_val;
+
+ FAPI_INF("%s: BC02 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc02[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC02, iv_mcs, l_attrs_dimm_bc02) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC03
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Host Interface DQ Driver Control Word
+/// From DDR4DB01 Spec Rev 1.0
+/// 2.5.5 Page 57 table 36
+///
+fapi2::ReturnCode eff_lrdimm_db01::dimm_bc03()
+{
+ uint8_t l_attrs_dimm_bc03[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // constants
+ // Little table to map Output Driver Imepdance Control according to DDR4DB02 4.5
+ static const std::vector< std::pair<uint64_t, uint8_t> > l_odic_map =
+ {
+ // Yes, this is the encoding listed in the JEDEC spec...
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM34, 0b001},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM40, 0b000},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM48, 0b010},
+ };
+
+ // Treat buffer as 0th rank. LRDIMM in memory controller's eyes only have 1 rank
+ constexpr size_t l_rank = 0;
+ fapi2::buffer<uint8_t> l_result = 0;
+ uint64_t l_ohm_value = 0;
+ uint8_t l_encoding = 0;
+ // attributes
+ uint8_t l_odic[MAX_RANK_PER_DIMM] = {};
+ FAPI_TRY( mss::vpd_mt_dram_drv_imp_dq_dqs(iv_dimm, &(l_odic[0])) );
+ // Get the Ohm value for rank 0
+ l_ohm_value = l_odic[l_rank];
+
+ // Now get the proper encoding for that value. Fail if not found
+ // Change for rev level
+ FAPI_ASSERT( mss::find_value_from_key(l_odic_map, l_ohm_value, l_encoding),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(1)
+ .set_PARAMETER(OUTPUT_IMPEDANCE)
+ .set_PARAMETER_VALUE(l_odic[mss::index(l_rank)])
+ .set_DIMM_IN_ERROR(iv_dimm),
+ "Bad value for output driver impedance: %d (%s)",
+ l_odic[mss::index(l_rank)], mss::c_str(iv_dimm));
+
+ l_result = l_encoding;
+
+ // Using a writeBit for clarity sake
+ // Enabling Host interface DQ/DQS driver
+ l_result.writeBit<BC03_DQ_DISABLE_POS>(BC03_DQ_ENABLE);
+
+ FAPI_TRY( eff_dimm_ddr4_bc03(iv_mcs, &l_attrs_dimm_bc03[0][0]) );
+ l_attrs_dimm_bc03[iv_port_index][iv_dimm_index] = l_result;
+
+ FAPI_INF("%s: BC03 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc03[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC03, iv_mcs, l_attrs_dimm_bc03) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC03
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Host Interface DQ Driver Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 57 Table 26
+///
+fapi2::ReturnCode eff_lrdimm_db02::dimm_bc03()
+{
+ uint8_t l_attrs_dimm_bc03[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // constants
+ // Little table to map Output Driver Imepdance Control according to DDR4DB02 4.5
+ static const std::vector< std::pair<uint64_t, uint8_t> > l_odic_map =
+ {
+ // Yes, this is the order and encoding listed in the JEDEC spec...
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM30, 0b011},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM34, 0b001},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM40, 0b000},
+ {fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM48, 0b010}
+ };
+
+ // Treat buffer as 0th rank. LRDIMM in our eyes only have 1 rank
+ constexpr size_t l_rank = 0;
+ fapi2::buffer<uint8_t> l_result = 0;
+ uint64_t l_ohm_value = 0;
+ uint8_t l_encoding = 0;
+ // attributes
+ uint8_t l_odic[MAX_RANK_PER_DIMM] = {};
+ FAPI_TRY( mss::vpd_mt_dram_drv_imp_dq_dqs(iv_dimm, &(l_odic[0])) );
+ // Get the Ohm value for rank 0
+ l_ohm_value = l_odic[l_rank];
+
+ // Now get the proper encoding for that value. Fail if not found
+ // Change for rev level
+ FAPI_ASSERT( mss::find_value_from_key(l_odic_map, l_ohm_value, l_encoding),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(1)
+ .set_PARAMETER(OUTPUT_IMPEDANCE)
+ .set_PARAMETER_VALUE(l_odic[mss::index(l_rank)])
+ .set_DIMM_IN_ERROR(iv_dimm),
+ "Bad value for output driver impedance: %d (%s)",
+ l_odic[mss::index(l_rank)], mss::c_str(iv_dimm));
+
+ l_result = l_encoding;
+
+ // Using a writeBit for clarity sake
+ // Enabling DQ/DQS drivers
+ l_result.writeBit<BC03_DQ_DISABLE_POS>(BC03_DQ_ENABLE);
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dimm_ddr4_bc03(iv_mcs, &l_attrs_dimm_bc03[0][0]) );
+ l_attrs_dimm_bc03[iv_port_index][iv_dimm_index] = l_result;
+
+ FAPI_INF("%s: BC03 settting: %d, vpd_drv_dram_imp is %d",
+ mss::c_str(iv_dimm),
+ l_attrs_dimm_bc03[iv_port_index][iv_dimm_index],
+ l_ohm_value);
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC03, iv_mcs, l_attrs_dimm_bc03) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC04
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note DRAM Interface MDQ RTT Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+/// @note Uses MDQ Read Termination Strength (RTT)
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 57 Table 27
+/// DRAM Interface MDQ/MDQS ODT Strength for Data Buffer
+/// Comes from SPD
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc04()
+{
+ uint8_t l_decoder_val = 0;
+
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc04[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc04(iv_mcs, &l_attrs_dimm_bc04[0][0]) );
+ // Update MCS attribute
+
+ // So the encoding from the SPD is the same as the encoding for the buffer control encoding
+ // Simple grab and insert
+ // Value is checked in decoder function for validity
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->data_buffer_mdq_rtt( iv_freq, l_decoder_val));
+
+ // Update MCS attribute
+
+ FAPI_INF("%s: BC04 settting (MDQ_RTT): %d", mss::c_str(iv_dimm), l_attrs_dimm_bc04[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC04, iv_mcs, l_attrs_dimm_bc04) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC05
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note DRAM Interface MDQ Driver Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 57 Table 28
+/// @note DRAM Interface MDQ/MDQS Output Driver Impedance control
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc05()
+{
+ uint8_t l_decoder_val;
+
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc05[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc05(iv_mcs, &l_attrs_dimm_bc05[0][0]) );
+
+ // Same as BC04, grab from SPD and put into BC
+ FAPI_TRY( iv_pDecoder->iv_module_decoder->data_buffer_mdq_drive_strength( iv_freq, l_decoder_val));
+ l_attrs_dimm_bc05[iv_port_index][iv_dimm_index] = l_decoder_val;
+
+ FAPI_INF("%s: BC05 settting (MDQ Drive Strenght): %d", mss::c_str(iv_dimm),
+ l_attrs_dimm_bc05[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC05, iv_mcs, l_attrs_dimm_bc05) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC07
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Rank Presence Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// 2.5.9 Page 58 Table 30
+/// Tells the buffer which drams are enabled
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc07()
+{
+ // Map for the bc07 attribute, Each bit and its position represents one rank
+ // 0b0 == enabled, 0b1 == disabled
+ // 1 rank 2 rank 3 rank 4 rank
+ constexpr uint8_t dram_map [MAX_RANK_PER_DIMM] = {0b1110, 0b1100, 0b1000, 0b0000};
+
+ uint8_t l_ranks_per_dimm = 0;
+
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc07[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( iv_pDecoder->num_package_ranks_per_dimm(iv_dimm, l_ranks_per_dimm) );
+
+ FAPI_TRY( eff_dimm_ddr4_bc07(iv_mcs, &l_attrs_dimm_bc07[0][0]) );
+
+ // Subtract so 1 rank == 0, 2 rank == 1, etc. For array mss::indexing
+ --l_ranks_per_dimm;
+ // Make sure we didn't overflow or screw up somehow
+ fapi2::Assert (l_ranks_per_dimm < MAX_RANK_PER_DIMM);
+
+ l_attrs_dimm_bc07[iv_port_index][iv_dimm_index] = dram_map[l_ranks_per_dimm];
+
+ FAPI_INF("%s: BC07 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc07[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC07, iv_mcs, l_attrs_dimm_bc07) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC08
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Power Saving Settings Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc08()
+{
+ // Some constants made for changing code in the future
+ // Hard coding values for now until characterization can be done.
+ // Not sure if info needs to be added to VPD or MRW or what
+
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc08[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ // Update MCS attribute
+ FAPI_TRY( eff_dimm_ddr4_bc08(iv_mcs, &l_attrs_dimm_bc08[0][0]) );
+ // BC08 is used to set the rank for Write Leveling training modes
+ // Defaulting to 0 because every dimm should have a rank 0, right?
+ // This attribute should be set in training...
+ l_attrs_dimm_bc08[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC08 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc08[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC08, iv_mcs, l_attrs_dimm_bc08) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC09
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Power Saving Settings Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc09()
+{
+ // Some constants made for changing code in the future
+ // Hard coding values for now until characterization can be done.
+ // Not sure if info needs to be added to VPD or MRW or what
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc09[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ fapi2::buffer<uint8_t> l_setting = 0;
+
+ // Disabling for now until characterization can be done
+ // Power/ performance setting
+ l_setting.writeBit<BC09_CKE_POWER_DOWN_ENABLE_POS> (BC09_CKE_POWER_DOWN_DISABLE);
+
+ // Update MCS attribute
+ FAPI_TRY( eff_dimm_ddr4_bc09(iv_mcs, &l_attrs_dimm_bc09[0][0]) );
+ l_attrs_dimm_bc09[iv_port_index][iv_dimm_index] = l_setting;
+
+ FAPI_INF("%s: BC09 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc09[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC09, iv_mcs, l_attrs_dimm_bc09) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets config for DIMM BC0a
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note LRDIMM Operating Speed
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc0a()
+{
+ uint8_t l_encoding = 0;
+
+ static const std::vector< std::pair<uint64_t, uint8_t> > l_freq_map =
+ {
+ // There's also 1600, 2933, and 3200 but Nimbus can't support those...
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT1866, 0b001},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2133, 0b010},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2400, 0b011},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2666, 0b100},
+ };
+
+ uint8_t l_attrs_dimm_bc0a[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_INF(" FREQ is %d enum is %d", iv_freq, fapi2::ENUM_ATTR_MSS_FREQ_MT2400);
+ FAPI_INF("%d", (iv_freq == fapi2::ENUM_ATTR_MSS_FREQ_MT2400));
+ // Find the correct mapping from freq to encoding
+ FAPI_ASSERT( mss::find_value_from_key(l_freq_map, uint64_t(iv_freq), l_encoding),
+ fapi2::MSS_INVALID_FREQ()
+ .set_FREQ(iv_freq),
+ "unknown FREQ %d for %s",
+ iv_freq,
+ mss::c_str(iv_dimm));
+
+ // Retrieve MCS attribute data
+ FAPI_TRY( eff_dimm_ddr4_bc0a(iv_mcs, &l_attrs_dimm_bc0a[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_bc0a[iv_port_index][iv_dimm_index] = l_encoding;
+
+ FAPI_INF("%s: BC0a settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0a[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0A, iv_mcs, l_attrs_dimm_bc0a) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0b
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// From DDR4DB01 Spec Rev 1.0
+/// 2.5.13 Page 60 table 34
+/// @note Operating Voltage
+///
+fapi2::ReturnCode eff_lrdimm_db01::dimm_bc0b()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0b[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0b(iv_mcs, &l_attrs_dimm_bc0b[0][0]) );
+
+ // Update MCS attribute
+ // Only option is to set it to 0 to signify 1.2 operating Voltage, everything else is reserved
+ l_attrs_dimm_bc0b[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC0b settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0b[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0B, iv_mcs, l_attrs_dimm_bc0b) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0b
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Operating Voltage and Host Side Output Slew Rate Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+///
+fapi2::ReturnCode eff_lrdimm_db02::dimm_bc0b()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0b[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0b(iv_mcs, &l_attrs_dimm_bc0b[0][0]) );
+
+ // Update MCS attribute
+ // Bits 0~1 (IBM numbering) are for slew rate
+ // Bit 3 is reserved, Bit 4 has to be 0 to signal 1.2 V Buffer Vdd Voltage
+ // Hard coding values to 0, sets slew rate to Moderate (according to Dan Phipps, this is fine)
+ l_attrs_dimm_bc0b[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC0b settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0b[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0B, iv_mcs, l_attrs_dimm_bc0b) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0c
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note LDQ Operation Control Word
+/// From DDR4DB01 Spec Rev 1.0
+/// Page 60 Table 24
+///
+fapi2::ReturnCode eff_lrdimm_db01::dimm_bc0c()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0c[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0c(iv_mcs, &l_attrs_dimm_bc0c[0][0]) );
+
+ // Update MCS attribute
+ // This attribute is used to set the training mode
+ // Setting it to 0 to signal default normal mode
+ l_attrs_dimm_bc0c[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC0c settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0c[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0D, iv_mcs, l_attrs_dimm_bc0c) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0c
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note LDQ Operation Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+///
+fapi2::ReturnCode eff_lrdimm_db02::dimm_bc0c()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0c[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0c(iv_mcs, &l_attrs_dimm_bc0c[0][0]) );
+
+ // Update MCS attribute
+ // Setting it to 0 to signal default normal mode
+ // This attribute is used to set the training mode
+ l_attrs_dimm_bc0c[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC0c settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0c[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0D, iv_mcs, l_attrs_dimm_bc0c) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0d
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note LDQ Operation Control Word
+/// From DDR4DB01 Spec Rev 1.0
+/// Page 61 Table 25
+/// All values are reserved for DB01, setting to 0
+///
+fapi2::ReturnCode eff_lrdimm_db01::dimm_bc0d()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0d[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0d(iv_mcs, &l_attrs_dimm_bc0d[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_bc0d[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC0d settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0d[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0D, iv_mcs, l_attrs_dimm_bc0d) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0d
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note LDQ Operation Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+/// @note This register is used by the Non Volatile controller (NVC) to change the mode of operation of the DDR4DB02
+/// Setting to 0 (LDQ port disabled, normal operation)
+///
+fapi2::ReturnCode eff_lrdimm_db02::dimm_bc0d()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0d[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0d(iv_mcs, &l_attrs_dimm_bc0d[0][0]) );
+
+ // Update MCS attribute
+ l_attrs_dimm_bc0d[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC0d settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0d[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0D, iv_mcs, l_attrs_dimm_bc0d) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0e
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Parity Control Word
+/// From DDR4DB02 Spec Rev 0.95
+/// Page 60 Table 24
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc0e()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0e[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0e(iv_mcs, &l_attrs_dimm_bc0e[0][0]) );
+
+ // Update MCS attribute
+ // Disabling parity checking for the BCOM bus (interal DRAM to buffer on dimm) and sequence checking by the data buffer
+ l_attrs_dimm_bc0e[iv_port_index][iv_dimm_index] = 0;
+
+
+ FAPI_INF("%s: BC0e settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0e[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0E, iv_mcs, l_attrs_dimm_bc0e) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines & sets effective config for DIMM BC0f
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Error Status Word for parity and sequence error
+///
+fapi2::ReturnCode eff_lrdimm::dimm_bc0f()
+{
+ // Retrieve MCS attribute data
+ uint8_t l_attrs_dimm_bc0f[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dimm_ddr4_bc0f(iv_mcs, &l_attrs_dimm_bc0f[0][0]) );
+
+ // Update MCS attribute
+ // BC0F is an error register so setting to 0 and it will change as reads as performed
+ l_attrs_dimm_bc0f[iv_port_index][iv_dimm_index] = 0;
+
+ FAPI_INF("%s: BC0f settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_bc0f[iv_port_index][iv_dimm_index] );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC0E, iv_mcs, l_attrs_dimm_bc0f) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Grab the VPD blobs and decode into attributes
+/// @param[in] i_target FAPI2 target (MCS)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_target)
+{
+ uint8_t l_mr_blob[mss::VPD_KEYWORD_MAX] = {0};
+ uint8_t l_cke_blob[mss::VPD_KEYWORD_MAX] = {0};
+ uint8_t l_dq_blob[mss::VPD_KEYWORD_MAX] = {0};
+ uint64_t l_freq = 0;
+
+ std::vector<uint8_t*> l_mt_blobs(PORTS_PER_MCS, nullptr);
+ fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_vpd_info(fapi2::MemVpdData::MT);
+
+ // For sanity. Not sure this will break us, but we're certainly making assumptions below.
+ static_assert(MAX_DIMM_PER_PORT == 2, "Max DIMM per port isn't 2");
+ FAPI_TRY( mss::freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq));
+ // We need to set up all VPD info before calling getVPD, the API assumes this
+ // For MR we need to tell the VPDInfo the frequency (err ... mt/s - why is this mhz?)
+ l_vpd_info.iv_freq_mhz = l_freq;
+ FAPI_INF("%s. VPD info - dimm data rate: %d MT/s", mss::c_str(i_target), l_vpd_info.iv_freq_mhz);
+
+ // Make sure to create 0 filled blobs for all the possible blobs, not just for the
+ // chiplets which are configured. This prevents the decoder from accessing nullptrs
+ // but the code which uses the VPD will only access the information for the chiplets
+ // which exist - so the 0's are meaningless
+ for (auto& b : l_mt_blobs)
+ {
+ b = new uint8_t[mss::VPD_KEYWORD_MAX];
+ memset(b, 0, mss::VPD_KEYWORD_MAX);
+ }
+
+ // For MT we need to fill in the rank information
+ // But, of course, the rank information can differ per port. However, the vpd interface doesn't
+ // allow this in a straight-forward way. So, we have to get VPD blobs for MCS which contain
+ // ports which have the rank configuration in question. This means, basically, we pass a MCS MT
+ // blob to the decoder for each MCA, regardless of whether the port configurations are the same.
+ for (const auto& p : find_targets<TARGET_TYPE_MCA>(i_target))
+ {
+ // 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] = {0};
+
+ // 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.
+ 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];
+
+ 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);
+
+ // Get the MCS blob for this specific rank combination *only if* we have DIMM. Remember,
+ // Cronus can give us functional MCA which have no DIMM - and we'd puke getting the VPD.
+ if ((l_vpd_info.iv_rank_count_dimm_0 != 0) || (l_vpd_info.iv_rank_count_dimm_1 != 0))
+ {
+ // If getVPD returns us an error, then we don't have VPD for the DIMM configuration.
+ // This is the root of our plug-rules: if you want a configuration of DIMM to be
+ // supported, it needs to have VPD defined. Likewise, if you don't want a configuration
+ // of DIMM supported be sure to leave it out of the VPD. Note that we don't return a specific
+ // plug-rule error as f/w (Dan) suggested this would duplicate errors leading to confusion.
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::MT;
+
+ // Check the max for giggles. Programming bug so we should assert.
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve MT size from VPD");
+
+ if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
+ {
+ FAPI_ERR("VPD MT keyword is too big for our array");
+ fapi2::Assert(false);
+ }
+
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_mt_blob[0])),
+ "Failed to retrieve MT VPD");
+ }
+ }// mca
+
+ // Only get the MR blob if we have a freq. It's possible for Cronus to give us an MCS which
+ // is connected to a controller which has 0 DIMM installed. In this case, we won't have
+ // a frequency, and thus we'd fail getting the VPD. So we initiaized the VPD to 0's and if
+ // there's no freq, we us a 0 filled VPD.
+ if (l_vpd_info.iv_freq_mhz != 0)
+ {
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::MR;
+
+ // Check the max for giggles. Programming bug so we should assert.
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve MR size from VPD");
+
+ if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
+ {
+ FAPI_ERR("VPD MR keyword is too big for our array");
+ fapi2::Assert(false);
+ }
+
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_mr_blob[0])),
+ "Failed to retrieve MR VPD");
+ }
+
+ // Get CKE data
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::CK;
+
+ // Check the max for giggles. Programming bug so we should assert.
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve CK size from VPD");
+
+ if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
+ {
+ FAPI_ERR("VPD CK keyword is too big for our array");
+ fapi2::Assert(false);
+ }
+
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_cke_blob[0])),
+ "Failed to retrieve DQ VPD");
+
+ // Get DQ data
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::DQ;
+
+ // Check the max for giggles. Programming bug so we should assert.
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve DQ size from VPD");
+
+ if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
+ {
+ FAPI_ERR("VPD DQ keyword is too big for our array");
+ fapi2::Assert(false);
+ }
+
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_dq_blob[0])),
+ "Failed to retrieve DQ VPD");
+
+ FAPI_TRY( mss::eff_decode(i_target, l_mt_blobs, l_mr_blob, l_cke_blob, l_dq_blob) );
+
+fapi_try_exit:
+
+ // delete the mt blobs
+ for (auto p : l_mt_blobs)
+ {
+ if (p != nullptr)
+ {
+ delete[] p;
+ }
+ }
+
+ return fapi2::current_err;
+}
+
+
+
+}//mss
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 e5f8c6d91..63abcb320 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 2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,1239 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
+// *HWP HWP Backup: Aandre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+
+#ifndef _MSS_EFF_DIMM_H_
+#define _MSS_EFF_DIMM_H_
+
+#include <fapi2.H>
+#include <lib/shared/mss_kind.H>
+#include <lib/spd/common/spd_decoder.H>
+#include <lib/eff_config/timing.H>
+namespace mss
+{
+
+///
+/// @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
+///
+class eff_dimm
+{
+ protected:
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_dimm;
+ fapi2::Target<fapi2::TARGET_TYPE_MCA> iv_mca;
+ fapi2::Target<fapi2::TARGET_TYPE_MCS> iv_mcs;
+ uint64_t iv_port_index;
+ uint64_t iv_dimm_index;
+
+ public:
+ uint64_t iv_freq;
+ int64_t iv_tCK_in_ps;
+ const std::shared_ptr<spd::decoder> iv_pDecoder;
+
+ // Assists testing with write ability on these MRW
+ // settings that are normally NOT writable
+ // using attribute accessors
+ // Could create getters & setters...
+ uint8_t iv_refresh_mode;
+ uint8_t iv_temp_refresh_range;
+
+ //Delete the default
+ eff_dimm () = delete;
+
+ ///
+ /// @brief constructor for the base eff_dimm class
+ /// @param[in] i_target the dimm target
+ /// @param[in] i_pDecoder the SPD decoder
+ /// @param[out] o_rc fapi2::ReturnCode
+ /// @note also sets class variables for parent MCA/ MCS and for freqs
+ ///
+ eff_dimm (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder,
+ fapi2::ReturnCode& o_rc) :
+ iv_dimm (i_target),
+ iv_pDecoder(i_pDecoder)
+ {
+ FAPI_DBG("Constructing EFF_DIMM Object");
+ iv_mca = find_target<fapi2::TARGET_TYPE_MCA>(iv_dimm);
+ iv_mcs = find_target<fapi2::TARGET_TYPE_MCS>(iv_dimm);
+ iv_port_index = mss::index(iv_mca);
+ iv_dimm_index = mss::index(iv_dimm);
+
+ FAPI_TRY( clock_period(i_target, iv_tCK_in_ps), "Failed to calculate clock period (tCK)" );
+
+ FAPI_TRY( mss::mrw_temp_refresh_range(iv_temp_refresh_range), "Failed mrw_temp_refresh_range()" );
+ FAPI_TRY( mss::mrw_fine_refresh_mode(iv_refresh_mode), "Failed mrw_fine_refresh_mode()" );
+
+ FAPI_TRY( mss::freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), iv_freq));
+
+ FAPI_INF("Calculated clock period - tCK (ps): %d for %s", iv_tCK_in_ps, mss::c_str(i_target));
+ FAPI_INF("Calculated frequency (ps): %d for %s", iv_freq, mss::c_str(i_target));
+
+ fapi_try_exit:
+ o_rc = fapi2::current_err;
+ return;
+ }
+
+ ///
+ /// @brief Grab the VPD blobs and decode into attributes
+ /// @param[in] i_target FAPI2 target (MCS)
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ static fapi2::ReturnCode decode_vpd(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target);
+
+ ///
+ /// @brief factory to make an eff_config DIMM object based on dimm kind (type, gen, and revision number)
+ /// @param[in] i_target the dimm target
+ /// @param[in] i_pDecoder the SPD decoder
+ /// @param[out] o_fact_obj a shared pointer of the eff_dimm type
+ ///
+ static fapi2::ReturnCode eff_dimm_factory (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder,
+ std::shared_ptr<eff_dimm>& o_fact_obj);
+
+ ///
+ /// @brief Determines & sets effective config for buffer and rev density
+ /// @param[in] i_target FAPI2 target
+ /// @param[in] i_pDecoder the SPD decoder
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ static fapi2::ReturnCode register_and_buffer_type( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder );
+
+ ///
+ /// @brief Default destructor
+ ///
+ virtual ~eff_dimm() = default;
+
+ ///
+ /// @brief Determines & sets effective config for eff_dram_mfg_id type from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_mfg_id();
+
+ ///
+ /// @brief Determines & sets effective config for primary stack type
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode primary_stack_type();
+
+ ///
+ /// @brief Determines & sets effective config for Hybrid memory type from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode hybrid_memory_type();
+
+ ///
+ /// @brief Determines & sets effective config for temperature controlled refresh mode
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode temp_refresh_mode();
+
+ ///
+ /// @brief Determines & sets effective config for refresh interval time (tREFI)
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trefi();
+
+ ///
+ /// @brief Determines & sets effective config for refresh cycle time (tRFC)
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trfc();
+
+ ///
+ /// @brief Determines & sets effective config for refresh cycle time (logical ranks) (tRFC_DLR)
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trfc_dlr();
+
+ ///
+ /// @brief Determines & sets effective config for dram density
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_density();
+
+ ///
+
+ /// @brief Determines & sets effective config for dram width
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_width();
+ ///
+ /// @brief Determines & sets effective config for dimm rcd mirror mode
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode rcd_mirror_mode();
+
+ ///
+ /// @brief Determines & sets effective config for dimm size
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_size();
+
+ ///
+ /// @brief Determines & sets effective config for dram bank bits
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_bank_bits();
+
+ ///
+ /// @brief Determines & sets effective config for dram row bits
+ /// @param[in] i_target FAPI2 target
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_row_bits();
+
+ ///
+ /// @brief Determines & sets effective config for number of ranks per dimm
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode ranks_per_dimm();
+
+ ///
+ /// @brief Determines & sets effective config for number of master ranks per dimm
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode master_ranks_per_dimm();
+
+ ///
+ /// @brief Determines & sets effective config for tDQS
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_dqs_time();
+
+ ///
+ /// @brief Determines & sets effective config for tCCD_L
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_tccd_l();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC00
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc00();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC01
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc01();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC02
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc02();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC03
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc03();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC04
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc04();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC05
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc05();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC06_07
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc06_07();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC08
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc08();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC09
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc09();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC10
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc10();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC11
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc11();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC12
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc12();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC13
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc13();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC14
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc14();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC15
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc15();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_1x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc1x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_2x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc2x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_3x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc3x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_4x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc4x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_5x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc5x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_6x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc6x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_7x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc7x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_8x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc8x();
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_9x
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rc9x();
+
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_AX
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rcax();
+
+
+ ///
+ /// @brief Determines & sets effective config for DIMM RC_BX
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_rcbx();
+
+ ///
+ /// @brief Determines & sets effective config for tWR
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_twr();
+
+ ///
+ /// @brief Determines & sets effective config for RBT
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode read_burst_type();
+
+ ///
+ /// @brief Determines & sets effective config for TM
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_tm();
+
+ ///
+ /// @brief Determines & sets effective config for cwl
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_cwl();
+
+ ///
+ /// @brief Determines & sets effective config for lpasr
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_lpasr();
+
+ ///
+ /// @brief Determines & sets effective config for additive latency
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode additive_latency();
+
+ ///
+ /// @brief Determines & sets effective config for DLL Reset
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dll_reset();
+
+ ///
+ /// @brief Determines & sets effective config for DLL Enable
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dll_enable();
+
+ ///
+ /// @brief Determines & sets effective config for Write Level Enable
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode write_level_enable();
+
+ ///
+ /// @brief Determines & sets effective config for Output Buffer
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode output_buffer();
+
+
+ ///
+ /// @brief Determines & sets effective config for Vref DQ Train Value
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode vref_dq_train_value();
+
+ ///
+ /// @brief Determines & sets effective config for Vref DQ Train Enable
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ 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
+ ///
+ fapi2::ReturnCode ca_parity_latency();
+
+ ///
+ /// @brief Determines & sets effective config for CA Parity
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode ca_parity();
+
+ ///
+ /// @brief Determines & sets effective config for CRC Error Clear
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode crc_error_clear();
+
+ ///
+ /// @brief Determines & sets effective config for CA Parity Error Status
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode ca_parity_error_status();
+
+ ///
+ /// @brief Determines & sets effective config for ODT Input Buffer
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode odt_input_buffer();
+ ///
+ /// @brief Determines & sets effective config for data_mask
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_mask();
+
+ ///
+ /// @brief Determines & sets effective config for write_dbi
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode write_dbi();
+
+ ///
+ /// @brief Determines & sets effective config for read_dbi
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode read_dbi();
+
+ ///
+ /// @brief Determines & sets effective config for Post Package Repair
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode post_package_repair();
+
+ ///
+ /// @brief Determines & sets effective config for rd_preamble_train
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode read_preamble_train();
+
+ ///
+ /// @brief Determines & sets effective config for rd_preamble
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode read_preamble();
+
+ ///
+ /// @brief Determines & sets effective config for wr_preamble
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode write_preamble();
+
+ ///
+ /// @brief Determines & sets effective config for self_ref_abort
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode self_refresh_abort();
+
+ ///
+ /// @brief Determines & sets effective config for cs_cmd_latency
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode cs_to_cmd_addr_latency();
+
+ ///
+ /// @brief Determines & sets effective config for int_vref_mon
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode internal_vref_monitor();
+
+ ///
+ /// @brief Determines & sets effective config for powerdown_mode
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode max_powerdown_mode();
+
+ ///
+ /// @brief Determines & sets effective config for mpr_rd_format
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode mpr_read_format();
+
+ ///
+ /// @brief Determines & sets effective config for CRC write latency
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode crc_wr_latency();
+
+ ///
+ /// @brief Determines & sets effective config for temperature readout
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode temp_readout();
+
+ ///
+ /// @brief Determines & sets effective config for per DRAM addressability
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode per_dram_addressability();
+
+ ///
+ /// @brief Determines & sets effective config for geardown mode
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode geardown_mode();
+
+ ///
+ /// @brief Determines & sets effective config for geardown mode
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode mpr_page();
+
+ ///
+ /// @brief Determines & sets effective config for MPR mode
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode mpr_mode();
+
+ ///
+ /// @brief Determines & sets effective config for write CRC
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode write_crc();
+
+ ///
+ /// @brief Determines & sets effective config for ZQ Calibration
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode zqcal_interval();
+
+ ///
+ /// @brief Determines & sets effective config for MEMCAL Calibration
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode memcal_interval();
+
+ ///
+ /// @brief Determines & sets effective config for tRP
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trp();
+
+ ///
+ /// @brief Determines & sets effective config for tRCD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trcd();
+
+ ///
+ /// @brief Determines & sets effective config for tRC
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trc();
+
+ ///
+ /// @brief Determines & sets effective config for tWTR_L
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_twtr_l();
+
+ ///
+ /// @brief Determines & sets effective config for tWTR_S
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_twtr_s();
+
+ ///
+ /// @brief Determines & sets effective config for tRRD_S (tRRD_S_slr)
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trrd_s();
+
+ ///
+ /// @brief Determines & sets effective config for tRRD_L (or tRRD_L_slr)
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trrd_l();
+
+ ///
+ /// @brief Determines & sets effective config for tRRD_DLR
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trrd_dlr();
+
+ ///
+ /// @brief Determines & sets effective config for tFAW (or tFAW_slr)
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_tfaw();
+
+ ///
+ /// @brief Determines & sets effective config for tFAW_DLR
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_tfaw_dlr();
+
+ ///
+ /// @brief Determines & sets effective config for tRAS
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_tras();
+
+ ///
+ /// @brief Determines & sets effective config for tRTP
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_trtp();
+
+ ///
+ /// @brief Sets the RTT_NOM value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS01
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom() = 0;
+
+ ///
+ /// @brief Sets the RTT_NOM value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS02
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr() = 0;
+
+ ///
+ /// @brief Sets the RTT_PARK value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS05
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC00
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc00() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC01
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc01() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC02
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc02() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC03
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc03() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC04
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc04() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC05
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc05() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC07
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc07() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC08
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc08() = 0;
+
+
+ ///
+ /// @brief Determines and sets DIMM BC09
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc09() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0a
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0a() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0b
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0b() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0c
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0c() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0d
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0d() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0e
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0e() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0f
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0f() = 0;
+
+};
+
+///
+/// @class mss::dimm::eff_lrdimm : eff_dimm
+/// @brief A class made to perform eff_config functions for DDR4 LRDIMMS
+/// @note this is a subclass of eff_dimm and parent class to eff_lrdimm_db01 and eff_lrdimm_db02
+///
+class eff_lrdimm : public eff_dimm
+{
+ public:
+ ///
+ /// @brief constructor for the eff_lrdimm class
+ /// @param[in] i_target the dimm target
+ /// @param[in] i_pDecoder the SPD decoder
+ /// @param[out] o_rc fapi2::ReturnCode
+ /// @note also sets class variables for parent MCA/ MCS and for freqs
+ /// @note calls eff_dimm ctor
+ ///
+ eff_lrdimm (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder,
+ fapi2::ReturnCode& o_rc):
+ eff_dimm (i_target, i_pDecoder, o_rc)
+ {
+ FAPI_DBG("Constructing LRDIMM");
+ }
+
+ ///
+ /// @brief default destructor
+ ///
+ virtual ~eff_lrdimm() = default;
+
+ ///
+ /// @brief Sets the RTT_NOM value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS01
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom() final;
+
+ ///
+ /// @brief Sets the RTT_NOM value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS02
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr() final;
+
+ ///
+ /// @brief Sets the RTT_PARK value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS05
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC00
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc00() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC01
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc01() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC02
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc02() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC03
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc03() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC04
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc04() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC05
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc05() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC07
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc07() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC08
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc08() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC09
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc09() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC0a
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0a() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC0b
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0b() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0c
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0c() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0d
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0d() = 0;
+
+ ///
+ /// @brief Determines and sets DIMM BC0e
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0e() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC0f
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0f() final;
+};
+
+///
+/// @class mss::dimm::eff_lrdimm_db01 : eff_lrdimm
+/// @brief A class made to perform eff_config functions for DDR4 LRDIMMS with Databuffer type 01
+///
+class eff_lrdimm_db01 : public eff_lrdimm
+{
+ protected:
+ public:
+ //Delete default
+ eff_lrdimm_db01 () = delete;
+
+ ///
+ /// @brief constructor for the eff_lrdimm_db01 (LRDIMM DataBuffer 1) class
+ /// @param[in] i_target the dimm target
+ /// @param[in] i_pDecoder the SPD decoder
+ /// @param[out] o_rc fapi2::ReturnCode
+ /// @note also sets class variables for parent MCA/ MCS and for freqs
+ /// @note calls eff_dimm ctor
+ ///
+ eff_lrdimm_db01 (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder,
+ fapi2::ReturnCode& o_rc) :
+ eff_lrdimm(i_target, i_pDecoder, o_rc)
+ {
+ FAPI_DBG("Constructing LRDIMM_DB01");
+ }
+ ///
+ /// @brief default destructor
+ ///
+ ~eff_lrdimm_db01() = default;
+
+ ///
+ /// @brief Determines and sets DIMM BC03
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc03();
+
+ ///
+ /// @brief Determines and sets DIMM BC0b
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0b();
+
+
+ ///
+ /// @brief Determines and sets DIMM BC0c
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0c();
+
+ ///
+ /// @brief Determines and sets DIMM BC0d
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0d();
+};
+
+///
+/// @class mss::dimm::eff_lrdimm_db02 : eff_lrdimm
+/// @brief A class made to perform eff_config functions for DDR4 LRDIMMS with Databuffer type 02
+///
+class eff_lrdimm_db02 : public eff_lrdimm
+{
+ protected:
+ public:
+ //Delete default
+ eff_lrdimm_db02() = delete;
+
+ ///
+ /// @brief constructor for the eff_lrdimm_db02 (LRDIMM DataBuffer 2) class
+ /// @param[in] i_target the dimm target
+ /// @param[in] i_pDecoder the SPD decoder
+ /// @param[out] o_rc fapi2::ReturnCode
+ /// @note also sets class variables for parent MCA/ MCS and for freqs
+ /// @note calls eff_dimm ctor
+ ///
+ eff_lrdimm_db02 (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder,
+ fapi2::ReturnCode& o_rc) :
+ eff_lrdimm(i_target, i_pDecoder, o_rc)
+ {
+ FAPI_DBG("Constructing LRDIMM_DB02");
+ }
+
+ ///
+ /// @brief default destructor
+ ///
+ ~eff_lrdimm_db02() = default;
+
+ ///
+ /// @brief Determines and sets DIMM BC03
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc03();
+
+ ///
+ /// @brief Determines and sets DIMM BC0b
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0b();
+
+ ///
+ /// @brief Determines and sets DIMM BC0c
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0c();
+
+ ///
+ /// @brief Determines and sets DIMM BC0d
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimm_bc0d();
+};
+
+///
+/// @class mss::dimm::eff_rdimm : eff_dimm
+/// @brief A class made to perform eff_config functions for DDR4 RDIMMS
+///
+class eff_rdimm : public eff_dimm
+{
+ public:
+ eff_rdimm() = delete;
+
+ ///
+ /// @brief constructor for the eff_rdimm_db01 (LRDIMM DataBuffer 1) class
+ /// @param[in] i_target the dimm target
+ /// @param[in] i_pDecoder the SPD decoder
+ /// @param[out] o_rc fapi2::ReturnCode
+ /// @note also sets class variables for parent MCA/ MCS and for freqs
+ /// @note calls eff_dimm ctor
+ ///
+ eff_rdimm (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<spd::decoder>& i_pDecoder,
+ fapi2::ReturnCode& o_rc) :
+ eff_dimm(i_target, i_pDecoder, o_rc)
+ {
+ FAPI_DBG("Constructing RDIMM");
+ }
+
+ ///
+ /// @brief default destructor
+ ///
+ ~eff_rdimm() = default;
+
+ ///
+ /// @brief Sets the RTT_NOM value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS01
+ ///
+ fapi2::ReturnCode dram_rtt_nom() final;
+
+ ///
+ /// @brief Sets the RTT_NOM value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS02
+ ///
+ fapi2::ReturnCode dram_rtt_wr() final;
+
+ ///
+ /// @brief Sets the RTT_PARK value from SPD
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note used for MRS05
+ ///
+ fapi2::ReturnCode dram_rtt_park() final;
+
+ ///
+ /// @brief Determines and sets DIMM BC00
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc00() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC01
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc01() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC02
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc02() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC03
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc03() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC04
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc04() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC05
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc05() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC07
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc07() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC08
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc08() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC09
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc09() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC0a
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc0a() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC0b
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc0b() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC0c
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc0c() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC0d
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc0d() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC0e
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc0e() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Determines and sets DIMM BC0f
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dimm_bc0f() final
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+};
+}//mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
deleted file mode 100644
index 6f14f4acd..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
+++ /dev/null
@@ -1,4100 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-///
-/// @file eff_config.C
-/// @brief Determine effective config for mss settings
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 2
-// *HWP Consumed by: FSP:HB
-//utils
-#include <math.h>
-
-// fapi2
-#include <fapi2.H>
-#include <vpd_access.H>
-#include <utility>
-
-// mss lib
-#include <lib/eff_config/eff_config.H>
-#include <lib/utils/fake_vpd.H>
-#include <lib/mss_vpd_decoder.H>
-#include <lib/spd/spd_factory.H>
-#include <lib/spd/common/spd_decoder.H>
-#include <lib/spd/common/rcw_settings.H>
-#include <lib/eff_config/timing.H>
-#include <lib/dimm/rank.H>
-#include <lib/utils/conversions.H>
-#include <lib/utils/find.H>
-
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-using fapi2::TARGET_TYPE_MCBIST;
-
-namespace mss
-{
-
-enum rc10_encode : uint8_t
-{
- DDR4_1866 = 0x01,
- DDR4_2133 = 0x02,
- DDR4_2400 = 0x03,
- DDR4_2666 = 0x04,
-};
-
-enum rc13_encode : uint8_t
-{
- DIRECT_CS_MODE = 0,
- LRDIMM = 0,
- RDIMM = 1,
-};
-
-enum rc3x_encode : uint8_t
-{
- MT1860_TO_MT1880 = 0x1F,
- MT2120_TO_MT2140 = 0x2C,
- MT2380_TO_MT2400 = 0x39,
- MT2660_TO_MT2680 = 0x47,
-};
-
-/////////////////////////
-// Non-member function implementations
-/////////////////////////
-
-///
-/// @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, ...)
-/// @return the IBT bit field e.g., 00, 01 ... (right aligned)
-/// @note Unrecognized IBT values will force an assertion.
-///
-static uint64_t ibt_helper(const uint8_t i_ibt)
-{
- switch(i_ibt)
- {
- // Off
- case 0:
- return 0b11;
- break;
-
- // 100Ohm
- case 10:
- return 0b00;
- break;
-
- // 150Ohm
- case 15:
- return 0b01;
- break;
-
- // 300Ohm
- case 30:
- return 0b10;
- break;
-
- default:
- FAPI_ERR("unknown IBT value %d", i_ibt);
- fapi2::Assert(false);
- };
-
- // Not reached, but 'return' off ...
- return 0b11;
-}
-
-/////////////////////////
-// Member Method implementation
-/////////////////////////
-
-///
-/// @brief Determines & sets effective config for DRAM generation from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_gen(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data )
-{
- //TODO: RTC 159777: Change eff_config class to use iv's for mcs, port and dimm position
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_gen(l_mcs, &l_mcs_attrs[0][0]) );
- FAPI_TRY( spd::dram_device_type(i_target, i_spd_data, l_decoder_val) );
-
- l_mcs_attrs[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_GEN, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}// dram_gen
-
-///
-/// @brief Determines & sets effective config for DIMM type from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_type(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data )
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dimm_type(l_mcs, &l_mcs_attrs[0][0]) );
- FAPI_TRY( spd::base_module_type(i_target, i_spd_data, l_decoder_val) );
-
- l_mcs_attrs[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_TYPE, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}// dimm_type
-
-///
-/// @brief Determines & sets effective config for eff_dram_mfg_id type from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_mfg_id(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint16_t l_decoder_val = 0;
- uint16_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_mfg_id(l_mcs, &l_mcs_attrs[0][0]) );
- FAPI_TRY( iv_pDecoder->dram_manufacturer_id_code(i_target, l_decoder_val) );
-
- l_mcs_attrs[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_MFG_ID, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}// dimm_type
-
-///
-/// @brief Determines & sets effective config for dram width
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_width(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Get & update MCS attribute
- FAPI_TRY( iv_pDecoder->device_width(i_target, l_decoder_val) );
- FAPI_TRY( eff_dram_width(l_mcs, &l_mcs_attrs[0][0]) );
-
- l_mcs_attrs[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_WIDTH, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Determines & sets effective config for the RTT_NOM value
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note used for MRS01
-///
-template<>
-fapi2::ReturnCode eff_config::dram_rtt_nom<KIND_RDIMM_DDR4>(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //Indexing info
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
-
- //Temp holders to grab attributes to then parse into value for this dimm and rank
- uint8_t l_rtt_nom[MAX_RANK_PER_DIMM] = {};
-
- //Size per JEDEC spec
- constexpr size_t RTT_NOM_SIZE = 8;
- // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
- // for index 1. So this doesn't correspond directly with the table in the JEDEC spec,
- // as that's not in "denominator order."
- // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
- constexpr uint8_t rtt_nom_map[] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
-
- size_t l_rtt_nom_index = 0;
- std::vector< uint64_t > l_ranks;
-
- FAPI_TRY( mss::vpd_mt_dram_rtt_nom(i_target, &(l_rtt_nom[0])) );
- FAPI_TRY( eff_dram_rtt_nom(l_mcs, &l_mcs_attrs[0][0][0]) );
-
- //Calculate the value for each rank and store in attribute
-
- FAPI_TRY(mss::rank::ranks(i_target, l_ranks));
-
- for (const auto& l_rank : l_ranks)
- {
- // We have to be careful about 0
- l_rtt_nom_index = (l_rtt_nom[mss::index(l_rank)] == 0) ?
- 0 : fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_NOM_OHM240 / l_rtt_nom[mss::index(l_rank)];
-
- //Make sure it's a valid index
- FAPI_ASSERT( (l_rtt_nom_index < RTT_NOM_SIZE),
- fapi2::MSS_BAD_MR_PARAMETER()
- .set_MR_NUMBER(5)
- .set_PARAMETER(RTT_NOM)
- .set_PARAMETER_VALUE(l_rtt_nom_index)
- .set_DIMM_IN_ERROR(i_target),
- "Bad value for RTT NOM: %d (%s)", l_rank, mss::c_str(i_target));
-
-
- // Map from RTT_NOM array to the value in the map
- l_decoder_val = rtt_nom_map[l_rtt_nom_index];
-
- //Store value and move to next rank
- l_mcs_attrs[l_port_num][l_dimm_num][mss::index(l_rank)] = l_decoder_val;
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_NOM, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for the RTT_NOM value
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note used for MRS01
-///
-template<>
-fapi2::ReturnCode eff_config::dram_rtt_nom<KIND_LRDIMM_DDR4>(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //Indexing info
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- std::vector< uint64_t > l_ranks;
-
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
- FAPI_TRY( eff_dram_rtt_nom(l_mcs, &l_mcs_attrs[0][0][0]) );
-
- //Get the value from the LRDIMM SPD
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_nom( iv_freq, l_decoder_val));
-
- //Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
- //Same value for every rank for LRDIMMs
- FAPI_TRY(mss::rank::ranks(i_target, l_ranks));
-
- for (const auto& l_rank : l_ranks)
- {
- l_mcs_attrs[l_port_num][l_dimm_num][mss::index(l_rank)] = l_decoder_val;
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_NOM, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-///
-/// @brief Determines & sets effective config for the RTT_WR value from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note used for MRS02
-///
-template<>
-fapi2::ReturnCode eff_config::dram_rtt_wr<KIND_RDIMM_DDR4>(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- std::vector< uint64_t > l_ranks;
-
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
-
- FAPI_TRY( eff_dram_rtt_wr(l_mcs, &l_mcs_attrs[0][0][0]) );
-
- //Get RTT_WR from VPD
- uint8_t l_dram_rtt_wr[MAX_RANK_PER_DIMM];
- FAPI_TRY( mss::vpd_mt_dram_rtt_wr(i_target, &(l_dram_rtt_wr[0])) );
-
- //Calculate the value for each rank and store in attribute
- FAPI_TRY(mss::rank::ranks(i_target, l_ranks));
-
- for (const auto& l_rank : l_ranks)
- {
- const auto l_index = mss::index(l_rank);
-
- switch (l_dram_rtt_wr[l_index])
- {
- case fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_DISABLE:
- l_decoder_val = 0b000;
- break;
-
- case fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_HIGHZ:
- l_decoder_val = 0b011;
- break;
-
- case fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM240:
- l_decoder_val = 0b010;
- break;
-
- case fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM80:
- l_decoder_val = 0b100;
- break;
-
- case fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_WR_OHM120:
- l_decoder_val = 0b001;
- break;
-
- default:
- FAPI_ERR("unknown RTT_WR 0x%x (%s rank %d), dynamic odt off",
- l_dram_rtt_wr[l_index], mss::c_str(i_target), l_rank);
- l_decoder_val = 0b000;
- break;
- };
-
- //Store value and move to next rank
- l_mcs_attrs[l_port_num][l_dimm_num][mss::index(l_rank)] = l_decoder_val;
- }
-
- //Set the attribute
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_WR, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for the RTT_WR value from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note used for MRS02
-///
-template<>
-fapi2::ReturnCode eff_config::dram_rtt_wr<KIND_LRDIMM_DDR4>(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- std::vector< uint64_t > l_ranks;
-
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
-
- //Get the value from the LRDIMM SPD
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_wr( iv_freq, l_decoder_val));
-
- //Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
- //Same value for every rank for LRDIMMs
- FAPI_TRY(mss::rank::ranks(i_target, l_ranks));
-
- for (const auto& l_rank : l_ranks)
- {
- l_mcs_attrs[l_port_num][l_dimm_num][mss::index(l_rank)] = l_decoder_val;
- }
-
- //Set the attribute
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_WR, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for the RTT_PARK value from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note used for MRS05
-///
-template <>
-fapi2::ReturnCode eff_config::dram_rtt_park<KIND_RDIMM_DDR4>(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //Indexing info
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- std::vector< uint64_t > l_ranks;
-
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
-
- // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
- // for index 1. So this doesn't correspond directly with the table in the JEDEC spec,
- // as that's not in "denominator order."
- constexpr uint64_t RTT_PARK_COUNT = 8;
- // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
- constexpr uint8_t rtt_park_map[RTT_PARK_COUNT] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
-
- uint8_t l_rtt_park[MAX_RANK_PER_DIMM];
-
- FAPI_TRY( mss::vpd_mt_dram_rtt_park(i_target, &(l_rtt_park[0])) );
- FAPI_TRY( eff_dram_rtt_park(l_mcs, &l_mcs_attrs[0][0][0]) );
-
- //Calculate the value for each rank and store in attribute
- FAPI_TRY(mss::rank::ranks(i_target, l_ranks));
-
-
- for (const auto& l_rank : l_ranks)
- {
- const auto l_index = mss::index(l_rank);
-
- // We have to be careful about 0
- uint8_t l_rtt_park_index = (l_rtt_park[l_index] == 0) ?
- 0 : fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_PARK_240OHM / l_rtt_park[l_index];
-
- FAPI_ASSERT( (l_rtt_park_index < RTT_PARK_COUNT),
- fapi2::MSS_BAD_MR_PARAMETER()
- .set_MR_NUMBER(5)
- .set_PARAMETER(RTT_PARK)
- .set_PARAMETER_VALUE(l_rank)
- .set_DIMM_IN_ERROR(i_target),
- "Bad value for RTT park: %d (%s)", l_rank, mss::c_str(i_target));
-
- // Map from RTT_PARK array to the value in the map
- l_mcs_attrs[l_port_num][l_dimm_num][l_index] = rtt_park_map[l_rtt_park_index];
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_PARK, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for the RTT_PARK value from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note used for MRS05
-///
-template <>
-fapi2::ReturnCode eff_config::dram_rtt_park<KIND_LRDIMM_DDR4>(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
-//Indexing info
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
- uint8_t l_decoder_val_01 = 0;
- uint8_t l_decoder_val_23 = 0;
-
- FAPI_TRY( eff_dram_rtt_park(l_mcs, &l_mcs_attrs[0][0][0]) );
-
- //Get the value from the LRDIMM SPD
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_park_ranks0_1( iv_freq, l_decoder_val_01));;
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_park_ranks2_3( iv_freq, l_decoder_val_23));;
-
- l_mcs_attrs[l_port_num][l_dimm_num][0] = l_decoder_val_01;
- l_mcs_attrs[l_port_num][l_dimm_num][1] = l_decoder_val_01;
- l_mcs_attrs[l_port_num][l_dimm_num][2] = l_decoder_val_23;
- l_mcs_attrs[l_port_num][l_dimm_num][3] = l_decoder_val_23;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_PARK, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for dram density
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_density(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
-
- uint8_t l_decoder_val = 0;
- FAPI_TRY( iv_pDecoder->sdram_density(i_target, l_decoder_val) );
-
- // Get & update MCS attribute
- {
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dram_density(l_mcs, &l_mcs_attrs[0][0]) );
-
- l_mcs_attrs[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DENSITY, l_mcs, l_mcs_attrs) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for number of ranks per dimm
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::ranks_per_dimm(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_ranks_per_dimm = 0;
- uint8_t l_attrs_ranks_per_dimm[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Get & update MCS attribute
- FAPI_TRY( eff_num_ranks_per_dimm(l_mcs, &l_attrs_ranks_per_dimm[0][0]) );
- FAPI_TRY( iv_pDecoder->logical_ranks_per_dimm(i_target, l_ranks_per_dimm) );
-
- l_attrs_ranks_per_dimm[l_port_num][l_dimm_num] = l_ranks_per_dimm;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_NUM_RANKS_PER_DIMM, l_mcs, l_attrs_ranks_per_dimm) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for stack type
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::primary_stack_type(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint8_t l_decoder_val = 0;
- FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(i_target, l_decoder_val) );
-
- // Get & update MCS attribute
- {
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_prim_stack_type(l_mcs, &l_mcs_attrs[0][0]) );
-
- l_mcs_attrs[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_PRIM_STACK_TYPE, l_mcs, l_mcs_attrs) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for dimm size
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @warn Dependent on the following attributes already set:
-/// @warn eff_dram_density, eff_sdram_width, eff_ranks_per_dimm
-///
-fapi2::ReturnCode eff_config::dimm_size(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Retrieve values needed to calculate dimm size
- uint8_t l_bus_width = 0;
- uint8_t l_sdram_width = 0;
- uint8_t l_sdram_density = 0;
- uint8_t l_logical_rank_per_dimm = 0;
-
- FAPI_TRY( iv_pDecoder->device_width(i_target, l_sdram_width) );
- FAPI_TRY( iv_pDecoder->prim_bus_width(i_target, l_bus_width) );
- FAPI_TRY( iv_pDecoder->sdram_density(i_target, l_sdram_density) );
- FAPI_TRY( iv_pDecoder->logical_ranks_per_dimm(i_target, l_logical_rank_per_dimm) );
-
- {
- // Calculate dimm size
- // Formula from SPD Spec
- // Total = SDRAM Capacity 8 * Primary Bus Width SDRAM Width * Logical Ranks per DIMM
- uint32_t l_dimm_size = 0;
- l_dimm_size = (l_sdram_density / 8.0) * (l_bus_width / l_sdram_width) * l_logical_rank_per_dimm;
-
- // Get & update MCS attribute
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint32_t l_attrs_dimm_size[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_size(l_mcs, &l_attrs_dimm_size[0][0]) );
-
- l_attrs_dimm_size[l_port_num][l_dimm_num] = l_dimm_size;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_SIZE, l_mcs, l_attrs_dimm_size) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for Hybrid memory type from SPD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::hybrid_memory_type(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_decoder_val = 0;
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Get & update MCS attribute
- FAPI_TRY( eff_hybrid_memory_type(l_mcs, &l_mcs_attrs[0][0]) );
- FAPI_TRY(iv_pDecoder->hybrid_media(i_target, l_decoder_val));
-
- l_mcs_attrs[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, l_mcs, l_mcs_attrs) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for refresh interval time (tREFI)
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trefi(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint64_t l_trefi_in_ps = 0;
-
- // Calculates appropriate tREFI based on fine refresh mode
- switch(iv_refresh_mode)
- {
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
-
- FAPI_TRY( calc_trefi( mss::refresh_rate::REF1X,
- iv_temp_refresh_range,
- l_trefi_in_ps),
- "Failed to calculate tREF1 for target %s", mss::c_str(i_target) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
-
- FAPI_TRY( calc_trefi( mss::refresh_rate::REF2X,
- iv_temp_refresh_range,
- l_trefi_in_ps),
- "Failed to calculate tREF2 for target %s", mss::c_str(i_target) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
-
- FAPI_TRY( calc_trefi( mss::refresh_rate::REF4X,
- iv_temp_refresh_range,
- l_trefi_in_ps),
- "Failed to calculate tREF4 for target %s", mss::c_str(i_target) );
- break;
-
- default:
- // Fine Refresh Mode will be a platform attribute set by the MRW,
- // which they "shouldn't" mess up as long as use "attribute" enums.
- // if openpower messes this up we can at least catch it
- FAPI_ASSERT(false,
- fapi2::MSS_INVALID_FINE_REFRESH_MODE().
- set_FINE_REF_MODE(iv_refresh_mode),
- "%s Incorrect Fine Refresh Mode received: %d ",
- mss::c_str(i_target),
- iv_refresh_mode);
- break;
- }
-
- {
- // Calculate refresh cycle time in nCK & set attribute
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
-
- std::vector<uint16_t> l_mcs_attrs_trefi(PORTS_PER_MCS, 0);
- uint64_t l_trefi_in_nck = 0;
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dram_trefi(l_mcs, l_mcs_attrs_trefi.data()) );
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_trefi_in_ps, static_cast<uint64_t>(iv_tCK_in_ps), INVERSE_DDR4_CORRECTION_FACTOR,
- l_trefi_in_nck),
- "Error in calculating tREFI for target %s, with value of l_trefi_in_ps: %d", mss::c_str(i_target), l_trefi_in_ps);
-
- FAPI_INF("tCK (ps): %d, tREFI (ps): %d, tREFI (nck): %d",
- iv_tCK_in_ps, l_trefi_in_ps, l_trefi_in_nck);
-
- // Update MCS attribute
- l_mcs_attrs_trefi[l_port_num] = l_trefi_in_nck;
-
- // casts vector into the type FAPI_ATTR_SET is expecting by deduction
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TREFI,
- l_mcs,
- UINT16_VECTOR_TO_1D_ARRAY(l_mcs_attrs_trefi, PORTS_PER_MCS)),
- "Failed to set tREFI attribute");
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}// refresh_interval
-
-///
-/// @brief Determines & sets effective config for refresh cycle time (tRFC)
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trfc(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- int64_t l_trfc_mtb = 0;
- int64_t l_trfc_in_ps = 0;
-
- // Selects appropriate tRFC based on fine refresh mode
- switch(iv_refresh_mode)
- {
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
- FAPI_TRY( iv_pDecoder->min_refresh_recovery_delay_time_1(i_target, l_trfc_mtb),
- "Failed to decode SPD for tRFC1" );
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
- FAPI_TRY( iv_pDecoder->min_refresh_recovery_delay_time_2(i_target, l_trfc_mtb),
- "Failed to decode SPD for tRFC2" );
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
- FAPI_TRY( iv_pDecoder->min_refresh_recovery_delay_time_4(i_target, l_trfc_mtb),
- "Failed to decode SPD for tRFC4" );
- break;
-
- default:
- // Fine Refresh Mode will be a platform attribute set by the MRW,
- // which they "shouldn't" mess up as long as use "attribute" enums.
- // if openpower messes this up we can at least catch it
- FAPI_ASSERT(false,
- fapi2::MSS_INVALID_FINE_REFRESH_MODE().
- set_FINE_REF_MODE(iv_refresh_mode),
- "%s Incorrect Fine Refresh Mode received: %d ",
- mss::c_str(i_target),
- iv_refresh_mode);
- break;
-
- }// switch
-
- // Calculate trfc (in ps)
- {
- constexpr int64_t l_trfc_ftb = 0;
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb) );
-
- FAPI_INF( "medium timebase (ps): %ld, fine timebase (ps): %ld, tRFC (MTB): %ld, tRFC(FTB): %ld",
- l_mtb, l_ftb, l_trfc_mtb, l_trfc_ftb );
-
- l_trfc_in_ps = spd::calc_timing_from_timebase(l_trfc_mtb, l_mtb, l_trfc_ftb, l_ftb);
- }
-
- {
- // Calculate refresh cycle time in nCK & set attribute
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
-
- uint16_t l_trfc_in_nck = 0;
- std::vector<uint16_t> l_mcs_attrs_trfc(PORTS_PER_MCS, 0);
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dram_trfc(l_mcs, l_mcs_attrs_trfc.data()),
- "Failed to retrieve tRFC attribute" );
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_trfc_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_in_nck),
- "Error in calculating l_tRFC for target %s, with value of l_trfc_in_ps: %d", mss::c_str(i_target), l_trfc_in_ps);
-
- FAPI_INF("tCK (ps): %d, tRFC (ps): %d, tRFC (nck): %d",
- iv_tCK_in_ps, l_trfc_in_ps, l_trfc_in_nck);
-
- // Update MCS attribute
- l_mcs_attrs_trfc[l_port_num] = l_trfc_in_nck;
-
- // casts vector into the type FAPI_ATTR_SET is expecting by deduction
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRFC,
- l_mcs,
- UINT16_VECTOR_TO_1D_ARRAY(l_mcs_attrs_trfc, PORTS_PER_MCS) ),
- "Failed to set tRFC attribute" );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for refresh cycle time (different logical ranks - tRFC_DLR)
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trfc_dlr(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
-
- uint8_t l_density = 0;
- uint64_t l_tCK_in_ps = 0;
- uint64_t l_trfc_dlr_in_ps = 0;
- uint8_t l_trfc_dlr_in_nck = 0;
- std::vector<uint8_t> l_mcs_attrs_trfc_dlr(PORTS_PER_MCS, 0);
-
- // Retrieve map params
- FAPI_TRY( iv_pDecoder->sdram_density(i_target, l_density), "Failed to get sdram density");
- FAPI_TRY ( mss::mrw_fine_refresh_mode(iv_refresh_mode), "Failed to get MRW attribute for fine refresh mode" );
-
- FAPI_INF("Retrieved SDRAM density: %d, fine refresh mode: %d",
- l_density, iv_refresh_mode);
-
- // Calculate refresh cycle time in ps
- FAPI_TRY( calc_trfc_dlr(iv_refresh_mode, l_density, l_trfc_dlr_in_ps), "Failed calc_trfc_dlr()" );
-
- // Calculate clock period (tCK) from selected freq from mss_freq
- FAPI_TRY( clock_period(i_target, l_tCK_in_ps), "Failed to calculate clock period (tCK)");
-
- // Calculate refresh cycle time in nck
- FAPI_TRY( spd::calc_nck(l_trfc_dlr_in_ps, l_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_dlr_in_nck));
-
- FAPI_INF("tCK (ps): %d, tRFC_DLR (ps): %d, tRFC_DLR (nck): %d",
- l_tCK_in_ps, l_trfc_dlr_in_ps, l_trfc_dlr_in_nck);
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dram_trfc_dlr(l_mcs, l_mcs_attrs_trfc_dlr.data()), "Failed to retrieve tRFC_DLR attribute" );
-
- // Update MCS attribute
- l_mcs_attrs_trfc_dlr[l_port_num] = l_trfc_dlr_in_nck;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRFC_DLR,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_mcs_attrs_trfc_dlr, PORTS_PER_MCS) ),
- "Failed to set tRFC_DLR attribute" );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for dimm rcd mirror mode
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::rcd_mirror_mode(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_mirror_mode = 0;
- uint8_t l_attrs_mirror_mode[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( eff_dimm_rcd_mirror_mode(l_mcs, &l_attrs_mirror_mode[0][0]) );
-
- // Update MCS attribute
- FAPI_TRY( iv_pDecoder->iv_module_decoder->register_to_dram_addr_mapping(l_mirror_mode) );
- l_attrs_mirror_mode[l_port_num][l_dimm_num] = l_mirror_mode;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RCD_MIRROR_MODE, l_mcs, l_attrs_mirror_mode) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for dram bank bits
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_bank_bits(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_bank_bits = 0;
- uint8_t l_attrs_bank_bits[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( eff_dram_bank_bits(l_mcs, &l_attrs_bank_bits[0][0]) );
- FAPI_TRY( iv_pDecoder->bank_bits(i_target, l_bank_bits) );
-
- l_attrs_bank_bits[l_port_num][l_dimm_num] = l_bank_bits;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_BANK_BITS, l_mcs, l_attrs_bank_bits) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for dram row bits
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_row_bits(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_row_bits = 0;
- uint8_t l_attrs_row_bits[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( eff_dram_row_bits(l_mcs, &l_attrs_row_bits[0][0]) );
- FAPI_TRY( iv_pDecoder->row_address_bits(i_target, l_row_bits) );
-
- l_attrs_row_bits[l_port_num][l_dimm_num] = l_row_bits;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_ROW_BITS, l_mcs, l_attrs_row_bits) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tDQS
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note Sets TDQS to off for x4, sets to on for x8
-///
-fapi2::ReturnCode eff_config::dram_dqs_time(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint8_t l_attrs_dqs_time[PORTS_PER_MCS] = {};
- uint8_t l_dram_width = 0;
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- //Get the DRAM width
- FAPI_TRY( iv_pDecoder->device_width(i_target, l_dram_width) );
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_tdqs(l_mcs, &l_attrs_dqs_time[0]) );
- FAPI_INF("SDRAM width: %d for target %s", l_dram_width, mss::c_str(i_target));
-
- //Only possible dram width are x4, x8. If x8, tdqs is available, else not available
- l_attrs_dqs_time[l_port_num] = (l_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ?
- fapi2::ENUM_ATTR_EFF_DRAM_TDQS_ENABLE : fapi2::ENUM_ATTR_EFF_DRAM_TDQS_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TDQS, l_mcs, l_attrs_dqs_time) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tCCD_L
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_tccd_l(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- int64_t l_tccd_in_ps = 0;
-
- // Get the tCCD_L timing values
- // tCCD_L is speed bin independent and is
- // the same for all bins within a speed grade.
- // It is safe to read this from SPD because the correct nck
- // value will be calulated based on our dimm speed.
-
- // TODO: RTC 163150 Clean up eff_config timing boilerplate
- {
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
- int64_t l_tccd_mtb = 0;
- int64_t l_tccd_ftb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb),
- "Failed medium_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb),
- "Failed fine_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->min_tccd_l(i_target, l_tccd_mtb),
- "Failed min_tccd_l() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_tccd_l(i_target, l_tccd_ftb),
- "Failed fine_offset_min_tccd_l() for %s", mss::c_str(i_target) );
-
- FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tCCD_L (MTB): %ld, tCCD_L(FTB): %ld",
- l_mtb, l_ftb, l_tccd_mtb, l_tccd_ftb );
-
- l_tccd_in_ps = spd::calc_timing_from_timebase(l_tccd_mtb, l_mtb, l_tccd_ftb, l_ftb);
- }
-
- {
- // Calculate refresh cycle time in nCK & set attribute
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
-
- uint8_t l_tccd_in_nck = 0;
- std::vector<uint8_t> l_mcs_attrs_tccd(PORTS_PER_MCS, 0);
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dram_tccd_l(l_mcs, l_mcs_attrs_tccd.data()),
- "Failed to retrieve tCCD attribute" );
-
- // Calculate nck
- FAPI_TRY ( spd::calc_nck(l_tccd_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_tccd_in_nck),
- "Error in calculating tccd for target %s, with value of l_tccd_in_ps: %d", mss::c_str(i_target), l_tccd_in_ps);
-
- FAPI_INF("tCK (ps): %d, tCCD_L (ps): %d, tCCD_L (nck): %d",
- iv_tCK_in_ps, l_tccd_in_ps, l_tccd_in_nck);
-
- // Update MCS attribute
- l_mcs_attrs_tccd[l_port_num] = l_tccd_in_nck;
-
- // casts vector into the type FAPI_ATTR_SET is expecting by deduction
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TCCD_L,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_mcs_attrs_tccd, PORTS_PER_MCS) ),
- "Failed to set tCCD_L attribute" );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC00
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc00(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc00[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc00(l_mcs, &l_attrs_dimm_rc00[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc00[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc00;
-
- FAPI_INF("%s: RC00 settting: %d", mss::c_str(i_target), l_attrs_dimm_rc00[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC00, l_mcs, l_attrs_dimm_rc00) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC01
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc01(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc01[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc01(l_mcs, &l_attrs_dimm_rc01[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc01[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc01;
-
- FAPI_INF("%s: RC01 settting: %d", mss::c_str(i_target), l_attrs_dimm_rc01[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC01, l_mcs, l_attrs_dimm_rc01) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC02
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc02(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc02[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc02(l_mcs, &l_attrs_dimm_rc02[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc02[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc02;
-
- FAPI_INF("%s: RC02 settting: %d", mss::c_str(i_target), l_attrs_dimm_rc02[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC02, l_mcs, l_attrs_dimm_rc02) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC03
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc03(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- fapi2::buffer<uint8_t> l_buffer;
-
- uint8_t l_attrs_dimm_rc03[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- uint8_t l_cs_output_drive = 0;
- uint8_t l_ca_output_drive = 0;
-
- FAPI_TRY( iv_pDecoder->iv_module_decoder->cs_signal_output_driver(l_cs_output_drive) );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->ca_signal_output_driver(l_ca_output_drive) );
-
- FAPI_INF( "%s: Retrieved register output drive, for CA: %d, CS: %d",
- mss::c_str(i_target), l_ca_output_drive, l_cs_output_drive );
-
- // Lets construct encoding byte for RCD setting
- {
- // Buffer insert constants for CS and CA output drive
- constexpr size_t CS_START = 4;
- constexpr size_t CA_START = 6;
- constexpr size_t LEN = 2;
-
- l_buffer.insertFromRight<CA_START, LEN>(l_ca_output_drive)
- .insertFromRight<CS_START, LEN>(l_cs_output_drive);
- }
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dimm_ddr4_rc03(l_mcs, &l_attrs_dimm_rc03[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc03[l_port_num][l_dimm_num] = l_buffer;
-
- FAPI_INF("%s: RC03 settting: %d", mss::c_str(i_target), l_attrs_dimm_rc03[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC03, l_mcs, l_attrs_dimm_rc03) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC04
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc04(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_attrs_dimm_rc04[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- uint8_t l_odt_output_drive = 0;
- uint8_t l_cke_output_drive = 0;
-
- fapi2::buffer<uint8_t> l_buffer;
-
- FAPI_TRY( iv_pDecoder->iv_module_decoder->odt_signal_output_driver(l_odt_output_drive) );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->cke_signal_output_driver(l_cke_output_drive) );
-
- FAPI_INF( "%s: Retrieved signal driver output, for CKE: %d, ODT: %d",
- mss::c_str(i_target), l_cke_output_drive, l_odt_output_drive );
-
- // Lets construct encoding byte for RCD setting
- {
- // Buffer insert constants for ODT and CKE output drive
- constexpr size_t CKE_START = 6;
- constexpr size_t ODT_START = 4;
- constexpr size_t LEN = 2;
-
- l_buffer.insertFromRight<CKE_START, LEN>(l_cke_output_drive)
- .insertFromRight<ODT_START, LEN>(l_odt_output_drive);
- }
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dimm_ddr4_rc04(l_mcs, &l_attrs_dimm_rc04[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc04[l_port_num][l_dimm_num] = l_buffer;
-
- FAPI_INF("%s: RC04 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc04[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC04, l_mcs, l_attrs_dimm_rc04) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC05
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc05(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_attrs_dimm_rc05[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- uint8_t l_a_side_output_drive = 0;
- uint8_t l_b_side_output_drive = 0;
-
- fapi2::buffer<uint8_t> l_buffer;
-
- FAPI_TRY( iv_pDecoder->iv_module_decoder->a_side_clk_output_driver(l_a_side_output_drive) );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->b_side_clk_output_driver(l_b_side_output_drive) );
-
- FAPI_INF( "%s: Retrieved register output drive for clock, b-side (Y0,Y2): %d, a-side (Y1,Y3): %d",
- mss::c_str(i_target), l_b_side_output_drive, l_a_side_output_drive );
-
- {
- // Buffer insert constants for ODT and CKE output drive
- constexpr size_t B_START = 6;
- constexpr size_t A_START = 4;
- constexpr size_t LEN = 2;
-
- // Lets construct encoding byte for RCD setting
- l_buffer.insertFromRight<B_START, LEN>(l_b_side_output_drive)
- .insertFromRight<A_START, LEN>(l_a_side_output_drive);
- }
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dimm_ddr4_rc05(l_mcs, &l_attrs_dimm_rc05[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc05[l_port_num][l_dimm_num] = l_buffer;
-
- FAPI_INF( "%s: RC05 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc05[l_port_num][l_dimm_num] )
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC05, l_mcs, l_attrs_dimm_rc05) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC06_07
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc06_07(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc06_07[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc06_07(l_mcs, &l_attrs_dimm_rc06_07[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc06_07[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc06_07;
-
- FAPI_INF( "%s: RC06_07 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc06_07[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC06_07, l_mcs, l_attrs_dimm_rc06_07) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC08
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc08(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc08[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc08(l_mcs, &l_attrs_dimm_rc08[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc08[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc08;
-
- FAPI_INF( "%s: RC08 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc08[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC08, l_mcs, l_attrs_dimm_rc08) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC09
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc09(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // TODO - RTC 160118: Clean up eff_config boiler plate that can moved into helper functions
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc09[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc09(l_mcs, &l_attrs_dimm_rc09[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc09[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc09;
-
- FAPI_INF( "%s: RC09 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc09[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC09, l_mcs, l_attrs_dimm_rc09) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC10
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc10(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc10[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc10(l_mcs, &l_attrs_dimm_rc10[0][0]) );
-
-
- switch(iv_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- l_attrs_dimm_rc10[l_port_num][l_dimm_num] = rc10_encode::DDR4_1866;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- l_attrs_dimm_rc10[l_port_num][l_dimm_num] = rc10_encode::DDR4_2133;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- l_attrs_dimm_rc10[l_port_num][l_dimm_num] = rc10_encode::DDR4_2400;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- l_attrs_dimm_rc10[l_port_num][l_dimm_num] = rc10_encode::DDR4_2666;
- break;
-
- default:
- FAPI_ERR("Invalid frequency for rc10 encoding received: %d", iv_freq);
- return fapi2::FAPI2_RC_FALSE;
- break;
- }
-
- FAPI_INF( "%s: RC10 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc10[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC10, l_mcs, l_attrs_dimm_rc10) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC11
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc11(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc11[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc11(l_mcs, &l_attrs_dimm_rc11[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc11[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc0b;
-
- FAPI_INF( "%s: RC11 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc11[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC11, l_mcs, l_attrs_dimm_rc11) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC12
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc12(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc12[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc12(l_mcs, &l_attrs_dimm_rc12[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc12[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc0c;
-
- FAPI_INF( "%s: R12 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc12[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC12, l_mcs, l_attrs_dimm_rc12) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC13
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc13(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_attrs_dimm_rc13[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- fapi2::buffer<uint8_t> l_buffer;
-
- // TODO - RTC 160116: Fix RC0D chip select setting for LRDIMMs
- constexpr uint8_t l_cs_mode = rc13_encode::DIRECT_CS_MODE;
- uint8_t l_mirror_mode = 0;
- uint8_t l_dimm_type = 0;
- uint8_t l_module_type = 0;
-
- FAPI_TRY( spd::base_module_type(i_target, iv_pDecoder->iv_spd_data, l_module_type) );
-
- l_dimm_type = (l_module_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) ?
- rc13_encode::RDIMM :
- rc13_encode::LRDIMM;
-
- FAPI_TRY( iv_pDecoder->iv_module_decoder->register_to_dram_addr_mapping(l_mirror_mode) );
-
- // Lets construct encoding byte for RCD setting
- {
- // CS
- constexpr size_t CS_START = 6;
- constexpr size_t CS_LEN = 2;
-
- // DIMM TYPE
- constexpr size_t DIMM_TYPE_START = 5;
- constexpr size_t DIMM_TYPE_LEN = 1;
-
- // MIRROR mode
- constexpr size_t MIRROR_START = 4;
- constexpr size_t MIRROR_LEN = 1;
-
- l_buffer.insertFromRight<CS_START, CS_LEN>(l_cs_mode)
- .insertFromRight<DIMM_TYPE_START, DIMM_TYPE_LEN>(l_dimm_type)
- .insertFromRight<MIRROR_START, MIRROR_LEN>(l_mirror_mode);
- }
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dimm_ddr4_rc13(l_mcs, &l_attrs_dimm_rc13[0][0]) );
-
- // Update MCS attribute
- FAPI_TRY( spd::base_module_type(i_target, iv_pDecoder->iv_spd_data, l_dimm_type) );
- l_attrs_dimm_rc13[l_port_num][l_dimm_num] = l_buffer;
-
- FAPI_INF( "%s: RC13 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc13[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC13, l_mcs, l_attrs_dimm_rc13) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC14
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc14(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc14[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc14(l_mcs, &l_attrs_dimm_rc14[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc14[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc0e;
-
- FAPI_INF( "%s: RC14 setting: 0x%0x", mss::c_str(i_target), l_attrs_dimm_rc14[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC14, l_mcs, l_attrs_dimm_rc14) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC15
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc15(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc15[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc15(l_mcs, &l_attrs_dimm_rc15[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc15[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc0f;
-
- FAPI_INF( "%s: RC15 setting: %d", mss::c_str(i_target), l_attrs_dimm_rc15[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC15, l_mcs, l_attrs_dimm_rc15) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_1x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc1x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_1x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_1x(l_mcs, &l_attrs_dimm_rc_1x[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_1x[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc1x;
-
- FAPI_INF( "%s: RC1X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_1x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_1x, l_mcs, l_attrs_dimm_rc_1x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_2x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc2x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_2x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_2x(l_mcs, &l_attrs_dimm_rc_2x[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_2x[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc2x;
-
- FAPI_INF( "%s: RC2X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_2x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_2x, l_mcs, l_attrs_dimm_rc_2x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_3x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc3x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_attrs_dimm_rc_3x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Retrieve MCS attribute data
- FAPI_TRY( eff_dimm_ddr4_rc_3x(l_mcs, &l_attrs_dimm_rc_3x[0][0]) );
-
- switch(iv_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- l_attrs_dimm_rc_3x[l_port_num][l_dimm_num] = rc3x_encode::MT1860_TO_MT1880;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- l_attrs_dimm_rc_3x[l_port_num][l_dimm_num] = rc3x_encode::MT2120_TO_MT2140;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- l_attrs_dimm_rc_3x[l_port_num][l_dimm_num] = rc3x_encode::MT2380_TO_MT2400;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- l_attrs_dimm_rc_3x[l_port_num][l_dimm_num] = rc3x_encode::MT2660_TO_MT2680;
- break;
-
- default:
- FAPI_ERR("Invalid frequency for rc_3x encoding received: %d", iv_freq);
- return fapi2::FAPI2_RC_FALSE;
- break;
- }
-
- FAPI_INF( "%s: RC3X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_3x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_3x, l_mcs, l_attrs_dimm_rc_3x) );
-
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_4x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc4x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_4x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_4x(l_mcs, &l_attrs_dimm_rc_4x[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_4x[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc4x;
-
- FAPI_INF( "%s: RC4X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_4x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_4x, l_mcs, l_attrs_dimm_rc_4x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_5x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc5x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_5x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_5x(l_mcs, &l_attrs_dimm_rc_5x[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_5x[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc5x;
-
- FAPI_INF( "%s: RC5X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_5x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_5x, l_mcs, l_attrs_dimm_rc_5x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_6x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc6x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_6x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_6x(l_mcs, &l_attrs_dimm_rc_6x[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_6x[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc6x;
-
- FAPI_INF( "%s: RC6X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_6x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_6x, l_mcs, l_attrs_dimm_rc_6x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_7x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc7x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint8_t l_attrs_dimm_rc_7x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- fapi2::buffer<uint8_t> l_rcd7x = 0;
-
- // All the IBT bit fields in the RCD control word are 2 bits long.
- constexpr uint64_t LEN = 2;
-
- // CA starts at bit 6, others are the same. So the field runs from START for LEN bits,
- // for example CA field is bits 6:7
- constexpr uint64_t CA_START = 6;
- uint8_t l_ibt_ca = 0;
-
- constexpr uint64_t CKE_START = 2;
- uint8_t l_ibt_cke = 0;
-
- constexpr uint64_t CS_START = 4;
- uint8_t l_ibt_cs = 0;
-
- constexpr uint64_t ODT_START = 0;
- uint8_t l_ibt_odt = 0;
-
- // Pull the individual settings from VPD, and shuffle them into RCD7x
- FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_ca(i_target, l_ibt_ca) );
- FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_cke(i_target, l_ibt_cke) );
- FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_cs(i_target, l_ibt_cs) );
- FAPI_TRY( mss::vpd_mt_dimm_rcd_ibt_odt(i_target, l_ibt_odt) );
-
- l_rcd7x.insertFromRight<CA_START, LEN>( ibt_helper(l_ibt_ca) );
- l_rcd7x.insertFromRight<CKE_START, LEN>( ibt_helper(l_ibt_cke) );
- l_rcd7x.insertFromRight<CS_START, LEN>( ibt_helper(l_ibt_cs) );
- l_rcd7x.insertFromRight<ODT_START, LEN>( ibt_helper(l_ibt_odt) );
-
- // Now write RCD7x out to the effective attribute
- FAPI_TRY( eff_dimm_ddr4_rc_7x(l_mcs, &l_attrs_dimm_rc_7x[0][0]) );
- l_attrs_dimm_rc_7x[l_port_num][l_dimm_num] = l_rcd7x;
-
- FAPI_INF( "%s: RC7X setting is 0x%x", mss::c_str(i_target), l_attrs_dimm_rc_7x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_7x, l_mcs, l_attrs_dimm_rc_7x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_8x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc8x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_8x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_8x(l_mcs, &l_attrs_dimm_rc_8x[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_8x[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc8x;
-
- FAPI_INF( "%s: RC8X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_8x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_8x, l_mcs, l_attrs_dimm_rc_8x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_9x
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rc9x(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_9x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_9x(l_mcs, &l_attrs_dimm_rc_9x[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_9x[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc9x;
-
- FAPI_INF( "%s: RC9X setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_9x[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_9x, l_mcs, l_attrs_dimm_rc_9x) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_AX
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rcax(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_ax[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_ax(l_mcs, &l_attrs_dimm_rc_ax[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_ax[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rcax;
-
- FAPI_INF( "%s: RCAX setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_ax[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_Ax, l_mcs, l_attrs_dimm_rc_ax) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DIMM RC_BX
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dimm_rcbx(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- // Retrieve MCS attribute data
- uint8_t l_attrs_dimm_rc_bx[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dimm_ddr4_rc_bx(l_mcs, &l_attrs_dimm_rc_bx[0][0]) );
-
- // Update MCS attribute
- l_attrs_dimm_rc_bx[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rcbx;
-
- FAPI_INF( "%s: RCBX setting: %d", mss::c_str(i_target), l_attrs_dimm_rc_bx[l_port_num][l_dimm_num] );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC_Bx, l_mcs, l_attrs_dimm_rc_bx) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tWR
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_twr(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
- int64_t l_twr_in_ps = 0;
-
- // Get the tWR timing values
- // tWR is speed bin independent and is
- // the same for all bins within a speed grade.
- // It is safe to read this from SPD because the correct nck
- // value will be calulated based on our dimm speed.
- {
- constexpr int64_t l_twr_ftb = 0;
- int64_t l_twr_mtb = 0;
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb),
- "Failed medium_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb),
- "Failed fine_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->min_write_recovery_time(i_target, l_twr_mtb),
- "Failed min_write_recovery_time() for %s", mss::c_str(i_target) );
-
- FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tWR (MTB): %ld, tWR(FTB): %ld",
- l_mtb, l_ftb, l_twr_mtb, l_twr_ftb);
-
- // Calculate twr (in ps)
- l_twr_in_ps = spd::calc_timing_from_timebase(l_twr_mtb, l_mtb, l_twr_ftb, l_ftb);
- }
-
- {
- std::vector<uint8_t> l_attrs_dram_twr(PORTS_PER_MCS, 0);
- uint8_t l_twr_in_nck = 0;
-
- // Calculate tNCK
- FAPI_TRY( spd::calc_nck(l_twr_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twr_in_nck),
- "Error in calculating l_twr_in_nck for target %s, with value of l_twr_in_ps: %d", mss::c_str(i_target), l_twr_in_ps);
-
- FAPI_INF( "tCK (ps): %d, tWR (ps): %d, tWR (nck): %d for target: %s",
- iv_tCK_in_ps, l_twr_in_ps, l_twr_in_nck, mss::c_str(i_target) );
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_twr(l_mcs, l_attrs_dram_twr.data()) );
-
- l_attrs_dram_twr[l_port_num] = l_twr_in_nck;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TWR,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_twr, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TWR");
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for RBT
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::read_burst_type(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint8_t l_attrs_rbt[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- FAPI_TRY( eff_dram_rbt(l_mcs, &l_attrs_rbt[0][0]) );
-
- l_attrs_rbt[l_port_num][l_dimm_num] = fapi2::ENUM_ATTR_EFF_DRAM_RBT_SEQUENTIAL;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RBT, l_mcs, l_attrs_rbt),
- "Failed setting attribute for RTB");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for TM
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note dram testing mode
-/// @note always disabled
-///
-fapi2::ReturnCode eff_config::dram_tm(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint8_t l_attrs_tm[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- FAPI_TRY( eff_dram_tm(l_mcs, &l_attrs_tm[0][0]) );
-
- l_attrs_tm[l_port_num][l_dimm_num] = fapi2::ENUM_ATTR_EFF_DRAM_TM_NORMAL;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TM, l_mcs, l_attrs_tm),
- "Failed setting attribute for BL");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for cwl
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note Sets CAS Write Latency, depending on frequency and ATTR_MSS_MT_PREAMBLE
-///
-fapi2::ReturnCode eff_config::dram_cwl(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
-
- // Taken from DDR4 JEDEC spec 1716.78C
- // Proposed DDR4 Full spec update(79-4A)
- // Page 26, Table 7
- static std::pair<uint64_t, uint8_t> CWL_TABLE_1 [6] =
- {
- {1600, 9},
- {1866, 10},
- {2133, 11},
- {2400, 12},
- {2666, 14},
- {3200, 16},
- };
- static std::pair<uint64_t, uint8_t> CWL_TABLE_2 [3] =
- {
- {2400, 14},
- {2666, 16},
- {3200, 18},
- };
-
- std::vector<uint8_t> l_attrs_cwl(PORTS_PER_MCS, 0);
- uint8_t l_cwl = 0;
- uint8_t l_preamble = 0;
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
- // Current index
- const auto l_port_num = index(l_mca);
-
-
- FAPI_TRY (vpd_mt_preamble (l_mca, l_preamble) );
-
- //get the first nibble as according to vpd. 4-7 is read, 0-3 for write
- l_preamble = l_preamble & 0x0F;
-
- FAPI_ASSERT( ((l_preamble == 0) || (l_preamble == 1)),
- fapi2::MSS_INVALID_VPD_MT_PREAMBLE()
- .set_VALUE(l_preamble)
- .set_DIMM_TARGET(i_target),
- "Target %s VPD_MT_PREAMBLE is invalid (not 1 or 0), value is %d",
- mss::c_str(i_target),
- l_preamble );
-
- // Using an if branch because a ternary conditional wasn't working with params for find_value_from_key
- if (l_preamble == 0)
- {
- FAPI_TRY( mss::find_value_from_key( CWL_TABLE_1,
- iv_freq, l_cwl),
- "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
- iv_freq,
- l_preamble);
- }
- else
- {
- FAPI_TRY( mss::find_value_from_key( CWL_TABLE_2,
- iv_freq, l_cwl),
- "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
- iv_freq,
- l_preamble);
-
- }
-
- FAPI_TRY( eff_dram_cwl(l_mcs, l_attrs_cwl.data()) );
- l_attrs_cwl[l_port_num] = l_cwl;
-
- FAPI_INF("Calculated CAS Write Latency is %d", l_cwl);
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_CWL,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_cwl, PORTS_PER_MCS)),
- "Failed setting attribute for cwl");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for lpasr
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note from JEDEC DDR4 DRAM MR2 page 26
-/// @note All DDR4 supports auto refresh, setting to default
-///
-fapi2::ReturnCode eff_config::dram_lpasr(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_lpasr(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_dram_lpasr(l_mcs, l_attrs_lpasr.data()) );
-
- l_attrs_lpasr[l_port_num] = fapi2::ENUM_ATTR_EFF_DRAM_LPASR_MANUAL_EXTENDED;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_LPASR,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_lpasr, PORTS_PER_MCS)),
- "Failed setting attribute for LPASR");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for additive latency
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::additive_latency(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_dram_al(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_dram_al(l_mcs, l_attrs_dram_al.data()) );
-
- l_attrs_dram_al[l_port_num] = fapi2::ENUM_ATTR_EFF_DRAM_AL_DISABLE;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_AL,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_al, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_AL");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DLL Reset
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dll_reset(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint8_t l_attrs_dll_reset[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- FAPI_TRY( eff_dram_dll_reset(l_mcs, &l_attrs_dll_reset[0][0]) );
-
- // Default is to reset DLLs during IPL.
- l_attrs_dll_reset[l_port_num][l_dimm_num] = fapi2::ENUM_ATTR_EFF_DRAM_DLL_RESET_YES;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DLL_RESET, l_mcs, l_attrs_dll_reset),
- "Failed setting attribute for BL");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for DLL Enable
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dll_enable(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- uint8_t l_attrs_dll_enable[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
- const auto l_dimm_num = index(i_target);
-
- FAPI_TRY( eff_dram_dll_enable(l_mcs, &l_attrs_dll_enable[0][0]) );
-
- // Enable DLLs by default.
- l_attrs_dll_enable[l_port_num][l_dimm_num] = fapi2::ENUM_ATTR_EFF_DRAM_DLL_ENABLE_YES;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DLL_ENABLE, l_mcs, l_attrs_dll_enable),
- "Failed setting attribute for BL");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for Write Level Enable
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::write_level_enable(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_wr_lvl_enable(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_dram_wr_lvl_enable(l_mcs, l_attrs_wr_lvl_enable.data()) );
-
- l_attrs_wr_lvl_enable[l_port_num] = fapi2::ENUM_ATTR_EFF_DRAM_WR_LVL_ENABLE_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_WR_LVL_ENABLE,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_wr_lvl_enable, PORTS_PER_MCS)),
- "Failed setting attribute for WR_LVL_ENABLE");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for Output Buffer
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::output_buffer(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_output_buffer(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_dram_output_buffer(l_mcs, l_attrs_output_buffer.data()) );
-
- l_attrs_output_buffer[l_port_num] = fapi2::ENUM_ATTR_EFF_DRAM_OUTPUT_BUFFER_ENABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_OUTPUT_BUFFER,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_output_buffer, PORTS_PER_MCS)),
- "Failed setting attribute for OUTPUT_BUFFER");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for Vref DQ Train Value
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::vref_dq_train_value(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
-
- uint8_t l_attrs_vref_dq_train_val[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
- std::vector< uint64_t > l_ranks;
-
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- //value to set.
- fapi2::buffer<uint8_t> l_vpd_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(i_target, l_vpd_value));
- l_vpd_value.extractToRight<VPD_TRAIN_VALUE_START, VPD_TRAIN_VALUE_LEN>(l_train_value);
-
- FAPI_ASSERT(l_train_value <= JEDEC_MAX_TRAIN_VALUE,
- fapi2::MSS_INVALID_VPD_VREF_DRAM_WR_RANGE()
- .set_MAX(JEDEC_MAX_TRAIN_VALUE)
- .set_VALUE(l_train_value)
- .set_DIMM_TARGET(i_target),
- "%s VPD DRAM VREF value out of range max 0x%02x value 0x%02x", mss::c_str(i_target),
- JEDEC_MAX_TRAIN_VALUE, l_train_value );
-
- // Attribute to set num dimm ranks is a pre-requisite
- FAPI_TRY( eff_vref_dq_train_value(l_mcs, &l_attrs_vref_dq_train_val[0][0][0]) );
- FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
-
- for(const auto& l_rank : l_ranks)
- {
- l_attrs_vref_dq_train_val[l_port_num][l_dimm_num][index(l_rank)] = l_train_value;
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_VALUE, l_mcs, l_attrs_vref_dq_train_val),
- "Failed setting attribute for ATTR_EFF_VREF_DQ_TRAIN_VALUE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for Vref DQ Train Enable
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::vref_dq_train_enable(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //Default mode for train enable should be normal operation mode - 0x00
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
-
- uint8_t l_attrs_vref_dq_train_enable[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
- std::vector< uint64_t > l_ranks;
-
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- // Attribute to set num dimm ranks is a pre-requisite
- FAPI_TRY( eff_vref_dq_train_enable(l_mcs, &l_attrs_vref_dq_train_enable[0][0][0]) );
- FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
-
- for(const auto& l_rank : l_ranks)
- {
- l_attrs_vref_dq_train_enable[l_port_num][l_dimm_num][index(l_rank)] = 0x00;
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_ENABLE, l_mcs, l_attrs_vref_dq_train_enable),
- "Failed setting attribute for ATTR_EFF_VREF_DQ_TRAIN_ENABLE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for Vref DQ Train Range
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::vref_dq_train_range(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
-
- // 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;
-
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- //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(i_target, 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(l_mcs, &l_attrs_vref_dq_train_range[0][0][0]) );
- FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
-
- for(const auto& l_rank : l_ranks)
- {
- l_attrs_vref_dq_train_range[l_port_num][l_dimm_num][index(l_rank)] = l_train_range;
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_RANGE, l_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
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::ca_parity_latency(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //TODO: RTC 159554 Update RAS related attributes
- std::vector<uint8_t> l_attrs_ca_parity_latency(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_ca_parity_latency(l_mcs, l_attrs_ca_parity_latency.data()) );
- l_attrs_ca_parity_latency[l_port_num] = fapi2::ENUM_ATTR_EFF_CA_PARITY_LATENCY_DISABLE;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CA_PARITY_LATENCY,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_ca_parity_latency, PORTS_PER_MCS)),
- "Failed setting attribute for CA_PARITY_LATENCY");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for CRC Error Clear
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::crc_error_clear(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //TODO: RTC 159554 Update RAS related attributes
- std::vector<uint8_t> l_attrs_crc_error_clear(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_crc_error_clear(l_mcs, l_attrs_crc_error_clear.data()) );
-
- l_attrs_crc_error_clear[l_port_num] = fapi2::ENUM_ATTR_EFF_CRC_ERROR_CLEAR_CLEAR;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CRC_ERROR_CLEAR,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_crc_error_clear, PORTS_PER_MCS)),
- "Failed setting attribute for CRC_ERROR_CLEAR");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for CA Parity Error Status
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::ca_parity_error_status(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //TODO: RTC 159554 Update RAS related attributes
- std::vector<uint8_t> l_attrs_ca_parity_error_status(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_ca_parity_error_status(l_mcs, l_attrs_ca_parity_error_status.data()) );
-
- l_attrs_ca_parity_error_status[l_port_num] = fapi2::ENUM_ATTR_EFF_CA_PARITY_ERROR_STATUS_CLEAR;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CA_PARITY_ERROR_STATUS,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_ca_parity_error_status, PORTS_PER_MCS)),
- "Failed setting attribute for CA_PARITY_ERROR_STATUS");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for CA Parity
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::ca_parity(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //TODO: RTC 159554 Update RAS related attributes
- std::vector<uint8_t> l_attrs_ca_parity(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_ca_parity(l_mcs, l_attrs_ca_parity.data()) );
-
- l_attrs_ca_parity[l_port_num] = fapi2::ENUM_ATTR_EFF_CA_PARITY_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CA_PARITY,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_ca_parity, PORTS_PER_MCS)),
- "Failed setting attribute for CA_PARITY");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for ODT Input Buffer
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::odt_input_buffer(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- // keeping this value as 0x01, given that we know that that works in sim
- constexpr uint8_t SIM_VALUE = 0x01;
- std::vector<uint8_t> l_attrs_odt_input_buffer(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- //keep simulation to values we know work
- uint8_t is_sim = 0;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), is_sim) );
-
-
- FAPI_TRY( eff_odt_input_buff(l_mcs, l_attrs_odt_input_buffer.data()) );
-
- //sim vs actual hardware value
- l_attrs_odt_input_buffer[l_port_num] = is_sim ? SIM_VALUE : fapi2::ENUM_ATTR_EFF_ODT_INPUT_BUFF_ACTIVATED;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_ODT_INPUT_BUFF,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_odt_input_buffer, PORTS_PER_MCS)),
- "Failed setting attribute for ODT_INPUT_BUFF");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for data_mask
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note Datamask is unnused and not needed because no DBI.
-/// @note Defaulted to 0
-///
-fapi2::ReturnCode eff_config::data_mask(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_data_mask(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_data_mask(l_mcs, l_attrs_data_mask.data()) );
-
- l_attrs_data_mask[l_port_num] = fapi2::ENUM_ATTR_EFF_DATA_MASK_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DATA_MASK,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_data_mask, PORTS_PER_MCS)),
- "Failed setting attribute for DATA_MASK");
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for write_dbi
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note DBI is not supported
-///
-fapi2::ReturnCode eff_config::write_dbi(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_write_dbi(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_write_dbi(l_mcs, l_attrs_write_dbi.data()) );
-
- l_attrs_write_dbi[l_port_num] = fapi2::ENUM_ATTR_EFF_WRITE_DBI_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_WRITE_DBI,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_write_dbi, PORTS_PER_MCS)),
- "Failed setting attribute for WRITE_DBI");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for read_dbi
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note read_dbi is not supported, so set to DISABLED (0)
-/// @note No logic for DBI
-///
-fapi2::ReturnCode eff_config::read_dbi(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
-
- std::vector<uint8_t> l_attrs_read_dbi(PORTS_PER_MCS, 0);
- FAPI_TRY( eff_read_dbi(l_mcs, l_attrs_read_dbi.data()) );
-
- l_attrs_read_dbi[l_port_num] = fapi2::ENUM_ATTR_EFF_READ_DBI_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_READ_DBI,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_read_dbi, PORTS_PER_MCS)),
- "Failed setting attribute for READ_DBI");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for Post Package Repair
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note write_dbi is not supported, so set to DISABLED (0)
-/// @note no logic for DBI
-///
-fapi2::ReturnCode eff_config::post_package_repair(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
-
- uint8_t l_decoder_val = 0;
- uint8_t l_attrs_dram_ppr[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( eff_dram_ppr(l_mcs, &l_attrs_dram_ppr[0][0]) );
- FAPI_TRY( iv_pDecoder->post_package_repair(i_target, l_decoder_val) );
-
- l_attrs_dram_ppr[l_port_num][l_dimm_num] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_PPR, l_mcs, l_attrs_dram_ppr),
- "Failed setting attribute for DRAM_PPR");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for rd_preamble_train
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::read_preamble_train(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
-
- std::vector<uint8_t> l_attrs_rd_preamble_train(PORTS_PER_MCS, 0);
- FAPI_TRY( eff_rd_preamble_train(l_mcs, l_attrs_rd_preamble_train.data()) );
-
- l_attrs_rd_preamble_train[l_port_num] = fapi2::ENUM_ATTR_EFF_RD_PREAMBLE_TRAIN_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_RD_PREAMBLE_TRAIN,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_rd_preamble_train, PORTS_PER_MCS)),
- "Failed setting attribute for RD_PREAMBLE_TRAIN");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for rd_preamble
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::read_preamble(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_rd_preamble(PORTS_PER_MCS, 0);
- uint8_t l_preamble = 0;
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY (vpd_mt_preamble (l_mca, l_preamble) ) ;
- l_preamble = l_preamble & 0xF0;
- l_preamble = l_preamble >> 4;
-
-
- FAPI_ASSERT( ((l_preamble == 0) || (l_preamble == 1)),
- fapi2::MSS_INVALID_VPD_MT_PREAMBLE()
- .set_VALUE(l_preamble)
- .set_DIMM_TARGET(i_target),
- "Target %s VPD_MT_PREAMBLE is invalid (not 1 or 0), value is %d",
- mss::c_str(i_target),
- l_preamble );
-
- FAPI_TRY( eff_rd_preamble(l_mcs, l_attrs_rd_preamble.data()) );
-
- l_attrs_rd_preamble[l_port_num] = l_preamble;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_RD_PREAMBLE,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_rd_preamble, PORTS_PER_MCS)),
- "Failed setting attribute for RD_PREAMBLE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for wr_preamble
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::write_preamble(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_wr_preamble(PORTS_PER_MCS, 0);
- uint8_t l_preamble = 0;
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY (vpd_mt_preamble (l_mca, l_preamble) ) ;
- l_preamble = l_preamble & 0x0F;
- FAPI_INF("WR preamble is %d", l_preamble);
-
- FAPI_ASSERT( ((l_preamble == 0) || (l_preamble == 1)),
- fapi2::MSS_INVALID_VPD_MT_PREAMBLE()
- .set_VALUE(l_preamble)
- .set_DIMM_TARGET(i_target),
- "Target %s VPD_MT_PREAMBLE is invalid (not 1 or 0), value is %d",
- mss::c_str(i_target),
- l_preamble );
-
- FAPI_TRY( eff_wr_preamble(l_mcs, l_attrs_wr_preamble.data()) );
-
- l_attrs_wr_preamble[l_port_num] = l_preamble;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_WR_PREAMBLE,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_wr_preamble, PORTS_PER_MCS)),
- "Failed setting attribute for RD_PREAMBLE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for self_ref_abort
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::self_refresh_abort(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_self_ref_abort(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_self_ref_abort(l_mcs, l_attrs_self_ref_abort.data()) );
-
- l_attrs_self_ref_abort[l_port_num] = fapi2::ENUM_ATTR_EFF_SELF_REF_ABORT_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_SELF_REF_ABORT,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_self_ref_abort, PORTS_PER_MCS)),
- "Failed setting attribute for SELF_REF_ABORT");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for cs_cmd_latency
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::cs_to_cmd_addr_latency(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_cs_cmd_latency(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_cs_cmd_latency(l_mcs, l_attrs_cs_cmd_latency.data()) );
-
- l_attrs_cs_cmd_latency[l_port_num] = fapi2::ENUM_ATTR_EFF_CS_CMD_LATENCY_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CS_CMD_LATENCY,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_cs_cmd_latency, PORTS_PER_MCS)),
- "Failed setting attribute for CS_CMD_LATENCY");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for int_vref_mon
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::internal_vref_monitor(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_int_vref_mon(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_internal_vref_monitor(l_mcs, l_attrs_int_vref_mon.data()) );
-
- l_attrs_int_vref_mon[l_port_num] = fapi2::ENUM_ATTR_EFF_INTERNAL_VREF_MONITOR_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_INTERNAL_VREF_MONITOR,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_int_vref_mon, PORTS_PER_MCS)),
- "Failed setting attribute for INT_VREF_MON");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for powerdown_mode
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::max_powerdown_mode(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_powerdown_mode(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_max_powerdown_mode(l_mcs, l_attrs_powerdown_mode.data()) );
-
- l_attrs_powerdown_mode[l_port_num] = fapi2::ENUM_ATTR_EFF_MAX_POWERDOWN_MODE_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MAX_POWERDOWN_MODE,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_powerdown_mode, PORTS_PER_MCS)),
- "Failed setting attribute for POWERDOWN_MODE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for mpr_rd_format
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::mpr_read_format(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_mpr_rd_format(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_mpr_rd_format(l_mcs, l_attrs_mpr_rd_format.data()) );
-
- //Serial format is standard for Nimbus and needed for PHY calibration (draminit_training)
- l_attrs_mpr_rd_format[l_port_num] = fapi2::ENUM_ATTR_EFF_MPR_RD_FORMAT_SERIAL;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MPR_RD_FORMAT,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_mpr_rd_format, PORTS_PER_MCS)),
- "Failed setting attribute for MPR_RD_FORMAT");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for CRC write latency
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::crc_wr_latency(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_crc_wr_latency(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- //keep simulation to values we know work
- uint8_t is_sim = 0;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), is_sim) );
-
- FAPI_TRY( eff_crc_wr_latency(l_mcs, l_attrs_crc_wr_latency.data()) );
-
- //keep simulation to values we know work
- if(is_sim)
- {
- l_attrs_crc_wr_latency[l_port_num] = 0x05;
- }
- //set the attribute according to frequency
- else
- {
- //TODO RTC:159481 - update CRC write latency to include 2667
- //currently, JEDEC defines the following
- //crc wr latency - freq
- //4 - 1600
- //5 - 1866, 2133, 2400
- //6 - TBD
- //Nimbus only supports 1866->2400 on the current list
- //2667 is not noted. We will set crc_wr_latency to 0x05 until JEDEC value is updated
- //When JEDEC defines the 2667 value we can change this, but leave the sim value as 0x05
- l_attrs_crc_wr_latency[l_port_num] = 0x05;
- }
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_CRC_WR_LATENCY,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_crc_wr_latency, PORTS_PER_MCS)),
- "Failed setting attribute for CRC WRITE LATENCY");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for temperature readout
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::temp_readout(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_temp_readout(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_temp_readout(l_mcs, l_attrs_temp_readout.data()) );
-
- //Disabled for mainline mode
- l_attrs_temp_readout[l_port_num] = fapi2::ENUM_ATTR_EFF_TEMP_READOUT_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_TEMP_READOUT,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_temp_readout, PORTS_PER_MCS)),
- "Failed setting attribute for TEMP_READOUT");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for per DRAM addressability
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::per_dram_addressability(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_per_dram_access(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_per_dram_access(l_mcs, l_attrs_per_dram_access.data()) );
-
- //PDA is disabled in mainline functionality
- l_attrs_per_dram_access[l_port_num] = fapi2::ENUM_ATTR_EFF_PER_DRAM_ACCESS_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_PER_DRAM_ACCESS,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_per_dram_access, PORTS_PER_MCS)),
- "Failed setting attribute for PER_DRAM_ACCESS");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for geardown mode
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::geardown_mode(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_geardown_mode(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- // Geardown maps directly to autoset = 0 gets 1/2 rate, 1 get 1/4 rate.
- FAPI_TRY( eff_geardown_mode(l_mcs, l_attrs_geardown_mode.data()) );
-
- // If the MRW states 'auto' we use what's in VPD, otherwise we use what's in the MRW.
- // We remove 1 from the value as that matches the expectations in the MR perfectly.
- l_attrs_geardown_mode[l_port_num] = mss::two_n_mode_helper(i_target);
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_GEARDOWN_MODE,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_geardown_mode, PORTS_PER_MCS)),
- "Failed setting attribute for GEARDOWN_MODE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for MPR page
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::mpr_page(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_mpr_page(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_mpr_page(l_mcs, l_attrs_mpr_page.data()) );
-
- //page0 is needed for PHY calibration algorithm (run in draminit_training)
- l_attrs_mpr_page[l_port_num] = fapi2::ENUM_ATTR_EFF_MPR_PAGE_PG0;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MPR_PAGE,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_mpr_page, PORTS_PER_MCS)),
- "Failed setting attribute for MPR_PAGE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for MPR mode
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::mpr_mode(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint8_t> l_attrs_mpr_mode(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_mpr_mode(l_mcs, l_attrs_mpr_mode.data()) );
-
- //MPR mode is disabled for mainline functionality
- l_attrs_mpr_mode[l_port_num] = fapi2::ENUM_ATTR_EFF_MPR_MODE_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MPR_MODE,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_mpr_mode, PORTS_PER_MCS)),
- "Failed setting attribute for MPR_MODE");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for write CRC
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::write_crc(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- //TODO: RTC 159554 Update RAS related attributes
- std::vector<uint8_t> l_attrs_write_crc(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_write_crc(l_mcs, l_attrs_write_crc.data()) );
-
- l_attrs_write_crc[l_port_num] = fapi2::ENUM_ATTR_EFF_WRITE_CRC_DISABLE;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_WRITE_CRC,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_write_crc, PORTS_PER_MCS)),
- "Failed setting attribute for WRITE_CRC");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for ZQ Calibration
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::zqcal_interval(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint32_t> l_attrs_zqcal_interval(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_zqcal_interval(l_mcs, l_attrs_zqcal_interval.data()) );
-
- // Calculate ZQCAL Interval based on the following equation from Ken:
- // 0.5
- // ------------------------------ = 13.333ms
- // (1.5 * 10) + (0.15 * 150)
- // (13333 * ATTR_MSS_FREQ) / 2
-
- l_attrs_zqcal_interval[l_port_num] = 13333 * iv_freq / 2;
-
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_ZQCAL_INTERVAL,
- l_mcs,
- UINT32_VECTOR_TO_1D_ARRAY(l_attrs_zqcal_interval, PORTS_PER_MCS)),
- "Failed setting attribute for ZQCAL_INTERVAL");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for MEMCAL Calibration
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::memcal_interval(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- std::vector<uint32_t> l_attrs_memcal_interval(PORTS_PER_MCS, 0);
-
- // Targets
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- // Current index
- const auto l_port_num = index(l_mca);
-
- FAPI_TRY( eff_memcal_interval(l_mcs, l_attrs_memcal_interval.data()) );
-
- // Calculate MEMCAL Interval based on 1sec interval across all bits per DP16
- // (62500 * ATTR_MSS_FREQ) / 2
- l_attrs_memcal_interval[l_port_num] = 62500 * iv_freq / 2;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_MEMCAL_INTERVAL,
- l_mcs,
- UINT32_VECTOR_TO_1D_ARRAY(l_attrs_memcal_interval, PORTS_PER_MCS)),
- "Failed setting attribute for MEMCAL_INTERVAL");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRP
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trp(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- int64_t l_trp_in_ps = 0;
-
- // Calculate tRP (in ps)
- {
- int64_t l_trp_mtb = 0;
- int64_t l_trp_ftb = 0;
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb),
- "Failed medium_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb),
- "Failed fine_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->min_row_precharge_delay_time(i_target, l_trp_mtb),
- "Failed min_row_precharge_delay_time() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trp(i_target, l_trp_ftb),
- "Failed fine_offset_min_trp() for %s", mss::c_str(i_target) );
-
- FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tRP (MTB): %ld, tRP(FTB): %ld",
- l_mtb, l_ftb, l_trp_mtb, l_trp_ftb);
-
- l_trp_in_ps = spd::calc_timing_from_timebase(l_trp_mtb, l_mtb, l_trp_ftb, l_ftb);
- }
-
- // SPD spec gives us the minimum... compute our worstcase (maximum) from JEDEC
- {
- // Declaring as int64_t to fix std::max compile
- const int64_t l_trp = mss::ps_to_cycles(i_target, mss::trtp());
- l_trp_in_ps = std::max( l_trp_in_ps , l_trp );
- }
-
- {
- std::vector<uint8_t> l_attrs_dram_trp(PORTS_PER_MCS, 0);
- uint8_t l_trp_in_nck = 0;
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_trp_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trp_in_nck),
- "Error in calculating dram_tRP nck for target %s, with value of l_trp_in_ps: %d", mss::c_str(i_target), l_trp_in_ps);
-
- FAPI_INF( "tCK (ps): %d, tRP (ps): %d, tRP (nck): %d for target: %s",
- iv_tCK_in_ps, l_trp_in_ps, l_trp_in_nck, mss::c_str(i_target) );
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_trp(l_mcs, l_attrs_dram_trp.data()) );
-
- l_attrs_dram_trp[l_port_num] = l_trp_in_nck ;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRP,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trp, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TRP");
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRCD
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trcd(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
- int64_t l_trcd_in_ps = 0;
-
- // Calculate tRCD (in ps)
- // Get the tRCD timing values
- // tRCD is speed bin dependent and has a unique
- // value for each speed bin so it is safe to
- // read from SPD because the correct nck
- // value will be calulated based on our dimm speed.
- {
- int64_t l_trcd_mtb = 0;
- int64_t l_trcd_ftb = 0;
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb),
- "Failed medium_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb),
- "Failed fine_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->min_ras_to_cas_delay_time(i_target, l_trcd_mtb),
- "Failed min_ras_to_cas_delay_time() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trcd(i_target, l_trcd_ftb),
- "Failed fine_offset_min_trcd() for %s", mss::c_str(i_target) );
-
- FAPI_INF("medium timebase MTB (ps): %ld, fine timebase FTB (ps): %ld, tRCD (MTB): %ld, tRCD (FTB): %ld",
- l_mtb, l_ftb, l_trcd_mtb, l_trcd_ftb);
-
- l_trcd_in_ps = spd::calc_timing_from_timebase(l_trcd_mtb, l_mtb, l_trcd_ftb, l_ftb);
- }
-
- {
- std::vector<uint8_t> l_attrs_dram_trcd(PORTS_PER_MCS, 0);
- uint8_t l_trcd_in_nck = 0;
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_trcd_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trcd_in_nck),
- "Error in calculating trcd for target %s, with value of l_trcd_in_ps: %d", mss::c_str(i_target), l_trcd_in_ps);
-
- FAPI_INF("tCK (ps): %d, tRCD (ps): %d, tRCD (nck): %d for target: %s",
- iv_tCK_in_ps, l_trcd_in_ps, l_trcd_in_nck, mss::c_str(i_target));
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_trcd(l_mcs, l_attrs_dram_trcd.data()) );
-
- l_attrs_dram_trcd[l_port_num] = l_trcd_in_nck;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRCD,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trcd, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TRCD");
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRC
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trc(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
- int64_t l_trc_in_ps = 0;
-
- // Calculate trc (in ps)
- {
- int64_t l_trc_mtb = 0;
- int64_t l_trc_ftb = 0;
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb),
- "Failed medium_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb),
- "Failed fine_timebase() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->min_active_to_active_refresh_delay_time(i_target, l_trc_mtb),
- "Failed min_active_to_active_refresh_delay_time() for %s", mss::c_str(i_target) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trc(i_target, l_trc_ftb),
- "Failed fine_offset_min_trc() for %s", mss::c_str(i_target) );
-
- FAPI_INF("medium timebase MTB (ps): %ld, fine timebase FTB (ps): %ld, tRCmin (MTB): %ld, tRCmin(FTB): %ld",
- l_mtb, l_ftb, l_trc_mtb, l_trc_ftb);
-
- l_trc_in_ps = spd::calc_timing_from_timebase(l_trc_mtb, l_mtb, l_trc_ftb, l_ftb);
- }
-
- {
- std::vector<uint8_t> l_attrs_dram_trc(PORTS_PER_MCS, 0);
- uint8_t l_trc_in_nck = 0;
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_trc_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trc_in_nck),
- "Error in calculating trc for target %s, with value of l_trc_in_ps: %d",
- mss::c_str(i_target), l_trc_in_ps );
-
- FAPI_INF( "tCK (ps): %d, tRC (ps): %d, tRC (nck): %d for target: %s",
- iv_tCK_in_ps, l_trc_in_ps, l_trc_in_nck, mss::c_str(i_target) );
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_trc(l_mcs, l_attrs_dram_trc.data()) );
-
- l_attrs_dram_trc[l_port_num] = l_trc_in_nck;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRC,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trc, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TRC");
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tWTR_L
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_twtr_l(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
- int64_t l_twtr_l_in_ps = 0;
-
- // Calculate twtr_l (in ps)
- {
- constexpr int64_t l_twtr_l_ftb = 0;
- int64_t l_twtr_l_mtb = 0;
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb) );
- FAPI_TRY( iv_pDecoder->min_twtr_l(i_target, l_twtr_l_mtb) );
-
- FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tWTR_S (MTB): %ld, tWTR_S (FTB): %ld",
- l_mtb, l_ftb, l_twtr_l_mtb, l_twtr_l_ftb );
-
- l_twtr_l_in_ps = spd::calc_timing_from_timebase(l_twtr_l_mtb, l_mtb, l_twtr_l_ftb, l_ftb);
- }
-
-
- {
- std::vector<uint8_t> l_attrs_dram_twtr_l(PORTS_PER_MCS, 0);
- int8_t l_twtr_l_in_nck = 0;
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_twtr_l_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_l_in_nck),
- "Error in calculating tWTR_L for target %s, with value of l_twtr_in_ps: %d", mss::c_str(i_target), l_twtr_l_in_ps );
-
- FAPI_INF( "tCK (ps): %d, tWTR_L (ps): %d, tWTR_L (nck): %d for target: %s",
- iv_tCK_in_ps, l_twtr_l_in_ps, l_twtr_l_in_nck, mss::c_str(i_target) );
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_twtr_l(l_mcs, l_attrs_dram_twtr_l.data()) );
-
- l_attrs_dram_twtr_l[l_port_num] = l_twtr_l_in_nck;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TWTR_L,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_twtr_l, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TWTR_L");
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tWTR_S
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_twtr_s(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
- int64_t l_twtr_s_in_ps = 0;
-
- // Calculate twtr_s (in ps)
- {
- constexpr int64_t l_twtr_s_ftb = 0;
- int64_t l_twtr_s_mtb = 0;
- int64_t l_ftb = 0;
- int64_t l_mtb = 0;
-
- FAPI_TRY( iv_pDecoder->medium_timebase(i_target, l_mtb) );
- FAPI_TRY( iv_pDecoder->fine_timebase(i_target, l_ftb) );
- FAPI_TRY( iv_pDecoder->min_twtr_s(i_target, l_twtr_s_mtb) );
-
- FAPI_INF("medium timebase (ps): %ld, fine timebase (ps): %ld, tWTR_S (MTB): %ld, tWTR_S (FTB): %ld",
- l_mtb, l_ftb, l_twtr_s_mtb, l_twtr_s_ftb );
-
- l_twtr_s_in_ps = spd::calc_timing_from_timebase(l_twtr_s_mtb, l_mtb, l_twtr_s_ftb, l_ftb);
- }
-
- {
- std::vector<uint8_t> l_attrs_dram_twtr_s(PORTS_PER_MCS, 0);
- uint8_t l_twtr_s_in_nck = 0;
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_twtr_s_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_s_in_nck),
- "Error in calculating tWTR_S for target %s, with value of l_twtr_in_ps: %d", mss::c_str(i_target), l_twtr_s_in_ps);
-
- FAPI_INF("tCK (ps): %d, tWTR_S (ps): %d, tWTR_S (nck): %d for target: %s",
- iv_tCK_in_ps, l_twtr_s_in_ps, l_twtr_s_in_nck, mss::c_str(i_target) );
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_twtr_s(l_mcs, l_attrs_dram_twtr_s.data()) );
-
- l_attrs_dram_twtr_s[l_port_num] = l_twtr_s_in_nck;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TWTR_S,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_twtr_s, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TWTR_S");
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRRD_S
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trrd_s(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- std::vector<uint8_t> l_attrs_dram_trrd_s(PORTS_PER_MCS, 0);
- uint64_t l_trrd_s_in_nck = 0;
- uint8_t l_stack_type = 0;
- uint8_t l_dram_width = 0;
-
- FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(i_target, l_stack_type) );
- FAPI_TRY( iv_pDecoder->device_width(i_target, l_dram_width),
- "Failed to access device_width()");
-
- // From the SPD Spec:
- // At some frequencies, a minimum number of clocks may be required resulting
- // in a larger tRRD_Smin value than indicated in the SPD.
- // tRRD_S (3DS) is speed bin independent.
- // So we won't read this from SPD and choose the correct value based on mss_freq
-
- if( l_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS)
- {
- FAPI_TRY( trrd_s_slr(i_target, l_trrd_s_in_nck) );
- }
- else
- {
- // Non-3DS
- FAPI_TRY( mss::trrd_s(i_target, l_dram_width, l_trrd_s_in_nck) );
- }
-
- FAPI_INF("SDRAM width: %d, tRRD_S (nck): %d for target: %s",
- l_dram_width, l_trrd_s_in_nck, mss::c_str(i_target));
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_trrd_s(l_mcs, l_attrs_dram_trrd_s.data()) );
-
- l_attrs_dram_trrd_s[l_port_num] = l_trrd_s_in_nck;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRRD_S,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trrd_s, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TRRD_S");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRRD_L
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trrd_l(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- std::vector<uint8_t> l_attrs_dram_trrd_l(PORTS_PER_MCS, 0);
- uint64_t l_trrd_l_in_nck = 0;
- uint8_t l_stack_type = 0;
- uint8_t l_dram_width = 0;
-
- FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(i_target, l_stack_type),
- "Failed prim_sdram_signal_loading()" );
- FAPI_TRY( iv_pDecoder->device_width(i_target, l_dram_width),
- "Failed to access device_width()");
-
- // From the SPD Spec:
- // At some frequencies, a minimum number of clocks may be required resulting
- // in a larger tRRD_Smin value than indicated in the SPD.
- // tRRD_S (3DS) is speed bin independent.
- // So we won't read this from SPD and choose the correct value based on mss_freq
-
- if( l_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS)
- {
- FAPI_TRY( trrd_l_slr(i_target, l_trrd_l_in_nck) );
- }
- else
- {
- FAPI_TRY( mss::trrd_l(i_target, l_dram_width, l_trrd_l_in_nck), "Failed trrd_l()" );
- }
-
- FAPI_INF("SDRAM width: %d, tRRD_L (nck): %d for target: %s",
- l_dram_width, l_trrd_l_in_nck, mss::c_str(i_target));
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_trrd_l(l_mcs, l_attrs_dram_trrd_l.data()) );
-
- l_attrs_dram_trrd_l[l_port_num] = l_trrd_l_in_nck;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRRD_L,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trrd_l, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TRRD_L");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRRD_dlr
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trrd_dlr(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- std::vector<uint8_t> l_attrs_dram_trrd_dlr(PORTS_PER_MCS, 0);
- constexpr uint64_t l_trrd_dlr_in_nck = trrd_dlr();
-
- FAPI_INF("tRRD_dlr (nck): %d for target: %s", l_trrd_dlr_in_nck, mss::c_str(i_target));
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_trrd_dlr(l_mcs, l_attrs_dram_trrd_dlr.data()) );
-
- l_attrs_dram_trrd_dlr[l_port_num] = l_trrd_dlr_in_nck;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRRD_DLR,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trrd_dlr, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TRRD_DLR");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tfaw
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_tfaw(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- std::vector<uint8_t> l_attrs_dram_tfaw(PORTS_PER_MCS, 0);
- uint64_t l_tfaw_in_nck = 0;
- uint8_t l_stack_type = 0;
- uint8_t l_dram_width = 0;
-
- FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(i_target, l_stack_type),
- "Failed prim_sdram_signal_loading()");
- FAPI_TRY( iv_pDecoder->device_width(i_target, l_dram_width),
- "Failed device_width()");
-
- if( l_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS)
- {
- FAPI_TRY( tfaw_slr(i_target, l_dram_width, l_tfaw_in_nck), "Failed tfaw_slr()");
- }
- else
- {
- FAPI_TRY( mss::tfaw(i_target, l_dram_width, l_tfaw_in_nck), "Failed tfaw()" );
- }
-
- FAPI_INF("SDRAM width: %d, tFAW (nck): %d for target: %s",
- l_dram_width, l_tfaw_in_nck, mss::c_str(i_target));
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_tfaw(l_mcs, l_attrs_dram_tfaw.data()) );
-
- l_attrs_dram_tfaw[l_port_num] = l_tfaw_in_nck;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TFAW,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_tfaw, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TFAW");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tFAW_DLR
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_tfaw_dlr(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- std::vector<uint8_t> l_attrs_dram_tfaw_dlr(PORTS_PER_MCS, 0);
- constexpr uint64_t l_tfaw_dlr_in_nck = tfaw_dlr();
-
- FAPI_INF("tFAW_dlr (nck): %d for target: %s", l_tfaw_dlr_in_nck, mss::c_str(i_target));
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_tfaw_dlr(l_mcs, l_attrs_dram_tfaw_dlr.data()) );
-
- l_attrs_dram_tfaw_dlr[l_port_num] = l_tfaw_dlr_in_nck;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TFAW_DLR,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_tfaw_dlr, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TFAW_DLR");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRAS
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_tras(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- // tRAS is bin independent so we don't read this from SPD
- // which will give the best timing value for the dimm
- // (like 2400 MT/s) which may be different than the system
- // speed (if we were being limited by VPD or MRW restrictions)
- const uint64_t l_tras_in_ps = mss::tras(i_target);
-
- // Calculate nck
- std::vector<uint8_t> l_attrs_dram_tras(PORTS_PER_MCS, 0);
- uint8_t l_tras_in_nck = 0;
-
- // Cast needed for calculations to be done on the same integral type
- // as required by template deduction. We have iv_tCK_in_ps as a signed
- // integer because we have other timing values that calculations do
- // addition with negative integers.
- FAPI_TRY( spd::calc_nck(l_tras_in_ps,
- static_cast<uint64_t>(iv_tCK_in_ps),
- INVERSE_DDR4_CORRECTION_FACTOR,
- l_tras_in_nck),
- "Error in calculating tras_l for target %s, with value of l_twtr_in_ps: %d",
- mss::c_str(i_target), l_tras_in_ps);
-
- FAPI_INF("tCK (ps): %d, tRAS (ps): %d, tRAS (nck): %d for target: %s",
- iv_tCK_in_ps, l_tras_in_ps, l_tras_in_nck, mss::c_str(i_target));
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_tras(l_mcs, l_attrs_dram_tras.data()) );
-
- l_attrs_dram_tras[l_port_num] = l_tras_in_nck;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRAS,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_tras, PORTS_PER_MCS)),
- "Failed setting attribute for tRAS");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for tRTP
-/// @param[in] i_target FAPI2 target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::dram_trtp(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_port_num = index(find_target<TARGET_TYPE_MCA>(i_target));
-
- // Values from proposed DDR4 Full spec update(79-4A)
- // Item No. 1716.78C
- // Page 241 & 246
- int64_t constexpr l_max_trtp_in_ps = trtp();
-
- std::vector<uint8_t> l_attrs_dram_trtp(PORTS_PER_MCS, 0);
- uint8_t l_calc_trtp_in_nck = 0;
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_max_trtp_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_calc_trtp_in_nck),
- "Error in calculating trtp for target %s, with value of l_twtr_in_ps: %d",
- mss::c_str(i_target), l_max_trtp_in_ps);
-
- FAPI_INF("tCK (ps): %d, tRTP (ps): %d, tRTP (nck): %d",
- iv_tCK_in_ps, l_max_trtp_in_ps, l_calc_trtp_in_nck);
-
- // Get & update MCS attribute
- FAPI_TRY( eff_dram_trtp(l_mcs, l_attrs_dram_trtp.data()) );
-
- l_attrs_dram_trtp[l_port_num] = l_calc_trtp_in_nck;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TRTP,
- l_mcs,
- UINT8_VECTOR_TO_1D_ARRAY(l_attrs_dram_trtp, PORTS_PER_MCS)),
- "Failed setting attribute for DRAM_TRTP");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Grab the VPD blobs and decode into attributes
-/// @param[in] i_target FAPI2 target (MCS)
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode eff_config::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_target)
-{
- uint8_t l_mr_blob[mss::VPD_KEYWORD_MAX] = {0};
- uint8_t l_cke_blob[mss::VPD_KEYWORD_MAX] = {0};
- uint8_t l_dq_blob[mss::VPD_KEYWORD_MAX] = {0};
-
- std::vector<uint8_t*> l_mt_blobs(PORTS_PER_MCS, nullptr);
- fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_vpd_info(fapi2::MemVpdData::MT);
-
- // For sanity. Not sure this will break us, but we're certainly making assumptions below.
- static_assert(MAX_DIMM_PER_PORT == 2, "Max DIMM per port isn't 2");
-
- // We need to set up all VPD info before calling getVPD, the API assumes this
- // For MR we need to tell the VPDInfo the frequency (err ... mt/s - why is this mhz?)
- l_vpd_info.iv_freq_mhz = iv_freq;
- FAPI_INF("%s. VPD info - dimm data rate: %d MT/s", mss::c_str(i_target), l_vpd_info.iv_freq_mhz);
-
- // Make sure to create 0 filled blobs for all the possible blobs, not just for the
- // chiplets which are configured. This prevents the decoder from accessing nullptrs
- // but the code which uses the VPD will only access the information for the chiplets
- // which exist - so the 0's are meaningless
- for (auto& b : l_mt_blobs)
- {
- b = new uint8_t[mss::VPD_KEYWORD_MAX];
- memset(b, 0, mss::VPD_KEYWORD_MAX);
- }
-
- // For MT we need to fill in the rank information
- // But, of course, the rank information can differ per port. However, the vpd interface doesn't
- // allow this in a straight-forward way. So, we have to get VPD blobs for MCS which contain
- // ports which have the rank configuration in question. This means, basically, we pass a MCS MT
- // blob to the decoder for each MCA, regardless of whether the port configurations are the same.
- for (const auto& p : find_targets<TARGET_TYPE_MCA>(i_target))
- {
- // 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] = {0};
-
- // 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.
- 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];
-
- 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);
-
- // Get the MCS blob for this specific rank combination *only if* we have DIMM. Remember,
- // Cronus can give us functional MCA which have no DIMM - and we'd puke getting the VPD.
- if ((l_vpd_info.iv_rank_count_dimm_0 != 0) || (l_vpd_info.iv_rank_count_dimm_1 != 0))
- {
- // If getVPD returns us an error, then we don't have VPD for the DIMM configuration.
- // This is the root of our plug-rules: if you want a configuration of DIMM to be
- // supported, it needs to have VPD defined. Likewise, if you don't want a configuration
- // of DIMM supported be sure to leave it out of the VPD. Note that we don't return a specific
- // plug-rule error as f/w (Dan) suggested this would duplicate errors leading to confusion.
- l_vpd_info.iv_vpd_type = fapi2::MemVpdData::MT;
-
- // Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
- "Failed to retrieve MT size from VPD");
-
- if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
- {
- FAPI_ERR("VPD MT keyword is too big for our array");
- fapi2::Assert(false);
- }
-
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_mt_blob[0])),
- "Failed to retrieve MT VPD");
- }
- }// mca
-
- // Only get the MR blob if we have a freq. It's possible for Cronus to give us an MCS which
- // is connected to a controller which has 0 DIMM installed. In this case, we won't have
- // a frequency, and thus we'd fail getting the VPD. So we initiaized the VPD to 0's and if
- // there's no freq, we us a 0 filled VPD.
- if (l_vpd_info.iv_freq_mhz != 0)
- {
- l_vpd_info.iv_vpd_type = fapi2::MemVpdData::MR;
-
- // Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
- "Failed to retrieve MR size from VPD");
-
- if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
- {
- FAPI_ERR("VPD MR keyword is too big for our array");
- fapi2::Assert(false);
- }
-
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_mr_blob[0])),
- "Failed to retrieve MR VPD");
- }
-
- // Until CK/DQ integration is working, we differentiate getting our fake_vpd for those ids.
- // This gives us an extended API we can use for testing which won't be seen by HB because we'd use this to limit it
-#ifndef __HOSTBOOT_MODULE
-
- // Get CKE data
- l_vpd_info.iv_vpd_type = fapi2::MemVpdData::CK;
-
- // Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
- "Failed to retrieve CK size from VPD");
-
- if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
- {
- FAPI_ERR("VPD CK keyword is too big for our array");
- fapi2::Assert(false);
- }
-
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_cke_blob[0])),
- "Failed to retrieve DQ VPD");
-
- // Get DQ data
- l_vpd_info.iv_vpd_type = fapi2::MemVpdData::DQ;
-
- // Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
- "Failed to retrieve DQ size from VPD");
-
- if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
- {
- FAPI_ERR("VPD DQ keyword is too big for our array");
- fapi2::Assert(false);
- }
-
- FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_dq_blob[0])),
- "Failed to retrieve DQ VPD");
-
-#endif
-
- FAPI_TRY( mss::eff_decode(i_target, l_mt_blobs, l_mr_blob, l_cke_blob, l_dq_blob) );
-
-fapi_try_exit:
-
- // delete the mt blobs
- for (auto p : l_mt_blobs)
- {
- if (p != nullptr)
- {
- delete[] p;
- }
- }
-
- return fapi2::current_err;
-}
-
-}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H
deleted file mode 100644
index 47128b68d..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H
+++ /dev/null
@@ -1,825 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-///
-/// @file eff_config.H
-/// @brief Determine effective config for mss settings
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP FW Owner: Brian Silver <bsilver@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 2
-// *HWP Consumed by: HB:FSP
-
-#ifndef _MSS_EFF_CONFIG_H_
-#define _MSS_EFF_CONFIG_H_
-
-// std lib
-#include <cstdint>
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <lib/spd/common/spd_decoder.H>
-
-#include <lib/eff_config/timing.H>
-#include <lib/utils/conversions.H>
-#include <lib/utils/find.H>
-#include <lib/shared/mss_kind.H>
-namespace mss
-{
-
-///
-/// @class eff_config
-/// @brief Determine effective config for mss settings
-///
-class eff_config
-{
- public:
- //TK - Make this constructor take this as param - AAM
- std::shared_ptr<spd::decoder> iv_pDecoder;
- int64_t iv_tCK_in_ps;
- uint64_t iv_freq;
- // Assists testing with write ability on these MRW
- // settings that are normally NOT writable
- // using attribute accessors
- // Could create getters & setters...
- uint8_t iv_refresh_mode;
- uint8_t iv_temp_refresh_range;
-
- ///
- /// @brief Constructor
- /// @param[in] i_target the fapi2::Target which we're configuring (MCS)
- /// @param[out] o_rc a return code which determines the success of the constructor
- ///
- eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, fapi2::ReturnCode& o_rc )
- {
- FAPI_TRY( clock_period(i_target, iv_tCK_in_ps), "Failed to calculate clock period (tCK)" );
- FAPI_TRY( mss::freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), iv_freq));
- FAPI_TRY( mss::mrw_temp_refresh_range(iv_temp_refresh_range), "Failed mrw_temp_refresh_range()" );
- FAPI_TRY( mss::mrw_fine_refresh_mode(iv_refresh_mode), "Failed mrw_fine_refresh_mode()" );
-
- FAPI_INF( "Calculated clock period - tCK (ps): %d for %s", iv_tCK_in_ps, mss::c_str(i_target) );
- FAPI_INF("Calculated frequency: %d on DIMM %s", iv_freq, mss::c_str(i_target));
-
-
- fapi_try_exit:
- o_rc = fapi2::current_err;
- return;
- }
-
- //
- // @brief Destructor
- //
- ~eff_config() = default;
-
- ////////////////////////
- // Methods
- ///////////////////////
-
- ///
- /// @brief Determines & sets effective config for DRAM generation from SPD
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data);
-
- ///
- /// @brief Determines & sets effective config for DIMM type
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data);
-
- ///
- /// @brief Determines & sets effective config for eff_dram_mfg_id type from SPD
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_mfg_id(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for primary stack type
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode primary_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for Hybrid memory type from SPD
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode hybrid_memory_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for refresh interval time (tREFI)
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trefi(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for refresh cycle time (tRFC)
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trfc(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for refresh cycle time (logical ranks) (tRFC_DLR)
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trfc_dlr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for dram density
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_density(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for dram width
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_width(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for the RTT_NOM value from SPD
- /// @tparam kind_t dimm_kind value
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- /// @note used for MRS01
- ///
- template<mss::kind_t>
- fapi2::ReturnCode dram_rtt_nom(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for the RTT_NOM value from SPD
- /// @tparam kind_t dimm_kind value
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- /// @note used for MRS02
- ///
- template<mss::kind_t>
- fapi2::ReturnCode dram_rtt_wr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for the RTT_PARK value from SPD
- /// @tparam kind_t dimm_kind value
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- /// @note used for MRS05
- ///
- template <mss::kind_t>
- fapi2::ReturnCode dram_rtt_park(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for dimm rcd mirror mode
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode rcd_mirror_mode(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for dimm size
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_size(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for dram bank bits
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_bank_bits(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for dram row bits
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_row_bits(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for number of ranks per dimm
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for number of master ranks per dimm
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode master_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tDQS
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_dqs_time(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tCCD_L
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_tccd_l(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC00
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC01
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC02
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC03
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC04
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC05
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC06_07
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc06_07(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC08
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc08(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC09
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc09(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC10
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc10(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC11
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc11(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC12
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc12(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC13
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc13(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC14
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc14(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC15
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc15(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_1x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc1x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_2x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc2x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_3x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc3x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_4x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc4x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_5x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc5x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_6x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc6x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_7x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc7x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_8x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc8x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_9x
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rc9x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_AX
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rcax(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
-
- ///
- /// @brief Determines & sets effective config for DIMM RC_BX
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dimm_rcbx(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tWR
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_twr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for RBT
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode read_burst_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for TM
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_tm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for cwl
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_cwl(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for lpasr
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_lpasr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for additive latency
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode additive_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DLL Reset
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dll_reset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for DLL Enable
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dll_enable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for Write Level Enable
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode write_level_enable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for Output Buffer
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode output_buffer(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
-
- ///
- /// @brief Determines & sets effective config for Vref DQ Train Value
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode vref_dq_train_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for Vref DQ Train Enable
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode vref_dq_train_enable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for Vref DQ Train Range
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode vref_dq_train_range(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for CA Parity Latency
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode ca_parity_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for CA Parity
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode ca_parity(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for CRC Error Clear
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode crc_error_clear(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for CA Parity Error Status
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode ca_parity_error_status(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for ODT Input Buffer
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode odt_input_buffer(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
- ///
- /// @brief Determines & sets effective config for data_mask
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode data_mask(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for write_dbi
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode write_dbi(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for read_dbi
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode read_dbi(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for Post Package Repair
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode post_package_repair(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for rd_preamble_train
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode read_preamble_train(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for rd_preamble
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode read_preamble(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for wr_preamble
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode write_preamble(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for self_ref_abort
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode self_refresh_abort(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for cs_cmd_latency
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode cs_to_cmd_addr_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for int_vref_mon
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode internal_vref_monitor(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for powerdown_mode
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode max_powerdown_mode(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for mpr_rd_format
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode mpr_read_format(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for CRC write latency
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode crc_wr_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for temperature readout
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode temp_readout(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for per DRAM addressability
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode per_dram_addressability(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for geardown mode
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode geardown_mode(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for geardown mode
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode mpr_page(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for MPR mode
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode mpr_mode(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for write CRC
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode write_crc(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for ZQ Calibration
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode zqcal_interval(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for MEMCAL Calibration
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode memcal_interval(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRP
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trp(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRCD
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trcd(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRC
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trc(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tWTR_L
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_twtr_l(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tWTR_S
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_twtr_s(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRRD_S (tRRD_S_slr)
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trrd_s(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRRD_L (or tRRD_L_slr)
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trrd_l(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRRD_DLR
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trrd_dlr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tFAW (or tFAW_slr)
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_tfaw(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tFAW_DLR
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_tfaw_dlr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRAS
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_tras(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Determines & sets effective config for tRTP
- /// @param[in] i_target FAPI2 target
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode dram_trtp(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target);
-
- ///
- /// @brief Grab the VPD blobs and decode into attributes
- /// @param[in] i_target FAPI2 target (MCS)
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
- ///
- fapi2::ReturnCode decode_vpd(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target);
-
- ///
- /// @brief Enforce the plug-rules per MCS
- /// @param[in] i_target FAPI2 target (MCS)
- /// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
- ///
- fapi2::ReturnCode enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target);
-
- ///
- /// @brief Enforce the plug-rules per MCA
- /// @param[in] i_target FAPI2 target (MCA)
- /// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
- ///
- fapi2::ReturnCode enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target);
-
-}; // eff_config
-
-} // mss
-#endif // _MSS_EFF_CONFIG_H_
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
index d0cecee59..6f3e2f6fe 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,9 +38,9 @@
#include <mss.H>
#include <lib/mss_vpd_decoder.H>
-#include <lib/eff_config/eff_config.H>
#include <lib/dimm/rank.H>
#include <lib/utils/assert_noexit.H>
+#include <lib/eff_config/plug_rules.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
@@ -358,7 +358,7 @@ fapi_try_exit:
/// @param[in] i_target FAPI2 target (MCS)
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
///
-fapi2::ReturnCode eff_config::enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target)
+fapi2::ReturnCode plug_rule::enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target)
{
// Check per-MCS plug rules. If those all pass, check each of our MCA
@@ -410,7 +410,7 @@ fapi_try_exit:
/// @param[in] i_target FAPI2 target (MCA)
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
///
-fapi2::ReturnCode eff_config::enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
+fapi2::ReturnCode plug_rule::enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
{
const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
index 928fdcf08..7d0ad15d0 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,6 +46,21 @@ namespace mss
namespace plug_rule
{
+
+///
+/// @brief Enforce the plug-rules per MCS
+/// @param[in] i_target FAPI2 target (MCS)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
+///
+fapi2::ReturnCode enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target);
+
+///
+/// @brief Enforce the plug-rules per MCA
+/// @param[in] i_target FAPI2 target (MCA)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
+///
+fapi2::ReturnCode enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target);
+
///
/// @brief Helper to evaluate the unsupported rank config override attribute
/// @param[in] i_dimm0_ranks count of the ranks on DIMM in slot 0
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
index cd331558c..d53ddb8ef 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
@@ -20266,6 +20266,26 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief ATTR_MSS_MRW_DRAM_WRITE_CRC getter
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generateParameters (SYSTEM)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Enables DRAM Write
+/// CRC
+///
+inline fapi2::ReturnCode mrw_dram_write_crc(uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_DRAM_WRITE_CRC, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MRW_DRAM_WRITE_CRC: 0x%lx (system target)",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
///
/// @brief ATTR_MSS_VPD_MR_0_VERSION_LAYOUT getter
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H
index e8b5716e2..f5d8660ae 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -143,7 +143,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes number of rows of DRAMs on RDIMM
+ /// @brief Decodes register and buffer type for LRDIMMs
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 131 (Bits 7~4)
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
index 316d817b2..d49c277a9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
@@ -44,14 +44,13 @@
// mss lib
#include <lib/spd/common/spd_decoder.H>
#include <lib/spd/spd_factory.H>
-#include <lib/eff_config/eff_config.H>
#include <lib/utils/pos.H>
#include <lib/utils/checker.H>
#include <lib/utils/find.H>
#include <lib/shared/mss_kind.H>
#include <lib/utils/find.H>
-
-
+#include <lib/dimm/eff_dimm.H>
+#include <lib/eff_config/plug_rules.H>
///
/// @brief Configure the attributes for each controller
/// @param[in] i_target the controller (e.g., MCS)
@@ -63,10 +62,6 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
{
fapi2::ReturnCode l_rc;
std::map<uint32_t, std::shared_ptr<mss::spd::decoder> > l_factory_caches;
-
- mss::eff_config l_eff_config(i_target, l_rc);
- FAPI_TRY(l_rc, "Unable to construct eff_config object for for %s", mss::c_str(i_target) );
-
// Caches
FAPI_TRY( mss::spd::populate_decoder_caches(i_target, l_factory_caches) );
@@ -78,16 +73,15 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
{
// Always set VPD attributes unless we enable the SPD_ONLY flag
// Enables skipping VPD decoder when a valid VPD template isn't available
- FAPI_TRY( l_eff_config.decode_vpd(i_target),
+ FAPI_TRY( mss::eff_dimm::decode_vpd(i_target),
"Unable to decode VPD for %s", mss::c_str(i_target) );
}
for( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
{
+ std::shared_ptr<mss::eff_dimm> l_eff_dimm;
+
const auto l_dimm_pos = mss::pos(l_dimm);
- uint8_t l_type = 0;
- uint8_t l_gen = 0;
- uint64_t l_kind = 0;
// TODO RTC:152390 Create function to do map checking on cached values
// Find decoder factory for this dimm position
@@ -98,131 +92,119 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
l_dimm_pos),
"Failed to get valid cache (main decoder)");
- l_eff_config.iv_pDecoder = l_it->second;
-
- // DRAM Gen and DIMM type not needed here since set in spd_factory...
- // but it doesn't hurt to do it twice
- FAPI_TRY( l_eff_config.dimm_type(l_dimm, l_it->second->iv_spd_data) );
- FAPI_TRY( l_eff_config.dram_gen(l_dimm, l_it->second->iv_spd_data) );
-
- FAPI_TRY( l_eff_config.dram_mfg_id(l_dimm) );
- FAPI_TRY( l_eff_config.dram_width(l_dimm) );
- FAPI_TRY( l_eff_config.dram_density(l_dimm) );
- FAPI_TRY( l_eff_config.ranks_per_dimm(l_dimm) );
- FAPI_TRY( l_eff_config.primary_stack_type(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_size(l_dimm) );
- FAPI_TRY( l_eff_config.hybrid_memory_type(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trefi(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trfc(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trfc_dlr(l_dimm) );
- FAPI_TRY( l_eff_config.rcd_mirror_mode(l_dimm) );
- FAPI_TRY( l_eff_config.dram_bank_bits(l_dimm) );
- FAPI_TRY( l_eff_config.dram_row_bits(l_dimm) );
- FAPI_TRY( l_eff_config.dram_dqs_time(l_dimm) );
- FAPI_TRY( l_eff_config.dram_tccd_l(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc00(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc01(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc02(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc03(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc04(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc05(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc06_07(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc08(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc09(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc10(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc11(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc12(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc13(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc14(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc15(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc1x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc2x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc3x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc4x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc5x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc6x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc7x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc8x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rc9x(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rcax(l_dimm) );
- FAPI_TRY( l_eff_config.dimm_rcbx(l_dimm) );
- FAPI_TRY( l_eff_config.dram_twr(l_dimm) );
- FAPI_TRY( l_eff_config.read_burst_type(l_dimm) );
- FAPI_TRY( l_eff_config.dram_tm(l_dimm) );
- FAPI_TRY( l_eff_config.dram_cwl(l_dimm) );
- FAPI_TRY( l_eff_config.dram_lpasr(l_dimm) );
- FAPI_TRY( l_eff_config.dll_enable(l_dimm) );
- FAPI_TRY( l_eff_config.dll_reset(l_dimm) );
- FAPI_TRY( l_eff_config.write_level_enable(l_dimm) );
- FAPI_TRY( l_eff_config.output_buffer(l_dimm) );
- FAPI_TRY( l_eff_config.vref_dq_train_value(l_dimm) );
- FAPI_TRY( l_eff_config.vref_dq_train_range(l_dimm) );
- FAPI_TRY( l_eff_config.vref_dq_train_enable(l_dimm) );
- FAPI_TRY( l_eff_config.ca_parity_latency(l_dimm) );
- FAPI_TRY( l_eff_config.ca_parity_error_status(l_dimm) );
- FAPI_TRY( l_eff_config.ca_parity(l_dimm) );
- FAPI_TRY( l_eff_config.crc_error_clear(l_dimm) );
- FAPI_TRY( l_eff_config.odt_input_buffer(l_dimm) );
- FAPI_TRY( l_eff_config.post_package_repair(l_dimm) );
- FAPI_TRY( l_eff_config.read_preamble_train(l_dimm) );
- FAPI_TRY( l_eff_config.read_preamble(l_dimm) );
- FAPI_TRY( l_eff_config.write_preamble(l_dimm) );
- FAPI_TRY( l_eff_config.self_refresh_abort(l_dimm) );
- FAPI_TRY( l_eff_config.cs_to_cmd_addr_latency(l_dimm) );
- FAPI_TRY( l_eff_config.internal_vref_monitor(l_dimm) );
- FAPI_TRY( l_eff_config.max_powerdown_mode(l_dimm) );
- FAPI_TRY( l_eff_config.mpr_read_format(l_dimm) );
- FAPI_TRY( l_eff_config.temp_readout(l_dimm) );
- FAPI_TRY( l_eff_config.crc_wr_latency(l_dimm) );
- FAPI_TRY( l_eff_config.per_dram_addressability(l_dimm) );
- FAPI_TRY( l_eff_config.geardown_mode(l_dimm) );
- FAPI_TRY( l_eff_config.mpr_page(l_dimm) );
- FAPI_TRY( l_eff_config.mpr_mode(l_dimm) );
- FAPI_TRY( l_eff_config.write_crc(l_dimm) );
- FAPI_TRY( l_eff_config.zqcal_interval(l_dimm) );
- FAPI_TRY( l_eff_config.memcal_interval(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trp(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trcd(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trc(l_dimm) );
- FAPI_TRY( l_eff_config.dram_twtr_l(l_dimm) );
- FAPI_TRY( l_eff_config.dram_twtr_s(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trrd_s(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trrd_l(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trrd_dlr(l_dimm) );
- FAPI_TRY( l_eff_config.dram_tfaw(l_dimm) );
- FAPI_TRY( l_eff_config.dram_tfaw_dlr(l_dimm) );
- FAPI_TRY( l_eff_config.dram_tras(l_dimm) );
- FAPI_TRY( l_eff_config.dram_trtp(l_dimm) );
- FAPI_TRY( l_eff_config.read_dbi(l_dimm) );
- FAPI_TRY( l_eff_config.write_dbi(l_dimm) );
- FAPI_TRY( l_eff_config.additive_latency(l_dimm) );
- FAPI_TRY( l_eff_config.data_mask(l_dimm) );
-
- FAPI_TRY( mss::eff_dram_gen(l_dimm, l_gen) );
- FAPI_TRY( mss::eff_dimm_type(l_dimm, l_type) );
- l_kind = mss::dimm_kind (l_type, l_gen);
-
- //One day we won't need this switch case, we can just specialize the methods via passed in target type
- //Till then, we have a story
- //TODO RTC: 166453
- switch (l_kind)
- {
- case mss::KIND_LRDIMM_DDR4:
- FAPI_TRY( l_eff_config.dram_rtt_nom<mss::KIND_LRDIMM_DDR4>(l_dimm) );
- FAPI_TRY( l_eff_config.dram_rtt_wr<mss::KIND_LRDIMM_DDR4>(l_dimm) );
- FAPI_TRY( l_eff_config.dram_rtt_park<mss::KIND_LRDIMM_DDR4>(l_dimm) );
- break;
-
- case mss::KIND_RDIMM_DDR4:
- FAPI_TRY( l_eff_config.dram_rtt_nom<mss::KIND_RDIMM_DDR4>(l_dimm) );
- FAPI_TRY( l_eff_config.dram_rtt_wr<mss::KIND_RDIMM_DDR4>(l_dimm) );
- FAPI_TRY( l_eff_config.dram_rtt_park<mss::KIND_RDIMM_DDR4>(l_dimm) );
- break;
-
- default:
- FAPI_ERR("Invalid DIMM type and or gen");
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- };
+ FAPI_TRY( mss::eff_dimm::eff_dimm_factory( l_dimm, l_it->second, l_eff_dimm));
+
+ FAPI_TRY( l_eff_dimm->dram_mfg_id() );
+ FAPI_TRY( l_eff_dimm->dram_width() );
+ FAPI_TRY( l_eff_dimm->dram_density() );
+ FAPI_TRY( l_eff_dimm->ranks_per_dimm() );
+ FAPI_TRY( l_eff_dimm->primary_stack_type() );
+ FAPI_TRY( l_eff_dimm->dimm_size() );
+ FAPI_TRY( l_eff_dimm->hybrid_memory_type() );
+ FAPI_TRY( l_eff_dimm->temp_refresh_mode() );
+ FAPI_TRY( l_eff_dimm->dram_trefi() );
+ FAPI_TRY( l_eff_dimm->dram_trfc() );
+ FAPI_TRY( l_eff_dimm->dram_trfc_dlr() );
+ FAPI_TRY( l_eff_dimm->rcd_mirror_mode() );
+ FAPI_TRY( l_eff_dimm->dram_bank_bits() );
+ FAPI_TRY( l_eff_dimm->dram_row_bits() );
+ FAPI_TRY( l_eff_dimm->dram_dqs_time() );
+ FAPI_TRY( l_eff_dimm->dram_tccd_l() );
+ FAPI_TRY( l_eff_dimm->dimm_rc00() );
+ FAPI_TRY( l_eff_dimm->dimm_rc01() );
+ FAPI_TRY( l_eff_dimm->dimm_rc02() );
+ FAPI_TRY( l_eff_dimm->dimm_rc03() );
+ FAPI_TRY( l_eff_dimm->dimm_rc04() );
+ FAPI_TRY( l_eff_dimm->dimm_rc05() );
+ FAPI_TRY( l_eff_dimm->dimm_rc06_07() );
+ FAPI_TRY( l_eff_dimm->dimm_rc08() );
+ FAPI_TRY( l_eff_dimm->dimm_rc09() );
+ FAPI_TRY( l_eff_dimm->dimm_rc10() );
+ FAPI_TRY( l_eff_dimm->dimm_rc11() );
+ FAPI_TRY( l_eff_dimm->dimm_rc12() );
+ FAPI_TRY( l_eff_dimm->dimm_rc13() );
+ FAPI_TRY( l_eff_dimm->dimm_rc14() );
+ FAPI_TRY( l_eff_dimm->dimm_rc15() );
+ FAPI_TRY( l_eff_dimm->dimm_rc1x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc2x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc3x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc4x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc5x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc6x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc7x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc8x() );
+ FAPI_TRY( l_eff_dimm->dimm_rc9x() );
+ FAPI_TRY( l_eff_dimm->dimm_rcax() );
+ FAPI_TRY( l_eff_dimm->dimm_rcbx() );
+ FAPI_TRY( l_eff_dimm->dram_twr() );
+ FAPI_TRY( l_eff_dimm->read_burst_type() );
+ FAPI_TRY( l_eff_dimm->dram_tm() );
+ FAPI_TRY( l_eff_dimm->dram_cwl() );
+ FAPI_TRY( l_eff_dimm->dram_lpasr() );
+ FAPI_TRY( l_eff_dimm->dll_enable() );
+ FAPI_TRY( l_eff_dimm->dll_reset() );
+ FAPI_TRY( l_eff_dimm->write_level_enable() );
+ FAPI_TRY( l_eff_dimm->output_buffer() );
+ FAPI_TRY( l_eff_dimm->vref_dq_train_value() );
+ FAPI_TRY( l_eff_dimm->vref_dq_train_range() );
+ FAPI_TRY( l_eff_dimm->vref_dq_train_enable() );
+ FAPI_TRY( l_eff_dimm->ca_parity_latency() );
+ FAPI_TRY( l_eff_dimm->ca_parity_error_status() );
+ FAPI_TRY( l_eff_dimm->ca_parity() );
+ FAPI_TRY( l_eff_dimm->crc_error_clear() );
+ FAPI_TRY( l_eff_dimm->odt_input_buffer() );
+ FAPI_TRY( l_eff_dimm->post_package_repair() );
+ FAPI_TRY( l_eff_dimm->read_preamble_train() );
+ FAPI_TRY( l_eff_dimm->read_preamble() );
+ FAPI_TRY( l_eff_dimm->write_preamble() );
+ FAPI_TRY( l_eff_dimm->self_refresh_abort() );
+ FAPI_TRY( l_eff_dimm->cs_to_cmd_addr_latency() );
+ FAPI_TRY( l_eff_dimm->internal_vref_monitor() );
+ FAPI_TRY( l_eff_dimm->max_powerdown_mode() );
+ FAPI_TRY( l_eff_dimm->mpr_read_format() );
+ FAPI_TRY( l_eff_dimm->temp_readout() );
+ FAPI_TRY( l_eff_dimm->crc_wr_latency() );
+ FAPI_TRY( l_eff_dimm->per_dram_addressability() );
+ FAPI_TRY( l_eff_dimm->geardown_mode() );
+ FAPI_TRY( l_eff_dimm->mpr_page() );
+ FAPI_TRY( l_eff_dimm->mpr_mode() );
+ FAPI_TRY( l_eff_dimm->write_crc() );
+ FAPI_TRY( l_eff_dimm->zqcal_interval() );
+ FAPI_TRY( l_eff_dimm->memcal_interval() );
+ FAPI_TRY( l_eff_dimm->dram_trp() );
+ FAPI_TRY( l_eff_dimm->dram_trcd() );
+ FAPI_TRY( l_eff_dimm->dram_trc() );
+ FAPI_TRY( l_eff_dimm->dram_twtr_l() );
+ FAPI_TRY( l_eff_dimm->dram_twtr_s() );
+ FAPI_TRY( l_eff_dimm->dram_trrd_s() );
+ FAPI_TRY( l_eff_dimm->dram_trrd_l() );
+ FAPI_TRY( l_eff_dimm->dram_trrd_dlr() );
+ FAPI_TRY( l_eff_dimm->dram_tfaw() );
+ FAPI_TRY( l_eff_dimm->dram_tfaw_dlr() );
+ FAPI_TRY( l_eff_dimm->dram_tras() );
+ FAPI_TRY( l_eff_dimm->dram_trtp() );
+ FAPI_TRY( l_eff_dimm->read_dbi() );
+ FAPI_TRY( l_eff_dimm->write_dbi() );
+ FAPI_TRY( l_eff_dimm->additive_latency() );
+ FAPI_TRY( l_eff_dimm->data_mask() );
+ FAPI_TRY( l_eff_dimm->dimm_bc00());
+ FAPI_TRY( l_eff_dimm->dimm_bc01());
+ FAPI_TRY( l_eff_dimm->dimm_bc02());
+ FAPI_TRY( l_eff_dimm->dimm_bc03());
+ FAPI_TRY( l_eff_dimm->dimm_bc04());
+ FAPI_TRY( l_eff_dimm->dimm_bc05());
+ FAPI_TRY( l_eff_dimm->dimm_bc07());
+ FAPI_TRY( l_eff_dimm->dimm_bc08());
+ FAPI_TRY( l_eff_dimm->dimm_bc09());
+ FAPI_TRY( l_eff_dimm->dimm_bc0a());
+ FAPI_TRY( l_eff_dimm->dimm_bc0b());
+ FAPI_TRY( l_eff_dimm->dimm_bc0c());
+ FAPI_TRY( l_eff_dimm->dimm_bc0d());
+ FAPI_TRY( l_eff_dimm->dimm_bc0e());
+ FAPI_TRY( l_eff_dimm->dimm_bc0f());
+ FAPI_TRY( l_eff_dimm->dram_rtt_nom () );
+ FAPI_TRY( l_eff_dimm->dram_rtt_wr () );
+ FAPI_TRY( l_eff_dimm->dram_rtt_park() );
}// dimm
// TODO RTC:160060 Clean up hard coded values at bottom of eff_config
@@ -233,15 +215,8 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, i_target, l_cal_step) );
}
- {
- // TODO RTC:162080 Logically link ATTR_MSS_MRW_TEMP_REFRESH_RANGE and MODE
- uint8_t l_temp_refresh_mode[mss::PORTS_PER_MCS] =
- {fapi2::ENUM_ATTR_EFF_TEMP_REFRESH_MODE_DISABLE, fapi2::ENUM_ATTR_EFF_TEMP_REFRESH_MODE_DISABLE};
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_EFF_TEMP_REFRESH_MODE, i_target, l_temp_refresh_mode ) );
- }
-
// Check plug rules. We check the MCS, and this will iterate down to children as needed.
- FAPI_TRY( l_eff_config.enforce_plug_rules(i_target) );
+ FAPI_TRY( mss::plug_rule::enforce_plug_rules(i_target) );
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
index 7f1619a9f..ed50f6d0c 100755
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2017 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -598,4 +598,15 @@
<mssAccessorName>mrw_unsupported_rank_config</mssAccessorName>
</attribute>
+ <attribute>
+ <id>ATTR_MSS_MRW_DRAM_WRITE_CRC</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description> Enables DRAM Write CRC</description>
+ <valueType>uint8</valueType>
+ <platInit/>
+ <enum> DISABLE = 0, ENABLE = 1 </enum>
+ <default> 0 </default>
+ <mssAccessorName>mrw_dram_write_crc</mssAccessorName>
+ </attribute>
+
</attributes>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml
index bfa10c003..49cc606e9 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml
@@ -145,7 +145,7 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>OHM34 = 34, OHM48 = 48</enum>
+ <enum>OHM30 = 30, OHM34 = 34, OHM40 = 40, OHM48 = 48</enum>
<mssUnits>ohm</mssUnits>
<mssBlobStart>22</mssBlobStart>
<mssBlobLength>16</mssBlobLength>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
index 07def3931..51d7a8e8c 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2017 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -239,5 +239,89 @@
</deconfigure>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_INVALID_LRDIMM_DB</rc>
+ <description>
+ Error with the LRDIMM databuffer type
+ </description>
+ <ffdc>DATA_BUFFER_GEN</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_UNSUPPORTED_DIMM_KIND</rc>
+ <description>
+ DIMM plugged in is not supported
+ </description>
+ <ffdc>DIMM_KIND</ffdc>
+ <ffdc>DIMM_TYPE</ffdc>
+ <ffdc>DRAM_GEN</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_RTT_WR</rc>
+ <description>
+ An invalid encoding recieved from VPD for RTT_WR/dynamic ODT value
+ </description>
+ <ffdc>RTT_WR</ffdc>
+ <ffdc>RANK</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_FREQ</rc>
+ <description>
+ An invalid Freq value has been set
+ </description>
+ <ffdc>FREQ</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_ERROR_CREATING_EFF_CONFIG_DIMM_OBJECT</rc>
+ <description>
+ Failed to create a dimm object, probably due to bad attribute settings
+ </description>
+ <ffdc>DIMM_TYPE</ffdc>
+ <ffdc>DRAM_GEN</ffdc>
+ <ffdc>REG_AND_BUFF_TYPE</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+
+
+
+
</hwpErrors>
OpenPOWER on IntegriCloud