summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2018-06-12 13:05:54 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2018-06-21 10:51:32 -0400
commitf5c960805358f1ecc373db55e42fde4772ac5c6e (patch)
treef476f3d15eef33fbdcb0aa27eea9daa431eb0d3e /src/import/chips/p9
parent866f841512dfe044ceb69c15ad85462d8e16ade1 (diff)
downloadtalos-hostboot-f5c960805358f1ecc373db55e42fde4772ac5c6e.tar.gz
talos-hostboot-f5c960805358f1ecc373db55e42fde4772ac5c6e.zip
Updates the training advanced algorithm
CQ:SW433145 RTC:194245 RTC:194985 Change-Id: I3022653dd2ab93f28b97a813c3277ae57846edee Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60698 Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60894 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C32
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H105
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C32
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H10
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C284
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H148
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C2
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml30
9 files changed, 511 insertions, 139 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 ff2ffda69..f8d7cfc7c 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
@@ -5078,6 +5078,38 @@ fapi_try_exit:
}
///
+/// @brief Determines and sets the ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS2 settings
+/// @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_pattern2()
+{
+ uint32_t l_special_patterns [PORTS_PER_MCS] = {};
+ FAPI_TRY( custom_training_adv_backup_patterns2( 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_PATTERNS2_DEFAULT_PATTERN0);
+
+ l_temp.insertFromRight<PATTERN1_START, PATTERN1_LEN>
+ (fapi2::ENUM_ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS2_DEFAULT_PATTERN1);
+
+ l_special_patterns[mss::index(iv_mca)] = l_temp;
+
+ FAPI_INF("%s setting training_adv_backup_pattern2 as 0x%08x", mss::c_str(iv_mca), l_temp);
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS2, iv_mcs, l_special_patterns) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Determines and sets the ATTR_MSS_CUSTOM_TRAINING_ADV_WR_PATTERN settings
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note overwrite the attribute to default values if it's set to 0
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 3eb69f099..85d36d904 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
@@ -785,6 +785,13 @@ class eff_dimm
fapi2::ReturnCode training_adv_backup_pattern();
///
+ /// @brief Determines and sets the ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS2 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_pattern2();
+
+ ///
/// @brief Determines and sets the ATTR_MSS_CUSTOM_TRAINING_ADV_WR_PATTERN settings
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note overwrite the attribute to default values if it's set to 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 c2cc8ee8f..7c3104315 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
@@ -9381,7 +9381,7 @@ fapi_try_exit:
/// pattern read 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: 0x8E8E for PATTERN0 0x2BC6 for
+/// is set to 0, using the default values of: 0x8E94 for PATTERN0 0x2BC6 for
/// PATTERN1 Set to default in
/// eff_config
///
@@ -9411,7 +9411,7 @@ fapi_try_exit:
/// pattern read 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: 0x8E8E for PATTERN0 0x2BC6 for
+/// is set to 0, using the default values of: 0x8E94 for PATTERN0 0x2BC6 for
/// PATTERN1 Set to default in
/// eff_config
///
@@ -9442,7 +9442,7 @@ fapi_try_exit:
/// pattern read 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: 0x8E8E for PATTERN0 0x2BC6 for
+/// is set to 0, using the default values of: 0x8E94 for PATTERN0 0x2BC6 for
/// PATTERN1 Set to default in
/// eff_config
///
@@ -9567,6 +9567,105 @@ fapi_try_exit:
}
///
+/// @brief ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS2 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 number 2 Used for custom_pattern_read 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: 0x13EC for
+/// PATTERN0 0x02FD for PATTERN1 Set to default in
+/// eff_config
+///
+inline fapi2::ReturnCode custom_training_adv_backup_patterns2(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_PATTERNS2,
+ 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_PATTERNS2: 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_PATTERNS2 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 number 2 Used for custom_pattern_read 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: 0x13EC for
+/// PATTERN0 0x02FD for PATTERN1 Set to default in
+/// eff_config
+///
+inline fapi2::ReturnCode custom_training_adv_backup_patterns2(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_PATTERNS2, 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_PATTERNS2: 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_PATTERNS2 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 number 2 Used for custom_pattern_read 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: 0x13EC for
+/// PATTERN0 0x02FD for PATTERN1 Set to default in
+/// eff_config
+///
+inline fapi2::ReturnCode custom_training_adv_backup_patterns2(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_PATTERNS2, 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_PATTERNS2: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MSS_CUSTOM_TRAINING_ADV_WR_PATTERN getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
/// @param[out] ref to the value uint8_t
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 225a25400..ce1655af4 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
@@ -76,6 +76,22 @@ namespace mss
{
///
+/// @brief Resets the FIR bit that is set by initcal
+/// @param[in] i_target the MCA
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode reset_initcal_fir_reg(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
+{
+ // Sets up the AND mask. Anything that's a 0 will cause the FIR there to be reset
+ fapi2::buffer<uint64_t> l_data;
+ l_data.flush<1>();
+ l_data.clearBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_2>();
+
+ // Does the scom to clear the register
+ return mss::putScom(i_target, MCA_IOM_PHY0_DDRPHY_FIR_REG_AND, l_data);
+}
+
+///
/// @brief Clears all training related errors - specialization for MCA
/// @param[in] i_target the port in question
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
@@ -103,6 +119,9 @@ fapi2::ReturnCode clear_initial_cal_errors( const fapi2::Target<TARGET_TYPE_MCA>
FAPI_TRY(mss::pc::reset_error_status0(i_target), "%s error resetting PC error status0", mss::c_str(i_target));
FAPI_TRY(mss::pc::reset_init_cal_error(i_target), "%s error resetting PC init cal errors", mss::c_str(i_target));
+ // Reset the FIR register
+ FAPI_TRY(reset_initcal_fir_reg(i_target));
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -1526,23 +1545,22 @@ fapi_try_exit:
///
/// @brief Set the custom pattern
/// @param[in] i_target the port target
+/// @param[in] i_pattern the human readable pattern to be configured
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template<>
-fapi2::ReturnCode configure_custom_pattern( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target )
+fapi2::ReturnCode configure_custom_pattern( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint32_t i_pattern )
{
- 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) );
+ // So first swizzle the pattern and then put it into the register
+ FAPI_TRY( mss::seq::swizzle_mpr_pattern(i_pattern, l_swizzled) );
FAPI_INF("%s the patterns before swizzle are 0x%08x and after 0x%08x",
mss::c_str(i_target),
- l_pattern,
+ i_pattern,
l_swizzled);
FAPI_TRY( mss::seq::setup_rd_wr_data( i_target, l_swizzled) );
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 7c69d4331..9195725ae 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
@@ -43,6 +43,13 @@ namespace mss
{
///
+/// @brief Resets the FIR bit that is set by initcal
+/// @param[in] i_target the MCA
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode reset_initcal_fir_reg(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target);
+
+///
/// @brief Perform initializations for the PHY
/// @param[in] i_target the MCBIST which has the PHYs to initialize
/// @return FAPI2_RC_SUCCESS iff ok
@@ -404,10 +411,11 @@ fapi2::ReturnCode rank_pair_primary_to_dimm(const fapi2::Target<T>& i_target, co
///
/// @brief Set the custom pattern
/// @param[in] i_target the port target
+/// @param[in] i_pattern the human readable pattern to be configured
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template<fapi2::TargetType T>
-fapi2::ReturnCode configure_custom_pattern( const fapi2::Target<T>& i_target );
+fapi2::ReturnCode configure_custom_pattern( const fapi2::Target<T>& i_target, const uint32_t i_pattern );
///
/// @brief Set the custom write pattern
/// @param[in] i_target the port target
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
index 122bb9e6f..b4dfb6110 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
@@ -62,6 +62,8 @@ namespace mss
namespace training
{
+// Below definitions are used to avoid linker errors
+constexpr custom_read_ctr::attr_func custom_read_ctr::DATA_PATTERNS[NUM_PATTERNS];
///
/// @brief Executes a cal step with workarounds
@@ -820,119 +822,35 @@ uint64_t coarse_wr_rd::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_
}
///
-/// @brief Executes the pre-cal step workaround
+/// @brief Executes a cal step with workarounds
/// @param[in] i_target - the MCA target on which to operate
/// @param[in] i_rp - the rank pair
/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode custom_read_ctr::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+fapi2::ReturnCode custom_read_ctr::execute( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
const uint8_t i_abort_on_error ) const
{
- FAPI_DBG("%s Running Pre-Custom RD CTR workaround steps on RP%d", mss::c_str(i_target), i_rp);
-
- // Sets up the patterns to run
- // Note: not technically a workaround
- {
- // Let's set the pattern to run
- FAPI_TRY( mss::configure_custom_pattern(i_target) );
-
- // Set staggered mode
- FAPI_TRY( mss::rc::change_staggered_pattern(i_target) );
-
- // Set custom read centering mode
- FAPI_TRY( mss::dp16::setup_custom_read_centering_mode(i_target), "Error in p9_mss_draminit_training %s",
- mss::c_str(i_target) );
- }
-
- // Runs initial pattern write
- {
- const auto l_ipw = std::make_shared<initial_pattern_write>();
-
- // Executes initial pattern write
- FAPI_TRY(l_ipw->execute(i_target, i_rp, i_abort_on_error), "%s failed to execute IPW", mss::c_str(i_target));
- }
-
- // Turn off refresh - this is an actual workaround
- FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
-fapi_try_exit:
- return fapi2::current_err;
+ reset_data_pattern();
+ return step::execute(i_target, i_rp, i_abort_on_error);
}
///
-/// @brief Runs the backup pattern if need be
+/// @brief Executes the pre-cal step workaround
/// @param[in] i_target - the MCA target on which to operate
/// @param[in] i_rp - the rank pair
/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
-/// @param[in,out] io_training_rc - the return code checking if training advanced failed
-/// @param[in] i_original_settings - the settings to restore if we take a failure on the backup patterns
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode custom_read_ctr::backup_pattern_run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+fapi2::ReturnCode custom_read_ctr::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
- const uint8_t i_abort_on_error,
- fapi2::ReturnCode& io_training_rc,
- const mss::dp16::rd_ctr_settings<fapi2::TARGET_TYPE_MCA>& i_original_settings ) const
+ const uint8_t i_abort_on_error ) const
{
- // If we got a fail, let's ignore the previous fails and run backup pattern
- if(io_training_rc != fapi2::FAPI2_RC_SUCCESS)
- {
- fapi2::ReturnCode l_fails_on_rp;
- fapi2::buffer<uint32_t> l_backup;
-
- // Log the error as recovered
- fapi2::logError(io_training_rc, fapi2::FAPI2_ERRL_SEV_RECOVERED);
- io_training_rc = fapi2::FAPI2_RC_SUCCESS;
-
- // Sets up the DIMM target for the rank
- // It's not needed until we process init cal failures, but it's a tad dangerous to have an uninitialized target
- fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
- FAPI_TRY( mss::rank_pair_primary_to_dimm(i_target,
- i_rp,
- l_dimm),
- "Failed getting the DIMM for %s", mss::c_str(i_target) );
-
- // 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(i_target) );
- FAPI_INF("%s rp%x running back up pattern for draminit_training_adv", mss::c_str(i_target), i_rp);
-
- // Clear the cal errors so we can retry
- FAPI_TRY( mss::clear_initial_cal_errors(i_target), "%s error resetting errors prior to init cal", mss::c_str(i_target));
-
- FAPI_TRY( mss::custom_training_adv_backup_patterns(i_target, l_backup) );
-
- // Put the backup into the registers
- FAPI_TRY( mss::seq::setup_rd_wr_data(i_target, l_backup) );
-
- // Runs initial pattern write
- {
- const auto l_ipw = std::make_shared<initial_pattern_write>();
-
- // Executes initial pattern write
- FAPI_TRY( l_ipw->execute(i_target, i_rp, i_abort_on_error), "%s failed to re-execute IPW", mss::c_str(i_target));
- }
-
- // Rerun the training for this rp
- FAPI_TRY( phy_step::run(i_target, i_rp, i_abort_on_error), "%s failed re-running CUSTOM_RD_CTR", mss::c_str(i_target));
-
- // Grab the return code for processing
- l_fails_on_rp = mss::process_initial_cal_errors(l_dimm);
-
- // If we took a fail, restore those settings
- if(l_fails_on_rp != fapi2::FAPI2_RC_SUCCESS)
- {
- // Log the error as recovered
- fapi2::logError(l_fails_on_rp, fapi2::FAPI2_ERRL_SEV_RECOVERED);
-
- // Restores our original settings and disable bits
- FAPI_TRY( i_original_settings.restore() );
- }
- }
+ FAPI_DBG("%s Running Pre-Custom RD CTR workaround steps on RP%d", mss::c_str(i_target), i_rp);
+ // Turn off refresh - this is an actual workaround
+ FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
fapi_try_exit:
return fapi2::current_err;
}
@@ -951,11 +869,16 @@ fapi2::ReturnCode custom_read_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_M
constexpr bool RUN_RD_CTR = true;
constexpr bool SKIP_RD_VREF = false;
- fapi2::ReturnCode l_fails_on_rp;
+ // Dummy RC value used to continue the loop
+ const fapi2::ReturnCode DUMMY_FAIL = fapi2::FAPI2_RC_INVALID_PARAMETER;
+ fapi2::ReturnCode l_fails_on_rp(DUMMY_FAIL);
// Save off registers in case adv training fails
mss::dp16::rd_ctr_settings<fapi2::TARGET_TYPE_MCA> l_original_settings(i_target, i_rp);
+
+ const auto l_ipw = std::make_shared<initial_pattern_write>();
+
// Sets up the DIMM target for the rank
// It's not needed until we process init cal failures, but it's a tad dangerous to have an uninitialized target
fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
@@ -967,19 +890,75 @@ fapi2::ReturnCode custom_read_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_M
// Setup the initial settings
FAPI_TRY( l_original_settings.save() );
- // Clear all of the errors before we start
- FAPI_TRY(mss::clear_initial_cal_errors(i_target), "%s error resetting errors prior to init cal", mss::c_str(i_target));
+ // Set staggered mode
+ FAPI_TRY( mss::rc::change_staggered_pattern(i_target) );
- // Now lets set the actual read_vref_config. We want to write/ clear this every time we run so seperate function
- FAPI_TRY( setup_read_vref_config1(i_target, RUN_RD_CTR, SKIP_RD_VREF),
- "%s Failed setting the read_vref_config1", mss::c_str(i_target) );
+ // Set custom read centering mode
+ FAPI_TRY( mss::dp16::setup_custom_read_centering_mode(i_target), "Error in p9_mss_draminit_training %s",
+ mss::c_str(i_target) );
- FAPI_TRY( phy_step::run(i_target, i_rp, i_abort_on_error) );
+ // Loops through all patterns while we have a failing case
+ while((iv_current_pattern < NUM_PATTERNS) && (l_fails_on_rp != fapi2::FAPI2_RC_SUCCESS))
+ {
+ uint32_t l_pattern = 0;
- // Grab the error for processing
- l_fails_on_rp = mss::process_initial_cal_errors(l_dimm);
+ // Log the error as recovered, IFF it's a real error
+ if(l_fails_on_rp != DUMMY_FAIL)
+ {
+ // Logs our error as recovered, as we are about ready to recover from it
+ fapi2::logError(l_fails_on_rp, fapi2::FAPI2_ERRL_SEV_RECOVERED);
+
+ // Resets up the dummy fail
+ l_fails_on_rp = DUMMY_FAIL;
+ FAPI_TRY(l_original_settings.restore());
+ }
- FAPI_TRY( backup_pattern_run( i_target, i_rp, i_abort_on_error, l_fails_on_rp, l_original_settings ));
+ // Let's set the pattern to run
+ FAPI_TRY( DATA_PATTERNS[iv_current_pattern]( i_target, l_pattern ) );
+ FAPI_INF("%s rp%lu: custom read centering about to kick off pattern number %lu with a value of 0x%08x",
+ mss::c_str(i_target), i_rp, iv_current_pattern, l_pattern);
+ FAPI_TRY( mss::configure_custom_pattern( i_target, l_pattern ) );
+ FAPI_TRY(l_ipw->execute(i_target, i_rp, i_abort_on_error));
+
+ // Clear all of the errors before we start
+ FAPI_TRY(mss::clear_initial_cal_errors(i_target), "%s error resetting errors prior to init cal", mss::c_str(i_target));
+
+ // Now lets set the actual read_vref_config. We want to write/ clear this every time we run so seperate function
+ FAPI_TRY( setup_read_vref_config1(i_target, RUN_RD_CTR, SKIP_RD_VREF),
+ "%s Failed setting the read_vref_config1", mss::c_str(i_target) );
+
+ FAPI_TRY( phy_step::run(i_target, i_rp, i_abort_on_error) );
+
+ // Let's keep track of the error.
+ // We don't want to error out here because we want to run on the other ports/ranks
+ // We'll add this to io_fails if we fail too many DQ's
+ l_fails_on_rp = mss::process_initial_cal_errors(l_dimm);
+
+ // Goes to the next pattern
+ ++iv_current_pattern;
+ }
+
+ // Log the error as recovered
+ // It's a real error at this point, but we "recover" by restoring the original settings
+ if((l_fails_on_rp != fapi2::FAPI2_RC_SUCCESS) && (l_fails_on_rp != DUMMY_FAIL))
+ {
+ // We detected an initcal error, set that training failed
+ iv_training_failed = true;
+
+ // Logs our error as recovered, as we are about ready to recovere from it
+ fapi2::logError(l_fails_on_rp, fapi2::FAPI2_ERRL_SEV_RECOVERED);
+
+ // Resets up the dummy fail
+ // Setting to success just for safety's sake
+ l_fails_on_rp = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_TRY(l_original_settings.restore());
+ }
+ // Training passes
+ else
+ {
+ iv_training_failed = false;
+ }
fapi_try_exit:
return fapi2::current_err;
@@ -1075,6 +1054,9 @@ fapi2::ReturnCode custom_write_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_
// Set staggered mode
FAPI_TRY( mss::rc::change_staggered_pattern(i_target) );
+ // Clear all of the errors before we start
+ FAPI_TRY(mss::clear_initial_cal_errors(i_target), "%s error resetting errors prior to init cal", mss::c_str(i_target));
+
// Run the calibrations tep
FAPI_TRY( phy_step::run(i_target, i_rp, i_abort_on_error) );
@@ -1084,12 +1066,20 @@ fapi2::ReturnCode custom_write_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_
// If we took a fail, restore those settings
if(l_rc != fapi2::FAPI2_RC_SUCCESS)
{
+ // We detected an initcal error, set that training failed
+ iv_training_failed = true;
+
// Log the error as recovered
fapi2::logError(l_rc, fapi2::FAPI2_ERRL_SEV_RECOVERED);
// Restores our original settings and disable bits
FAPI_TRY( l_original_settings.restore() );
}
+ // Training passes
+ else
+ {
+ iv_training_failed = false;
+ }
fapi_try_exit:
return fapi2::current_err;
@@ -1138,6 +1128,79 @@ fapi_try_exit:
}
///
+/// @brief Sets up and runs the calibration step
+/// @param[in] i_target - the MCA target on which to operate
+/// @param[in] i_rp - the rank pair
+/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode custom_training_facade::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const
+{
+ bool l_training_fail = false;
+
+ // Original WR and RD settings - used to restore starting settings we take any fails
+ mss::dp16::rd_ctr_settings<fapi2::TARGET_TYPE_MCA> l_rd_settings(i_target, i_rp);
+
+ // Saves off the original settings
+ FAPI_TRY(l_rd_settings.save());
+
+ // Resets the RD CTR pattern count
+ iv_rd_ctr->reset_data_pattern();
+
+ // Loops until we pass OR RD CTR runs out of patterns to try
+ do
+ {
+ // Run RD first
+ FAPI_TRY(iv_rd_ctr->pre_workaround(i_target, i_rp, i_abort_on_error));
+ FAPI_TRY(iv_rd_ctr->run(i_target, i_rp, i_abort_on_error));
+ FAPI_TRY(iv_rd_ctr->post_workaround(i_target, i_rp, i_abort_on_error));
+
+ // Gets our training result from custom RD CTR
+ l_training_fail = iv_rd_ctr->training_failed();
+
+ // If we didn't pass, exit out - we've exhausted all of our options
+ if(l_training_fail)
+ {
+ FAPI_ERR("%s rp%lu exhausted all of the custom RD CTR patterns. Exiting!", mss::c_str(i_target), i_rp);
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+ else
+ {
+ FAPI_INF("%s rp%lu passed on custom RD CTR. On to custom WR CTR", mss::c_str(i_target), i_rp);
+ }
+
+ // Here we know we're passing
+ // Therefore we should try to run the writes
+ FAPI_TRY(iv_wr_ctr->pre_workaround(i_target, i_rp, i_abort_on_error));
+ FAPI_TRY(iv_wr_ctr->run(i_target, i_rp, i_abort_on_error));
+ FAPI_TRY(iv_wr_ctr->post_workaround(i_target, i_rp, i_abort_on_error));
+
+ // Gets our training result from custom WR CTR
+ l_training_fail = iv_wr_ctr->training_failed();
+
+ // If we fail the custom write centering, it could have been due to bad RD settings, so hit restore the original RD settings
+ if(l_training_fail)
+ {
+ FAPI_ERR("%s rp%lu custom WR CTR failed. Restoring read values (in the hopes that the read caused the fail) and continuing.",
+ mss::c_str(i_target), i_rp);
+ FAPI_TRY(l_rd_settings.restore());
+ }
+ else
+ {
+ FAPI_INF("%s rp%lu custom WR CTR passed! continuing..", mss::c_str(i_target), i_rp);
+ }
+
+ // Run while training is failing and we still have custom RD centering patterns to try
+ }
+ while((l_training_fail) && (!iv_rd_ctr->is_out_of_patterns()));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Creates the vector of training steps to loop over
/// @param[in] i_cal_steps - the bit mask of calibration steps
/// @param[in] i_sim - simulation mode or not
@@ -1223,15 +1286,24 @@ std::vector<std::shared_ptr<step>> steps_factory(const fapi2::buffer<uint32_t>&
l_steps.push_back(std::make_shared<coarse_wr_rd>());
}
+ // We can't run custom pattern RD as it requires initial pattern write, so skipping it in SIM mode
+ const bool CUSTOM_RD = (!i_sim) && i_cal_steps.getBit<mss::cal_steps::TRAINING_ADV_RD>();
+
+ // Run custom WR CTR and custom RD CTR together
+ if(CUSTOM_RD && i_cal_steps.getBit<mss::cal_steps::TRAINING_ADV_WR>())
+ {
+ FAPI_INF("Custom RD_CTR and Custom WR_CTR are enabled");
+ l_steps.push_back(std::make_shared<custom_training_facade>());
+ }
// Training Advanced Read - aka custom pattern RD CTR
- if(i_cal_steps.getBit<mss::cal_steps::TRAINING_ADV_RD>())
+ else if(CUSTOM_RD)
{
FAPI_INF("Custom RD_CTR is enabled");
l_steps.push_back(std::make_shared<custom_read_ctr>());
}
// Training Advanced Write - aka custom pattern WR CTR
- if(i_cal_steps.getBit<mss::cal_steps::TRAINING_ADV_WR>())
+ else if(i_cal_steps.getBit<mss::cal_steps::TRAINING_ADV_WR>())
{
FAPI_INF("Custom WR_CTR is enabled");
l_steps.push_back(std::make_shared<custom_write_ctr>());
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H
index 2476a0324..447b2d1d6 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H
@@ -42,6 +42,7 @@
#include <lib/eff_config/timing.H>
#include <lib/phy/read_cntrl.H>
#include <lib/dimm/ddr4/latch_wr_vref.H>
+#include <lib/mss_attribute_accessors.H>
namespace mss
{
@@ -120,9 +121,9 @@ class step
/// @param[in] i_abort_on_error - whether or not we are aborting on cal error
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
///
- fapi2::ReturnCode execute( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const uint64_t i_rp,
- const uint8_t i_abort_on_error ) const;
+ virtual fapi2::ReturnCode execute( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const;
///
/// @brief Calculates the number of cycles a given calibration step will take
@@ -681,12 +682,18 @@ class coarse_wr_rd : public phy_step
class custom_read_ctr : public phy_step
{
public:
+ // Type def to beautify
+ using attr_func = fapi2::ReturnCode (*)(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&,
+ uint32_t&);
+
///
/// @brief Base constructor
///
custom_read_ctr() :
phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_CUSTOM_RD>(),
- "CUSTOM_READ_CTR")
+ "CUSTOM_READ_CTR"),
+ iv_current_pattern(0),
+ iv_training_failed(false)
{}
///
@@ -695,6 +702,17 @@ class custom_read_ctr : public phy_step
~custom_read_ctr() override = default;
///
+ /// @brief Executes a cal step with workarounds
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode execute( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
/// @brief Sets up and runs the calibration step
/// @param[in] i_target - the MCA target on which to operate
/// @param[in] i_rp - the rank pair
@@ -728,26 +746,51 @@ class custom_read_ctr : public phy_step
const uint8_t i_abort_on_error ) const override;
///
- /// @brief Runs the backup pattern if need be
- /// @param[in] i_target - the MCA target on which to operate
- /// @param[in] i_rp - the rank pair
- /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
- /// @param[in,out] io_training_rc - the return code checking if training advanced failed
- /// @param[in] i_original_settings - the settings to restore if we take a failure on the backup patterns
- /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
- ///
- fapi2::ReturnCode backup_pattern_run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const uint64_t i_rp,
- const uint8_t i_abort_on_error,
- fapi2::ReturnCode& io_training_rc,
- const mss::dp16::rd_ctr_settings<fapi2::TARGET_TYPE_MCA>& i_original_settings ) const;
-
- ///
/// @brief Calculates the number of cycles a given calibration step will take
/// @param[in] i_target - the MCA target on which to operate
/// @return l_cycles - the number of cycles a given calibration step wil take
///
uint64_t calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const override;
+
+ ///
+ /// @brief Resets the current pattern
+ /// @note Marked as constant as the current pattern is mutable
+ ///
+ void reset_data_pattern() const
+ {
+ iv_current_pattern = 0;
+ }
+
+ ///
+ /// @brief Returns true if we exhausted all of our training patterns
+ /// @return true if the current pattern is greater than our maximum number of patterns
+ ///
+ bool is_out_of_patterns() const
+ {
+ return iv_current_pattern >= NUM_PATTERNS;
+ }
+
+ ///
+ /// @brief Returns true if training failed
+ /// @return result of init cal training - true if a fail was detected
+ ///
+ inline bool training_failed() const
+ {
+ return iv_training_failed;
+ }
+
+ private:
+
+ // Declares the accessors for which RD CTR patterns to run in what order
+ constexpr static const uint32_t NUM_PATTERNS = 3;
+ constexpr static attr_func DATA_PATTERNS[NUM_PATTERNS] =
+ {
+ custom_training_adv_patterns,
+ custom_training_adv_backup_patterns,
+ custom_training_adv_backup_patterns2,
+ };
+ mutable uint64_t iv_current_pattern;
+ mutable bool iv_training_failed;
};
///
@@ -761,7 +804,8 @@ class custom_write_ctr : public phy_step
///
custom_write_ctr() :
phy_step( fapi2::buffer<uint64_t>().setBit<MCA_DDRPHY_PC_INIT_CAL_CONFIG0_P0_ENA_CUSTOM_WR>(),
- "CUSTOM_WRITE_CTR")
+ "CUSTOM_WRITE_CTR"),
+ iv_training_failed(false)
{}
///
@@ -786,6 +830,70 @@ class custom_write_ctr : public phy_step
/// @return l_cycles - the number of cycles a given calibration step wil take
///
uint64_t calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const override;
+
+ ///
+ /// @brief Returns true if training failed
+ /// @return result of init cal training - true if a fail was detected
+ ///
+ inline bool training_failed() const
+ {
+ return iv_training_failed;
+ }
+
+ private:
+ mutable bool iv_training_failed;
+};
+
+
+///
+/// @class custom_training_facade
+/// @brief Overall custom training algorithm
+/// @note Due to interactions between write and read calibrations, using a facade class to setup the combined custom training algorithm
+///
+class custom_training_facade : public step
+{
+ public:
+ ///
+ /// @brief Base constructor
+ ///
+ custom_training_facade() :
+ step( "CUSTOM_WRRD_CTR"),
+ iv_rd_ctr(std::make_shared<custom_read_ctr>()),
+ iv_wr_ctr(std::make_shared<custom_write_ctr>())
+ {}
+
+ ///
+ /// @brief Custom destructor
+ ///
+ ~custom_training_facade() override = default;
+
+ ///
+ /// @brief Sets up and runs the calibration step
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @param[in] i_rp - the rank pair
+ /// @param[in] i_abort_on_error - whether or not we are aborting on cal error
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rp,
+ const uint8_t i_abort_on_error ) const override;
+
+ ///
+ /// @brief Calculates the number of cycles a given calibration step will take
+ /// @param[in] i_target - the MCA target on which to operate
+ /// @return l_cycles - the number of cycles a given calibration step wil take
+ ///
+ uint64_t calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) const override
+ {
+ // This class doesn't run training itself
+ // iv_rd_ctr and iv_wr_ctr run it for us
+ // As such, a dummy value of 0 is ok here (it's needed by the API, but not useful in this case)
+ return 0;
+ }
+
+ private:
+ std::shared_ptr<custom_read_ctr> iv_rd_ctr;
+ std::shared_ptr<custom_write_ctr> iv_wr_ctr;
};
///
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 070b89139..711eca0ad 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
@@ -347,6 +347,8 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
"Failed training_adv_pattern for %s", mss::c_str(l_dimm) );
FAPI_TRY( l_eff_dimm->training_adv_backup_pattern(),
"Failed training_adv_backup_pattern for %s", mss::c_str(l_dimm) );
+ FAPI_TRY( l_eff_dimm->training_adv_backup_pattern2(),
+ "Failed training_adv_backup_pattern2 for %s", mss::c_str(l_dimm) );
//Let's do some checking
FAPI_TRY( mss::check::temp_refresh_mode(),
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
index 8a63dfb88..36d391ffa 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
@@ -1981,13 +1981,13 @@
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:
- 0x8E8E for PATTERN0
+ 0x8E94 for PATTERN0
0x2BC6 for PATTERN1
Set to default in eff_config
</description>
<valueType>uint32</valueType>
<initToZero></initToZero>
- <enum>DEFAULT_PATTERN0 = 0x8E8E, DEFAULT_PATTERN1 = 0x2BC6</enum>
+ <enum>DEFAULT_PATTERN0 = 0x8E94, DEFAULT_PATTERN1 = 0x2BC6</enum>
<writeable/>
<array>2</array>
<mssAccessorName>custom_training_adv_patterns</mssAccessorName>
@@ -2020,6 +2020,32 @@
</attribute>
<attribute>
+ <id>ATTR_MSS_CUSTOM_TRAINING_ADV_BACKUP_PATTERNS2</id>
+ <targetType>TARGET_TYPE_MCS</targetType>
+ <description>
+ Special training backup pattern number 2
+ Used for custom_pattern_read 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:
+ 0x13EC for PATTERN0
+ 0x02FD for PATTERN1
+ Set to default in eff_config
+ </description>
+ <valueType>uint32</valueType>
+ <initToZero></initToZero>
+ <enum>DEFAULT_PATTERN0 = 0x13EC, DEFAULT_PATTERN1 = 0x02FD</enum>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>custom_training_adv_backup_patterns2</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MSS_CUSTOM_TRAINING_ADV_WR_PATTERN</id>
<targetType>TARGET_TYPE_MCS</targetType>
<description>
OpenPOWER on IntegriCloud