summaryrefslogtreecommitdiffstats
path: root/src/usr/i2c
diff options
context:
space:
mode:
authorDean Sanner <dsanner@us.ibm.com>2014-09-08 13:58:12 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-09-26 13:56:00 -0500
commit84d598c4c7de197f01dcd0adb20eea27b614e9e1 (patch)
tree9ca325894cc25ea0d7fd539b7be7fc5387d0dcf3 /src/usr/i2c
parent8f526d154b379761cdd0b2dd6656532e46d89a11 (diff)
downloadtalos-hostboot-84d598c4c7de197f01dcd0adb20eea27b614e9e1.tar.gz
talos-hostboot-84d598c4c7de197f01dcd0adb20eea27b614e9e1.zip
Move pcie power off prior to starting PCIe clocks
This commit moves pcie power off prior to starting PCIe clocks. It also created i2cResetMaster() function to be called before SBE Update in istep 9. Change-Id: I330a5cabf1e778c1354aa3d93d4dedfded7bf013 CQ: SW276751 Backport: release-fips820 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13235 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Dean Sanner <dsanner@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/i2c')
-rwxr-xr-xsrc/usr/i2c/i2c.C245
1 files changed, 207 insertions, 38 deletions
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index b3a723e44..c82ff28a1 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -40,8 +40,9 @@
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
#include <targeting/common/targetservice.H>
-#include <devicefw/driverif.H>
+#include <targeting/common/utilFilter.H>
#include <targeting/common/predicates/predicates.H>
+#include <devicefw/driverif.H>
#include <i2c/i2creasoncodes.H>
#include <i2c/i2cif.H>
@@ -73,6 +74,7 @@ TRAC_INIT( & g_trac_i2cr, "I2CR", KILOBYTE );
#define I2C_RESET_DELAY_NS (5 * NS_PER_MSEC) // Sleep for 5 ms after reset
#define MAX_I2C_ENGINES 3 // Maximum of 3 engines per I2C Master
#define P8_MASTER_ENGINES 2 // Number of Engines used in P8
+#define P8_MASTER_PORTS 2 // Number of Ports used in P8
#define CENTAUR_MASTER_ENGINES 1 // Number of Engines in a Centaur
// ----------------------------------------------
@@ -1349,53 +1351,61 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
do
{
- mode.value = 0x0ull;
+ // Need to send slave stop to all ports on the engine
+ for( uint32_t port = 0; port < P8_MASTER_PORTS; port++ )
+ {
+ // @todo RTC 109926 - only do port 0 for FSI I2C
- mode.bit_rate_div = i_args.bit_rate_divisor;
- mode.port_num = i_args.port;
- mode.enhanced_mode = 1;
+ mode.value = 0x0ull;
- TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
- "mode[0x%lx]: 0x%016llx",
- masterAddrs[i_args.engine].mode, mode.value );
+ mode.port_num = port;
+ mode.enhanced_mode = 1;
+ mode.bit_rate_div = i_args.bit_rate_divisor;
- err = deviceWrite( i_target,
- &mode.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].mode ) );
+ TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
+ "mode[0x%lx]: 0x%016llx",
+ masterAddrs[i_args.engine].mode, mode.value );
- if( err )
- {
- break;
- }
+ err = deviceWrite( i_target,
+ &mode.value,
+ size,
+ DEVICE_SCOM_ADDRESS(
+ masterAddrs[i_args.engine].mode ) );
- cmd.value = 0x0ull;
- cmd.with_stop = 1;
+ if( err )
+ {
+ break;
+ }
- TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
- "cmd[0x%lx]: 0x%016llx",
- masterAddrs[i_args.engine].command, cmd.value );
+ cmd.value = 0x0ull;
+ cmd.with_stop = 1;
- err = deviceWrite( i_target,
- &cmd.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].command ) );
+ TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
+ "cmd[0x%lx]: 0x%016llx",
+ masterAddrs[i_args.engine].command, cmd.value );
- if( err )
- {
- break;
- }
+ err = deviceWrite( i_target,
+ &cmd.value,
+ size,
+ DEVICE_SCOM_ADDRESS(
+ masterAddrs[i_args.engine].command ) );
- // Now wait for cmd Complete
- err = i2cWaitForCmdComp( i_target,
- i_args );
+ if( err )
+ {
+ break;
+ }
+
+ // Now wait for cmd Complete
+ err = i2cWaitForCmdComp( i_target,
+ i_args );
+
+ if( err )
+ {
+ break;
+ }
+
+ } // end of port for-loop
- if( err )
- {
- break;
- }
} while( 0 );
TRACDCOMP( g_trac_i2c,
@@ -1754,5 +1764,164 @@ errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target,
return err;
}
+/**
+ * @brief This function will handle everything required to reset each I2C master
+ * engine based on the input argement
+ * @todo RTC 115832 - additional enums will be added. Currently just
+ * supporting I2C_RESET_PROC_HOST
+ */
+errlHndl_t i2cResetMasters ( i2cResetType i_resetType )
+{
+ errlHndl_t err = NULL;
+ bool error_found = false;
+ bool mutex_needs_unlock = false;
+ mutex_t * engineLock = NULL;
+ misc_args_t io_args;
+
+ TRACFCOMP( g_trac_i2c,
+ ENTER_MRK"i2cResetMasters(): %d",
+ i_resetType );
+
+ // @todo RTC 115834 - Check for and support additional reset types
+
+
+ do
+ {
+ // Get list of Procs
+ TARGETING::TargetHandleList procList;
+
+ TARGETING::getAllChips(procList,
+ TARGETING::TYPE_PROC,
+ true); // true: return functional targets
+
+ if( 0 == procList.size() )
+ {
+ TRACFCOMP(g_trac_i2c,
+ INFO_MRK"i2cResetMasters: No Processor chips found!");
+ }
+
+ TRACUCOMP( g_trac_i2c,
+ INFO_MRK"i2cResetMasters: I2C Master Procs: %d",
+ procList.size() );
+
+ // Do resets to each Processor
+ for( uint32_t proc = 0; proc < procList.size(); proc++ )
+ {
+
+ // @todo RTC 115832 - look at supporting all engines, but for now
+ // just reseting engine 0 since that's what SBE Update uses
+ for( uint32_t engine = 0; engine < 1; engine++ )
+ {
+
+ error_found = false;
+ mutex_needs_unlock = false;
+
+ // Get the mutex for the requested engine
+ switch( engine )
+ {
+ case 0:
+ engineLock = procList[proc]->getHbMutexAttr<TARGETING::ATTR_I2C_ENGINE_MUTEX_0>();
+ break;
+
+ case 1:
+ engineLock = procList[proc]->getHbMutexAttr<TARGETING::ATTR_I2C_ENGINE_MUTEX_1>();
+ break;
+
+ case 2:
+ engineLock = procList[proc]->getHbMutexAttr<TARGETING::ATTR_I2C_ENGINE_MUTEX_2>();
+ break;
+
+ default:
+ TRACFCOMP( g_trac_i2c,
+ ERR_MRK"Invalid engine for getting Mutex! "
+ "engine=%d", engine );
+ // @todo RTC:69113 - Create an error here
+ break;
+ };
+
+ // Lock on this engine
+ TRACUCOMP( g_trac_i2c,
+ INFO_MRK"i2cResetMasters: Obtaining lock for "
+ "engine: %d", engine );
+ (void)mutex_lock( engineLock );
+ mutex_needs_unlock = true;
+ TRACUCOMP( g_trac_i2c,
+ INFO_MRK"i2cResetMasters: Locked on engine: %d",
+ engine );
+
+ TRACUCOMP( g_trac_i2c,
+ INFO_MRK"i2cResetMasters: Reset 0x%X engine = %d",
+ TARGETING::get_huid(procList[proc]), engine );
+
+ io_args.engine = engine;
+ io_args.port = 0; // default to port 0
+
+ // Hardcode to 400KHz - should be a safe speed
+ err = i2cSetBusVariables ( procList[proc],
+ SET_I2C_BUS_400KHZ,
+ io_args );
+
+ if( err )
+ {
+ error_found = true;
+
+ TRACFCOMP( g_trac_i2c,
+ ERR_MRK"i2cResetMasters: Error Setting Bus "
+ "Variables: tgt=0x%X engine=%d",
+ TARGETING::get_huid(procList[proc]), engine );
+
+ // If we get error skip resetting this target, but still
+ // need to reset other I2C engines
+ errlCommit( err,
+ I2C_COMP_ID );
+
+ // Don't continue or break - need mutex unlock
+ }
+
+
+ // Now reset the engine/bus
+ if ( error_found == false )
+ {
+ err = i2cReset ( procList[proc],
+ io_args);
+
+ if( err )
+ {
+ TRACFCOMP( g_trac_i2c,
+ ERR_MRK"i2cResetMasters: Error reseting "
+ "tgt=0x%X, engine=%d",
+ TARGETING::get_huid(procList[proc]), engine);
+
+ // If we get errors on the reset, we still need to
+ // to reset the other I2C engines
+ errlCommit( err,
+ I2C_COMP_ID );
+
+ // Don't continue or break - need mutex unlock
+ }
+ }
+
+ // Check if we need to unlock the mutex
+ if ( mutex_needs_unlock == true )
+ {
+ // Unlock
+ (void) mutex_unlock( engineLock );
+ TRACUCOMP( g_trac_i2c,
+ INFO_MRK"i2cResetMasters: Unlocked engine: %d",
+ engine );
+ }
+
+ } // end for-loop engine
+
+ } // end for-loop processor
+
+ } while( 0 );
+
+ TRACFCOMP( g_trac_i2c,
+ EXIT_MRK"i2cResetMasters(): err rc=0x%X, plid=0x%X",
+ ERRL_GETRC_SAFE(err), ERRL_GETPLID_SAFE(err));
+
+ return err;
+}
} // end namespace I2C
OpenPOWER on IntegriCloud