From 8f549e7548fb45819fc4fd8637448f428f14eec1 Mon Sep 17 00:00:00 2001 From: Mark Pizzutillo Date: Mon, 16 Sep 2019 17:08:27 -0400 Subject: Add code and workarounds for *_omi_setup and *_omi_train for Swift Change-Id: I139357a553e621b25b46bee6303357c712b67be2 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/83848 Tested-by: FSP CI Jenkins Dev-Ready: Steven B Janssen Tested-by: Jenkins Server Tested-by: PPE CI Reviewed-by: STEPHEN GLANCY Reviewed-by: Christian R Geddes Reviewed-by: Louis Stermole Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/83905 Reviewed-by: Daniel M Crowell Tested-by: Daniel M Crowell --- .../explorer/procedures/hwp/memory/exp_omi_setup.C | 55 ++++----- .../explorer/procedures/hwp/memory/exp_omi_train.C | 45 ++++++-- .../procedures/hwp/memory/exp_omi_train_check.C | 115 +++++++++++++++++++ .../procedures/hwp/memory/exp_omi_train_check.H | 29 +++++ .../procedures/hwp/memory/exp_omi_train_check.mk | 5 + .../procedures/hwp/memory/lib/i2c/exp_i2c.H | 38 ++++++- .../procedures/hwp/memory/lib/omi/exp_omi_utils.C | 34 +++++- .../procedures/hwp/memory/lib/omi/exp_omi_utils.H | 13 +++ .../memory/lib/workarounds/exp_omi_workarounds.C | 101 ++++++++++------- .../memory/lib/workarounds/exp_omi_workarounds.H | 38 ++++--- .../xml/error_info/exp_omi_train_errors.xml | 29 +++++ .../procedures/xml/error_info/mss_exp_errors.xml | 22 ++++ .../chips/p9a/procedures/hwp/memory/lib/mc/omi.H | 7 +- .../memory/lib/workarounds/p9a_omi_workarounds.C | 123 ++++++++++++++++----- .../memory/lib/workarounds/p9a_omi_workarounds.H | 52 ++++++++- .../p9a/procedures/hwp/memory/p9a_omi_setup.C | 74 +++++++++++++ .../p9a/procedures/hwp/memory/p9a_omi_setup.H | 29 +++++ .../p9a/procedures/hwp/memory/p9a_omi_setup.mk | 5 + .../p9a/procedures/hwp/memory/p9a_omi_train.C | 31 ++++-- .../procedures/hwp/memory/p9a_omi_train_check.C | 62 +++++++++-- .../xml/error_info/p9a_omi_train_errors.xml | 18 ++- 21 files changed, 771 insertions(+), 154 deletions(-) (limited to 'src/import') diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C index 0581cb8cf..2eb53635e 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C @@ -34,6 +34,7 @@ // *HWP Consumed by: Memory #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include extern "C" { @@ -54,17 +56,14 @@ extern "C" fapi2::ReturnCode exp_omi_setup( const fapi2::Target& i_target) { mss::display_git_commit_info("exp_omi_setup"); + uint8_t l_gem_menterp_workaround = 0; // Declares variables - fapi2::buffer l_data; - fapi2::buffer dlx_config1_data; - uint8_t l_edpl_disable = 0; - bool l_is_enterprise = false; - bool l_is_half_dimm = false; - bool l_workaround_required = false; std::vector l_boot_config_data; + + // BOOT CONFIG 0 uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_NON_DL_TRAINING; - uint8_t l_gem_menterp_workaround = 0; + // Gets the data setup FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_boot_config_data)); @@ -75,12 +74,27 @@ extern "C" // Note: This does not kick off OMI training FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_boot_config_data)); + // Check FW status for success + FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::DELAY_1MS, 100)); + FAPI_TRY(mss::exp::workarounds::omi::gem_menterp(i_target, l_gem_menterp_workaround)); - // If no workaround, we can perform menterp reads/writes (explorer) - // If workaround (gem). we need to bypass menterp. Can also bypass dlx_config1 since it's a noop - if (!l_gem_menterp_workaround) + // If no workaround (explorer), we can perform menterp reads/writes + // If workaround (gemini). we need to bypass menterp. Can also bypass dlx_config1 too since it's a noop + if (l_gem_menterp_workaround) + { + return fapi2::FAPI2_RC_SUCCESS; + } + + // Set up DLX_CONFIG1 { + fapi2::buffer l_data; + fapi2::buffer l_dlx_config1_data; + + uint8_t l_edpl_disable = 0; + bool l_is_enterprise = false; + bool l_is_half_dimm = false; + // Gets the configuration information from attributes FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise)); FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm)); @@ -102,24 +116,15 @@ extern "C" FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data)); // Set the EDPL according the attribute - FAPI_TRY(mss::exp::omi::read_dlx_config1(i_target, dlx_config1_data)); - mss::exp::omi::set_edpl_enable_bit(dlx_config1_data, l_edpl_disable); - FAPI_TRY(mss::exp::omi::write_dlx_config1(i_target, dlx_config1_data)); + FAPI_TRY(mss::exp::omi::read_dlx_config1(i_target, l_dlx_config1_data)); + mss::exp::omi::set_edpl_enable_bit(l_dlx_config1_data, !l_edpl_disable); + FAPI_TRY(mss::exp::omi::write_dlx_config1(i_target, l_dlx_config1_data)); FAPI_INF("%s EDPL enable: %s", mss::c_str(i_target), l_edpl_disable ? "false" : "true"); } - // Run the workaround if it's needed - FAPI_TRY(mss::exp::workarounds::omi::is_prbs_ocmb_required(i_target, l_workaround_required)); - - if (l_workaround_required) - { - uint8_t l_dl_x4_backoff_en = 0; - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en), - "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); - - FAPI_TRY(mss::exp::workarounds::omi::prbs_ocmb(i_target, l_dl_x4_backoff_en)); - } + // Perform p9a workaround + // Train mode 6 (state 3) + FAPI_TRY(mss::exp::workarounds::omi::pre_training_prbs(i_target)); fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C index 81b2a601a..0e21e87ef 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C @@ -37,8 +37,12 @@ #include #include #include +#include +#include #include #include +#include +#include extern "C" { @@ -52,18 +56,41 @@ extern "C" { mss::display_git_commit_info("exp_omi_train"); - std::vector l_data; - uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_ONLY_DL_TRAINING; + // Perform p9a workaround + // Train mode 1 (PATTERN_A) + FAPI_TRY(mss::exp::workarounds::omi::training_prbs(i_target)); - // Gets the data setup - FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_data)); + // BOOT CONFIG 1 + { + bool l_ocmb_is_explorer = false; - // Sets DL_TRAIN field - FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_data, l_dl_layer_boot_mode )); + std::vector l_data; + uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_ONLY_DL_TRAINING; - // Issues the command and checks for completion - // Note: the status check also checks for the OMI training completion, so after we run this command, we're good to go - FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_data)); + // Gets the data setup + FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_data)); + + // Sets DL_TRAIN field + FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_data, l_dl_layer_boot_mode )); + + // Issues the command and checks for completion + FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_data)); + + // Check for expected busy status (this won't work for gemini) + FAPI_TRY(mss::exp::workarounds::omi::ocmb_is_explorer(i_target, l_ocmb_is_explorer)); + + if (l_ocmb_is_explorer) + { + // Explorer & P9A environment should see a busy status until auto train is kicked off from both sides + FAPI_TRY(mss::exp::i2c::check_fw_status_busy(i_target)); + } + else + { + // Gemini should return success code + FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::DELAY_1MS, 100)); + } + + } fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C index d106223ac..26bba128b 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C @@ -22,3 +22,118 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// @file exp_omi_train_check.C +/// @brief Check that omi training was successful from explorer side +/// +/// *HWP HWP Owner: Mark Pizzutillo +/// *HWP HWP Backup: Louis Stermole +/// *HWP Team: Memory +/// *HWP Level: 2 +/// *HWP Consumed by: HB + +#include +#include +#include +#include +#include +#include +#include +#include + +/// +/// @brief Check that the OCMB's omi state machine is in its expected state after OMI training +/// @param[in] i_target the OCMB target to check +/// @return FAPI2_RC_SUCCESS iff ok +/// @note the functionality of this procedure was made to match that of p9a_omi_train_check +/// +fapi2::ReturnCode exp_omi_train_check(const fapi2::Target& i_target) +{ + mss::display_git_commit_info("exp_omi_train_check"); + + FAPI_INF("%s Start exp_omi_train_check", mss::c_str(i_target)); + + // Const + constexpr uint8_t STATE_MACHINE_SUCCESS = 0b111; // This value is from Lonny Lambrecht + constexpr uint8_t MAX_LOOP_COUNT = 10; // Retry times + const auto& l_omi = mss::find_target(i_target); + const auto& l_proc = mss::find_target(i_target); + + // Declares variables + fapi2::buffer l_omi_status; + fapi2::buffer l_omi_training_status; + fapi2::buffer l_dl0_error_hold; + fapi2::buffer l_expected_dl0_error_hold; + fapi2::buffer l_dl0_config1; + uint8_t l_state_machine_state = 0; + uint8_t l_tries = 0; + uint32_t l_omi_freq = 0; + + do + { + // Delay + fapi2::delay(500 * mss::DELAY_1MS, 10 * mss::DELAY_1MS); + + // Check OMI training status + FAPI_TRY(mss::exp::omi::train::omi_train_status(i_target, l_state_machine_state, l_omi_status)); + l_tries++; + + } + while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS); + + // Note: this is very useful debug information while trying to debug training during polling + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_TRAINING_STATUS, l_omi_training_status)); + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_CONFIG1, l_dl0_config1)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_OMI_MHZ, l_proc, l_omi_freq)); + + + FAPI_ASSERT(l_state_machine_state == STATE_MACHINE_SUCCESS, + fapi2::EXP_OMI_TRAIN_ERR() + .set_OCMB_TARGET(i_target) + .set_OMI_TARGET(l_omi) + .set_EXPECTED_SM_STATE(STATE_MACHINE_SUCCESS) + .set_ACTUAL_SM_STATE(l_state_machine_state) + .set_DL0_STATUS(l_omi_status) + .set_DL0_TRAINING_STATUS(l_omi_training_status) + .set_DL0_CONFIG1(l_dl0_config1) + .set_OMI_FREQ(l_omi_freq), + "%s EXP OMI Training Failure, expected state:%d/actual state:%d", + mss::c_str(i_target), + STATE_MACHINE_SUCCESS, + l_state_machine_state + ); + + // Finally, make sure fw_status is good + FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::common_timings::DELAY_1MS, 100)); + + // Check for errors in ERROR_HOLD until we get a proper FIR API setup + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_ERROR_HOLD, l_dl0_error_hold)); + + // Training done bit + l_expected_dl0_error_hold.setBit(); + + if (l_dl0_error_hold != l_expected_dl0_error_hold) + { + // To get to this point, we had to have completed training, so these errors are not catastrophic + // We don't need to assert out, but let's make sure we print them out + FAPI_INF("%s EXPLR_DLX_DL0_ERROR_HOLD REG 0x%016llx " + "did not match expected value. REG contents: 0x%016llx Expected: 0x%016llx", + mss::c_str(i_target), + EXPLR_DLX_DL0_ERROR_HOLD, + l_dl0_error_hold, + l_expected_dl0_error_hold); + } + + FAPI_INF("%s End exp_omi_train_check, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx", + mss::c_str(i_target), + STATE_MACHINE_SUCCESS, + l_state_machine_state, + l_omi_status, + l_omi_training_status); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; + +}// exp_omi_train_check diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H index 1c9478e67..0adb51ce9 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H @@ -22,3 +22,32 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// @file exp_omi_train_check.C +/// @brief Check that omi training was successful from explorer side +/// +/// *HWP HWP Owner: Mark Pizzutillo +/// *HWP HWP Backup: Louis Stermole +/// *HWP Team: Memory +/// *HWP Level: 2 +/// *HWP Consumed by: HB + +#ifndef _EXP_OMI_TRAIN_CHECK_H_ +#define _EXP_OMI_TRAIN_CHECK_H_ + +#include + +typedef fapi2::ReturnCode (*exp_omi_train_check_FP_t)(const fapi2::Target&); + +extern "C" +{ + + /// + /// @brief Check that the OCMB's omi state machine is in its expected state after OMI training + /// @param[in] i_target the OCMB target to check + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode exp_omi_train_check(const fapi2::Target& i_target); +} + +#endif diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk index 1d6b16395..93566fadd 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk @@ -22,3 +22,8 @@ # permissions and limitations under the License. # # IBM_PROLOG_END_TAG +-include 00exp_common.mk + +PROCEDURE=exp_omi_train_check +$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE))) +$(call BUILD_PROCEDURE) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H index 60fd07529..c430c650e 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H @@ -295,11 +295,39 @@ inline fapi2::ReturnCode boot_config(const fapi2::Target& i_target) +{ + uint8_t l_status = ~(0); + + std::vector l_data; + FAPI_TRY(get_fw_status(i_target, l_data)); + + FAPI_TRY(status::get_status_code(i_target, l_data, l_status)); + + // Post bootconfig1, we should see a busy status until p9a_omi_train is kicked off (setting axone to AUTO_TRAIN) + // explorer will return busy status until then. if we have another status, then we may not have executed bootconfig1 + // or some previous command correctly, so we should check it here + // After p9a_omi_train, exp_omi_train_check will check fw_status for success (in addition to checking training completion) + // to make sure things went smoothly + FAPI_ASSERT( l_status == status_codes::FW_BUSY, + fapi2::MSS_EXP_I2C_FW_BOOT_CONFIG_STATUS_CODE_INVALID(). + set_TARGET(i_target). + set_STATUS_CODE(l_status). + set_CMD_ID(FW_STATUS), + "Status code did not return BUSY (%d) as expected post BOOT_CONFIG1, received (%d) for " TARGIDFORMAT , + status_codes::FW_BUSY, l_status, TARGID ); + + return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C index 47e85362f..f8133bafb 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C @@ -40,6 +40,7 @@ #include #include #include +#include namespace mss { @@ -75,12 +76,17 @@ fapi2::ReturnCode setup_omi_dl0_config0( l_config0.insertFromRight(i_train_mode); + l_config0.writeBit(0); + + FAPI_DBG("Writing 0x%16llx to EXPLR_DLX_DL0_CONFIG0 (0x%16llx) of %s", + l_config0, EXPLR_DLX_DL0_CONFIG0, mss::c_str(i_target)); + // All other bits will be left at their default values FAPI_TRY( fapi2::putScom(i_target, EXPLR_DLX_DL0_CONFIG0, l_config0), "Error writing EXPLR_DLX_DL0_CONFIG0 on %s", mss::c_str(i_target)); fapi_try_exit: - return fapi2::FAPI2_RC_SUCCESS; + return fapi2::current_err; } namespace train @@ -142,6 +148,32 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Check the OMI train status on the OCMB chip +/// +/// @param[in] i_target OCMB chil +/// @param[out] o_state_machine_state training state mahcine +/// @param[out] o_omi_training_status training status +/// @return fapi2::ReturnCode +/// +fapi2::ReturnCode omi_train_status(const fapi2::Target& i_target, + uint8_t& o_state_machine_state, + fapi2::buffer& o_omi_training_status) +{ + fapi2::buffer l_omi_status; + + // Check OMI training status + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_STATUS, l_omi_status)); + + o_omi_training_status = l_omi_status; + o_state_machine_state = 0; + l_omi_status.extractToRight(o_state_machine_state); + +fapi_try_exit: + return fapi2::current_err; +} + } // ns train } // ns omi diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H index cb52d1ac0..5022271ee 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H @@ -230,6 +230,19 @@ namespace train /// fapi2::ReturnCode setup_fw_boot_config( const fapi2::Target& i_target, std::vector& o_data ); + +/// +/// @brief Check the OMI train status on the OCMB chip +/// +/// @param[in] i_target OCMB chil +/// @param[out] o_state_machine_state training state mahcine +/// @param[out] o_omi_training_status training status +/// @return fapi2::ReturnCode +/// +fapi2::ReturnCode omi_train_status(const fapi2::Target& i_target, + uint8_t& o_state_machine_state, + fapi2::buffer& o_omi_training_status); + } // ns train } // ns omi diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C index 1bfe94371..eae18dd1f 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C @@ -51,46 +51,33 @@ namespace workarounds { namespace omi { + /// -/// @brief Determine if OCMB PRBS workaround needs to be performed +/// @brief Determine if the OCMB is an explorer /// -/// @param[in] i_ocmb_chip OCMB target -/// @param[out] o_required workaround needs to be performed -/// @return FAPI2_RC_SUCCESS iff success +/// @param[in] i_ocmb_chip OCMB chip +/// @param[out] o_explorer true/false is explorer +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note Used for exp_omi_train procedure to differentiate fw_status behavior with gemini /// -fapi2::ReturnCode is_prbs_ocmb_required( - const fapi2::Target i_ocmb_chip, - bool& o_required) +fapi2::ReturnCode ocmb_is_explorer(const fapi2::Target& i_ocmb_chip, bool& o_explorer) { - // Check chip type - uint8_t l_proc_type = 0; - const auto& l_proc_chip = mss::find_target(i_ocmb_chip); - FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, l_proc_chip, l_proc_type), - "Error getting ATTR_NAME of %s", mss::c_str(l_proc_chip)); - - // OCMB Workaround Logic: - // Axone: OCMB workaround off - // Non-axone (Apollo): OCMB workaround on - // P10 - No workaround required (no enum for this yet, so we must revisit this when the time comes) - o_required = l_proc_type != fapi2::ENUM_ATTR_NAME_AXONE; + uint8_t l_name = 0; + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_ocmb_chip, l_name)); + + o_explorer = (l_name == fapi2::ENUM_ATTR_NAME_EXPLORER); fapi_try_exit: return fapi2::current_err; } - /// -/// @brief Performs OCMB PRBS workaround +/// @brief Set configurable delay based on the PRBS ATTR and SIM mode /// -/// @param[in] i_ocmb_chip OCMB chip -/// @param[in] i_dl_x4_backoff_en backoff enable +/// @param[in] i_ocmb_chip OCMB target /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success /// -fapi2::ReturnCode prbs_ocmb( - const fapi2::Target i_ocmb_chip, - const uint8_t i_dl_x4_backoff_en) +fapi2::ReturnCode prbs_delay(const fapi2::Target& i_ocmb_chip) { - FAPI_DBG("Performing PRBS OCMB workaround on %s", mss::c_str(i_ocmb_chip)); - uint8_t l_sim = 0; uint32_t l_prbs_time = 0; uint64_t l_prbs_time_scaled = 0; @@ -101,23 +88,10 @@ fapi2::ReturnCode prbs_ocmb( "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)"); l_prbs_time_scaled = l_prbs_time * mss::common_timings::DELAY_1MS; - // State 6 - FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_ocmb_chip, - mss::omi::train_mode::TX_TRAINING_STATE3, - i_dl_x4_backoff_en)); - - // Set configurable delay based on the PRBS ATTR and SIM mode FAPI_TRY(fapi2::delay(l_prbs_time_scaled, mss::common_timings::DELAY_1US)); FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns", (l_sim ? mss::common_timings::DELAY_1US : l_prbs_time_scaled)); - // Enable training state 1 to send Pattern A - FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_ocmb_chip, - mss::omi::train_mode::TX_PATTERN_A, - i_dl_x4_backoff_en)); - - // Not calling with ENABLE_AUTO_TRAINING for explorer - fapi_try_exit: return fapi2::current_err; } @@ -174,6 +148,53 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Workaround for exp_omi_train to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode training_prbs(const fapi2::Target& i_target) +{ + uint8_t l_dl_x4_backoff_en = 0; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en), + "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); + + // Train mode 1 (PATTERN_A) + FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_target, + mss::omi::train_mode::TX_PATTERN_A, + l_dl_x4_backoff_en)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Workaround for exp_omi_setup to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode pre_training_prbs(const fapi2::Target& i_target) +{ + uint8_t l_dl_x4_backoff_en = 0; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en), + "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); + + // State 6 + FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_target, + mss::omi::train_mode::TX_TRAINING_STATE3, + l_dl_x4_backoff_en)); + + // Set configurable delay based on the PRBS ATTR and SIM mode + FAPI_TRY(prbs_delay(i_target)); + +fapi_try_exit: + return fapi2::current_err; +} + } // omi } // workarounds } // exp diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H index 5d45f2e13..f99eceda5 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H @@ -48,26 +48,22 @@ namespace omi { /// -/// @brief Determine if OCMB PRBS workaround needs to be performed +/// @brief Determine if the OCMB is an explorer /// -/// @param[in] i_ocmb_chip OCMB target -/// @param[out] o_required workaround needs to be performed -/// @return FAPI2_RC_SUCCESS iff success +/// @param[in] i_ocmb_chip OCMB chip +/// @param[out] o_explorer true/false is explorer +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note Used for exp_omi_train procedure to differentiate fw_status behavior with gemini /// -fapi2::ReturnCode is_prbs_ocmb_required( - const fapi2::Target i_ocmb_chip, - bool& o_required); +fapi2::ReturnCode ocmb_is_explorer(const fapi2::Target& i_ocmb_chip, bool& o_explorer); /// -/// @brief Performs OCMB PRBS workaround +/// @brief Set configurable delay based on the PRBS ATTR and SIM mode /// -/// @param[in] i_ocmb_chip OCMB chip -/// @param[in] i_dl_x4_backoff_en backoff enable +/// @param[in] i_ocmb_chip OCMB target /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success /// -fapi2::ReturnCode prbs_ocmb( - const fapi2::Target i_ocmb_chip, - const uint8_t i_dl_x4_backoff_en); +fapi2::ReturnCode prbs_delay(const fapi2::Target& i_ocmb_chip); /// /// @brief Determine if we need to bypass MENTERP register reads/writes @@ -86,6 +82,22 @@ fapi2::ReturnCode gem_menterp(const fapi2::Target /// fapi2::ReturnCode gem_setup_config(const fapi2::Target& i_target); +/// +/// @brief Workaround for exp_omi_train to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode training_prbs(const fapi2::Target& i_target); + +/// +/// @brief Workaround for exp_omi_setup to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode pre_training_prbs(const fapi2::Target& i_target); + } // omi } // workarounds } // exp diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml index 42589401b..9b735dd02 100644 --- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml +++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml @@ -23,4 +23,33 @@ + + + RC_EXP_OMI_TRAIN_ERR + + exp_omi_train_check did not see expected trained status from OCMB DL0 status register + + OCMB_TARGET + EXPECTED_SM_STATE + ACTUAL_SM_STATE + DL0_STATUS + DL0_TRAINING_STATUS + DL0_CONFIG1 + OMI_FREQ + + OCMB_TARGET + HIGH + + + OMI_TARGET, OCMB_TARGET + HIGH + + + OCMB_TARGET + + + OCMB_TARGET + + + diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml index a081d1cc7..ae2cf7f56 100644 --- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml +++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml @@ -372,6 +372,28 @@ + + RC_MSS_EXP_I2C_FW_BOOT_CONFIG_STATUS_CODE_INVALID + + Unexpected Explorer status code returned during OMI link training pattern handshake. + Expected FW_BUSY, but received STATUS_CODE in FFDC data + + TARGET + STATUS_CODE + CMD_ID + + CODE + MEDIUM + + + TARGET + HIGH + + + TARGET + + + RC_MSS_EXP_I2C_FW_STATUS_BUSY diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H index 5cf787640..48f5cb222 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H @@ -252,13 +252,13 @@ fapi2::ReturnCode setup_mc_config0( l_val.template insertFromRight( - mss::omi::phy_ctr_mode::PHY_CTR_MODE_50US); + mss::omi::phy_ctr_mode::PHY_CTR_MODE_60MS); // CFG_DL0_RUNLANE_OVRD_ENABLE: When enabled, the dl0 will drive run lane to the PHY for all training states. l_val.writeBit(0); // CFG_DL0_PWRMGT_ENABLE: dl0 power management enabled - l_val.writeBit(1); + l_val.writeBit(0); // CFG_DL0_QUARTER_WIDTH_BACKOFF_ENABLE: dl0 x1 backoff enabled l_val.writeBit(0); @@ -283,6 +283,9 @@ fapi2::ReturnCode setup_mc_config0( // CFG_DL0_RESET: dl0 reset - Reset dl0 back to traning state 0 l_val.writeBit(0); + FAPI_DBG("Writing 0x%16llx to MC_REG2_DL0_CONFIG0 (0x%16llx) of %s", + l_val, TT::MC_REG2_DL0_CONFIG0, mss::c_str(i_target)); + FAPI_TRY( mss::putScom(i_target, TT::MC_REG2_DL0_CONFIG0, l_val) ); fapi_try_exit: diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C index e4ac4af7c..783091c62 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C @@ -59,7 +59,7 @@ namespace mc /// @param[in] i_proc_type PROC type/name /// @return true/false perform workaround /// -bool is_prbs_omi_required_helper(const uint8_t i_ocmb_type, const uint8_t i_proc_type) +bool is_prbs_omi_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type) { // OMI Workaround Logic: // Explorer+Axone: OMI/PROC-side workaround off @@ -70,66 +70,91 @@ bool is_prbs_omi_required_helper(const uint8_t i_ocmb_type, const uint8_t i_proc } /// -/// @brief Determine whether to perform PRBS OMI workaround +/// @brief Helper function to determine whether PRBS axone OMI workarounds will be performed, that can be unit tested +/// +/// @param[in] i_ocmb_type OCMB type/name +/// @param[in] i_proc_type PROC type/name +/// @return true/false perform workaround +/// +bool is_prbs_omi_axone_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type) +{ + // OMI Workaround Logic: + // Explorer+Axone: Workaround on. + // Else: None + return ((i_proc_type == fapi2::ENUM_ATTR_NAME_AXONE) + && (i_ocmb_type == fapi2::ENUM_ATTR_NAME_EXPLORER)); // Explorer && axone +} + +/// +/// @brief Perform PRBS delay from prbs time and sim attributes +/// +/// @param[in] i_omi OMI target +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code +/// +fapi2::ReturnCode prbs_delay(const fapi2::Target& i_omi) +{ + uint8_t l_sim = 0; + uint32_t l_prbs_time = 0; + uint64_t l_prbs_time_scaled = 0; + + FAPI_TRY( mss::attr::get_is_simulation( l_sim) ); + + FAPI_TRY(mss::attr::get_omi_dl_preipl_prbs_time(i_omi, l_prbs_time), + "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)"); + l_prbs_time_scaled = l_prbs_time * mss::common_timings::DELAY_1MS; + + FAPI_TRY(fapi2::delay(l_prbs_time_scaled, mss::common_timings::DELAY_1US)); + FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns", + (l_sim ? mss::common_timings::DELAY_1US : l_prbs_time_scaled)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Get PROC and OCMB types /// /// @param[in] i_ocmb_chip OCMB chip /// @param[in] i_proc_chip PROC chip /// @param[out] o_required workaround required /// @return FAPI2_RC_SUCCESS iff success /// -fapi2::ReturnCode is_prbs_omi_required( +fapi2::ReturnCode get_ocmb_proc_types( const fapi2::Target i_ocmb_chip, const fapi2::Target i_proc_chip, - bool& o_required) + uint8_t& o_ocmb_type, + uint8_t& o_proc_type) { - uint8_t l_ocmb_type = 0; - uint8_t l_proc_type = 0; - - FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_ocmb_chip, l_ocmb_type), + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_ocmb_chip, o_ocmb_type), "Error getting ATTR_NAME of %s", mss::c_str(i_ocmb_chip)); - FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_proc_chip, l_proc_type), + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_proc_chip, o_proc_type), "Error getting ATTR_NAME of %s", mss::c_str(i_proc_chip)); - o_required = is_prbs_omi_required_helper(l_ocmb_type, l_proc_type); - fapi_try_exit: return fapi2::current_err; } /// -/// @brief Perform the PRBS OMI workaround +/// @brief Perform the PRBS OMI workaround for gemini configurations /// /// @param[in] i_omi OMI /// @param[in] i_dl_x4_backoff_en backoff enable bit /// @return fapi2::FAPI2_RC_SUCCESS iff ok /// -fapi2::ReturnCode prbs_omi( +fapi2::ReturnCode omi_training_prbs_gem( const fapi2::Target i_omi, const uint8_t i_dl_x4_backoff_en) { FAPI_DBG("Performing PRBS OMI workaround on %s", mss::c_str(i_omi)); - uint32_t l_prbs_time = 0; - uint64_t l_prbs_time_scaled = 0; - uint8_t l_sim = 0; - FAPI_TRY(mss::attr::get_is_simulation(l_sim)); - - // Get PRBS time - FAPI_TRY(mss::attr::get_omi_dl_preipl_prbs_time(i_omi, l_prbs_time), - "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)"); - l_prbs_time_scaled = l_prbs_time * mss::common_timings::DELAY_1MS; - // *_CONFIG0 should be the last one written, since it starts the training. // We are not using the pre-ipl PRBS auto training mode because it doesn't function properly in Axone // Enable training state 6 to send TS3 FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_TRAINING_STATE3, i_dl_x4_backoff_en)); - // Set configurable delay based on the PRBS ATTR and SIM mode - FAPI_TRY(fapi2::delay(l_prbs_time_scaled, mss::common_timings::DELAY_1US)); - FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns", - (l_sim ? mss::common_timings::DELAY_1US : l_prbs_time_scaled)); + FAPI_TRY(prbs_delay(i_omi)); // Enable training state 1 to send Pattern A FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_PATTERN_A, i_dl_x4_backoff_en)); @@ -138,6 +163,50 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Perform p9a_omi_train workaround for Axone+Explorer +/// +/// @param[in] i_omi OMI target +/// @param[in] i_dl_x4_backoff_en backoff enable field +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode omi_training_prbs( + const fapi2::Target i_omi, + const uint8_t i_dl_x4_backoff_en) +{ + FAPI_DBG("Performing OMI Train axone workaround on %s", mss::c_str(i_omi)); + + // Training mode 1: send Pattern A + FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_PATTERN_A, i_dl_x4_backoff_en)); + + FAPI_TRY(fapi2::delay(100 * mss::common_timings::DELAY_1MS, mss::common_timings::DELAY_1MS)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform p9a_omi_setup (pre-training) workaround for Axone+Explorer +/// +/// @param[in] i_omi OMI target +/// @param[in] i_dl_x4_backoff_en backoff enable field +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode pre_omi_training_prbs( + const fapi2::Target i_omi, + const uint8_t i_dl_x4_backoff_en) +{ + FAPI_DBG("Performing OMI Setup axone workaround on %s", mss::c_str(i_omi)); + + // Training mode 4: send State 1 + FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_TRAINING_STATE1, i_dl_x4_backoff_en)); + + FAPI_TRY(prbs_delay(i_omi)); + +fapi_try_exit: + return fapi2::current_err; +} + } // mc } // workarounds } // mss diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H index 45828a2af..4491a91e3 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H @@ -51,29 +51,69 @@ namespace mc /// @param[in] i_proc_type PROC type/name /// @return true/false perform workaround /// -bool is_prbs_omi_required_helper(const uint8_t i_ocmb_type, const uint8_t i_proc_type); +bool is_prbs_omi_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type); /// -/// @brief Determine whether to perform PRBS OMI workaround +/// @brief Helper function to determine whether PRBS axone OMI workarounds will be performed, that can be unit tested +/// +/// @param[in] i_ocmb_type OCMB type/name +/// @param[in] i_proc_type PROC type/name +/// @return true/false perform workaround +/// +bool is_prbs_omi_axone_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type); + +/// +/// @brief Perform PRBS delay from prbs time and sim attributes +/// +/// @param[in] i_omi OMI target +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code +/// +fapi2::ReturnCode prbs_delay(const fapi2::Target& i_omi); + +/// +/// @brief Get PROC and OCMB types /// /// @param[in] i_ocmb_chip OCMB chip /// @param[in] i_proc_chip PROC chip /// @param[out] o_required workaround required /// @return FAPI2_RC_SUCCESS iff success /// -fapi2::ReturnCode is_prbs_omi_required( +fapi2::ReturnCode get_ocmb_proc_types( const fapi2::Target i_ocmb_chip, const fapi2::Target i_proc_chip, - bool& o_required); + uint8_t& o_ocmb_type, + uint8_t& o_proc_type); /// -/// @brief Perform the PRBS OMI workaround +/// @brief Perform the PRBS OMI workaround for gemini configurations /// /// @param[in] i_omi OMI /// @param[in] i_dl_x4_backoff_en backoff enable bit /// @return fapi2::FAPI2_RC_SUCCESS iff ok /// -fapi2::ReturnCode prbs_omi( +fapi2::ReturnCode omi_training_prbs_gem( + const fapi2::Target i_omi, + const uint8_t i_dl_x4_backoff_en); + +/// +/// @brief Perform p9a_omi_train workaround for Axone+Explorer +/// +/// @param[in] i_omi OMI target +/// @param[in] i_dl_x4_backoff_en backoff enable field +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode omi_training_prbs( + const fapi2::Target i_omi, + const uint8_t i_dl_x4_backoff_en); + +/// +/// @brief Perform p9a_omi_setup (pre-training) workaround for Axone+Explorer +/// +/// @param[in] i_omi OMI target +/// @param[in] i_dl_x4_backoff_en backoff enable field +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode pre_omi_training_prbs( const fapi2::Target i_omi, const uint8_t i_dl_x4_backoff_en); diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C index 06edf3375..eaccc18c9 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C @@ -22,3 +22,77 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file p9a_omi_setup.C +/// @brief Setup the OMI +/// +// *HWP HWP Owner: Mark Pizzutillo +// *HWP HWP Backup: Louis Stermole +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include + +/// +/// @brief Setup OMI for axone +/// @param[in] i_target the axone OMI target to operate on +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode p9a_omi_setup( const fapi2::Target& i_target ) +{ + mss::display_git_commit_info("p9a_omi_setup"); + + FAPI_INF("%s Start p9a_omi_setup", mss::c_str(i_target)); + + const auto& l_mc = mss::find_target(i_target); + const auto& l_ocmbs = mss::find_targets(i_target); + + FAPI_TRY(mss::mc::setup_mc_mcn_config(l_mc)); + FAPI_TRY(mss::mc::setup_mc_config1(i_target)); + FAPI_TRY(mss::mc::setup_mc_cya_bits(i_target)); + FAPI_TRY(mss::mc::setup_mc_error_action(i_target)); + FAPI_TRY(mss::mc::setup_mc_rmt_config(i_target)); + + if(l_ocmbs.empty()) + { + // No ocmbs, no training needed + // Ensuring we don't try to access an empty vector + return fapi2::FAPI2_RC_SUCCESS; + } + + { + // Only one OCMB per OMI for axone + const auto& l_ocmb = l_ocmbs[0]; + const auto& l_proc = mss::find_target(i_target); + uint8_t l_dl_x4_backoff_en = 0; + bool l_axone_workarounds_required = false; + uint8_t l_proc_type = 0; + uint8_t l_ocmb_type = 0; + + // Get BACKOFF_ENABLE CHIP_EC attribute + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, l_ocmb, l_dl_x4_backoff_en), + "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); + + // Determine if workaround will be performed, if so, perform it + FAPI_TRY(mss::workarounds::mc::get_ocmb_proc_types(l_ocmb, l_proc, l_ocmb_type, l_proc_type)); + l_axone_workarounds_required = mss::workarounds::mc::is_prbs_omi_axone_required(l_ocmb_type, l_proc_type); + + if (l_axone_workarounds_required) + { + // TX_TRAINING_STATE1 + FAPI_TRY(mss::workarounds::mc::pre_omi_training_prbs(i_target, l_dl_x4_backoff_en)); + } + + return fapi2::FAPI2_RC_SUCCESS; + } + +fapi_try_exit: + return fapi2::current_err; +} diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H index a5e089214..cf364294b 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H @@ -22,3 +22,32 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file p9a_omi_setup.H +/// @brief Setup the OMI +/// +// *HWP HWP Owner: Mark Pizzutillo +// *HWP HWP Backup: Louis Stermole +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#ifndef P9A_OMI_SETUP_H_ +#define P9A_OMI_SETUP_H_ + +#include + +typedef fapi2::ReturnCode (*p9a_omi_setup_FP_t) (const fapi2::Target&); + +extern "C" +{ + /// + /// @brief Setup OMI for axone + /// @param[in] i_target the axone OMI target to operate on + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode p9a_omi_setup( const fapi2::Target& i_target ); +} + +#endif diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk index c4264c879..1edeebce8 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk @@ -22,3 +22,8 @@ # permissions and limitations under the License. # # IBM_PROLOG_END_TAG +-include 00p9a_common.mk + +PROCEDURE=p9a_omi_setup +$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE))) +$(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C index 5913df90d..2075dfc5a 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C @@ -62,15 +62,8 @@ fapi2::ReturnCode p9a_omi_train( const fapi2::Target& i_ FAPI_INF("%s Start p9a_omi_train", mss::c_str(i_target)); - const auto& l_mc = mss::find_target(i_target); const auto& l_ocmbs = mss::find_targets(i_target); - FAPI_TRY(mss::mc::setup_mc_mcn_config(l_mc)); - FAPI_TRY(mss::mc::setup_mc_config1(i_target)); - FAPI_TRY(mss::mc::setup_mc_cya_bits(i_target)); - FAPI_TRY(mss::mc::setup_mc_error_action(i_target)); - FAPI_TRY(mss::mc::setup_mc_rmt_config(i_target)); - if(l_ocmbs.empty()) { // No ocmbs, no training needed @@ -82,18 +75,32 @@ fapi2::ReturnCode p9a_omi_train( const fapi2::Target& i_ const auto& l_ocmb = l_ocmbs[0]; const auto& l_proc = mss::find_target(l_ocmb); uint8_t l_dl_x4_backoff_en = 0; - bool l_workaround_required = false; + bool l_gem_or_non_axone_workaround = false; + bool l_axone_workarounds_required = false; + uint8_t l_proc_type = 0; + uint8_t l_ocmb_type = 0; // Get BACKOFF_ENABLE CHIP_EC attribute FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, l_ocmb, l_dl_x4_backoff_en), "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); - // Determine if workaround will be performed, if so, perform it - FAPI_TRY(mss::workarounds::mc::is_prbs_omi_required(l_ocmb, l_proc, l_workaround_required)); + // Determine if workarounds will be performed, if so, perform them + FAPI_TRY(mss::workarounds::mc::get_ocmb_proc_types(l_ocmb, l_proc, l_ocmb_type, l_proc_type)); + l_gem_or_non_axone_workaround = mss::workarounds::mc::is_prbs_omi_required(l_ocmb_type, l_proc_type); + l_axone_workarounds_required = mss::workarounds::mc::is_prbs_omi_axone_required(l_ocmb_type, l_proc_type); - if (l_workaround_required) + if (l_axone_workarounds_required) + { + // TX_PATTERN_A + FAPI_TRY(mss::workarounds::mc::omi_training_prbs(i_target, l_dl_x4_backoff_en)); + } + else if (l_gem_or_non_axone_workaround) { - FAPI_TRY(mss::workarounds::mc::prbs_omi(i_target, l_dl_x4_backoff_en)); + // TX_TRAINING_STATE_3, TX_PATTERN_A + FAPI_TRY(mss::workarounds::mc::omi_training_prbs_gem(i_target, l_dl_x4_backoff_en)); + + // 2 second delay for gemini + FAPI_TRY(fapi2::delay(2 * mss::common_timings::DELAY_1S, mss::common_timings::DELAY_1MS)); } // Enable auto training diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C index 8a010bded..9aae6b90f 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C @@ -59,48 +59,94 @@ fapi2::ReturnCode p9a_omi_train_check( const fapi2::Target l_omi_status; fapi2::buffer l_omi_training_status; + fapi2::buffer l_dl0_error_hold; + fapi2::buffer l_expected_dl0_error_hold; + fapi2::buffer l_dl0_config1; uint8_t l_state_machine_state = 0; uint8_t l_tries = 0; + uint32_t l_omi_freq = 0; + + const auto& l_ocmbs = mss::find_targets(i_target); + + // Sanity check for no empty vector + if (l_ocmbs.empty()) + { + // No training could have occurred + return fapi2::FAPI2_RC_SUCCESS; + } + + const auto& l_proc = mss::find_target(l_ocmbs[0]); FAPI_TRY(mss::mc::omi_train_status(i_target, l_state_machine_state, l_omi_status)); - while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS) + do { // Delay - fapi2::delay(mss::DELAY_100US, 10 * mss::DELAY_1MS); + fapi2::delay(500 * mss::DELAY_1MS, 10 * mss::DELAY_1MS); // Check OMI training status FAPI_TRY(mss::mc::omi_train_status(i_target, l_state_machine_state, l_omi_status)); - // Note: this is very useful debug information while trying to debug training during polling - FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_TRAINING_STATUS, l_omi_training_status)); l_tries++; + } + while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS); + // Note: this is very useful debug information while trying to debug training during polling FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_TRAINING_STATUS, l_omi_training_status)); + FAPI_TRY(fapi2::getScom(i_target, P9A_MC_REG2_DL0_CONFIG1, l_dl0_config1)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_OMI_MHZ, l_proc, l_omi_freq)); + FAPI_ASSERT(l_state_machine_state == STATE_MACHINE_SUCCESS, fapi2::P9A_OMI_TRAIN_ERR() - .set_TARGET(i_target) + .set_OMI_TARGET(i_target) + .set_OCMB_TARGET(l_ocmbs[0]) .set_EXPECTED_SM_STATE(STATE_MACHINE_SUCCESS) .set_ACTUAL_SM_STATE(l_state_machine_state) .set_DL0_STATUS(l_omi_status) - .set_DL0_TRAINING_STATUS(l_omi_training_status), - "%s OMI Training Failure, expected state:%d/actual state:%d", + .set_DL0_TRAINING_STATUS(l_omi_training_status) + .set_DL0_CONFIG1(l_dl0_config1) + .set_OMI_FREQ(l_omi_freq), + "%s P9A OMI Training Failure, expected state:%d/actual state:%d", mss::c_str(i_target), STATE_MACHINE_SUCCESS, l_state_machine_state ); + // Check errors in ERROR_HOLD until we get a proper FIR API setup + FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_ERROR_HOLD, l_dl0_error_hold)); + + // Training completion bit set + l_expected_dl0_error_hold.setBit(); + + // Lost block bit set: this results in p9a only, from the + // necessary pre-training workarounds, and is expected to be set + // TK - We will need to the proper FIR unmasking later + l_expected_dl0_error_hold.setBit(); + + if (l_dl0_error_hold != l_expected_dl0_error_hold) + { + // To get to this point, we had to have completed training, so these errors are not catastrophic + // We don't need to assert out, but let's make sure we print them out + FAPI_INF("%s P9A_MC_REG2_DL0_ERROR_HOLD REG 0x%016llx " + "did not match expected value. REG contents: 0x%016llx Expected: 0x%016llx", + mss::c_str(i_target), + P9A_MC_REG2_DL0_ERROR_HOLD, + l_dl0_error_hold, + l_expected_dl0_error_hold); + } + FAPI_INF("%s End p9a_omi_train_check, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx", mss::c_str(i_target), STATE_MACHINE_SUCCESS, l_state_machine_state, l_omi_status, l_omi_training_status); + return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: diff --git a/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml b/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml index 555c491c5..48f8f2ea2 100644 --- a/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml +++ b/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml @@ -5,7 +5,7 @@ - + @@ -28,22 +28,28 @@ RC_P9A_OMI_TRAIN_ERR - Procedure: p9a_omi_train failure + p9a_omi_train_check did not see expected trained status from OMI DL0 status register - TARGET + OMI_TARGET EXPECTED_SM_STATE ACTUAL_SM_STATE DL0_STATUS DL0_TRAINING_STATUS + DL0_CONFIG1 + OMI_FREQ - TARGET + OMI_TARGET + HIGH + + + OMI_TARGET, OCMB_TARGET HIGH - TARGET + OMI_TARGET - TARGET + OMI_TARGET -- cgit v1.2.1