diff options
author | Mark Pizzutillo <Mark.Pizzutillo@ibm.com> | 2019-08-26 18:02:37 -0400 |
---|---|---|
committer | Christian R Geddes <crgeddes@us.ibm.com> | 2019-09-27 13:49:09 -0500 |
commit | 48abe5e8afb54e389f45233e66e100a501d038e8 (patch) | |
tree | 2a930b0edc5367239fc100baf5df1b45185cf8eb /src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils | |
parent | 04d5973bec03c271184ff87f1e0dbb3aa57857d4 (diff) | |
download | talos-hostboot-48abe5e8afb54e389f45233e66e100a501d038e8.tar.gz talos-hostboot-48abe5e8afb54e389f45233e66e100a501d038e8.zip |
Add support for new pmic sequencing SPD fields
Change-Id: I8847090585161375fbb2c0ef853cffed80a67cc3
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/82961
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/83375
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/ocmb/common/procedures/hwp/pmic/lib/utils')
3 files changed, 173 insertions, 92 deletions
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H index 1d1b4feaf..4cb511dae 100644 --- a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H +++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H @@ -156,9 +156,11 @@ enum class attr_eff_engine_fields PMIC0_MFG_ID = 43, PMIC1_MFG_ID = 44, + PMIC0_SEQUENCE = 45, + PMIC1_SEQUENCE = 46, // Dispatcher set to last enum value - DISPATCHER = PMIC1_MFG_ID, + DISPATCHER = PMIC1_SEQUENCE, }; /// @@ -220,7 +222,8 @@ enum ffdc_codes SET_PMIC0_MFG_ID = 0x107C, SET_PMIC1_MFG_ID = 0x107D, - SET_DRAM_MODULE_HEIGHT = 0x107E, + SET_PMIC0_SEQUENCE = 0x107E, + SET_PMIC1_SEQUENCE = 0x107F, }; /// @@ -292,41 +295,6 @@ struct consts<mss::pmic::product::JEDEC_COMPLIANT> static constexpr uint32_t VOLT_STEP = 5; }; -/// -/// @brief PMIC traits that change depending on DIMM module height -/// -/// @tparam H module_height enum -/// -template<mss::pmic::module_height H> -struct pmic_traits; - -/// -/// @brief pmic traits for 1U dimms -/// -template <> -struct pmic_traits<mss::pmic::module_height::HEIGHT_1U> -{ - static constexpr uint8_t PMICS_PER_DIMM = 2; -}; - -/// -/// @brief pmic traits for 2U dimms -/// -template <> -struct pmic_traits<mss::pmic::module_height::HEIGHT_2U> -{ - static constexpr uint8_t PMICS_PER_DIMM = 2; -}; - -/// -/// @brief pmic traits for 4U dimms -/// -template <> -struct pmic_traits<mss::pmic::module_height::HEIGHT_4U> -{ - static constexpr uint8_t PMICS_PER_DIMM = 4; -}; - namespace i2c { diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C index 65bf83b5a..ec85b7da4 100644 --- a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C +++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C @@ -380,5 +380,143 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Order PMICs by sequence defined in the SPD +/// +/// @param[in] i_dimm DIMM target to pull SPD fields from +/// @param[in] i_dimm_index index of the DIMM target +/// @param[in] i_pmics_per_dimm number of PMICs per dimm +/// @param[in,out] io_pmics vector of PMICs that will be re-ordered in place +/// @return fapi2::ReturnCode +/// +fapi2::ReturnCode order_pmics_by_sequence( + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> i_dimm, + const uint8_t i_dimm_index, + const uint8_t i_pmics_per_dimm, + std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& io_pmics) +{ + const auto l_begin_offset = i_dimm_index * i_pmics_per_dimm; + const auto l_iterator_begin = io_pmics.begin() + l_begin_offset; + const auto l_iterator_end = l_iterator_begin + i_pmics_per_dimm; + + fapi2::ReturnCode l_rc_0_out = fapi2::FAPI2_RC_SUCCESS; + fapi2::ReturnCode l_rc_1_out = fapi2::FAPI2_RC_SUCCESS; + + std::sort(l_iterator_begin, l_iterator_end, [&l_rc_0_out, &l_rc_1_out, i_dimm] ( + const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& l_first_pmic, + const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& l_second_pmic) -> bool + { + // Here we should only be dealing with PMICs of the same DIMM. So we can just check the first one which dimm we're on + uint8_t l_sequence_pmic_0 = 0; + uint8_t l_sequence_pmic_1 = 0; + + // Need to pull out the RC's manually. Goto's in lambdas apparently don't play nicely + fapi2::ReturnCode l_rc_0 = mss::pmic::get_sequence[mss::index(l_first_pmic)](i_dimm, l_sequence_pmic_0); + fapi2::ReturnCode l_rc_1 = mss::pmic::get_sequence[mss::index(l_second_pmic)](i_dimm, l_sequence_pmic_1); + + // Hold on to an error if we see one + if (l_rc_0 != fapi2::FAPI2_RC_SUCCESS) + { + l_rc_0_out = l_rc_0; + } + if (l_rc_1 != fapi2::FAPI2_RC_SUCCESS) + { + l_rc_1_out = l_rc_1; + } + + return l_sequence_pmic_0 < l_sequence_pmic_1; + }); + + FAPI_TRY(l_rc_0_out, "Error getting sequencing attributes for PMICs associated with DIMM 0 target %s", + mss::c_str(i_dimm)); + FAPI_TRY(l_rc_1_out, "Error getting sequencing attributes for PMICs associated with DIMM 1 target %s", + mss::c_str(i_dimm)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Enable pmics using manual mode (direct VR enable, no SPD fields) +/// @param[in] i_pmics vector of PMICs to enable +/// +fapi2::ReturnCode enable_manual(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>> i_pmics) +{ + using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>; + using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>; + using FIELDS = pmicFields<mss::pmic::product::JEDEC_COMPLIANT>; + + for (const auto& l_pmic : i_pmics) + { + fapi2::buffer<uint8_t> l_programmable_mode; + l_programmable_mode.writeBit<FIELDS::R2F_SECURE_MODE>(CONSTS::PROGRAMMABLE_MODE); + + FAPI_INF("Enabling PMIC %s with default settings", mss::c_str(l_pmic)); + + // Make sure power is applied and we can read the PMIC + FAPI_TRY(mss::pmic::poll_for_pbulk_good(l_pmic), + "pmic_enable: poll for pbulk good either failed, or returned not good status on PMIC %s", + mss::c_str(l_pmic)); + + // Enable programmable mode + FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(l_pmic, REGS::R2F, l_programmable_mode)); + + // Start VR Enable + FAPI_TRY(mss::pmic::start_vr_enable(l_pmic), + "Error starting VR_ENABLE on PMIC %s", mss::c_str(l_pmic)); + } + +fapi_try_exit: + return fapi2::current_err; +} +/// +/// @brief Function to enable 1U and 2U pmics +/// +/// @param[in] i_pmic_target - the pmic target +/// @param[in] i_dimm_target - the dimm target that the PMIC resides on +/// @param[in] i_vendor_id - the vendor ID of the PMIC to bias +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS if successful +/// +fapi2::ReturnCode enable_chip_1U_2U(const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target, + const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target, + const uint16_t i_vendor_id) +{ + FAPI_INF("Setting PMIC %s settings from SPD", mss::c_str(i_pmic_target)); + + // Make sure it is TI or IDT + FAPI_ASSERT((i_vendor_id == mss::pmic::vendor::IDT || + i_vendor_id == mss::pmic::vendor::TI), + fapi2::PMIC_CHIP_NOT_RECOGNIZED() + .set_TARGET(i_pmic_target) + .set_VENDOR_ID(i_vendor_id), + "Unknown PMIC: %s with vendor ID 0x%04hhX", + mss::c_str(i_pmic_target), + uint8_t(i_vendor_id) ); + + if (i_vendor_id == mss::pmic::vendor::IDT) + { + FAPI_TRY(mss::pmic::bias_with_spd_settings<mss::pmic::vendor::IDT>(i_pmic_target, i_dimm_target), + "enable_chip<IDT, 1U/2U>: Error biasing PMIC %s with SPD settings", + mss::c_str(i_pmic_target)); + } + else // assert done in pmic_enable.C that vendor is IDT or TI + { + FAPI_TRY(mss::pmic::bias_with_spd_settings<mss::pmic::vendor::TI>(i_pmic_target, i_dimm_target), + "enable_chip<TI, 1U/2U>: Error biasing PMIC %s with SPD settings", + mss::c_str(i_pmic_target)); + } + + // Start VR Enable + FAPI_TRY(mss::pmic::start_vr_enable(i_pmic_target), + "Error starting VR_ENABLE on PMIC %s", mss::c_str(i_pmic_target)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; } + +} // pmic } // mss diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H index 5de810f55..a393209a6 100644 --- a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H +++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H @@ -57,6 +57,13 @@ typedef fapi2::ReturnCode (*pmic_attr_ptr_signed)(const fapi2::Target<fapi2::TAR int8_t& o_value); // Pointers below allow for run-time attribute getter selection by PMIC ID (0,1) +// PMIC0/1 sequence order +static constexpr pmic_attr_ptr get_sequence[] = +{ + mss::attr::get_pmic0_sequence, + mss::attr::get_pmic1_sequence +}; + // Voltage Setting static constexpr pmic_attr_ptr get_swa_voltage_setting[] = { @@ -504,6 +511,21 @@ fapi_try_exit: } /// +/// @brief Order PMICs by sequence defined in the SPD +/// +/// @param[in] i_dimm DIMM target to pull SPD fields from +/// @param[in] i_dimm_index index of the DIMM target +/// @param[in] i_pmics_per_dimm number of PMICs per dimm +/// @param[in,out] io_pmics vector of PMICs that will be re-ordered in place +/// @return fapi2::ReturnCode +/// +fapi2::ReturnCode order_pmics_by_sequence( + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> i_dimm, + const uint8_t i_dimm_index, + const uint8_t i_pmics_per_dimm, + std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& io_pmics); + +/// /// @brief Bias with spd voltages for IDT pmic /// /// @param[in] i_pmic_target PMIC target @@ -725,69 +747,22 @@ fapi_try_exit: //------------------- ENABLE FUNCTIONS-----------------// /// -/// @brief template function for the chip-specific enable functions -/// -/// @tparam H module_height -/// @param[in] i_pmic_target - the pmic target -/// @param[in] i_dimm_target - the dimm target that the PMIC resides on -/// @param[in] i_vendor_id - the vendor ID of the PMIC to bias -/// @param[in] i_mode enable mode operation -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS if successful +/// @brief Enable pmics using manual mode (direct VR enable, no SPD fields) +/// @param[in] i_pmics vector of PMICs to enable /// -template <mss::pmic::module_height H> -fapi2::ReturnCode enable_chip(const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target, - const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target, - const uint16_t i_vendor_id); +fapi2::ReturnCode enable_manual(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>> i_pmics); /// -/// @brief enable procedure for IDT PMIC and 1U or 2U DIMM +/// @brief Function to enable 1U and 2U pmics /// -/// @param[in] i_pmic_target - the pmic_target +/// @param[in] i_pmic_target - the pmic target /// @param[in] i_dimm_target - the dimm target that the PMIC resides on /// @param[in] i_vendor_id - the vendor ID of the PMIC to bias -/// @param[in] i_mode enable mode operation /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS if successful /// -template <> -inline fapi2::ReturnCode enable_chip<mss::pmic::module_height::HEIGHT_1U>( - const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target, - const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target, - const uint16_t i_vendor_id) -{ - FAPI_INF("Setting PMIC %s settings from SPD", mss::c_str(i_pmic_target)); - - // Make sure it is TI or IDT - FAPI_ASSERT((i_vendor_id == mss::pmic::vendor::IDT || - i_vendor_id == mss::pmic::vendor::TI), - fapi2::PMIC_CHIP_NOT_RECOGNIZED() - .set_TARGET(i_pmic_target) - .set_VENDOR_ID(i_vendor_id), - "Unknown PMIC: %s with vendor ID 0x%04hhX", - mss::c_str(i_pmic_target), - uint8_t(i_vendor_id) ); - - if (i_vendor_id == mss::pmic::vendor::IDT) - { - FAPI_TRY(mss::pmic::bias_with_spd_settings<mss::pmic::vendor::IDT>(i_pmic_target, i_dimm_target), - "enable_chip<IDT, 1U/2U>: Error biasing PMIC %s with SPD settings", - mss::c_str(i_pmic_target)); - } - else // assert done in pmic_enable.C that vendor is IDT or TI - { - FAPI_TRY(mss::pmic::bias_with_spd_settings<mss::pmic::vendor::TI>(i_pmic_target, i_dimm_target), - "enable_chip<TI, 1U/2U>: Error biasing PMIC %s with SPD settings", - mss::c_str(i_pmic_target)); - } - - // Start VR Enable - FAPI_TRY(mss::pmic::start_vr_enable(i_pmic_target), - "Error starting VR_ENABLE on PMIC %s", mss::c_str(i_pmic_target)); - - return fapi2::FAPI2_RC_SUCCESS; - -fapi_try_exit: - return fapi2::current_err; -} +fapi2::ReturnCode enable_chip_1U_2U(const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target, + const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target, + const uint16_t i_vendor_id); } } // mss |