summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Geddes <crgeddes@us.ibm.com>2019-11-06 11:17:13 -0600
committerDaniel M Crowell <dcrowell@us.ibm.com>2019-11-07 23:34:48 -0600
commitc3689a69137b76f117ac9524a8f7ec189e133b04 (patch)
tree630b37a42d7041f5c27d9ae17556654c8c779f57 /src
parentc016e9860f3dcd56e1332ca455bad8471952c92b (diff)
downloadtalos-hostboot-c3689a69137b76f117ac9524a8f7ec189e133b04.tar.gz
talos-hostboot-c3689a69137b76f117ac9524a8f7ec189e133b04.zip
Fixes to PMIC presence detection
While performing presence detection on the PMIC targets we need to first read the parent OCMB's SPD to see what device address the PMIC is on. There was a bug where we were attempting to read the parent OCMB's spd without first checking if the OCMB is present itself. This commit adds a check to ensure we dont attempt i2c reads on devices that are not present. Also this commit adds a check to make sure we do not attempt presence detection on GEMINI ocmbs Change-Id: I999189b3b97210bb37b7ba1fdb2d86658d770e36 CQ: SW480414 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/86564 Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/fapiwrap/fapiWrapif.H15
-rw-r--r--src/usr/fapiwrap/fapiWrap.C51
-rw-r--r--src/usr/fapiwrap/makefile2
-rw-r--r--src/usr/i2c/i2cTargetPres.C37
4 files changed, 81 insertions, 24 deletions
diff --git a/src/include/usr/fapiwrap/fapiWrapif.H b/src/include/usr/fapiwrap/fapiWrapif.H
index e3a50f3b7..6a59e4c3f 100644
--- a/src/include/usr/fapiwrap/fapiWrapif.H
+++ b/src/include/usr/fapiwrap/fapiWrapif.H
@@ -60,12 +60,19 @@ namespace FAPIWRAP
* @brief This function wraps around the FAPI2 HWP "get_pmic_i2c_addr" which
* takes in a DDIMM's DDR4 SPD data and a PMIC's position relative to
* its parent OCMB's chip and returns the device address of that pmic
- * @param[in] i_spd - Binary blob containing addresses a given OCMB's PMICs
+ * This wrapper will actually lookup the SPD of a given ocmb target so
+ * the caller doesnt need to worry about it.
+ * @param[in] i_ocmbChip - Parent ocmb of the PMIC we wish to find the device addres of
* @param[in] i_pmic_id - PMIC's position relative to parent OCMB
- * @return uint8_t 0 if invalid pmic_id is passed, PMIC's devAddress otherwise
+ * @param[out]o_pmic_devAddr - If this pmic exists on the ocmb then return the device address
+ found in the SPD. Otherwise return NO_PMIC_DEV_ADDR
+ * @return errlHndl_t - nullptr if no error, otherwise contains error
*/
- uint8_t get_pmic_dev_addr( const char* i_spd,
- const uint8_t i_pmic_id);
+ errlHndl_t get_pmic_dev_addr( TARGETING::Target * i_ocmbChip,
+ const uint8_t i_pmic_id,
+ uint8_t& o_pmic_devAddr);
+
+ constexpr uint8_t NO_PMIC_DEV_ADDR = 0xFF;
}
diff --git a/src/usr/fapiwrap/fapiWrap.C b/src/usr/fapiwrap/fapiWrap.C
index a65b7c233..8950e0a92 100644
--- a/src/usr/fapiwrap/fapiWrap.C
+++ b/src/usr/fapiwrap/fapiWrap.C
@@ -23,12 +23,18 @@
/* */
/* IBM_PROLOG_END_TAG */
-#include <fapiwrap/fapiWrapif.H> // interface definitions
+// Platform includes
+#include <fapiwrap/fapiWrapif.H> // interface definitions
#include <fapi2/plat_hwp_invoker.H> // FAPI_INVOKE_HWP
-#include <trace/interface.H> // tracing includes
+#include <trace/interface.H> // tracing includes
+#include <vpd/spdenums.H> // DDIMM_DDR4_SPD_SIZE
+#include <devicefw/driverif.H> // deviceRead
+// Imported Includes
#include <exp_getidec.H> // exp_getidec
#include <pmic_i2c_addr_get.H> // get_pmic_i2c_addr
+#include <chipids.H> // for GEMINI ID
+
trace_desc_t* g_trac_fapiwrap;
TRAC_INIT(&g_trac_fapiwrap, FAPIWRAP_COMP_NAME, 6*KILOBYTE, TRACE::BUFFER_SLOW);
@@ -57,9 +63,44 @@ namespace FAPIWRAP
return l_errl;
}
- uint8_t get_pmic_dev_addr( const char* i_spd,
- const uint8_t i_pmic_id)
+ errlHndl_t get_pmic_dev_addr( TARGETING::Target * i_ocmbChip,
+ const uint8_t i_pmic_id,
+ uint8_t& o_pmic_devAddr)
{
- return get_pmic_i2c_addr(i_spd, i_pmic_id);
+ errlHndl_t l_errl = nullptr;
+
+ do{
+
+ auto l_chipId = i_ocmbChip->getAttr< TARGETING::ATTR_CHIP_ID>();
+
+ if( l_chipId == POWER_CHIPID::GEMINI_16)
+ {
+ // If this is a Gemini OCMB then there are no PMIC targets
+ // so just set the out parm to NO_PMIC_DEV_ADDR and break
+ o_pmic_devAddr = NO_PMIC_DEV_ADDR;
+ break;
+ }
+
+ uint8_t l_spdBlob[SPD::DDIMM_DDR4_SPD_SIZE];
+ size_t l_spdSize = SPD::DDIMM_DDR4_SPD_SIZE;
+
+ l_errl = deviceRead(i_ocmbChip,
+ l_spdBlob,
+ l_spdSize,
+ DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD_WITHOUT_EFD));
+
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_fapiwrap, ERR_MRK"get_pmic_dev_addr() "
+ "Error reading SPD associated with OCMB 0x%.08X",
+ TARGETING::get_huid(i_ocmbChip));
+ break;
+ }
+
+ o_pmic_devAddr = get_pmic_i2c_addr(reinterpret_cast<char *>(l_spdBlob),
+ i_pmic_id);
+
+ }while(0);
+ return l_errl;
}
} \ No newline at end of file
diff --git a/src/usr/fapiwrap/makefile b/src/usr/fapiwrap/makefile
index 96d96e48b..1916630db 100644
--- a/src/usr/fapiwrap/makefile
+++ b/src/usr/fapiwrap/makefile
@@ -35,6 +35,8 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
# to get ffdc_includes.H
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
+# to get chipids.H
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
# HWP include directories :
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
diff --git a/src/usr/i2c/i2cTargetPres.C b/src/usr/i2c/i2cTargetPres.C
index 2aba61de3..c7c9421a3 100644
--- a/src/usr/i2c/i2cTargetPres.C
+++ b/src/usr/i2c/i2cTargetPres.C
@@ -32,7 +32,6 @@
#include <initservice/initserviceif.H>
#include <errl/errlmanager.H>
#include "i2c_common.H"
-#include <vpd/spdenums.H>
#include <fapiwrap/fapiWrapif.H>
extern trace_desc_t* g_trac_i2c;
@@ -269,23 +268,16 @@ errlHndl_t pmicI2CPresencePerformOp(DeviceFW::OperationType i_opType,
errlHndl_t l_errl = nullptr;
bool l_pmicPresent = 0;
+ uint8_t l_devAddr;
TARGETING::Target* l_parentOcmb = TARGETING::getImmediateParentByAffinity(i_target);
-
- uint8_t l_spdBlob[SPD::DDIMM_DDR4_SPD_SIZE];
- size_t l_spdSize = SPD::DDIMM_DDR4_SPD_SIZE;
+ auto l_parentHwasState = l_parentOcmb->getAttr<TARGETING::ATTR_HWAS_STATE>();
do{
- l_errl = deviceRead(l_parentOcmb,
- l_spdBlob,
- l_spdSize,
- DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD_WITHOUT_EFD));
-
- if(l_errl)
+ if(! l_parentHwasState.present)
{
- TRACFCOMP( g_trac_i2c, ERR_MRK"pmicI2CPresencePerformOp() "
- "Error reading SPD associated with PMIC 0x%.08X, failed to determine presence",
- TARGETING::get_huid(i_target));
+ // If the parent chip is not present, then neither is the pmic
+ // so just break out and return not present
break;
}
@@ -294,13 +286,28 @@ errlHndl_t pmicI2CPresencePerformOp(DeviceFW::OperationType i_opType,
// PMICs will have a different device address depending on the vendor.
// Prior to doing present detection on a pmic we must first query the
// device address from the parent OCMB's SPD
- uint8_t l_devAddr = FAPIWRAP::get_pmic_dev_addr(reinterpret_cast<char *>(l_spdBlob),
- l_relPos);
+ l_errl = FAPIWRAP::get_pmic_dev_addr(l_parentOcmb,
+ l_relPos,
+ l_devAddr);
+ if (l_errl)
+ {
+ TRACFCOMP( g_trac_i2c, ERR_MRK"pmicI2CPresencePerformOp() "
+ "Error attempting to read pmic device address on OCMB 0x%.08X",
+ TARGETING::get_huid(l_parentOcmb));
+ break;
+ }
assert(l_devAddr != 0,
"Found devAddr for PMIC 0x%.08x to be 0, this cannot be. Check SPD and REL_POS on target",
TARGETING::get_huid(i_target));
+ if(l_devAddr == FAPIWRAP::NO_PMIC_DEV_ADDR)
+ {
+ // There is no pmic device address for this rel position on this ocmb so
+ // break and return not present.
+ break;
+ }
+
i_target->setAttr<TARGETING::ATTR_DYNAMIC_I2C_DEVICE_ADDRESS>(l_devAddr);
l_errl = genericI2CTargetPresenceDetect(i_target,
OpenPOWER on IntegriCloud