summaryrefslogtreecommitdiffstats
path: root/src/usr/i2c/i2c.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/i2c/i2c.C')
-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