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.C163
1 files changed, 120 insertions, 43 deletions
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index 23398fbc3..0a32c1ca8 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -56,6 +56,7 @@ TRAC_INIT( & g_trac_i2c, "I2C", KILOBYTE );
trace_desc_t* g_trac_i2cr = NULL;
TRAC_INIT( & g_trac_i2cr, "I2CR", KILOBYTE );
+
// Easy macro replace for unit testing
//#define TRACUCOMP(args...) TRACFCOMP(args)
#define TRACUCOMP(args...)
@@ -105,7 +106,15 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
args.devAddr = va_arg( i_args, uint64_t );
TRACDCOMP( g_trac_i2c,
- ENTER_MRK"i2cPerformOp()" );
+ ENTER_MRK"i2cPerformOp(): i_opType=%d, "
+ "p=%d, engine=%d, devAddr=0x%lx",
+ (uint64_t) i_opType, args.port, args.engine, args.devAddr );
+
+ TRACUCOMP( g_trac_i2c,
+ ENTER_MRK"i2cPerformOp(): i_opType=%d, p/e/devAddr= "
+ "%d/%d/0x%x, len=%d",
+ (uint64_t) i_opType, args.port, args.engine, args.devAddr,
+ io_buflen);
do
{
@@ -135,6 +144,8 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
break;
}
+ // @todo RTC:72715 - Check that target is an I2C master
+
// Get the mutex for the requested engine
mutex_t * engineLock = NULL;
switch( args.engine )
@@ -153,8 +164,9 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
default:
TRACFCOMP( g_trac_i2c,
- ERR_MRK"Invalid engine for getting Mutex!" );
- // TODO - Create an error here
+ ERR_MRK"Invalid engine for getting Mutex! "
+ "args.engine=%d", args.engine );
+ // @todo RTC:69113 - Create an error here
break;
};
@@ -278,7 +290,7 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
uint64_t devAddr = i_args.devAddr;
uint64_t port = i_args.port;
- // TODO - hardcoded to 400KHz for now
+ // @todo RTC:72715 - Add multiple bus speed support (set to 400KHz for now)
uint64_t interval = I2C_TIMEOUT_INTERVAL( I2C_CLOCK_DIVISOR_400KHZ );
uint64_t timeoutCount = I2C_TIMEOUT_COUNT( interval );
@@ -298,8 +310,8 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
// Do Command/Mode reg setups.
err = i2cSetup( i_target,
i_buflen,
- true,
- true,
+ true, // i_readNotWrite
+ true, // i_withStop
i_args );
if( err )
@@ -324,7 +336,11 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
break;
}
- while( 0 == status.fifo_entry_count )
+ // Wait for 1 of 2 indictators to read from FIFO:
+ // 1) fifo_entry_count !=0
+ // 2) Data Request bit is on
+ while( (0 == status.fifo_entry_count) &&
+ (0 == status.data_request) )
{
nanosleep( 0, (interval * 1000) );
@@ -338,6 +354,12 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
break;
}
+
+ TRACUCOMP( g_trac_i2c, "i2cRead() Wait Loop: status=0x%016llx "
+ ".fifo_entry_count=%d, .data_request=%d",
+ status.value, status.fifo_entry_count, status.data_request);
+
+
if( 0 == timeoutCount-- )
{
TRACFCOMP( g_trac_i2c,
@@ -381,6 +403,10 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
size,
DEVICE_SCOM_ADDRESS( masterAddrs[engine].fifo ) );
+ TRACUCOMP( g_trac_i2c,
+ INFO_MRK"i2cRead() - FIFO[0x%lx] = 0x%016llx",
+ masterAddrs[engine].fifo, fifo.value);
+
if( err )
{
break;
@@ -388,9 +414,11 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
*((uint8_t*)o_buffer + bytesRead) = fifo.byte_0;
- TRACSCOMP( g_trac_i2cr,
- "I2C READ DATA : engine %.2X : devAddr %.2X : byte %d : %.2X",
- engine, devAddr, bytesRead, fifo.byte_0 );
+ TRACUCOMP( g_trac_i2cr,
+ "I2C READ DATA : engine %.2X : port %.2x : "
+ "devAddr %.2X : byte %d : %.2X (0x%lx)",
+ engine, port, devAddr, bytesRead,
+ fifo.byte_0, fifo.value );
}
if( err )
@@ -449,8 +477,8 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target,
// Do Command/Mode reg setups
err = i2cSetup( i_target,
io_buflen,
- false,
- true,
+ false, // i_readNotWrite
+ true, // i_withStop
i_args );
if( err )
@@ -483,9 +511,11 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target,
break;
}
- TRACSCOMP( g_trac_i2cr,
- "I2C WRITE DATA : engine %.2X : devAddr %.2X : byte %d : %.2X",
- engine, devAddr, bytesWritten, fifo.byte_0 );
+ TRACUCOMP( g_trac_i2cr,
+ "I2C WRITE DATA : engine %.2X : port %.2X : "
+ "devAddr %.2X : byte %d : %.2X (0x%lx)",
+ engine, port, devAddr, bytesWritten,
+ fifo.byte_0, fifo.value );
}
if( err )
@@ -533,7 +563,8 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target,
uint64_t devAddr = i_args.devAddr;
TRACDCOMP( g_trac_i2c,
- ENTER_MRK"i2cSetup()" );
+ ENTER_MRK"i2cSetup(): buf_len=%d, r_nw=%d, w_stop=%d",
+ i_buflen, i_readNotWrite, i_withStop );
// Define the registers that we'll use
modereg mode;
@@ -541,8 +572,6 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target,
do
{
- // TODO - Validate some of the arg values passed in
-
// Wait for Command complete before we start
err = i2cWaitForCmdComp( i_target,
i_args );
@@ -557,16 +586,22 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target,
// - port number
mode.value = 0x0ull;
- // TODO - Hard code to 400KHz until we get attributes in place to get this from
- // the target.
+
+
+ // @todo RTC:72715 - Add multiple bus speed support
+ // Hard code to 400KHz until we get attributes in place to get
+ // this from the target.
mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ;
mode.port_num = port;
+ TRACUCOMP( g_trac_i2c,"i2cSetup(): set mode = 0x%lx", mode.value);
+
err = deviceWrite( i_target,
&mode.value,
size,
DEVICE_SCOM_ADDRESS( masterAddrs[engine].mode ) );
+
if( err )
{
break;
@@ -581,10 +616,19 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target,
cmd.with_start = 1;
cmd.with_stop = (i_withStop ? 1 : 0);
cmd.with_addr = 1;
- cmd.device_addr = devAddr;
+
+ // cmd.device_addr is 7 bits
+ // devAddr though is a uint64_t
+ // -- value stored in LSB byte of uint64_t
+ // -- LS-bit is unused, creating the 7 bit cmd.device_addr
+ // So will be masking for LSB, and then shifting to push off LS-bit
+ cmd.device_addr = (0x000000FF & devAddr) >> 1;
+
cmd.read_not_write = (i_readNotWrite ? 1 : 0);
cmd.length_b = i_buflen;
+ TRACUCOMP( g_trac_i2c,"i2cSetup(): set cmd = 0x%lx", cmd.value);
+
err = deviceWrite( i_target,
&cmd.value,
size,
@@ -617,10 +661,13 @@ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target,
// Define the registers that we'll use
statusreg status;
- // TODO - hardcoded to 400KHz for now.
+ // @todo RTC:72715 - Add multiple bus speed support (set to 400KHz for now)
uint64_t interval = I2C_TIMEOUT_INTERVAL( I2C_CLOCK_DIVISOR_400KHZ );
uint64_t timeoutCount = I2C_TIMEOUT_COUNT( interval );
+ TRACUCOMP(g_trac_i2c, "i2cWaitForCmdComp(): timeoutCount=%d, interval=%d",
+ timeoutCount, interval);
+
do
{
// Check the Command Complete bit
@@ -700,6 +747,11 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target,
break;
}
+ TRACUCOMP(g_trac_i2c,"i2cReadStatusReg(): "
+ INFO_MRK"status[0x%lx]: 0x%016llx",
+ masterAddrs[engine].status, o_statusReg.value );
+
+
// Check for Errors
// Per the specification it is a requirement to check for errors each time
// that the status register is read.
@@ -783,13 +835,6 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target,
i_statusVal.value );
}
- if( 1 == i_statusVal.data_request )
- {
- errorFound = true;
- TRACFCOMP( g_trac_i2c,
- ERR_MRK"I2C Data Request Error! - status reg: %016llx",
- i_statusVal.value );
- }
if( 1 == i_statusVal.stop_error )
{
@@ -807,6 +852,8 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target,
i_statusVal.value );
// Get the Interrupt Register value to add to the log
+ // - i2cGetInterrupts() adds intRegVal to trace, so it ill be added
+ // to error log below
err = i2cGetInterrupts( i_target,
i_args,
intRegVal );
@@ -815,6 +862,7 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target,
{
break;
}
+
}
if( errorFound )
@@ -838,10 +886,7 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target,
i_statusVal.value,
intRegVal );
- // TODO - RTC entry to be created to allow for adding a target to an errorlog.
- // Once that is implemented, the target will be used here to add to the log.
-
- // TODO - Add I2C traces to this log.
+ // @todo RTC:69113 - Add target and I2C traces to the errorlog.
break;
}
@@ -862,7 +907,7 @@ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target,
{
errlHndl_t err = NULL;
- // TODO - hardcoded to 400KHz for now
+ // @todo RTC:72715 - support multiple bus speeds (set to 400KHz for now)
uint64_t interval = I2C_TIMEOUT_INTERVAL( I2C_CLOCK_DIVISOR_400KHZ );
uint64_t timeoutCount = I2C_TIMEOUT_COUNT( interval );
@@ -885,7 +930,17 @@ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target,
break;
}
- while( I2C_MAX_FIFO_CAPACITY <= status.fifo_entry_count )
+ TRACUCOMP( g_trac_i2c, "i2cWaitForFifoSpace(): status=0x%016llx "
+ "I2C_MAX_FIFO_CAPACITY=%d, status.fifo_entry_count=%d",
+ status.value, I2C_MAX_FIFO_CAPACITY,
+ status.fifo_entry_count);
+
+
+ // 2 Conditions to wait on:
+ // 1) FIFO is full
+ // 2) Data Request bit is not set
+ while( (I2C_MAX_FIFO_CAPACITY <= status.fifo_entry_count) &&
+ (0 == status.data_request) )
{
// FIFO is full, wait before writing any data
nanosleep( 0, (interval * 1000) );
@@ -958,6 +1013,11 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target,
do
{
reset.value = 0x0;
+
+ TRACUCOMP(g_trac_i2c,"i2cReset() "
+ "reset[0x%lx]: 0x%016llx",
+ masterAddrs[engine].reset, reset.value );
+
err = deviceWrite( i_target,
&reset.value,
size,
@@ -1009,12 +1069,18 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
do
{
mode.value = 0x0ull;
- // TODO - Hard code to 400KHz until we get attributes in place to get this from
- // the target.
+
+ // @todo RTC:72715 - support multiple bus speeds
+ // Hard code to 400KHz until we get attributes in place to get
+ // this from the target.
mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ;
mode.port_num = port;
mode.enhanced_mode = 1;
+ TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
+ "mode[0x%lx]: 0x%016llx",
+ masterAddrs[engine].mode, mode.value );
+
err = deviceWrite( i_target,
&mode.value,
size,
@@ -1028,6 +1094,10 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
cmd.value = 0x0ull;
cmd.with_stop = 1;
+ TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
+ "cmd[0x%lx]: 0x%016llx",
+ masterAddrs[engine].command, cmd.value );
+
err = deviceWrite( i_target,
&cmd.value,
size,
@@ -1085,6 +1155,10 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target,
break;
}
+ TRACUCOMP(g_trac_i2c,"i2cGetInterrupts(): "
+ "interrupt[0x%lx]: 0x%016llx",
+ masterAddrs[engine].interrupt, intreg.value );
+
// Return the data read
o_intRegValue = intreg.value;
} while( 0 );
@@ -1107,7 +1181,7 @@ errlHndl_t i2cSetupMasters ( void )
modereg mode;
size_t size = sizeof(uint64_t);
- TRACFCOMP( g_trac_i2c,
+ TRACDCOMP( g_trac_i2c,
ENTER_MRK"i2cSetupMasters()" );
do
@@ -1151,7 +1225,7 @@ errlHndl_t i2cSetupMasters ( void )
break;
}
- TRACDCOMP( g_trac_i2c,
+ TRACUCOMP( g_trac_i2c,
INFO_MRK"I2C Master Centaurs: %d",
centList.size() );
@@ -1172,7 +1246,8 @@ errlHndl_t i2cSetupMasters ( void )
// Write Mode Register:
mode.value = 0x0ull;
- // TODO - Hard code to 400KHz until we get attributes in place
+ // @todo RTC:72715 - support multiple bus speeds
+ // Hard code to 400KHz until we get attributes in place
// to get this from the target.
mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ;
err = deviceWrite( centList[centaur],
@@ -1238,7 +1313,7 @@ errlHndl_t i2cSetupMasters ( void )
break;
}
- TRACDCOMP( g_trac_i2c,
+ TRACUCOMP( g_trac_i2c,
INFO_MRK"I2C Master Procs: %d",
procList.size() );
@@ -1259,7 +1334,8 @@ errlHndl_t i2cSetupMasters ( void )
// Write Mode Register:
mode.value = 0x0ull;
- // TODO - Hard code to 400KHz until we get attributes in place
+ // @todo RTC:72715 - support multiple bus speeds
+ // Hard code to 400KHz until we get attributes in place
// to get this from the target.
mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ;
err = deviceWrite( procList[proc],
@@ -1293,10 +1369,11 @@ errlHndl_t i2cSetupMasters ( void )
}
} while( 0 );
- TRACFCOMP( g_trac_i2c,
+ TRACDCOMP( g_trac_i2c,
EXIT_MRK"i2cSetupMasters()" );
return err;
}
+
} // end namespace I2C
OpenPOWER on IntegriCloud