Skip to content

Commit

Permalink
Driver changes to support i2c mux
Browse files Browse the repository at this point in the history
- Updated data structures gpioAddr_t, eeprom_addr_t, misc_args_t, nvdimm_addr_t
  and tpm_info_t with I2C MUX data members. Also added constructors to these
  structures to default there data members with the correct default info.
- Updated macros DEVICE_I2C_PARMS, DEVICE_I2C_ADDRESS and
  DEVICE_I2C_ADDRESS_OFFSET to take the I2C MUX bus selector parameter and the
  I2C MUX entity path.
- Added method i2cAccessMux to file i2c.H/.C that will setup the call for the
  I2C MUX.  Method i2cCommonOP calls i2cAccessMux which then calls i2cCommonOp
  with appropriate parameters for the I2C MUX: i2cCommonOP -> i2cAccessMux
  -> i2cCommonOP.
- Updated i2ctest.H with new I2C MUX params to get it to pass.

RTC:191352
Change-Id: I6a70860eb2286bbd23d6157d72351b8adfa21aac
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66651
Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@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>
  • Loading branch information
velozr authored and dcrowell77 committed Dec 7, 2018
1 parent 082f936 commit b63c847
Show file tree
Hide file tree
Showing 27 changed files with 1,566 additions and 324 deletions.
1 change: 1 addition & 0 deletions src/build/configs/axone.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set DJVPD_READ_FROM_HW
66 changes: 47 additions & 19 deletions src/include/usr/devicefw/driverif.H
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@

#endif // not PARSER

namespace I2C_MUX
{
enum SELECTOR: uint8_t
{
NOT_APPLICABLE = 0xFF,
};
}

namespace DeviceFW
{
/** @enum AccessType_DriverOnly
Expand All @@ -57,6 +65,7 @@ namespace DeviceFW
FSI_I2C,
SBEFIFOSCOM,
I2CSCOM,
I2C_MUX,
LAST_DRIVER_ACCESS_TYPE
};

Expand Down Expand Up @@ -119,22 +128,29 @@ namespace DeviceFW
/**
* @brief Macro that handles the I2C parameters
*/
#define DEVICE_I2C_PARMS(port, engine, devAddr, offset_len, offset)\
#define DEVICE_I2C_PARMS(port, engine, devAddr, offset_len,\
offset, muxSelector, i_i2cMuxPath)\
static_cast<uint64_t>( port ),\
static_cast<uint64_t>( engine ),\
static_cast<uint64_t>( devAddr ),\
static_cast<uint64_t>( offset_len ),\
static_cast<uint8_t*>( offset )
static_cast<uint8_t*>( offset ),\
static_cast<uint64_t>( muxSelector), \
static_cast<const TARGETING::EntityPath*>(i_i2cMuxPath)

/**
* Construct the device addressing parameters for the I2C device ops.
* @param[in] i_port - Which port to use from the I2C master.
* @param[in] i_engine - Which I2C master engine to use.
* @param[in] i_devAddr - The device address on a given engine/port.
* @note '0' and 'NULL' added to line up with other DeviceFW::I2C
* @param[in] i_i2cMuxBusSelector - The I2C MUX bus selector
* @param[in] i_i2cMuxPath - The I2C MUX entity path
* @note '0' and 'nullptr' added to line up with other DeviceFW::I2C
*/
#define DEVICE_I2C_ADDRESS( i_port, i_engine, i_devAddr )\
DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, 0, NULL)
#define DEVICE_I2C_ADDRESS( i_port, i_engine, i_devAddr, \
i_i2cMuxBusSelector, i_i2cMuxPath )\
DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\
0, nullptr, i_i2cMuxBusSelector, i_i2cMuxPath)

/**
* Construct the device addressing parameters for the I2C-offset device ops.
Expand All @@ -143,10 +159,13 @@ namespace DeviceFW
* @param[in] i_devAddr - The device address on a given engine/port.
* @param[in] i_offset_len - Length of offset (in bytes)
* @param[in] i_offset - Offset into I2C device
* @param[in] i_i2cMuxBusSelector - The I2C MUX bus selector
* @param[in] i_i2cMuxPath - The I2C MUX entity path
*/
#define DEVICE_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr, i_offset_len, i_offset)\
DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, i_offset_len, i_offset)

