summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/phy
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2017-09-29 13:34:18 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-10-02 23:46:33 -0400
commit1fe17ef6ff369ac8c1ae6b5a8b3cc294f8233a03 (patch)
treeff75068ffe46f46d882a651e221d1e77984ca4b7 /src/import/chips/p9/procedures/hwp/memory/lib/phy
parent3890040afa1dc93d58476d68df35cb44d49c57b2 (diff)
downloadtalos-hostboot-1fe17ef6ff369ac8c1ae6b5a8b3cc294f8233a03.tar.gz
talos-hostboot-1fe17ef6ff369ac8c1ae6b5a8b3cc294f8233a03.zip
Updates code to disable DQS on bad nibble
If we have a bad nibble on a x4 DIMM, then we want to disable the associated DQS to conserve power. This commit updates the code to disable the DQS on a bad DRAM for a x4 DIMM. Change-Id: I083d1739e431cc1229e60ab6067ac61c1b1a8ce7 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46940 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@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/46946 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/phy')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C69
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H10
2 files changed, 76 insertions, 3 deletions
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 129c37515..871c36fba 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
@@ -3196,6 +3196,67 @@ fapi_try_exit:
}
///
+/// @brief Configures the DQS_DISABLE register based upon the bad DQ information for x4 DRAM
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[in] i_dq_disable - the DQ disable information
+/// @param[in] i_reg - the DQS disable bit register to update
+///
+fapi2::ReturnCode reset_dqs_disable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const fapi2::buffer<uint64_t>& i_dq_disable,
+ const uint64_t i_reg)
+{
+ // Declaring the mappings from bad DQ to bad DQS
+ constexpr uint64_t BAD_DQ = MCA_DDRPHY_DP16_DATA_BIT_DISABLE0_RP0_P0_0_01_DISABLE_15;
+ constexpr uint64_t BAD_DQ_LEN = BITS_PER_NIBBLE;
+ constexpr uint64_t BAD_DQS = MCA_DDRPHY_DP16_DATA_BIT_DISABLE1_RP0_P0_0_01_DISABLE_16_23;
+ constexpr uint64_t BAD_DQS_LEN = 2;
+
+ // An entire nibble is bad if all of it's bits are set, so 0xf
+ constexpr uint64_t ALL_BAD = 0xf;
+
+ // Declares variables
+ fapi2::buffer<uint64_t> l_dqs_disable;
+ const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
+
+ // Checks if this DIMM is a x8 DIMM first, if so, skip it as a chip kill here is beyond our corrective capabilities
+ uint8_t l_width = 0;
+ FAPI_TRY(mss::eff_dram_width(i_target, l_width));
+
+ // Skip if the DIMIM is a x8
+ if(l_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8)
+ {
+ FAPI_INF("%s is a x8 DIMM, clearing DQS register 0x%016lx", mss::c_str(i_target), i_reg);
+ return mss::putScom(l_mca, i_reg, l_dqs_disable);
+ }
+
+ // Due to plug rules check, we should be a x4 now, so let's reset some DQS bits
+ for(uint64_t l_nibble = 0; l_nibble < NIBBLES_PER_DP; ++l_nibble)
+ {
+ // If we have a whole nibble bad, set the bad DQS bits
+ const auto DQ_START = BAD_DQ + (l_nibble * BAD_DQ_LEN);
+ const auto DQS_START = BAD_DQS + (l_nibble * BAD_DQS_LEN);
+
+ uint64_t l_nibble_disable = 0;
+
+ FAPI_TRY(i_dq_disable.extractToRight(l_nibble_disable, DQ_START, BAD_DQ_LEN));
+
+ if(l_nibble_disable == ALL_BAD)
+ {
+ FAPI_INF("%s found that nibble %lu was all bad on DQS reg 0x%016llx",
+ mss::c_str(i_target), l_nibble, i_reg);
+ FAPI_TRY(l_dqs_disable.setBit(DQS_START, BAD_DQS_LEN));
+ }
+ }
+
+ // Sets up the DQS register
+ FAPI_INF("%s setting DQS disable register 0x%016llx to 0x%016llx", mss::c_str(i_target), i_reg, l_dqs_disable);
+ FAPI_TRY(mss::putScom(l_mca, i_reg, l_dqs_disable), "%s failed to set 0x%016llx", mss::c_str(l_mca), i_reg);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Reset the bad-bits masks for a port - helper for ease of testing
/// @note Read the bad bits from the f/w attributes and stuff them in the
/// appropriate registers.
@@ -3215,7 +3276,7 @@ fapi2::ReturnCode reset_bad_bits_helper( const fapi2::Target<fapi2::TARGET_TYPE_
for (const auto& r : l_ranks)
{
uint64_t l_rp = 0;
- uint64_t l_dimm_index = rank::get_dimm_from_rank(r);
+ const uint64_t l_dimm_index = rank::get_dimm_from_rank(r);
FAPI_TRY( mss::rank::get_pair_from_rank(mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target), r, l_rp) );
FAPI_INF("%s processing bad bits for DIMM%d rank %d (%d) rp %d", mss::c_str(i_target), l_dimm_index, mss::index(r), r,
@@ -3236,13 +3297,15 @@ fapi2::ReturnCode reset_bad_bits_helper( const fapi2::Target<fapi2::TARGET_TYPE_
for (const auto& a : l_addrs)
{
- uint64_t l_register_value = (l_bad_bits[l_byte_index] << 8) | l_bad_bits[l_byte_index + 1];
+ const uint64_t l_register_value = (l_bad_bits[l_byte_index] << 8) | l_bad_bits[l_byte_index + 1];
- FAPI_INF("%s writing 0x%0lX value 0x%0lX from 0x%X, 0x%X",
+ FAPI_INF("%s writing 0x%016lX value 0x%016lX from 0x02%X, 0x%02X",
mss::c_str(i_target), a.first, l_register_value,
l_bad_bits[l_byte_index], l_bad_bits[l_byte_index + 1]);
FAPI_TRY( mss::putScom(mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target), a.first, l_register_value) );
+
+ FAPI_TRY(reset_dqs_disable(i_target, l_register_value, a.second));
l_byte_index += 2;
}
}
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 322310162..521a0afc1 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
@@ -1008,6 +1008,16 @@ fapi2::ReturnCode reset_bad_bits_helper(const fapi2::Target<fapi2::TARGET_TYPE_D
const uint8_t i_bad_dq[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT]);
///
+/// @brief Configures the DQS_DISABLE register based upon the bad DQ information for x4 DRAM
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[in] i_dq_disable - the DQ disable information
+/// @param[in] i_reg - the DQS disable bit register to update
+///
+fapi2::ReturnCode reset_dqs_disable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const fapi2::buffer<uint64_t>& i_dq_disable,
+ const uint64_t i_reg);
+
+///
/// @brief Configure the DP16 io_tx config0 registers
/// @tparam T the fapi2::TargetType
/// @tparam TT the target traits
OpenPOWER on IntegriCloud