diff options
author | Stephen Glancy <sglancy@us.ibm.com> | 2019-08-09 10:45:34 -0400 |
---|---|---|
committer | Daniel M Crowell <dcrowell@us.ibm.com> | 2019-08-16 09:28:22 -0500 |
commit | 7b8bfcc23ac6ce0f228bd5db5d3eaf4f173e42e4 (patch) | |
tree | be9e8f11f6aea0254116668d4d2da97f42631ff1 /src/import/chips/p9/procedures/hwp/memory | |
parent | 67fcaa2aafc5302195c086cb63b85b3c1353face (diff) | |
download | talos-hostboot-7b8bfcc23ac6ce0f228bd5db5d3eaf4f173e42e4.tar.gz talos-hostboot-7b8bfcc23ac6ce0f228bd5db5d3eaf4f173e42e4.zip |
Adds NVDIMM RD DQ delay workaround
NVDIMM requires a +2 offset be added to the RD DQ delays
Change-Id: I98bf2a534140f5966ad4a781bd3809ac4a569be5
CQ:SW472567
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/82016
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+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>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/82041
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: Daniel M Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory')
3 files changed, 121 insertions, 2 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C index 798447c83..f9e3b08d7 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C @@ -59,6 +59,79 @@ namespace mss namespace workarounds { +// Putting the NVDIMM workarounds here as it's a bit of a hybrid case +// Also there are issues as the nvdimm_workarounds.* files are picked up externally +namespace nvdimm +{ + +/// +/// @brief Checks if the NVDIMM RD DQ delay adjust is needed +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_is_needed true if the workaround is needed +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode is_adjust_rd_dq_delay_needed( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + bool& o_is_needed ) +{ + uint8_t l_hybrid_type[mss::MAX_DIMM_PER_PORT] = {}; + uint8_t l_is_hybrid[mss::MAX_DIMM_PER_PORT] = {}; + o_is_needed = false; + + FAPI_TRY(mss::eff_hybrid_memory_type(i_target, l_hybrid_type)); + FAPI_TRY(mss::eff_hybrid(i_target, l_is_hybrid)); + + // This workaround is only needed if we're dealing with NVDIMM + // We only need DIMM0 as NVDIMM will only ever be single drop + o_is_needed = (l_hybrid_type[0] == fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID) && + (l_is_hybrid[0] == fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Adjusts NVDIMM RD DQ delays +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_rp the rank pair on which to adjust delays +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode adjust_rd_dq_delay( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp ) +{ + // Constexpr's for some general beautification + constexpr uint64_t VALUE0_START = MCA_DDRPHY_DP16_READ_DELAY0_RANK_PAIR0_P0_0_01_RD; + constexpr uint64_t VALUE1_START = MCA_DDRPHY_DP16_READ_DELAY0_RANK_PAIR0_P0_0_01_RD_DELAY1; + typedef mss::dp16Traits<fapi2::TARGET_TYPE_MCA> TT; + + bool l_is_needed = false; + std::vector<fapi2::buffer<uint64_t>> l_data; + FAPI_TRY(is_adjust_rd_dq_delay_needed(i_target, l_is_needed)); + + // If the adjust is not needed, exit out + if(!l_is_needed) + { + FAPI_INF("%s RD DQ delay adjust isn't needed. Skipping the workaround", mss::c_str(i_target)); + return fapi2::FAPI2_RC_SUCCESS; + } + + // Read + FAPI_TRY(mss::scom_suckah(i_target, TT::READ_DELAY_REG[i_rp], l_data)); + + // Modify + for(auto& l_info : l_data) + { + update_rd_dq_delay<VALUE0_START>(l_info); + update_rd_dq_delay<VALUE1_START>(l_info); + } + + // Write + FAPI_TRY(mss::scom_blastah(i_target, TT::READ_DELAY_REG[i_rp], l_data)); + +fapi_try_exit: + return fapi2::current_err; +} + +} // close namespace nvdimm + namespace dp16 { diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H index daf9780d6..ddee4f42a 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -52,6 +52,48 @@ namespace mss namespace workarounds { +// Putting the NVDIMM workarounds here as it's a bit of a hybrid case +// Also there are issues as the nvdimm_workarounds.* files are picked up externally +namespace nvdimm +{ + +/// +/// @brief Updates a single RD DQ value for the NVDIMM workaround +/// @tparam P the bit position to update +/// @param[in,out] io_data the data bufffer to update +/// +template<uint64_t P> +void update_rd_dq_delay(fapi2::buffer<uint64_t>& io_data) +{ + constexpr uint64_t MAX_VALUE = 0x7f; + constexpr uint64_t OFFSET = 2; + constexpr uint64_t LEN = MCA_DDRPHY_DP16_READ_DELAY0_RANK_PAIR0_P0_0_01_RD_LEN; + uint64_t l_value = 0; + io_data.extractToRight<P, LEN>(l_value); + l_value += OFFSET; + l_value = std::min(l_value, MAX_VALUE); + io_data.insertFromRight<P, LEN>(l_value); +} + +/// +/// @brief Checks if the NVDIMM RD DQ delay adjust is needed +/// @param[in] i_target the fapi2 target of the port +/// @param[out] o_is_needed true if the workaround is needed +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode is_adjust_rd_dq_delay_needed( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + bool& o_is_needed ); + +/// +/// @brief Adjusts NVDIMM RD DQ delays +/// @param[in] i_target the fapi2 target of the port +/// @param[in] i_rp the rank pair on which to adjust delays +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode adjust_rd_dq_delay( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp ); + +} // close namespace nvdimm + namespace dp16 { 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 95a662883..67c3074a2 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 @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2017,2018 */ +/* Contributors Listed Below - COPYRIGHT 2017,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -43,6 +43,7 @@ #include <lib/phy/seq.H> #include <lib/phy/ddr_phy.H> #include <lib/phy/mss_training.H> +#include <lib/workarounds/dp16_workarounds.H> using fapi2::TARGET_TYPE_MCBIST; using fapi2::TARGET_TYPE_MCA; @@ -125,6 +126,9 @@ extern "C" { FAPI_TRY( l_step->execute(p, rp, l_cal_abort_on_error) ); } + + // Adjusts values for NVDIMM's + FAPI_TRY(mss::workarounds::nvdimm::adjust_rd_dq_delay(p, rp)); }// rank pairs // Resetting current_err. |