#define DEVICE_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr,\
i_offset_len, i_offset, i_i2cMuxBusSelector, i_i2cMuxPath)\
DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\
i_offset_len, i_offset, i_i2cMuxBusSelector, i_i2cMuxPath)

/**
* Construct the device addressing parameters for locking the page
Expand All @@ -162,7 +181,8 @@ namespace DeviceFW
* want to lock the page mutex or not. This bool allows
* us to switch pages mid read without hitting a deadlock.
*/
#define DEVICE_I2C_CONTROL_PAGE_OP( i_port, i_engine, i_shouldLock, i_desired_page, i_lockMutex )\
#define DEVICE_I2C_CONTROL_PAGE_OP( i_port, i_engine, i_shouldLock,\
i_desired_page, i_lockMutex )\
DeviceFW::I2C,\
static_cast<uint64_t>(i_port),\
static_cast<uint64_t>(i_engine),\
Expand All @@ -177,42 +197,50 @@ namespace DeviceFW
* @param[in] i_port - Which port to use from the I2C master.
* @param[in] i_engine - Which I2C master engine to use.
* @param[in] i_devAddr - The device address on a given engine/port.
* @note '0' and 'NULL' added to line up with other DeviceFW::I2C
* @note '0' and 'nullptr' added to line up with other DeviceFW::I2C
*/
#define DEVICE_HOSTI2C_ADDRESS( i_port, i_engine, i_devAddr )\
DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, 0, NULL)
DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\
0, nullptr)

/**
* Construct the device addressing parameters for the Host I2C-offset device ops.
* Construct the device addressing parameters for the Host I2C-offset
* device ops.
* @param[in] i_port - Which port to use from the I2C master.
* @param[in] i_engine - Which I2C master engine to use.
* @param[in] i_devAddr - The device address on a given engine/port.
* @param[in] i_offset_len - Length of offset (in bytes)
* @param[in] i_offset - Offset into I2C device
*/
#define DEVICE_HOSTI2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr, i_offset_len, i_offset)\
DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, i_offset_len, i_offset)
#define DEVICE_HOSTI2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr,\
i_offset_len, i_offset)\
DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\
i_offset_len, i_offset)

/**
* Construct the device addressing parameters for the FSI I2C device ops.
* @param[in] i_port - Which port to use from the I2C master.
* @param[in] i_engine - Which I2C master engine to use.
* @param[in] i_devAddr - The device address on a given engine/port.
* @note '0' and 'NULL' added to line up with other DeviceFW::I2C
* @note '0' and 'nullptr' added to line up with other DeviceFW::I2C
*/
#define DEVICE_FSI_I2C_ADDRESS( i_port, i_engine, i_devAddr )\
DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, 0, NULL)
DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine,\
i_devAddr, 0, nullptr)

/**
* Construct the device addressing parameters for the FSI I2C-offset device ops.
* Construct the device addressing parameters for the FSI I2C-offset
* device ops.
* @param[in] i_port - Which port to use from the I2C master.
* @param[in] i_engine - Which I2C master engine to use.
* @param[in] i_devAddr - The device address on a given engine/port.
* @param[in] i_offset_len - Length of offset (in bytes)
* @param[in] i_offset - Offset into I2C device
*/
#define DEVICE_FSI_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr, i_offset_len, i_offset)\
DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, i_offset_len, i_offset)
#define DEVICE_FSI_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr,\
i_offset_len, i_offset)\
DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\
i_offset_len, i_offset)

