summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2019-10-11 17:26:41 -0400
committerChristian R Geddes <crgeddes@us.ibm.com>2019-11-12 11:03:31 -0600
commit50b0357dd001a70e4e0da7a3e34b04d852dde21b (patch)
tree786844d88b682d23ca938e07f84a39fe9d870b7d
parent0b50210ae6e66161da3a930fca0fbaf9eb075acb (diff)
downloadtalos-hostboot-50b0357dd001a70e4e0da7a3e34b04d852dde21b.tar.gz
talos-hostboot-50b0357dd001a70e4e0da7a3e34b04d852dde21b.zip
Adds NVDIMM RCW drive strength workaround
An NVDIMM supplier updated the drive strength values for for the RCW's command/address/control signals. The new drive strength causes the parts to fail writes/reads. This commit restores the old drive strength values. Change-Id: If4d44f08cff2522de463b9a2ac57853950aa3356 CQ:SW478491 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/85229 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: JEREMY R NEATON <jrneaton@us.ibm.com> Reviewed-by: TSUNG K YEUNG <tyeung@us.ibm.com> Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/85426 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R Geddes <crgeddes@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C70
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H51
3 files changed, 135 insertions, 0 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 5074a5b4d..2c3a3a757 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
@@ -51,6 +51,7 @@
#include <lib/phy/dp16.H>
#include <lib/mss_attribute_accessors_manual.H>
#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
+#include <lib/workarounds/eff_config_workarounds.H>
namespace mss
{
@@ -1567,6 +1568,7 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dimm_rc03()
{
+ constexpr uint8_t NVDIMM_RCW_WORKAROUND_VALUE = 0x08;
fapi2::buffer<uint8_t> l_buffer;
uint8_t l_attrs_dimm_rc03[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
@@ -1589,6 +1591,10 @@ fapi2::ReturnCode eff_dimm::dimm_rc03()
l_buffer.insertFromRight<CA_START, LEN>(l_ca_output_drive)
.insertFromRight<CS_START, LEN>(l_cs_output_drive);
}
+
+ // Update the value if the NVDIMM workaround is needed
+ FAPI_TRY(mss::workarounds::eff_config::nvdimm_rc_drive_strength(iv_dimm, NVDIMM_RCW_WORKAROUND_VALUE, l_buffer));
+
// Retrieve MCS attribute data
FAPI_TRY( eff_dimm_ddr4_rc03(iv_mcs, &l_attrs_dimm_rc03[0][0]) );
@@ -1608,6 +1614,7 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dimm_rc04()
{
+ constexpr uint8_t NVDIMM_RCW_WORKAROUND_VALUE = 0x0a;
uint8_t l_attrs_dimm_rc04[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
uint8_t l_odt_output_drive = 0;
uint8_t l_cke_output_drive = 0;
@@ -1631,6 +1638,9 @@ fapi2::ReturnCode eff_dimm::dimm_rc04()
.insertFromRight<ODT_START, LEN>(l_odt_output_drive);
}
+ // Update the value if the NVDIMM workaround is needed
+ FAPI_TRY(mss::workarounds::eff_config::nvdimm_rc_drive_strength(iv_dimm, NVDIMM_RCW_WORKAROUND_VALUE, l_buffer));
+
// Retrieve MCS attribute data
FAPI_TRY( eff_dimm_ddr4_rc04(iv_mcs, &l_attrs_dimm_rc04[0][0]) );
@@ -1650,6 +1660,7 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dimm_rc05()
{
+ constexpr uint8_t NVDIMM_RCW_WORKAROUND_VALUE = 0x0a;
uint8_t l_attrs_dimm_rc05[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
uint8_t l_a_side_output_drive = 0;
uint8_t l_b_side_output_drive = 0;
@@ -1673,6 +1684,9 @@ fapi2::ReturnCode eff_dimm::dimm_rc05()
.insertFromRight<A_START, LEN>(l_a_side_output_drive);
}
+ // Update the value if the NVDIMM workaround is needed
+ FAPI_TRY(mss::workarounds::eff_config::nvdimm_rc_drive_strength(iv_dimm, NVDIMM_RCW_WORKAROUND_VALUE, l_buffer));
+
// Retrieve MCS attribute data
FAPI_TRY( eff_dimm_ddr4_rc05(iv_mcs, &l_attrs_dimm_rc05[0][0]) );
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C
index 080023b8a..dae18167b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C
@@ -22,3 +22,73 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+
+#include <fapi2.H>
+#include <lib/mss_attribute_accessors.H>
+#include <lib/workarounds/eff_config_workarounds.H>
+
+namespace mss
+{
+
+namespace workarounds
+{
+
+namespace eff_config
+{
+
+///
+/// @brief Checks if the NVDIMM RC drive strength workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[out] o_is_needed true if the workaround is needed
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode is_nvdimm_rc_drive_strength_needed(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ bool& o_is_needed)
+{
+ o_is_needed = false;
+
+ uint8_t l_hybrid = 0;
+ uint8_t l_hybrid_type = 0;
+ uint32_t l_size = 0;
+
+ FAPI_TRY(mss::eff_hybrid(i_target, l_hybrid));
+ FAPI_TRY(mss::eff_hybrid_memory_type(i_target, l_hybrid_type));
+ FAPI_TRY(mss::eff_dimm_size(i_target, l_size));
+
+ if(l_hybrid == fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID &&
+ l_hybrid_type == fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM &&
+ l_size == fapi2::ENUM_ATTR_EFF_DIMM_SIZE_32GB)
+ {
+ o_is_needed = true;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Updates the RC drive strength if the workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_override_value the value to override if the workaround needs to be applied
+/// @param[in,out] io_rc_value Register Control word value to update
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode nvdimm_rc_drive_strength(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_override_value,
+ fapi2::buffer<uint8_t>& io_rc_value)
+{
+ bool l_is_needed = false;
+ FAPI_TRY(is_nvdimm_rc_drive_strength_needed(i_target, l_is_needed));
+
+ // If the workaround is needed, overwrite it to be ALL_MODERATE values
+ // Otherwise keep it as it is
+ io_rc_value = l_is_needed ? fapi2::buffer<uint8_t>(i_override_value) : io_rc_value;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns eff_config
+} // ns workarounds
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H
index ad8bee571..f41d9b89c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H
@@ -22,3 +22,54 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file eff_config_workarounds.H
+/// @brief Workarounds for effective config
+/// Workarounds are very device specific, so there is no attempt to generalize
+/// this code in any way.
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _EFF_CONFIG_WORKAROUNDS_H_
+#define _EFF_CONFIG_WORKAROUNDS_H_
+
+#include <fapi2.H>
+
+namespace mss
+{
+
+namespace workarounds
+{
+
+namespace eff_config
+{
+
+///
+/// @brief Checks if the NVDIMM RC drive strength workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[out] o_is_needed true if the workaround is needed
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode is_nvdimm_rc_drive_strength_needed(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ bool& o_is_needed);
+
+///
+/// @brief Updates the RC drive strength if the workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_override_value the value to override if the workaround needs to be applied
+/// @param[in,out] io_rc_value Register Control word value to update
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode nvdimm_rc_drive_strength(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_override_value,
+ fapi2::buffer<uint8_t>& io_rc_value);
+
+} // ns eff_config
+} // ns workarounds
+} // ns mss
+#endif
OpenPOWER on IntegriCloud