diff options
author | Stephen Glancy <sglancy@us.ibm.com> | 2019-10-11 17:26:41 -0400 |
---|---|---|
committer | Christian R Geddes <crgeddes@us.ibm.com> | 2019-11-12 11:03:31 -0600 |
commit | 50b0357dd001a70e4e0da7a3e34b04d852dde21b (patch) | |
tree | 786844d88b682d23ca938e07f84a39fe9d870b7d /src/import/chips/p9/procedures/hwp/memory/lib | |
parent | 0b50210ae6e66161da3a930fca0fbaf9eb075acb (diff) | |
download | talos-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>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib')
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 |