/** Construct the device addressing parameters for the SBE FIFO Scom
* device ops.
Expand Down
3 changes: 3 additions & 0 deletions src/include/usr/i2c/i2creasoncodes.H
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ enum i2cModuleId
I2C_CHOOSE_EEPROM_PAGE = 0x0E,
FAPI_I2C_PERFORM_OP = 0x0F,
READ_I2C_ATTRIBUTES = 0x10,
I2C_ACCESS_MUX = 0x11,
};


Expand Down Expand Up @@ -95,6 +96,8 @@ enum i2cReasonCode
I2C_INVALID_EEPROM_PAGE_REQUEST = I2C_COMP_ID | 0x11, // Invalid EEPROM page request
I2C_FAILURE_UNLOCKING_EEPROM_PAGE = I2C_COMP_ID | 0x12, // Error while attempting to unlock the eeprom page
INVALID_MASTER_TARGET = I2C_COMP_ID | 0x13, // Master I2C target not valid
I2C_MUX_TARGET_NOT_FOUND = I2C_COMP_ID | 0x14, // The MUX target is not valid (null)
I2C_MUX_TARGET_NON_FUNCTIONAL = I2C_COMP_ID | 0x15, // The MUX target is non functional
};


Expand Down
9 changes: 8 additions & 1 deletion src/include/usr/i2c/tpmddif.H
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#ifndef __TPMDDIF_H
#define __TPMDDIF_H

#include "usr/devicefw/driverif.H" // I2C_MUX::NOT_APPLICABLE

namespace TPMDD
{

Expand Down Expand Up @@ -79,6 +81,9 @@ struct tpm_info_t
size_t offset; ///< TPM Device register offset
tpm_addr_size_t addrSize; ///< I2C Addr size

uint8_t i2cMuxBusSelector; ///< The Selector for the I2C MUX
TARGETING::EntityPath i2cMuxPath; ///< I2C MUX path

/**
* @brief Construct a default tpm_info_t
*/
Expand All @@ -93,7 +98,9 @@ struct tpm_info_t
tpmEnabled(false),
devAddr(0),
offset(0),
addrSize(LAST_DEVICE_TYPE)
addrSize(LAST_DEVICE_TYPE),
i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE),
i2cMuxPath()
{
}
};
Expand Down
13 changes: 9 additions & 4 deletions src/usr/gpio/gpiodd.C
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2014,2015 */
/* Contributors Listed Below - COPYRIGHT 2014,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
Expand Down Expand Up @@ -35,7 +35,6 @@
#include "gpiodd.H"
#include <gpio/gpioddreasoncodes.H>


trace_desc_t * g_trac_gpio = NULL;
TRAC_INIT( & g_trac_gpio, GPIO_COMP_NAME, KILOBYTE );

Expand Down Expand Up @@ -187,7 +186,9 @@ errlHndl_t gpioRead( TARGETING::Target * i_target,
i_gpioInfo.engine,
i_gpioInfo.i2cDeviceAddr,
GPIO_ADDR_SIZE,
reinterpret_cast<uint8_t*>(&(i_gpioInfo.portAddr))
reinterpret_cast<uint8_t*>(&(i_gpioInfo.portAddr)),
i_gpioInfo.i2cMuxBusSelector,
&(i_gpioInfo.i2cMuxPath)
)
);
if(err)
Expand Down Expand Up @@ -217,7 +218,9 @@ errlHndl_t gpioWrite ( TARGETING::Target * i_target,
DEVICE_I2C_ADDRESS
( i_gpioInfo.i2cPort,
i_gpioInfo.engine,
i_gpioInfo.i2cDeviceAddr
i_gpioInfo.i2cDeviceAddr,
i_gpioInfo.i2cMuxBusSelector,
&(i_gpioInfo.i2cMuxPath)
)
);
if(err)
Expand Down Expand Up @@ -312,6 +315,8 @@ errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target,
io_gpioInfo.engine = gpioData.engine;
io_gpioInfo.i2cPort = gpioData.port;
io_gpioInfo.i2cDeviceAddr = gpioData.devAddr;
io_gpioInfo.i2cMuxBusSelector = gpioData.i2cMuxBusSelector;
io_gpioInfo.i2cMuxPath = gpioData.i2cMuxPath;
}

return err;
Expand Down
19 changes: 18 additions & 1 deletion src/usr/gpio/gpiodd.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2014,2015 */
/* Contributors Listed Below - COPYRIGHT 2014,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
Expand Down Expand Up @@ -40,6 +40,23 @@ namespace GPIO
uint8_t i2cPort;
uint8_t engine;
uint8_t i2cDeviceAddr;
uint8_t i2cMuxBusSelector;
TARGETING::EntityPath i2cMuxPath;

/**
* @brief Construct a default gpioAddr_t
*/
gpioAddr_t()
: i2cMasterPath(),
deviceType(INVALID_GPIO),
portAddr(0),
i2cPort(0),
engine(0),
i2cDeviceAddr(0),
i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE),
i2cMuxPath()
{
}
};

