summaryrefslogtreecommitdiffstats
path: root/src/import/chips/ocmb/common/procedures/hwp
diff options
context:
space:
mode:
authorMark Pizzutillo <Mark.Pizzutillo@ibm.com>2019-08-06 18:23:07 -0400
committerChristian R Geddes <crgeddes@us.ibm.com>2019-08-13 14:35:15 -0500
commit24762ab00d2ac17a7b48002fb312e3c41e56c32a (patch)
tree5ea48499ba3cdef1026964782a8e8263c39d35fc /src/import/chips/ocmb/common/procedures/hwp
parent08db2d6a3a0bafa6d76a0f281541a6aa2b4d2156 (diff)
downloadblackbird-hostboot-24762ab00d2ac17a7b48002fb312e3c41e56c32a.tar.gz
blackbird-hostboot-24762ab00d2ac17a7b48002fb312e3c41e56c32a.zip
Fix issue in pmic_enable where VR_ENABLE did not kick off
Also fixing a small issue/oversight. The PMIC requires enabled startup sequences to "enable" the rails of previous sequences. Change-Id: Id8a5baf54f7aef0c7e6aa97539fc78196c011dbf Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/81828 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Dev-Ready: Steven B Janssen <janssens@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Devon A Baughen <devon.baughen1@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/81860 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')
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C58
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H4
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C7
3 files changed, 62 insertions, 7 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 40841c1e0..65bf83b5a 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
@@ -179,7 +179,6 @@ fapi_try_exit:
/// @param[in] i_dimm_target dimm target of PMIC
/// @param[in] i_id PMIC0 or PMIC1
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
-/// @note TK - this function may greatly change. It relies on SPD fields that may not be correct.
///
fapi2::ReturnCode bias_with_spd_startup_seq(
const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
@@ -203,6 +202,15 @@ fapi2::ReturnCode bias_with_spd_startup_seq(
mss::pmic::get_swd_sequence_delay
};
+ static const std::vector<uint8_t> SEQUENCE_REGS =
+ {
+ 0, // 0 would imply no sequence config (won't occur due to assert in bias_with_spd_startup_seq)
+ REGS::R40_POWER_ON_SEQUENCE_CONFIG_1,
+ REGS::R41_POWER_ON_SEQUENCE_CONFIG_2,
+ REGS::R42_POWER_ON_SEQUENCE_CONFIG_3,
+ REGS::R43_POWER_ON_SEQUENCE_CONFIG_4
+ };
+
// Arrays to store the attribute data
uint8_t l_sequence_orders[CONSTS::NUMBER_OF_RAILS];
uint8_t l_sequence_delays[CONSTS::NUMBER_OF_RAILS];
@@ -229,6 +237,7 @@ fapi2::ReturnCode bias_with_spd_startup_seq(
{
fapi2::buffer<uint8_t> l_power_on_sequence_config;
+ uint8_t l_highest_sequence = 0;
// Zero out sequence registers first
FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R40_POWER_ON_SEQUENCE_CONFIG_1, l_power_on_sequence_config));
@@ -236,19 +245,40 @@ fapi2::ReturnCode bias_with_spd_startup_seq(
FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R42_POWER_ON_SEQUENCE_CONFIG_3, l_power_on_sequence_config));
FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R43_POWER_ON_SEQUENCE_CONFIG_4, l_power_on_sequence_config));
- // Set the registers appropriately.
- // We do manual reversing here (see above) so that we can also place in the delays as they're supposed to be
+ // Set the registers appropriately. We kind of need to do this greedy algorithm here since
+ // the SPD has fields of sequence per rail, the PMIC wants rails per sequence.
+ // 1. For each rail, set that bit in the corresponding sequence, and enable that sequence
+ // 2. Set that rail bit for each of the following sequences
+ // 3. Record the highest sequence used throughout the run
+ // 4. Clear out registers of sequences higher than the highest used (clear the set rail bits)
+ // We do this because for each rail, we may not know what the highest sequence will be yet.
+ // It makes the most sense to assume all sequences, then clear those that aren't used.
for (uint8_t l_rail_index = mss::pmic::rail::SWA; l_rail_index <= mss::pmic::rail::SWD; ++l_rail_index)
{
- if (l_sequence_orders[l_rail_index] != 0) // If 0, it will not be sequenced
+ static constexpr uint8_t NO_SEQUENCE = 0;
+ const uint8_t l_rail_sequence = l_sequence_orders[l_rail_index];
+
+ if (l_rail_sequence != NO_SEQUENCE) // If 0, it will not be sequenced
{
+ // Update the new highest working sequence
+ l_highest_sequence = std::max(l_rail_sequence, l_highest_sequence);
// Set the register contents appropriately
FAPI_TRY(mss::pmic::set_startup_seq_register(i_pmic_target, l_rail_index,
- l_sequence_orders[l_rail_index], l_sequence_delays[l_rail_index]));
+ l_rail_sequence, l_sequence_delays[l_rail_index]));
}
// else, zero, do nothing.
}
+
+ // Now erase the registers that are higher than our highest sequence (in order to satisfy note 2
+ // for registers R40 - R43):
+ // - 2. If bit [7] = ‘0’, bits [6:3] must be programmed as ‘0000’. If bit [7] = ‘1’,
+ // - at least one of the bits [6:3] must be programmed as ‘1’.
+ for (++l_highest_sequence; l_highest_sequence < SEQUENCE_REGS.size(); ++l_highest_sequence)
+ {
+ fapi2::buffer<uint8_t> l_clear;
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, SEQUENCE_REGS[l_highest_sequence], l_power_on_sequence_config));
+ }
}
fapi_try_exit:
@@ -326,10 +356,24 @@ fapi2::ReturnCode set_startup_seq_register(
l_power_on_sequence_config.clearBit<DELAY_START, FIELDS::DELAY_FLD_LENGTH>();
l_power_on_sequence_config = l_power_on_sequence_config + i_delay;
- l_power_on_sequence_config.setBit(SEQUENCE_BITS[i_rail]);
- l_power_on_sequence_config.setBit(SEQUENCE_ENABLE_REVERSED);
+ FAPI_TRY(l_power_on_sequence_config.setBit(SEQUENCE_BITS[i_rail]));
+ FAPI_TRY(l_power_on_sequence_config.setBit(SEQUENCE_ENABLE_REVERSED));
FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, SEQUENCE_REGS[i_round], l_power_on_sequence_config));
+
+ // The startup sequence registers after the provided one must set the bits of the rail we just enabled in
+ // the current sequence. So here, we iterate through the remaining sequences and set those bits.
+ // since we don't know the information about all the rails within this one function (others may be
+ // set in later calls to this function) we will set these for each sequence register now, and then
+ // clear them out later when we know exactly which sequences will be enabled and which ones won't
+ for (uint8_t l_round_modify = i_round; l_round_modify < SEQUENCE_REGS.size(); ++l_round_modify)
+ {
+ l_power_on_sequence_config.flush<0>();
+ FAPI_TRY(mss::pmic::i2c::reg_read(i_pmic_target, SEQUENCE_REGS[l_round_modify], l_power_on_sequence_config));
+ FAPI_TRY(l_power_on_sequence_config.setBit(SEQUENCE_BITS[i_rail]));
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, SEQUENCE_REGS[l_round_modify], l_power_on_sequence_config));
+ }
+
return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
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 5e6d43216..c74762c38 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
@@ -780,6 +780,10 @@ inline fapi2::ReturnCode enable_chip<mss::pmic::module_height::HEIGHT_1U>(
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:
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C b/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C
index 1318bab0c..d13574ac8 100644
--- a/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C
@@ -57,6 +57,13 @@ extern "C"
auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_ocmb_target);
auto l_pmics = mss::find_targets<fapi2::TARGET_TYPE_PMIC>(i_ocmb_target);
+ // Check that we have PMICs (we wouldn't on gemini, for example)
+ if (l_pmics.empty())
+ {
+ FAPI_INF("No PMICs to enable on %s, exiting.", mss::c_str(i_ocmb_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
// Sort by index (low to high) since find_targets may not return the correct order
std::sort(l_dimms.begin(), l_dimms.end(),
[] (const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& l_first_dimm,
OpenPOWER on IntegriCloud