From 1f637430444512e67b2bf62e3761d3813d690a5a Mon Sep 17 00:00:00 2001 From: Corey Swenson Date: Thu, 26 Mar 2015 08:14:37 -0500 Subject: Disable OCC Sensor Cache during Centaur I2C access at Runtime Change-Id: I4520421f3d3e1c7cb7f58874bd4076acced7ddd3 RTC: 125538 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16653 Tested-by: Jenkins Server Reviewed-by: Michael Baiocchi Reviewed-by: A. Patrick Williams III --- src/include/usr/i2c/i2cif.H | 29 ++++++++++++++ src/usr/i2c/eepromdd.C | 48 +++++++++++++++++++++-- src/usr/i2c/runtime/rt_i2c.C | 93 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/include/usr/i2c/i2cif.H b/src/include/usr/i2c/i2cif.H index d9d5a0133..ccedce873 100644 --- a/src/include/usr/i2c/i2cif.H +++ b/src/include/usr/i2c/i2cif.H @@ -28,6 +28,9 @@ namespace I2C { +// @todo RTC 125540 - Ensure no possible Centaur i2c collisions during HB IPL +// Need to re-evaluate the ifdef/ifndef in this file +#ifndef __HOSTBOOT_RUNTIME /** * @enum i2cProcessType * @@ -173,6 +176,32 @@ struct MasterInfo_t */ void getMasterInfo( const TARGETING::Target* i_chip, std::list& o_info ); +#endif // !__HOSTBOOT_RUNTIME + +#ifdef __HOSTBOOT_RUNTIME +/** + * @brief This function disables the OCC sensor cache for the specified target + * + * @param[in] i_target - I2C Master Target device + * @param[out] o_disabled - Indicates the sensor cache was enabled + * and is now disabled + * + * @return errHndl_t - NULL if successful, otherwise a pointer to + * the error log. + */ +errlHndl_t i2cDisableSensorCache( TARGETING::Target * i_target, + bool & o_disabled ); + +/** + * @brief This function enables the OCC sensor cache for the specified target + * + * @param[in] i_target - I2C Master Target device + * + * @return errHndl_t - NULL if successful, otherwise a pointer to + * the error log. + */ +errlHndl_t i2cEnableSensorCache( TARGETING::Target * i_target ); +#endif //__HOSTBOOT_RUNTIME }; // end namespace I2C diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C index eb5ceb2ad..372fcc75a 100755 --- a/src/usr/i2c/eepromdd.C +++ b/src/usr/i2c/eepromdd.C @@ -46,13 +46,10 @@ #include #include #include +#include #include "eepromdd.H" #include "errlud_i2c.H" -#ifndef __HOSTBOOT_RUNTIME -#include -#endif - // ---------------------------------------------- // Globals // ---------------------------------------------- @@ -125,6 +122,13 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, "i_opType=%d, chip=%d, offset=%d, len=%d", (uint64_t) i_opType, i2cInfo.chip, i2cInfo.offset, io_buflen); +#ifdef __HOSTBOOT_RUNTIME + // At runtime the OCC sensor cache will need to be diabled to avoid I2C + // collisions. This bool indicates the sensor cache was enabled but is + // now disabled and needs to be re-enabled when the eeprom op completes. + bool scacDisabled = false; +#endif //__HOSTBOOT_RUNTIME + do { // Read Attributes needed to complete the operation @@ -185,6 +189,18 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, break; } +#ifdef __HOSTBOOT_RUNTIME + // Disable Sensor Cache if the I2C master target is MEMBUF + if( theTarget->getAttr() == + TARGETING::TYPE_MEMBUF ) + { + err = I2C::i2cDisableSensorCache(theTarget,scacDisabled); + if ( err ) + { + break; + } + } +#endif //__HOSTBOOT_RUNTIME // Do the read or write if( i_opType == DeviceFW::READ ) @@ -240,6 +256,30 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, } } while( 0 ); +#ifdef __HOSTBOOT_RUNTIME + // Re-enable sensor cache if it was disabled before the eeprom op and + // the I2C master target is MEMBUF + if( scacDisabled && + (theTarget->getAttr() == TARGETING::TYPE_MEMBUF) ) + { + errlHndl_t tmp_err = NULL; + + tmp_err = I2C::i2cEnableSensorCache(theTarget); + + if( err && tmp_err) + { + delete tmp_err; + TRACFCOMP(g_trac_eeprom, + ERR_MRK" Enable Sensor Cache failed for HUID=0x%.8X", + TARGETING::get_huid(theTarget)); + } + else if(tmp_err) + { + err = tmp_err; + } + } +#endif //__HOSTBOOT_RUNTIME + // If there is an error, add parameter info to log if ( err != NULL ) { diff --git a/src/usr/i2c/runtime/rt_i2c.C b/src/usr/i2c/runtime/rt_i2c.C index bdadbbed4..8704b6be1 100755 --- a/src/usr/i2c/runtime/rt_i2c.C +++ b/src/usr/i2c/runtime/rt_i2c.C @@ -32,6 +32,7 @@ // ---------------------------------------------- // Includes // ---------------------------------------------- +#include #include #include #include @@ -56,6 +57,11 @@ TRAC_INIT( & g_trac_i2c, I2C_COMP_NAME, KILOBYTE ); namespace I2C { +const uint64_t SCAC_CONFIG_REG = 0x00000000020115CEULL; +const uint64_t SCAC_CONFIG_SET = 0x00000000020115CFULL; +const uint64_t SCAC_CONFIG_CLR = 0x00000000020115D0ULL; +const uint64_t SCAC_ENABLE_MSK = 0x8000000000000000ULL; + // ------------------------------------------------------------------ // i2cPerformOp // ------------------------------------------------------------------ @@ -68,6 +74,9 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, { errlHndl_t err = NULL; + TRACDCOMP( g_trac_i2c, + ENTER_MRK"i2cPerformOp()" ); + // Get the args out of the va_list // Address, Port, Engine, Device Addr. // Other args set below @@ -263,4 +272,88 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, TARGETING::TYPE_MEMBUF, i2cPerformOp ); +// ------------------------------------------------------------------ +// i2cDisableSensorCache +// ------------------------------------------------------------------ +errlHndl_t i2cDisableSensorCache ( TARGETING::Target * i_target, + bool & o_disabled ) +{ + errlHndl_t err = NULL; + + o_disabled = false; + + TRACDCOMP( g_trac_i2c, + ENTER_MRK"i2cDisableSensorCache()" ); + + do + { + uint64_t scacData = 0x0; + size_t dataSize = sizeof(scacData); + + // Read the scac config reg to get the enabled/disabled bit + err = DeviceFW::deviceOp( DeviceFW::READ, + i_target, + &scacData, + dataSize, + DEVICE_SCOM_ADDRESS(SCAC_CONFIG_REG) ); + if ( err ) + { + break; + } + + // Disable SCAC if it's enabled + if( scacData & SCAC_ENABLE_MSK ) + { + o_disabled = true; // Enable SCAC again after op completes + scacData = SCAC_ENABLE_MSK; + + // Write the scac clear reg to disable the sensor cache + err = DeviceFW::deviceOp( DeviceFW::WRITE, + i_target, + &scacData, + dataSize, + DEVICE_SCOM_ADDRESS(SCAC_CONFIG_CLR) ); + if ( err ) + { + break; + } + + // Wait 30 msec for outstanding sensor cache + // operations to complete + nanosleep(0,30 * NS_PER_MSEC); + } + } while( 0 ); + + TRACDCOMP( g_trac_i2c, + EXIT_MRK"i2cDisableSensorCache()" ); + + return err; +} // end i2cDisableSensorCache + +// ------------------------------------------------------------------ +// i2cEnableSensorCache +// ------------------------------------------------------------------ +errlHndl_t i2cEnableSensorCache ( TARGETING::Target * i_target ) +{ + errlHndl_t err = NULL; + + TRACDCOMP( g_trac_i2c, + ENTER_MRK"i2cEnableSensorCache()" ); + + uint64_t scacData = SCAC_ENABLE_MSK; + size_t dataSize = sizeof(scacData); + + // Write the scac set reg to enable the sensor cache + err = DeviceFW::deviceOp( DeviceFW::WRITE, + i_target, + &scacData, + dataSize, + DEVICE_SCOM_ADDRESS(SCAC_CONFIG_SET) ); + + TRACDCOMP( g_trac_i2c, + EXIT_MRK"i2cEnableSensorCache()" ); + + return err; +} // end i2cEnableSensorCache + } // end namespace I2C -- cgit v1.2.1