/**
Expand Down
74 changes: 69 additions & 5 deletions src/usr/hwas/common/hwas.C
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,57 @@ errlHndl_t check_current_proc_mem_to_use_is_still_valid (bool o_match)
return l_err;
}

/**
* @brief Do presence detect on only MUX targets and enable HWAS state
*
* @param[in] i_sysTarget the top level target (CLASS_SYS)
* @return errlHndl_t return nullptr if no error,
* else return a handle to an error entry
*
*/
errlHndl_t discoverMuxTargetsAndEnable(const Target &i_sysTarget)
{
HWAS_DBG(ENTER_MRK"discoverMuxTargetsAndEnable");

errlHndl_t l_err{nullptr};

do
{
// Only get MUX targets
const PredicateCTM l_muxPred(CLASS_CHIP, TYPE_I2C_MUX);
TARGETING::PredicatePostfixExpr l_muxPredExpr;
l_muxPredExpr.push(&l_muxPred);
TargetHandleList l_pMuxCheckPres;
targetService().getAssociated( l_pMuxCheckPres, (&i_sysTarget),
TargetService::CHILD, TargetService::ALL, &l_muxPredExpr);

// Do the presence detect on only MUX targets
l_err = platPresenceDetect(l_pMuxCheckPres);

// If an issue with platPresenceDetect, then exit, returning
// error back to caller
if (nullptr != l_err)
{
break;
}

// Enable the HWAS State for the MUXes
const bool l_present(true);
const bool l_functional(true);
const uint32_t l_errlEid(0);
for (TargetHandle_t pTarget : l_pMuxCheckPres)
{
// set HWAS state to show MUX is present and functional
enableHwasState(pTarget, l_present, l_functional, l_errlEid);
}
} while (0);

HWAS_DBG(EXIT_MRK"discoverMuxTargetsAndEnable exit with %s",
(nullptr == l_err ? "no error" : "error"));

return l_err;
}

errlHndl_t discoverTargets()
{
HWAS_DBG("discoverTargets entry");
Expand Down Expand Up @@ -635,7 +686,17 @@ errlHndl_t discoverTargets()
HWAS_DBG("pSys %.8X - marked present",
pSys->getAttr<ATTR_HUID>());

// find list of all we need to call platPresenceDetect against
// Certain targets have dependencies on the MUX, so it is best to
// presence detect and enable the MUX before moving on to these targets.
// Please take this into consideration if code needs to be rearranged
// in the future.
errl = discoverMuxTargetsAndEnable(*pSys);

if (errl != NULL)
{
break; // break out of the do/while so that we can return
}

PredicateCTM predEnc(CLASS_ENC);
PredicateCTM predChip(CLASS_CHIP);
PredicateCTM predDimm(CLASS_LOGICAL_CARD, TYPE_DIMM);
Expand Down Expand Up @@ -698,10 +759,13 @@ errlHndl_t discoverTargets()
uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES];
bzero(pgData, sizeof(pgData));

// Cache the target type
auto l_targetType = pTarget->getAttr<ATTR_TYPE>();
if( (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP) &&
(pTarget->getAttr<ATTR_TYPE>() != TYPE_TPM) &&
(pTarget->getAttr<ATTR_TYPE>() != TYPE_SP) &&
(pTarget->getAttr<ATTR_TYPE>() != TYPE_BMC) )
(l_targetType != TYPE_TPM) &&
(l_targetType != TYPE_SP) &&
(l_targetType != TYPE_BMC) &&
(l_targetType != TYPE_I2C_MUX) )
{
// read Chip ID/EC data from these physical chips
errl = platReadIDEC(pTarget);
Expand All @@ -720,7 +784,7 @@ errlHndl_t discoverTargets()
errlCommit(errl, HWAS_COMP_ID);
// errl is now NULL
}
else if (pTarget->getAttr<ATTR_TYPE>() == TYPE_PROC)
else if (l_targetType == TYPE_PROC)
{
// read partialGood vector from these as well.
errl = platReadPartialGood(pTarget, pgData);
Expand Down

0 comments on commit b63c847

Please sign in to comment.