From 2f8905f6acaf354967ef9dbb9ba96239625d2b61 Mon Sep 17 00:00:00 2001 From: Stephen Glancy Date: Thu, 9 Apr 2020 09:46:33 -0400 Subject: [PATCH] Adds explorer 2666 CCS write workaround Explorer has a bug where CCS will not send out proper data for CCS writes (and PDA commands) at 2666 due to a 0 value programmed into the WRDATA_DLY in the SRQ. The workaround is in two parts: 1. override the CWL attribute to be 18 instead of 14 2. program in the proper MRS in draminit Change-Id: I70f2cbcae0cc67cd0ae4859f8946a5f5a0c3c49c Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/94823 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Dev-Ready: STEPHEN GLANCY Reviewed-by: Louis Stermole Reviewed-by: ANDRE A MARIN Tested-by: Hostboot CI Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/95079 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Christian R Geddes --- .../procedures/hwp/memory/exp_draminit.C | 7 + .../hwp/memory/lib/ccs/ccs_traits_explorer.H | 2 +- .../exp_ccs_2666_write_workarounds.C | 171 ++++++++++++++++++ .../exp_ccs_2666_write_workarounds.H | 69 +++++++ .../hwp/memory/p9a_mss_eff_config.C | 4 + src/usr/isteps/istep07/makefile | 3 +- src/usr/isteps/istep13/makefile | 2 +- 7 files changed, 255 insertions(+), 3 deletions(-) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C index 0b2630990cd..f937526b556 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C @@ -45,6 +45,7 @@ #include #include #include +#include extern "C" { @@ -89,6 +90,12 @@ extern "C" FAPI_TRY(mss::exp::host_fw_phy_init_with_eye_capture(i_target, l_crc, l_phy_params)); } + // Loops through the ports and issues the workaround for CCS writes at 2666 + for(const auto& l_port : mss::find_targets(i_target)) + { + FAPI_TRY(mss::exp::workarounds::updates_mode_registers(l_port)); + } + // Unmask registers after draminit training FAPI_TRY(mss::unmask::after_draminit_training(i_target), "%s Failed after_draminit_training", mss::c_str(i_target)); diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H index 610b1482e79..92a6f8764f1 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H @@ -43,7 +43,7 @@ #include #include #include -#include +#include /// /// @class ccsTraits diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.C index 66f9c9bc350..f058aab7c0c 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.C @@ -22,3 +22,174 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_ccs_2666_workarounds.H +/// @brief Workarounds for explorer CCS write issue at 2666 +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Mark Pizzutillo +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: Memory + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ +namespace exp +{ +namespace workarounds +{ + +/// +/// @brief Determine if the CCS 2666 write workaround is needed +/// @param[in] i_target port target on which to operate +/// @param[out] o_is_needed true if the workaround needs to be run +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode is_ccs_2666_write_needed(const fapi2::Target& i_target, + bool& o_is_needed) +{ + constexpr uint64_t FREQ_NEEDS_WORKAROUND = 2666; + constexpr bool NO_RCD = false; + + uint64_t l_freq = 0; + bool l_has_rcd = false; + o_is_needed = false; + + FAPI_TRY(mss::attr::get_freq(i_target, l_freq)); + FAPI_TRY(mss::unmask::has_rcd(i_target, l_has_rcd)); + + // The workaround is needed if we're at 2666 and do not have an RCD + o_is_needed = (l_freq == FREQ_NEEDS_WORKAROUND) && + (l_has_rcd == NO_RCD); + FAPI_DBG("%s freq:%lu, RCD:%s, workaround %s needed", + mss::c_str(i_target), l_freq, l_has_rcd ? "yes" : "no", o_is_needed ? "is" : "not"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Updates CAS write latency if the workaround is needed +/// @param[in] i_target port target on which to operate +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note This is the first part of the CCS 2666 write workaround +/// The CWL needs to be increased to 18 for 2666 (non RDIMM) +/// This will put a non-zero value in the WRDATA_DLY, allowing for good CCS writes +/// +fapi2::ReturnCode update_cwl(const fapi2::Target& i_target) +{ + constexpr uint64_t WORKAROUND_CWL = 18; + bool l_is_needed = false; + + FAPI_TRY(is_ccs_2666_write_needed(i_target, l_is_needed)); + + // If the workaround is not needed, skip it + if(l_is_needed == false) + { + return fapi2::FAPI2_RC_SUCCESS; + } + + // Update the CWL to the workaround value + FAPI_TRY(mss::attr::set_dram_cwl(i_target, WORKAROUND_CWL)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper that adds the MR2 commands +/// @param[in] i_target port target on which to operate +/// @param[out] o_instructions CCS instructions +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note Unit test helper +/// +fapi2::ReturnCode updates_mode_registers_helper(const fapi2::Target& i_target, + std::vector& o_instructions) +{ + // The PHY puts us into self time refresh mode prior + // We need to exit self time refresh mode by holding the CKE high + // The time for this is tXPR = tRFC(min) + 10 ns + // This is 560ns -> 746 clocks. rounded up to 750 for saftey + constexpr uint16_t TXPR_SAFE_MARGIN = 750; + + o_instructions.clear(); + + o_instructions.push_back(mss::ccs::des_command(TXPR_SAFE_MARGIN)); + + for(const auto& l_dimm : mss::find_targets(i_target)) + { + fapi2::ReturnCode l_mrs_rc = fapi2::FAPI2_RC_SUCCESS; + mss::ddr4::mrs02_data l_data(l_dimm, l_mrs_rc); + + std::vector> l_ranks; + FAPI_TRY(mss::rank::ranks_on_dimm(l_dimm, l_ranks)); + FAPI_TRY(l_mrs_rc); + + // Loops through all ranks on this DIMM and adds them to the CCS instructions to execute + for(const auto& l_rank_info : l_ranks) + { + FAPI_TRY(mss::mrs_engine( l_dimm, + l_data, + l_rank_info.get_port_rank(), + mrsTraits::mrs_tmod(i_target), + o_instructions )); + } + } + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Updates MR2 to have the proper CWL value if the workaround is needed +/// @param[in] i_target port target on which to operate +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note This is the second part of the CCS 2666 write workaround +/// The CWL needs to be programmed into MR2 +/// This cannot be done with the Microchip FW as we do not have a parameter for CWL +/// +fapi2::ReturnCode updates_mode_registers(const fapi2::Target& i_target) +{ + bool l_is_needed = false; + + FAPI_TRY(is_ccs_2666_write_needed(i_target, l_is_needed)); + + // If the workaround is not needed, skip it + if(l_is_needed == false) + { + return fapi2::FAPI2_RC_SUCCESS; + } + + // Update the CWL to the workaround value + { + mss::ccs::program l_program; + + // Adds the instructions + FAPI_TRY(updates_mode_registers_helper(i_target, l_program.iv_instructions)); + + // Executes the CCS commands + FAPI_TRY(mss::ccs::execute(mss::find_target(i_target), + l_program, + i_target)); + } + +fapi_try_exit: + return fapi2::current_err; +} + + +} // workarounds +} // exp +} // mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.H index 958678a8cc7..71d260df07c 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_ccs_2666_write_workarounds.H @@ -22,3 +22,72 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_ccs_2666_workarounds.H +/// @brief Workarounds for explorer CCS write issue at 2666 +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Mark Pizzutillo +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: Memory + +#ifndef _EXP_CCS_2666_WRITE_WORKAROUNDS_H_ +#define _EXP_CCS_2666_WRITE_WORKAROUNDS_H_ + +#include +#include + +namespace mss +{ +namespace exp +{ +namespace workarounds +{ + +/// +/// @brief Determine if the CCS 2666 write workaround is needed +/// @param[in] i_target port target on which to operate +/// @param[out] o_is_needed true if the workaround needs to be run +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode is_ccs_2666_write_needed(const fapi2::Target& i_target, + bool& o_is_needed); + +/// +/// @brief Updates CAS write latency if the workaround is needed +/// @param[in] i_target port target on which to operate +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note This is the first part of the CCS 2666 write workaround +/// The CWL needs to be increased to 18 for 2666 (non RDIMM) +/// This will put a non-zero value in the WRDATA_DLY, allowing for good CCS writes +/// +fapi2::ReturnCode update_cwl(const fapi2::Target& i_target); + +/// +/// @brief Helper that adds the MR2 commands +/// @param[in] i_target port target on which to operate +/// @param[out] o_instructions CCS instructions +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note Unit test helper +/// +fapi2::ReturnCode updates_mode_registers_helper(const fapi2::Target& i_target, + std::vector& o_instructions); + +/// +/// @brief Updates MR2 to have the proper CWL value if the workaround is needed +/// @param[in] i_target port target on which to operate +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note This is the second part of the CCS 2666 write workaround +/// The CWL needs to be programmed into MR2 +/// This cannot be done with the Microchip FW as we do not have a parameter for CWL +/// +fapi2::ReturnCode updates_mode_registers(const fapi2::Target& i_target); + + +} // workarounds +} // exp +} // mss + +#endif diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C index 11e40b20079..44b48d65f22 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C @@ -51,6 +51,7 @@ #include #include #include +#include /// /// @brief Configure the attributes for each controller @@ -135,6 +136,9 @@ fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target