summaryrefslogtreecommitdiffstats
path: root/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C')
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C138
1 files changed, 138 insertions, 0 deletions
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
OpenPOWER on IntegriCloud