summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory
diff options
context:
space:
mode:
authorJacob Harvey <jlharvey@us.ibm.com>2017-08-14 15:16:43 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-08-29 11:40:18 -0400
commitee5398301736c96d0d5ffcfd147585b2e29f5a16 (patch)
treee7a1efd99e41212711d36ec93f4a91d3954e6130 /src/import/chips/p9/procedures/hwp/memory
parent2b881ebf90218af1ce41918b214498c2574940e1 (diff)
downloadtalos-hostboot-ee5398301736c96d0d5ffcfd147585b2e29f5a16.tar.gz
talos-hostboot-ee5398301736c96d0d5ffcfd147585b2e29f5a16.zip
Implementing draminit_training_adv
Set default pattern to john's new one and backup to supernova 2.0 Change-Id: I406bb5c5652cff9fe4690e5bd9b03cc431d75f61 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44709 Dev-Ready: JACOB L. HARVEY <jlharvey@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44780 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C79
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H174
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C91
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H9
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C42
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H16
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/read_cntrl.H20
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.C30
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H125
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H16
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C162
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.H9
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C2
16 files changed, 720 insertions, 81 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 2f8ee1126..faf07a39f 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
@@ -4770,16 +4770,87 @@ fapi_try_exit:
}
///
+/// @brief Determines and sets the CUSTOM_TRAINING_ADV_PATTERNS settings for training advance
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note overwrite the attribute to default values if it's set to 0
+///
+fapi2::ReturnCode eff_dimm::training_adv_pattern()
+{
+ uint32_t l_special_patterns [PORTS_PER_MCS] = {};
+ FAPI_TRY( custom_training_adv_patterns( iv_mcs, &(l_special_patterns[0])) );
+
+ // Let's not write the defaults if someone wants to overwrite the attribute
+ // 0 is an invalid pattern, so if it's 0, the attribute is empty
+ if ( l_special_patterns[mss::index(iv_mca)] == 0)
+ {
+ fapi2::buffer<uint32_t> l_temp;
+
+ l_temp.insertFromRight<PATTERN0_START, PATTERN0_LEN>
+ (fapi2::ENUM_ATTR_MSS_CUSTOM_TRAINING_ADV_PATTERNS_DEFAULT_PATTERN0);
+
+ l_temp.insertFromRight<PATTERN1_START, PATTERN1_LEN>
+ (fapi2::ENUM_ATTR_MSS_CUSTOM_TRAINING_ADV_PATTERNS_DEFAULT_PATTERN1);
+
+ l_special_patterns[mss::index(iv_mca)] = l_temp;
+
+ FAPI_INF("%s setting training_adv_pattern as 0x%08x", mss::c_str(iv_mca), l_temp);
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_CUSTOM_TRAINING_ADV_PATTERNS, iv_mcs, l_special_patterns) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines and sets the CUSTOM_TRAINING_ADV_BACKUP_PATTERNS settings for training advance
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note overwrite the attribute to default values if it's set to 0
+///
+fapi2::ReturnCode eff_dimm::training_adv_backup_pattern()
+{
+ uint32_t l_special_patterns [PORTS_PER_MCS] = {};
+ FAPI_TRY( custom_training_adv_backup_patterns( iv_mcs, &(l_special_patterns[0])) );
+
+ // Let's set the backup pattern as well
+ if ( l_special_patterns[mss::index(iv_mca)] == 0)
+ {
+ fapi2::buffer<uint32_t> l_temp;
+
+ l_temp.insertFromRight<PATTERN0_START, PATTERN0_LEN>
+ (fapi2::ENUM_ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS_DEFAULT_PATTERN0);
+
+ l_temp.insertFromRight<PATTERN1_START, PATTERN1_LEN>
+ (fapi2::ENUM_ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS_DEFAULT_PATTERN1);
+
+ l_special_patterns[mss::index(iv_mca)] = l_temp;
+
+ FAPI_INF("%s setting training_adv_backup_pattern as 0x%08x", mss::c_str(iv_mca), l_temp);
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS, iv_mcs, l_special_patterns) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Determines and sets the cal_step_enable values
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
fapi2::ReturnCode eff_dimm::cal_step_enable()
{
- const uint32_t l_cal_step_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ?
- RUN_CAL_SKIP_WR_RD_2D_VREF : RUN_ALL_CAL_STEPS);
+ fapi2::buffer<uint32_t> l_cal_step_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ?
+ RUN_CAL_SKIP_WR_RD_2D_VREF : RUN_ALL_CAL_STEPS);
+
+ // We only run draminit training advance on DD2 modules
+ l_cal_step_value = l_cal_step_value.writeBit<mss::TRAINING_ADV>( !mss::chip_ec_nimbus_lt_2_0(iv_mcs) );
- FAPI_DBG("%s %s running HW VREF cal. cal_step value: 0x%0x VREF", mss::c_str(iv_mcs),
- mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? "not" : "", l_cal_step_value);
+ FAPI_DBG("%s %s running HW VREF cal. cal_step value: 0x%08x VREF, running training advance %s",
+ mss::c_str(iv_mcs),
+ mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? "not" : "",
+ l_cal_step_value,
+ l_cal_step_value.getBit<mss::TRAINING_ADV>() ? "yes" : "no");
// Sets up the vector
std::vector<uint32_t> l_cal_step(PORTS_PER_MCS, l_cal_step_value);
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 6da286528..d4f058100 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
@@ -746,6 +746,20 @@ class eff_dimm
fapi2::ReturnCode rdvref_enable_bit();
///
+ /// @brief Determines and sets the ATTR_MSS_CUSTOM_TRAINING_ADV_PATTERNS settings
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note overwrite the attribute to default values if it's set to 0
+ ///
+ fapi2::ReturnCode training_adv_pattern();
+
+ ///
+ /// @brief Determines and sets the ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS settings
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @note overwrite the attribute to default values if it's set to 0
+ ///
+ fapi2::ReturnCode training_adv_backup_pattern();
+
+ ///
/// @brief Determines and sets ATTR_MSS_PHY_SEQ_REFRESH_
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
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 25579e105..f9c12454a 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
@@ -9273,11 +9273,12 @@ fapi_try_exit:
/// MRD - Fine (LRDIMM) [5] WR_LEVEL [6] INITIAL_PAT_WR [7] WR_VREF_LATCH [8] DWL
/// (LRDIMM) [9] MWD - Coarse (LRDIMM) [10] MWD - Fine (LRDIMM) [11] HWL (LRDIMM)
/// [12] DQS_ALIGN [13] RDCLK_ALIGN [14] READ_CTR_2D_VREF [15] READ_CTR [16]
-/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20]:[31]
-/// Reserved for future use COARSE_WR and COARSE_RD will be consumed together to
-/// form COARSE_LVL. WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is
-/// enabled, as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. Note:
-/// LRDIMM steps will only be enabled for LRDIMMs and won't run on
+/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20] TRAINING_ADV
+/// Only set for DD2.* machines [21]:[31] Reserved for future use COARSE_WR and
+/// COARSE_RD will be consumed together to form COARSE_LVL. WRITE_CTR will be run,
+/// even if only WRITE_CTR_2D_VREF is enabled, as the WR 2D VREF HW cal depends upon
+/// WRITE_CTR 1D to function. Note: LRDIMM steps will only be enabled for LRDIMMs
+/// and won't run on
/// RDIMMs.
///
inline fapi2::ReturnCode cal_step_enable(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t& o_value)
@@ -9305,11 +9306,12 @@ fapi_try_exit:
/// MRD - Fine (LRDIMM) [5] WR_LEVEL [6] INITIAL_PAT_WR [7] WR_VREF_LATCH [8] DWL
/// (LRDIMM) [9] MWD - Coarse (LRDIMM) [10] MWD - Fine (LRDIMM) [11] HWL (LRDIMM)
/// [12] DQS_ALIGN [13] RDCLK_ALIGN [14] READ_CTR_2D_VREF [15] READ_CTR [16]
-/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20]:[31]
-/// Reserved for future use COARSE_WR and COARSE_RD will be consumed together to
-/// form COARSE_LVL. WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is
-/// enabled, as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. Note:
-/// LRDIMM steps will only be enabled for LRDIMMs and won't run on
+/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20] TRAINING_ADV
+/// Only set for DD2.* machines [21]:[31] Reserved for future use COARSE_WR and
+/// COARSE_RD will be consumed together to form COARSE_LVL. WRITE_CTR will be run,
+/// even if only WRITE_CTR_2D_VREF is enabled, as the WR 2D VREF HW cal depends upon
+/// WRITE_CTR 1D to function. Note: LRDIMM steps will only be enabled for LRDIMMs
+/// and won't run on
/// RDIMMs.
///
inline fapi2::ReturnCode cal_step_enable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
@@ -9338,11 +9340,12 @@ fapi_try_exit:
/// MRD - Fine (LRDIMM) [5] WR_LEVEL [6] INITIAL_PAT_WR [7] WR_VREF_LATCH [8] DWL
/// (LRDIMM) [9] MWD - Coarse (LRDIMM) [10] MWD - Fine (LRDIMM) [11] HWL (LRDIMM)
/// [12] DQS_ALIGN [13] RDCLK_ALIGN [14] READ_CTR_2D_VREF [15] READ_CTR [16]
-/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20]:[31]
-/// Reserved for future use COARSE_WR and COARSE_RD will be consumed together to
-/// form COARSE_LVL. WRITE_CTR will be run, even if only WRITE_CTR_2D_VREF is
-/// enabled, as the WR 2D VREF HW cal depends upon WRITE_CTR 1D to function. Note:
-/// LRDIMM steps will only be enabled for LRDIMMs and won't run on
+/// WRITE_CTR_2D_VREF [17] WRITE_CTR [18] COARSE_WR [19] COARSE_RD [20] TRAINING_ADV
+/// Only set for DD2.* machines [21]:[31] Reserved for future use COARSE_WR and
+/// COARSE_RD will be consumed together to form COARSE_LVL. WRITE_CTR will be run,
+/// even if only WRITE_CTR_2D_VREF is enabled, as the WR 2D VREF HW cal depends upon
+/// WRITE_CTR 1D to function. Note: LRDIMM steps will only be enabled for LRDIMMs
+/// and won't run on
/// RDIMMs.
///
inline fapi2::ReturnCode cal_step_enable(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array)
@@ -9371,13 +9374,15 @@ fapi_try_exit:
/// @param[out] ref to the value uint32_t
/// @note Generated by gen_accessors.pl generateParameters (D)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Special training pattern used for draminit_training_advance. Used for read
-/// centering There can be two patterns used here. The first 0-15 bits are for
-/// PATTERN1, bits 16-32 are for PATTERN2. If this attribute is set to 0, using the
-/// default values of: 0x952D for PATTERN1 0x594A for
-/// PATTERN2
+/// @note Special training pattern used in draminit_training_advance. Used for custom
+/// pattern write There can be two patterns used here. This attribute is before
+/// swizzling for endianness of the registers. CODE WILL SWIZZLE FOR THE SYSTEM The
+/// first 0-15 bits are for PATTERN0, bits 16-32 are for PATTERN1. If this attribute
+/// is set to 0, using the default values of: 0x13EC for PATTERN0 0x02FD for
+/// PATTERN1 Set to default in
+/// eff_config
///
-inline fapi2::ReturnCode custom_training_adv_pattern(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+inline fapi2::ReturnCode custom_training_adv_patterns(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
uint32_t& o_value)
{
uint32_t l_value[2];
@@ -9399,13 +9404,15 @@ fapi_try_exit:
/// @param[out] ref to the value uint32_t
/// @note Generated by gen_accessors.pl generateParameters (D.1)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Special training pattern used for draminit_training_advance. Used for read
-/// centering There can be two patterns used here. The first 0-15 bits are for
-/// PATTERN1, bits 16-32 are for PATTERN2. If this attribute is set to 0, using the
-/// default values of: 0x952D for PATTERN1 0x594A for
-/// PATTERN2
+/// @note Special training pattern used in draminit_training_advance. Used for custom
+/// pattern write There can be two patterns used here. This attribute is before
+/// swizzling for endianness of the registers. CODE WILL SWIZZLE FOR THE SYSTEM The
+/// first 0-15 bits are for PATTERN0, bits 16-32 are for PATTERN1. If this attribute
+/// is set to 0, using the default values of: 0x13EC for PATTERN0 0x02FD for
+/// PATTERN1 Set to default in
+/// eff_config
///
-inline fapi2::ReturnCode custom_training_adv_pattern(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+inline fapi2::ReturnCode custom_training_adv_patterns(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
uint32_t& o_value)
{
uint32_t l_value[2];
@@ -9428,13 +9435,15 @@ fapi_try_exit:
/// @param[out] uint32_t* memory to store the value
/// @note Generated by gen_accessors.pl generateParameters (E)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Special training pattern used for draminit_training_advance. Used for read
-/// centering There can be two patterns used here. The first 0-15 bits are for
-/// PATTERN1, bits 16-32 are for PATTERN2. If this attribute is set to 0, using the
-/// default values of: 0x952D for PATTERN1 0x594A for
-/// PATTERN2
+/// @note Special training pattern used in draminit_training_advance. Used for custom
+/// pattern write There can be two patterns used here. This attribute is before
+/// swizzling for endianness of the registers. CODE WILL SWIZZLE FOR THE SYSTEM The
+/// first 0-15 bits are for PATTERN0, bits 16-32 are for PATTERN1. If this attribute
+/// is set to 0, using the default values of: 0x13EC for PATTERN0 0x02FD for
+/// PATTERN1 Set to default in
+/// eff_config
///
-inline fapi2::ReturnCode custom_training_adv_pattern(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
+inline fapi2::ReturnCode custom_training_adv_patterns(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
uint32_t* o_array)
{
if (o_array == nullptr)
@@ -9456,6 +9465,105 @@ fapi_try_exit:
}
///
+/// @brief ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
+/// @param[out] ref to the value uint32_t
+/// @note Generated by gen_accessors.pl generateParameters (D)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Special training backup pattern Used for custom_pattern_write in
+/// draminit_training_advance. If the main patterns fail, the code will try running
+/// this pattern Used for read centering There can be two patterns used here. This
+/// attribute is before swizzling for endianness of the registers. CODE WILL SWIZZLE
+/// FOR THE SYSTEM The first 0-15 bits are for PATTERN0, bits 16-32 are for
+/// PATTERN1. If this attribute is set to 0, using the default values of: 0xEA0C for
+/// PATTERN0 0xA6C9 for PATTERN1 Set to default in
+/// eff_config
+///
+inline fapi2::ReturnCode custom_training_adv_backup_patterns(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint32_t& o_value)
+{
+ uint32_t l_value[2];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS,
+ i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[out] ref to the value uint32_t
+/// @note Generated by gen_accessors.pl generateParameters (D.1)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Special training backup pattern Used for custom_pattern_write in
+/// draminit_training_advance. If the main patterns fail, the code will try running
+/// this pattern Used for read centering There can be two patterns used here. This
+/// attribute is before swizzling for endianness of the registers. CODE WILL SWIZZLE
+/// FOR THE SYSTEM The first 0-15 bits are for PATTERN0, bits 16-32 are for
+/// PATTERN1. If this attribute is set to 0, using the default values of: 0xEA0C for
+/// PATTERN0 0xA6C9 for PATTERN1 Set to default in
+/// eff_config
+///
+inline fapi2::ReturnCode custom_training_adv_backup_patterns(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint32_t& o_value)
+{
+ uint32_t l_value[2];
+ auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS, l_mca.getParent<fapi2::TARGET_TYPE_MCS>(),
+ l_value) );
+ o_value = l_value[mss::index(l_mca)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
+/// @param[out] uint32_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (E)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Special training backup pattern Used for custom_pattern_write in
+/// draminit_training_advance. If the main patterns fail, the code will try running
+/// this pattern Used for read centering There can be two patterns used here. This
+/// attribute is before swizzling for endianness of the registers. CODE WILL SWIZZLE
+/// FOR THE SYSTEM The first 0-15 bits are for PATTERN0, bits 16-32 are for
+/// PATTERN1. If this attribute is set to 0, using the default values of: 0xEA0C for
+/// PATTERN0 0xA6C9 for PATTERN1 Set to default in
+/// eff_config
+///
+inline fapi2::ReturnCode custom_training_adv_backup_patterns(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
+ uint32_t* o_array)
+{
+ if (o_array == nullptr)
+ {
+ FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ uint32_t l_value[2];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MSS_VREF_CAL_ENABLE getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
/// @param[out] ref to the value uint16_t
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H
index 16f87310f..e901055e8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H
@@ -237,7 +237,11 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
l_total_cycles = i_cal_steps_enabled.getBit<WR_LEVEL>() ? wr_lvl_cycles(i_target) : 0;
l_total_cycles += i_cal_steps_enabled.getBit<DQS_ALIGN>() ? dqs_align_cycles(i_target) : 0;
l_total_cycles += i_cal_steps_enabled.getBit<RDCLK_ALIGN>() ? rdclk_align_cycles(i_target) : 0;
- l_total_cycles += i_cal_steps_enabled.getBit<READ_CTR>() ? read_ctr_cycles(i_target) : 0;
+
+ // We run either read centering during normal draminit_training and also during draminit_training_advance,
+ // can't be run twice in one cal though
+ l_total_cycles += ( i_cal_steps_enabled.getBit<READ_CTR>() || i_cal_steps_enabled.getBit<TRAINING_ADV>())
+ ? read_ctr_cycles(i_target) : 0;
l_total_cycles += i_cal_steps_enabled.getBit<WRITE_CTR>() ? l_write_cntr_cycles : 0;
l_total_cycles += i_cal_steps_enabled.getBit<COARSE_WR>() ? coarse_wr_cycles(i_target) : 0;
l_total_cycles += i_cal_steps_enabled.getBit<COARSE_RD>() ? coarse_rd_cycles(i_target) : 0;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
index 5d8aaf71f..bd920c3a3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
@@ -700,6 +700,7 @@ fapi_try_exit:
/// @param[in] i_target the port target
/// @param[in] i_rp the rank pair we are calibrating
/// @param[in] i_cal_abort_on_error denoting if we aborted on first fail
+/// @param[out] o_cal_fail a flag that gets set to true if there was a cal fail
/// @param[in,out] io_fails a vector storing all of our cal fails
/// @return FAPI2_RC_SUCCESS iff all of the scoms and functionality were good
///
@@ -707,6 +708,7 @@ template<>
fapi2::ReturnCode find_and_log_cal_errors(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
const uint64_t i_cal_abort_on_error,
+ bool& o_cal_fail,
std::vector<fapi2::ReturnCode>& io_fails)
{
fapi2::ReturnCode l_rc (fapi2::FAPI2_RC_SUCCESS);
@@ -725,6 +727,8 @@ fapi2::ReturnCode find_and_log_cal_errors(const fapi2::Target<fapi2::TARGET_TYPE
if (l_rc != fapi2::FAPI2_RC_SUCCESS)
{
+ o_cal_fail = true;
+
// If we're aborting on error we jump to the end and error out.
// We don't care about other ports or ranks because the hardware stopped when it saw the error
if (i_cal_abort_on_error)
@@ -799,8 +803,6 @@ fapi2::ReturnCode draminit_training_error_handler( const std::vector<fapi2::Retu
fapi2::logError(l_iter, fapi2::FAPI2_ERRL_SEV_RECOVERED);
}
- return fapi2::current_err;
-
// If we're cronus, let's bomb out
#else
@@ -954,7 +956,8 @@ fapi2::ReturnCode setup_read_vref_config1( const fapi2::Target<fapi2::TARGET_TYP
l_data.writeBit<TT::RDVREF_CALIBRATION_ENABLE>( i_cal_steps_enabled.getBit<READ_CTR_2D_VREF>() );
// Check to see if READ_CENTERING is disabled, if so, set the bit
- l_data.writeBit<TT::SKIP_RDCENTERING>( !i_cal_steps_enabled.getBit<READ_CTR>() );
+ l_data.writeBit<TT::SKIP_RDCENTERING>( !(i_cal_steps_enabled.getBit<READ_CTR>()
+ || i_cal_steps_enabled.getBit<TRAINING_ADV>()) );
FAPI_INF("%s %s read VREF cal, read centering is %s",
mss::c_str(i_target),
@@ -986,9 +989,8 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
FAPI_TRY( mss::is_simulation(l_sim) );
// This is the buffer which will be written to CAL_CONFIG0. It starts
- // life assuming no cal sequences, no rank pairs - but we set the abort-on-error
- // bit ahead of time.
- l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ABORT_ON_ERROR>(l_cal_abort_on_error);
+ // life assuming no cal sequences, no rank pairs
+
// Sadly, the bits in the register don't align directly with the bits in the attribute.
// So, arrange the bits accordingly and write the config register.
@@ -1010,12 +1012,29 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_COARSE_RD>(
i_cal_steps_enabled.getBit<COARSE_RD>());
- // Always turn on initial pattern write in h/w, never for sim (makes the DIMM behavioral lose it's mind)
+ // Turn on initial pattern write only in h/w, never for sim (makes the DIMM behavioral lose it's mind)
if (!l_sim)
{
+ // If we are running training advance, none of the steps above can be enabled.
+ // If they are, we have a code bug and should fapi2:Assert.
+ // This isn't dependent on system or attributes but code structure
+ if ( l_cal_config != 0 && i_cal_steps_enabled.getBit<TRAINING_ADV>())
+ {
+ FAPI_ERR("Error setting up draminit training advance. Set CUSTOM_RD with other cal steps");
+ fapi2::Assert( false );
+ }
+
+ // Enable CUSTOM_RD for training ADV. If this bit is set, only TRAINING_ADV and INIT_PAT_WR can be set
+ // We assert this above.
+ l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_CUSTOM_RD>(
+ i_cal_steps_enabled.getBit<TRAINING_ADV>());
+
l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_INITIAL_PAT_WR>(
i_cal_steps_enabled.getBit<INITIAL_PAT_WR>());
}
+
+ // Moved this down here so we can make the training advance check above
+ l_cal_config.writeBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ABORT_ON_ERROR>(l_cal_abort_on_error);
}
// Blast the VREF config with the proper setting for these cal bits if there were any enable bits set
@@ -1083,7 +1102,7 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
FAPI_TRY( l_cal_config.setBit(MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_RANK_PAIR + rp) );
}
- FAPI_INF("cal_config for %s: 0x%04lx (steps: 0x%08lx)",
+ FAPI_INF("cal_config for %s: 0x%04lx (steps: 0x%08x)",
mss::c_str(i_target), uint16_t(l_cal_config), uint32_t(i_cal_steps_enabled));
FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0, l_cal_config) );
@@ -1215,7 +1234,10 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
}
// Execute WR_LEVEL
- FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) );
+ FAPI_TRY( execute_cal_steps_helper(i_target,
+ i_rp,
+ l_steps_to_execute,
+ i_abort_on_error) );
// Restore normal terminations
l_rtt_inst.clear();
@@ -1223,21 +1245,28 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
if (!l_rtt_inst.empty())
{
- l_program.iv_instructions.insert(l_program.iv_instructions.end(), l_rtt_inst.begin(), l_rtt_inst.end() );
+ l_program.iv_instructions.insert(l_program.iv_instructions.end(),
+ l_rtt_inst.begin(),
+ l_rtt_inst.end() );
FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
}
}
- // run Initial Pattern Write
+ // run Initial Pattern Write and custom read centering if enabled
if(i_cal_steps_enabled.getBit<mss::cal_steps::INITIAL_PAT_WR>())
{
// Sets up the cal steps in the buffer
fapi2::buffer<uint32_t> l_steps_to_execute;
l_steps_to_execute.writeBit<mss::cal_steps::INITIAL_PAT_WR>
(i_cal_steps_enabled.getBit<mss::cal_steps::INITIAL_PAT_WR>());
+ l_steps_to_execute.writeBit<mss::cal_steps::TRAINING_ADV>
+ (i_cal_steps_enabled.getBit<mss::cal_steps::TRAINING_ADV>());
- FAPI_INF("%s Running Initial Pattern Write on RP%d 0x%08lx",
- mss::c_str(i_target), i_rp, l_steps_to_execute);
+ FAPI_INF("%s Running Initial Pattern Write and TRAINING_ADV(%s) on RP%d 0x%08x",
+ mss::c_str(i_target),
+ (i_cal_steps_enabled.getBit<mss::cal_steps::TRAINING_ADV>() ? "yes" : "no"),
+ i_rp,
+ l_steps_to_execute);
// Undertake the calibration steps
FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) );
@@ -1250,7 +1279,7 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
fapi2::buffer<uint32_t> l_steps_to_execute;
l_steps_to_execute.setBit<mss::cal_steps::DQS_ALIGN>();
- FAPI_INF("%s Running DQS align on RP%d 0x%08lx",
+ FAPI_INF("%s Running DQS align on RP%d 0x%08x",
mss::c_str(i_target), i_rp, l_steps_to_execute);
// Undertake the calibration steps
@@ -1274,7 +1303,7 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
mss::cal_steps::RDCLK_ALIGN_TO_RD_CTR_LEN,
mss::cal_steps::RDCLK_ALIGN>(l_steps_to_execute);
- FAPI_INF("%s Running rd_clk align through read centering vref on RP%d 0x%08lx", mss::c_str(i_target), i_rp,
+ FAPI_INF("%s Running rd_clk align through read centering vref on RP%d 0x%08x", mss::c_str(i_target), i_rp,
l_steps_to_execute);
// Undertake the calibration steps
@@ -1292,7 +1321,7 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
}
// Run cal steps after RD_CTR if any are selected - note: WRITE_CTR takes place after RD_CTR
- if (i_cal_steps_enabled.getBit<mss::cal_steps::WRITE_CTR, mss::cal_steps::WR_VREF_TO_COARSE_RD_LEN>())
+ if (i_cal_steps_enabled.getBit<mss::cal_steps::WRITE_CTR_2D_VREF, mss::cal_steps::WR_VREF_TO_COARSE_RD_LEN>())
{
fapi2::buffer<uint32_t> l_steps_to_execute( i_cal_steps_enabled );
l_steps_to_execute.clearBit<mss::cal_steps::DRAM_ZQCAL, mss::cal_steps::DRAM_ZQCAL_UP_TO_WRITE_CTR_2D_VREF>();
@@ -1301,7 +1330,7 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
// Gets set iff the bit is set in i_steps_to_execute
l_steps_to_execute.writeBit<WR_VREF_LATCH>( i_cal_steps_enabled.getBit<WR_VREF_LATCH>() );
- FAPI_DBG("%s Running remaining cal steps on RP%d 0x%08lx", mss::c_str(i_target), i_rp, l_steps_to_execute);
+ FAPI_DBG("%s Running remaining cal steps on RP%d 0x%08x", mss::c_str(i_target), i_rp, l_steps_to_execute);
FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) );
}
@@ -1783,6 +1812,34 @@ fapi_try_exit:
}
///
+/// @brief Set the custom pattern
+/// @param[in] i_target the port target
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+template<>
+fapi2::ReturnCode configure_custom_pattern( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target )
+{
+ uint32_t l_pattern = 0;
+ uint32_t l_swizzled = 0;
+
+ // Set the custom patterns for training advance
+ // So first get the pattern from the attribute and then put it into the register
+
+ FAPI_TRY( mss::custom_training_adv_patterns( i_target, l_pattern) );
+ FAPI_TRY( mss::seq::swizzle_mpr_pattern(l_pattern, l_swizzled) );
+
+ FAPI_INF("%s the patterns before swizzle are 0x%08x and after 0x%08x",
+ mss::c_str(i_target),
+ l_pattern,
+ l_swizzled);
+
+ FAPI_TRY( mss::seq::setup_rd_wr_data( i_target, l_swizzled) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Flush the output drivers
/// @param[in] i_target the target associated with the phy reset sequence
/// @return FAPI2_RC_SUCCESS iff setup was successful
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
index 39db82147..e111d9778 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
@@ -424,6 +424,13 @@ fapi2::ReturnCode reset_seq_rd_wr_data( const fapi2::Target<fapi2::TARGET_TYPE_M
template<fapi2::TargetType T>
fapi2::ReturnCode rank_pair_primary_to_dimm(const fapi2::Target<T>& i_target, const uint64_t i_rp,
fapi2::Target<fapi2::TARGET_TYPE_DIMM>& o_dimm);
+///
+/// @brief Set the custom pattern
+/// @param[in] i_target the port target
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode configure_custom_pattern( const fapi2::Target<T>& i_target );
///
/// @brief Handle draminit_training cal fails
@@ -440,6 +447,7 @@ fapi2::ReturnCode draminit_training_error_handler ( const std::vector<fapi2::Ret
/// @param[in] i_target the port target
/// @param[in] i_rp the rank pair we are calibrating
/// @param[in] i_cal_abort_on_error denoting if we aborted on first fail
+/// @param[out] o_cal_fail a flag that gets set to true if there was a cal fail
/// @param[in,out] io_fails a vector storing all of our cal fails
/// @return FAPI2_RC_SUCCESS iff all of the scoms and functionality were good
///
@@ -447,6 +455,7 @@ template<fapi2::TargetType T>
fapi2::ReturnCode find_and_log_cal_errors(const fapi2::Target<T>& i_target,
const uint64_t i_rp,
const uint64_t i_cal_abort_on_error,
+ bool& o_cal_fail,
std::vector<fapi2::ReturnCode>& io_fails);
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
index eebb2b5f1..b6e2782a9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
@@ -252,6 +252,18 @@ const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::IO_TX_PFET_TERM_REG
MCA_DDRPHY_DP16_IO_TX_PFET_TERM_P0_4,
};
+// Receiver configuration for the DP16.
+const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::DP16_RX_REGS
+{
+ {
+ MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_0,
+ MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_1,
+ MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_2,
+ MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_3,
+ MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_4,
+ },
+};
+
// Definition of the DD1 DP16 RD_VREF Control registers
// Note: For DD2 if we use the DD2_PERBIT_RDVREF_DISABLE, then these registers are still valid
// DP16 RD_VREF Control registers all come in pairs - one per 8 bits
@@ -267,6 +279,7 @@ const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::DD1_RD_VREF_CNTRL_REG
},
};
+
// Definition of the DD2 DP16 RD_VREF Control registers
// Note: DO NOT use this for DD1 as it will lead to a runtime scom access error
// DD2 DP16 RD_VREF Control registers all come in one register per pair of bits
@@ -1401,11 +1414,38 @@ fapi_try_exit:
};
///
-/// @brief Reset CTLE_CNTL MCA specialization - for all DP16 in the target
+/// @brief Set RX_CONFIG0_P0_DP16_0_READ_CENTERING_MODE - for all DP16 in the target
/// @param[in] i_target the fapi2 target of the port
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
template<>
+fapi2::ReturnCode setup_custom_read_centering_mode( const fapi2::Target<TARGET_TYPE_MCA>& i_target )
+{
+ typedef dp16Traits<TARGET_TYPE_MCA> TT;
+
+ constexpr uint8_t CUSTOM_READ_CENTERING = 0b11;
+ std::vector< fapi2::buffer< uint64_t > > l_data;
+
+ const auto& DP16_RX_REGS = TT::DP16_RX_REGS;
+ FAPI_TRY( mss::scom_suckah(i_target, DP16_RX_REGS, l_data) );
+
+ for (auto& l_reg_data : l_data)
+ {
+ l_reg_data.insertFromRight<TT::READ_CENTERING_MODE, TT::READ_CENTERING_MODE_LEN>(CUSTOM_READ_CENTERING);
+ FAPI_INF("%s setting custom read centering mode 0x%016lx", mss::c_str(i_target), l_reg_data);
+ }
+
+ FAPI_TRY( mss::scom_blastah(i_target, DP16_RX_REGS, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Reset CTLE_CNTL MCA specialization - for all DP16 in the target
+/// @param[in] i_target the fapi2 target of the port
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+template<>
fapi2::ReturnCode reset_ctle_cntl( const fapi2::Target<TARGET_TYPE_MCA>& i_target )
{
typedef dp16Traits<TARGET_TYPE_MCA> TT;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
index 4b2a7a2d0..8c1c752dc 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
@@ -180,6 +180,7 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
static const std::vector< uint64_t > DD1_RD_VREF_CNTRL_REG;
static const std::vector< uint64_t > DD2_RD_VREF_CNTRL_REG;
static const std::vector< uint64_t > DRIFT_LIMITS_REG;
+ static const std::vector< uint64_t > DP16_RX_REGS;
static const std::vector<std::vector<std::pair<uint64_t, uint64_t>>> BIT_DISABLE_REG;
@@ -205,6 +206,7 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
static const std::vector< uint64_t > RD_STATUS0_REG;
static const std::vector< uint64_t > WR_ERROR0_REG;
+
// Definitions of the gate delay and waterfall bits' locations
constexpr static const uint64_t GATE_DELAY_BIT_POS[NUM_QUAD_PER_DP16] =
{
@@ -223,6 +225,10 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
enum
{
+ // Name changes for dd2 to P9N2_MCA_DDRPHY_DP16_RX_CONFIG0_P0_0
+ READ_CENTERING_MODE = MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_0_01_READ_CENTERING_MODE,
+ READ_CENTERING_MODE_LEN = MCA_DDRPHY_DP16_RX_PEAK_AMP_P0_0_01_READ_CENTERING_MODE_LEN,
+
DLL_CNTL_INIT_RXDLL_CAL_RESET = MCA_DDRPHY_DP16_DLL_CNTL0_P0_0_01_INIT_RXDLL_CAL_RESET,
DLL_CNTL_INIT_RXDLL_CAL_SKIP = MCA_DDRPHY_DP16_DLL_CNTL0_P0_1_01_REGS_RXDLL_CAL_SKIP,
DLL_CNTL_INIT_RXDLL_CAL_SKIP_LEN = MCA_DDRPHY_DP16_DLL_CNTL0_P0_1_01_REGS_RXDLL_CAL_SKIP_LEN,
@@ -2115,6 +2121,16 @@ inline void set_blue_waterfall_range( const fapi2::Target<T>& i_target,
}
///
+/// @brief Set RX_CONFIG0_P0_DP16_0_READ_CENTERING_MODE
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = dp16Traits<T> >
+fapi2::ReturnCode setup_custom_read_centering_mode( const fapi2::Target<T>& i_target );
+
+///
/// @brief Reset rd_lvl_status0 registers
/// @tparam T fapi2 Target Type - derived
/// @tparam TT traits type defaults to dp16Traits<T>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/read_cntrl.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/read_cntrl.H
index 055f0ba1d..e19067ed4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/read_cntrl.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/read_cntrl.H
@@ -318,6 +318,26 @@ fapi_try_exit:
}
///
+/// @brief Set STAGGERED_PATTERN bit in read_config0
+/// @param[in] i_target the fapi2 target of the port
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = rcTraits<T> >
+inline fapi2::ReturnCode change_staggered_pattern( const fapi2::Target<T>& i_target)
+{
+ fapi2::buffer<uint64_t> l_data;
+ FAPI_TRY( read_config0( i_target, l_data) );
+
+ l_data.setBit<TT::STAGGERED_PATTERN>();
+
+ FAPI_TRY( write_config0( i_target, l_data) );
+
+ FAPI_DBG("%s set staggered_pattern rc_config0: 0x%016llx", mss::c_str(i_target), l_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief reset rc_config0
/// @param[in] i_target fapi2 target of the port
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.C
index 8c5f0b02d..e506abb02 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.C
@@ -39,6 +39,7 @@
#include <generic/memory/lib/utils/c_str.H>
#include <lib/utils/bit_count.H>
#include <lib/eff_config/timing.H>
+#include <lib/shared/mss_const.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_DIMM;
@@ -174,6 +175,35 @@ fapi2::ReturnCode reset_timing1( const fapi2::Target<TARGET_TYPE_MCA>& i_target
return mss::putScom(i_target, TT::SEQ_TIMING1_REG, l_data);
}
+///
+/// @brief Swizzle the MPR pattern to switch bit order in each byte
+/// @param[in] i_patterns the patterns to put in SEQ_RDWR_DATA0 and _DATA1 registers
+/// @param[out] The swizzle pattern
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode swizzle_mpr_pattern( const uint32_t i_pattern, uint32_t& o_swizzled)
+{
+ constexpr uint64_t BYTES_PER_32 = 4;
+ fapi2::buffer<uint32_t> l_buf (i_pattern);
+
+ // loop over each byte and reverse the bits
+ for (size_t count = 0; count < BYTES_PER_32; ++count)
+ {
+ fapi2::buffer<uint8_t> l_temp;
+ FAPI_TRY( l_buf.extract(l_temp, count * BITS_PER_BYTE, BITS_PER_BYTE) );
+
+ // reverse is in swizzle.H. Reverses all of the bits in the buffer
+ mss::reverse(l_temp);
+ FAPI_TRY( l_buf.insert(l_temp, count * BITS_PER_BYTE, BITS_PER_BYTE) );
+ }
+
+ o_swizzled = l_buf;
+
+ FAPI_INF("0x%08x unswizzle 0x%08x swizzled that dizzle", i_pattern, o_swizzled);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
/// @brief reset SEQ_TIMING2
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H
index 3386b9b09..a310cde85 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H
@@ -357,6 +357,80 @@ fapi_try_exit:
}
///
+/// @brief Read SEQ_RDWR_DATA0 register
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to seqTraits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = seqTraits<T> >
+inline fapi2::ReturnCode read_rd_wr_data0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::SEQ_RDWR_DATA0, o_data), "%s failed to read rd_wr_data0 register",
+ mss::c_str(i_target) );
+ FAPI_DBG("%s read rd_wr_data0: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write SEQ_RDWR_DATA0 register
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to seqTraits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = seqTraits<T> >
+inline fapi2::ReturnCode write_rd_wr_data0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_DBG("%s write rd_wr_data0: 0x%016lx", mss::c_str(i_target), i_data);
+ FAPI_TRY( mss::putScom(i_target, TT::SEQ_RDWR_DATA0, i_data), "%s failed to write seq_rd_wr_data0 register",
+ mss::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Read SEQ_RDWR_DATA1 register
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to seqTraits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = seqTraits<T> >
+inline fapi2::ReturnCode read_rd_wr_data1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::SEQ_RDWR_DATA1, o_data), "%s failed to read rd_wr_data1 register",
+ mss::c_str(i_target) );
+ FAPI_DBG("%s rd_wr_data1: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write SEQ_RDWR_DATA1 register
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to seqTraits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = seqTraits<T> >
+inline fapi2::ReturnCode write_rd_wr_data1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_DBG("%s write rd_wr_data1: 0x%016lx", mss::c_str(i_target), i_data);
+ FAPI_TRY( mss::putScom(i_target, TT::SEQ_RDWR_DATA1, i_data), "%s failed to write seq_rd_wr_data1 register",
+ mss::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Setup odt_wr/rd_config
/// @tparam T fapi2 Target Type - derived
/// @tparam TT traits type defaults to seqTraits<T>
@@ -383,12 +457,12 @@ fapi2::ReturnCode reset_rd_wr_data( const fapi2::Target<T>& i_target )
fapi2::buffer<uint64_t> l_data;
l_data.insertFromRight<TT::MPR_PATTERN, TT::MPR_PATTERN_LEN>(MPR01_PATTERN);
- FAPI_INF("seq_rd_wr0 0x%llx", l_data);
+ FAPI_INF("%s seq_rd_wr0 0x%llx", mss::c_str(i_target), l_data);
FAPI_TRY( mss::putScom(i_target, TT::SEQ_RDWR_DATA0, l_data), "%s failed to reset seq_rd_wr0 register via write",
mss::c_str(i_target) );
l_data.insertFromRight<TT::MPR_PATTERN, TT::MPR_PATTERN_LEN>(MPR23_PATTERN);
- FAPI_INF("seq_rd_wr1 0x%llx", l_data);
+ FAPI_INF("%s seq_rd_wr1 0x%llx", mss::c_str(i_target), l_data);
FAPI_TRY( mss::putScom(i_target, TT::SEQ_RDWR_DATA1, l_data), "%s failed to reset seq_rd_wr1 register via write",
mss::c_str(i_target) );
@@ -397,6 +471,53 @@ fapi_try_exit:
}
///
+/// @brief Swizzle the MPR pattern for the register
+/// @param[in] i_patterns the patterns to put in SEQ_RDWR_DATA0 and _DATA1 registers
+/// @param[out] The swizzled pattern
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode swizzle_mpr_pattern( const uint32_t i_pattern, uint32_t& o_swizzled);
+
+///
+/// @brief Setup odt_wr/rd_config
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to seqTraits<T>
+/// @param[in] i_target the target associated with this cal setup
+/// @param[in] i_patterns the patterns to put in SEQ_RDWR_DATA0 and _DATA1 registers
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+template< fapi2::TargetType T, typename TT = seqTraits<T> >
+fapi2::ReturnCode setup_rd_wr_data( const fapi2::Target<T>& i_target, const uint32_t i_patterns)
+{
+ fapi2::buffer<uint32_t> l_data (i_patterns);
+ fapi2::buffer<uint64_t> l_temp;
+
+
+ FAPI_TRY( read_rd_wr_data0(i_target, l_temp),
+ "%s failed to reading rd_wr_data",
+ mss::c_str(i_target) );
+
+ l_data.extractToRight<mss::PATTERN0_START, mss::PATTERN0_LEN>(l_temp);
+
+ FAPI_TRY( write_rd_wr_data0(i_target, l_temp),
+ "%s failed to writing rd_wr_data",
+ mss::c_str(i_target) );
+
+ FAPI_TRY( read_rd_wr_data1(i_target, l_temp),
+ "%s failed to read rd_wr0 register via write",
+ mss::c_str(i_target) );
+
+ l_data.extractToRight<mss::PATTERN1_START, mss::PATTERN1_LEN>(l_temp);
+
+ FAPI_TRY( write_rd_wr_data1(i_target, l_temp),
+ "%s failed to write seq_rd_wr1 register via write",
+ mss::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief reset SEQ_CONFIG0
/// @tparam T fapi2 Target Type - derived
/// @tparam TT traits type defaults to seqTraits<T>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
index be658549e..5dcf336db 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
@@ -216,10 +216,11 @@ enum cal_steps : uint64_t
WRITE_CTR = 17, ///< Write Centering
COARSE_WR = 18, ///< Initial Coarse Pattern Write
COARSE_RD = 19, ///< Coarse Read Centering
+ TRAINING_ADV = 20, ///< Flag for draminit training advance in the attribute/ CUSTOM_READ_CTR in code
// Not *exactly* a cal step but go w/it
- RUN_ALL_CAL_STEPS = 0xFFFFF000,
- RUN_CAL_SKIP_WR_RD_2D_VREF = 0xFFFD7000,
+ RUN_ALL_CAL_STEPS = 0xFFFFF800,
+ RUN_CAL_SKIP_WR_RD_2D_VREF = 0xFFFD7800,
INITIAL_PAT_WR_TO_RD_CTR_LEN = inclusive_range(INITIAL_PAT_WR, READ_CTR),
WR_VREF_TO_COARSE_RD_LEN = inclusive_range(WRITE_CTR_2D_VREF, COARSE_RD),
@@ -228,6 +229,17 @@ enum cal_steps : uint64_t
DRAM_ZQCAL_UP_TO_WRITE_CTR_2D_VREF = WRITE_CTR_2D_VREF,
};
+///
+/// @brief enums for draminit_training_adv procedure
+///
+enum training_advance
+{
+ PATTERN0_START = 0,
+ PATTERN0_LEN = 16,
+ PATTERN1_START = 16,
+ PATTERN1_LEN = 16
+};
+
// Static consts for DDR4 voltages used in p9_mss_volt
enum voltages : uint64_t
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
index b440ebd9a..533a53905 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
@@ -123,6 +123,9 @@ extern "C"
FAPI_TRY( mss::cal_step_enable(p, l_cal_steps_enabled), "Error in p9_mss_draminit_training" );
}
+ // Clear the Training Advance bit because this is used in training_adv and not in training
+ l_cal_steps_enabled.clearBit<mss::TRAINING_ADV>();
+
FAPI_DBG("cal steps enabled: 0x%x special training: 0x%x", l_cal_steps_enabled, i_special_training);
// ZQCAL (for DRAMs and LRDIMM data buffers) isn't a PHY calibration,
@@ -171,10 +174,11 @@ extern "C"
// THE PROCESSING OF THE ERRORS. (it's hard to figure out which DIMM failed, too) BRS.
for (const auto& rp : l_pairs)
{
+ bool l_cal_fail = false;
FAPI_INF("Execute cal on rp %d %s", rp, mss::c_str(p));
FAPI_TRY( mss::setup_and_execute_cal(p, rp, l_cal_steps_enabled, l_cal_abort_on_error) );
- FAPI_TRY( mss::find_and_log_cal_errors(p, rp, l_cal_abort_on_error, l_fails) );
+ FAPI_TRY( mss::find_and_log_cal_errors(p, rp, l_cal_abort_on_error, l_cal_fail, l_fails) );
}// rank pairs
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
index 98795e185..cb431f5d1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
@@ -24,7 +24,7 @@
/* IBM_PROLOG_END_TAG */
///
/// @file p9_mss_draminit_training_adv.C
-/// @brief Train dram
+/// @brief Perform read_centering again but with a custom pattern for better eye
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
@@ -36,30 +36,164 @@
#include <mss.H>
#include <vector>
-#include <p9_mss_draminit_training.H>
+#include <p9_mss_draminit_training_adv.H>
#include <lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
-#include <lib/workarounds/dp16_workarounds.H>
-#include <lib/workarounds/dqs_align_workarounds.H>
-#include <lib/fir/unmask.H>
-#include <lib/dimm/ddr4/zqcal.H>
+#include <lib/phy/dp16.H>
+#include <lib/phy/seq.H>
+#include <lib/phy/ddr_phy.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
extern "C"
{
- ///
- /// @brief Train dram
- /// @param[in] i_target, the McBIST of the ports of the dram you're training
- /// @param[in] i_special_training, optional CAL_STEP_ENABLE override. Used in sim, debug
- /// @param[in] i_abort_on_error, optional CAL_ABORT_ON_ERROR override. Used in sim, debug
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
+///
+/// @brief Perform training_adv on the dimms (perform read centering with custom pattern)
+/// @param[in] i_target, the McBIST of the ports of the dram you're training
+/// @param[in] i_abort_on_error, optional CAL_ABORT_ON_ERROR override. Used in sim, debug
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note turn off rd cntr periodic cal if training_adv is run. Add OFF value for CUSTOM_PATTERN?
+///
+
fapi2::ReturnCode p9_mss_draminit_training_adv( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const uint32_t i_special_training,
const uint8_t i_abort_on_error)
{
+ std::vector<fapi2::ReturnCode> l_fails;
+ uint8_t l_cal_abort_on_error = i_abort_on_error;
+
+ FAPI_INF("Start draminit training advance %s", mss::c_str(i_target));
+
+ // If there are no DIMMs installed, we don't need to bother. In fact, we can't as we didn't setup
+ // attributes for the PHY, etc.
+ if (mss::count_dimm(i_target) == 0)
+ {
+ FAPI_INF("... skipping draminit_training_adv %s - no DIMM ...", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ if (i_abort_on_error == CAL_ADV_ABORT_SENTINAL)
+ {
+ FAPI_TRY( mss::cal_abort_on_error(l_cal_abort_on_error) );
+ }
+
+ // If Custom Read Centering or Custom Write Centering was performed,
+ // an Initial Pattern Write of 5555 hex, the reset value of the registers described in,
+ // must be performed before any periodic calibration routines are performed.
+ // Clean out any previous calibration results, set bad-bits and configure the ranks.
+ for( const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
+ {
+ fapi2::buffer<uint32_t> l_cal_steps_enabled;
+ FAPI_TRY( mss::cal_step_enable(p, l_cal_steps_enabled), "Error in p9_mss_draminit_training %s", mss::c_str(i_target) );
+
+ if (!l_cal_steps_enabled.getBit<mss::TRAINING_ADV>())
+ {
+ FAPI_INF("ATTR_MSS_CAL_STEPS_ENABLED says to skip draminit training advance, so skipping %s",
+ mss::c_str(i_target));
+ continue;
+ }
+
+ // If we see the bit to for training_adv, let's set up our cal config.
+ // As per the PHY spec, only INITIAL_PAT_WRITE and the CUSTOM_RD_PATTERN bits should be set
+ // TRAINING_ADV == CUSTOM_RD_PATTERN
+ l_cal_steps_enabled = 0;
+ l_cal_steps_enabled.setBit<mss::INITIAL_PAT_WR>().setBit<mss::TRAINING_ADV>();
+
+ // Keep track of the last error seen by a rank pair
+ fapi2::ReturnCode l_rank_pair_error(fapi2::FAPI2_RC_SUCCESS);
+
+ // Clear all of the errors before we start
+ FAPI_TRY(mss::clear_initial_cal_errors(p), "%s error resetting errors prior to init cal", mss::c_str(p));
+
+ // Returned from set_rank_pairs, it tells us how many rank pairs
+ // we configured on this port.
+ std::vector<uint64_t> l_pairs;
+
+ // Let's set the pattern to run
+ FAPI_TRY( mss::configure_custom_pattern(p) );
+
+ // Set staggered mode
+ FAPI_TRY( mss::rc::change_staggered_pattern(p) );
+
+ // Set custom read centering mode
+ FAPI_TRY( mss::dp16::setup_custom_read_centering_mode(p), "Error in p9_mss_draminit_training %s",
+ mss::c_str(i_target) );
+
+ // Get our rank pairs.
+ FAPI_TRY( mss::rank::get_rank_pairs(p, l_pairs), "Error in p9_mss_draminit_training" );
+
+ // For each rank pair we need to calibrate, pop a ccs instruction in an array and execute it.
+ // NOTE: IF YOU CALIBRATE MORE THAN ONE RANK PAIR PER CCS PROGRAM, MAKE SURE TO CHANGE
+ // THE PROCESSING OF THE ERRORS. (it's hard to figure out which DIMM failed, too) BRS.
+ for (const auto& rp : l_pairs)
+ {
+ bool l_cal_fail = false;
+
+ std::vector<fapi2::ReturnCode> l_temp_fails;
+ FAPI_TRY( mss::setup_and_execute_cal(p, rp, l_cal_steps_enabled, l_cal_abort_on_error) );
+ FAPI_TRY( mss::find_and_log_cal_errors(p, rp, l_cal_abort_on_error, l_cal_fail, l_temp_fails) );
+
+ // If we got a fail, let's ignore the previous fails and run backup pattern
+ if (l_cal_fail)
+ {
+ l_cal_fail = false;
+
+ // Clear the disable bits from last run.
+ // This function restores bad_bits to how the attribute has them
+ // (which was updated at the end of regular training)
+ // So we won't run on known bad bits, but will rerun on the iffy bits from last custom_pattern run
+ FAPI_TRY( mss::dp16::reset_bad_bits( p ) );
+ FAPI_INF("%s rp%x running back up pattern for draminit_training_adv", mss::c_str(p), rp);
+
+ // Clear the cal errors so we can retry
+ FAPI_TRY(mss::clear_initial_cal_errors(p), "%s error resetting errors prior to init cal", mss::c_str(p));
+
+ fapi2::buffer<uint32_t> l_backup;
+ FAPI_TRY( mss::custom_training_adv_backup_patterns( p, l_backup) );
+
+ // Put the backup into the registers
+ FAPI_TRY( mss::seq::setup_rd_wr_data( p, l_backup) );
+
+ // Rerun the training for this rp
+ FAPI_TRY( mss::setup_and_execute_cal(p, rp, l_cal_steps_enabled, l_cal_abort_on_error) );
+ FAPI_TRY( mss::find_and_log_cal_errors(p, rp, l_cal_abort_on_error, l_cal_fail, l_fails) );
+
+ // If l_cal_fail == true here, error out
+ if (l_cal_fail)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
+
+ // Let's get the DIMM since we train per rank pair (primary rank pair)
+ FAPI_TRY( mss::rank_pair_primary_to_dimm(p,
+ rp,
+ l_dimm),
+ "Failed getting the DIMM for %s rp %x", mss::c_str(p), rp);
+
+ FAPI_ASSERT( l_cal_fail == false,
+ fapi2::MSS_DRAMINIT_TRAINING_CUSTOM_PATTERN_RD_ERROR()
+ .set_PORT_POSITION(mss::index(p))
+ .set_RANKGROUP_POSITION(rp)
+ .set_MCA_TARGET(p)
+ .set_DIMM_TARGET(l_dimm),
+ "%s rp%x Failed Draminit_training_adv", mss::c_str(p), rp);
+ }
+ }
+ }// rank pairs
+
+ // Resetting current_err.
+ // The error has either already been "logged" or we have exited and returned the error up the call stack.
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // If we fail draminit_training_adv, we should exit out the ipl / reconfigure
+ // Shouldn't really get here but let's do it anyways
+ if (l_fails.size() != 0)
+ {
+ FAPI_TRY(l_fails[0]);
+ }
+
return fapi2::FAPI2_RC_SUCCESS;
+ fapi_try_exit:
+ return fapi2::current_err;
}
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.H
index 82469414d..363f0be15 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.H
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.H
@@ -22,8 +22,8 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/// @file p9_mss_draminit_trainingi_adv.H
-/// @brief Train DRAM
+/// @file p9_mss_draminit_training_adv.H
+/// @brief Perform custom read centering
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
@@ -37,7 +37,6 @@
#include <fapi2.H>
typedef fapi2::ReturnCode (*p9_mss_draminit_training_adv_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&,
- const uint32_t,
const uint8_t);
// Use a special sentinal to let you know you need to read the attribute (which is 1/0)
@@ -47,14 +46,12 @@ extern "C"
{
///
- /// @brief Train dram, assumes effective config has run
+ /// @brief Training advance, performs read_centering but with custom pattern for better eye
/// @param[in] i_target the McBIST of the ports of the dram you're training
- /// @param[in] i_special_training optional CAL_STEP_ENABLE override. Used in sim, debug
/// @param[in] i_abort_on_error, optional CAL_ABORT_ON_ERROR override. Used in sim, debug
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_draminit_training_adv( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- const uint32_t i_special_training = 0,
const uint8_t i_abort_on_error = CAL_ADV_ABORT_SENTINAL);
}
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 54d071b5a..6982eecaf 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
@@ -214,6 +214,8 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
// Sets up the calibration steps
FAPI_TRY( l_eff_dimm->cal_step_enable(), "Error from p9_mss_eff_config");
FAPI_TRY( l_eff_dimm->rdvref_enable_bit(), "Error from p9_mss_eff_config");
+ FAPI_TRY( l_eff_dimm->training_adv_pattern(), "Error from p9_mss_eff_config");
+ FAPI_TRY( l_eff_dimm->training_adv_backup_pattern(), "Error from p9_mss_eff_config");
//Let's do some checking
FAPI_TRY( mss::check::temp_refresh_mode(), "Error from p9_mss_eff_config");
OpenPOWER on IntegriCloud