summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/errl/errludlogregister.C9
-rw-r--r--src/usr/errl/test/errluserdetailtest.H2
-rw-r--r--src/usr/fsi/fsidd.C92
-rw-r--r--src/usr/fsi/fsidd.H28
-rw-r--r--src/usr/hwas/hwasPlat.C3
-rwxr-xr-xsrc/usr/i2c/eepromdd.C129
-rwxr-xr-xsrc/usr/i2c/i2c.C767
-rwxr-xr-xsrc/usr/i2c/i2c.H242
-rwxr-xr-xsrc/usr/i2c/test/i2ctest.H9
9 files changed, 860 insertions, 421 deletions
diff --git a/src/usr/errl/errludlogregister.C b/src/usr/errl/errludlogregister.C
index 81f537aa4..77e385dbb 100644
--- a/src/usr/errl/errludlogregister.C
+++ b/src/usr/errl/errludlogregister.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -170,6 +172,11 @@ void ErrlUserDetailsLogRegister::readRegister(
uint64_t reg_data = 0;
size_t reg_size = sizeof(reg_data);
+ if ( i_accessType == DeviceFW::FSI)
+ {
+ reg_size = sizeof(uint32_t);
+ }
+
TRACDCOMP(g_trac_errl, "LogRegister: deviceOpValist()");
errlHndl_t errl;
errl = DeviceFW::deviceOpValist(DeviceFW::READ,
diff --git a/src/usr/errl/test/errluserdetailtest.H b/src/usr/errl/test/errluserdetailtest.H
index 17b9e454e..9cc82869b 100644
--- a/src/usr/errl/test/errluserdetailtest.H
+++ b/src/usr/errl/test/errluserdetailtest.H
@@ -405,7 +405,7 @@ public:
ErrlUserDetailsLogRegister(c_target, &reg2_data, reg2_size,
DEVICE_MVPD_ADDRESS(3,0)).addToLog(errl);
- uint64_t reg3_data = 0;
+ uint32_t reg3_data = 0;
size_t reg3_size = sizeof(reg3_data);
errl_deviceRead = DeviceFW::deviceRead(c_target,
&reg3_data, reg3_size,
diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C
index 865e27f89..6fd24209e 100644
--- a/src/usr/fsi/fsidd.C
+++ b/src/usr/fsi/fsidd.C
@@ -106,7 +106,10 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
mutex_lock(&g_fsiOpMux);
do{
- if (unlikely(io_buflen < sizeof(uint32_t)))
+
+ if (unlikely( ( io_buflen != 4 ) &&
+ ( io_buflen != 2 ) &&
+ ( io_buflen != 1 ) ) )
{
TRACFCOMP( g_trac_fsi, ERR_MRK "FSI::ddOp> Invalid data length : io_buflen=%d", io_buflen );
/*@
@@ -115,9 +118,9 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
* @reasoncode FSI::RC_INVALID_LENGTH
* @userdata1 FSI Address
* @userdata2 Data Length
- * @devdesc FsiDD::ddOp> Invalid data length (!= 4 bytes)
- * @custdesc A problem occurred during the
- * IPL of the system.
+ * @devdesc FsiDD::ddOp> Invalid data length (!= 4,2,1 bytes)
+ * @custdesc An internal function called the FSI device driver
+ * with an improper data length.
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
FSI::MOD_FSIDD_DDOP,
@@ -125,13 +128,11 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
i_addr,
TO_UINT64(io_buflen),
true /*SW error*/);
+
l_err->collectTrace(FSI_COMP_NAME);
break;
}
- // default to the fail path
- io_buflen = 0;
-
// look for NULL
if( NULL == i_target )
{
@@ -184,24 +185,24 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
{
l_err = Singleton<FsiDD>::instance().read(i_target,
i_addr,
- static_cast<uint32_t*>(io_buffer));
+ static_cast<uint32_t*>(io_buffer),
+ io_buflen);
if(l_err)
{
break;
}
- io_buflen = sizeof(uint32_t);
}
// do the write
else if( DeviceFW::WRITE == i_opType )
{
l_err = Singleton<FsiDD>::instance().write(i_target,
i_addr,
- static_cast<uint32_t*>(io_buffer));
+ static_cast<uint32_t*>(io_buffer),
+ io_buflen);
if(l_err)
{
break;
}
- io_buflen = sizeof(uint32_t);
}
else
{
@@ -228,6 +229,12 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
}while(0);
+ if ( l_err )
+ {
+ // On fail, assume no data was read or written
+ io_buflen = 0;
+ }
+
mutex_unlock(&g_fsiOpMux);//@fixme - RTC:98898
return l_err;
@@ -368,7 +375,8 @@ void getFsiLinkInfo( TARGETING::Target* i_slave,
*/
errlHndl_t FsiDD::read(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen)
{
TRACDCOMP(g_trac_fsi, "FsiDD::read(i_target=%.8X,i_address=0x%llX)> ", TARGETING::get_huid(i_target), i_address);
errlHndl_t l_err = NULL;
@@ -393,7 +401,8 @@ errlHndl_t FsiDD::read(TARGETING::Target* i_target,
}
// perform the read operation
- l_err = read( addr_info, o_buffer );
+ l_err = read( addr_info, o_buffer, i_buflen );
+
if(l_err)
{
break;
@@ -408,7 +417,8 @@ errlHndl_t FsiDD::read(TARGETING::Target* i_target,
*/
errlHndl_t FsiDD::write(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::write(i_target=%.8X,i_address=0x%llX)> ", TARGETING::get_huid(i_target), i_address);
errlHndl_t l_err = NULL;
@@ -433,7 +443,7 @@ errlHndl_t FsiDD::write(TARGETING::Target* i_target,
}
// perform the write operation
- l_err = write( addr_info, o_buffer );
+ l_err = write( addr_info, o_buffer, i_buflen );
if(l_err)
{
break;
@@ -1052,7 +1062,8 @@ FsiDD::~FsiDD()
* using the master processor chip to drive it
*/
errlHndl_t FsiDD::read(uint64_t i_address,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::read(i_address=0x%llx)> ", i_address);
@@ -1063,7 +1074,7 @@ errlHndl_t FsiDD::read(uint64_t i_address,
addr_info.absAddr = i_address;
// call to low-level read function
- errlHndl_t l_err = read( addr_info, o_buffer );
+ errlHndl_t l_err = read( addr_info, o_buffer, i_buflen );
return l_err;
}
@@ -1074,7 +1085,8 @@ errlHndl_t FsiDD::read(uint64_t i_address,
* using the master processor chip to drive it
*/
errlHndl_t FsiDD::write(uint64_t i_address,
- uint32_t* i_buffer)
+ uint32_t* i_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::write(i_address=0x%llx)> ", i_address);
@@ -1085,7 +1097,7 @@ errlHndl_t FsiDD::write(uint64_t i_address,
addr_info.absAddr = i_address;
// call to low-level write function
- errlHndl_t l_err = write( addr_info, i_buffer );
+ errlHndl_t l_err = write( addr_info, i_buffer, i_buflen );
return l_err;
}
@@ -1095,7 +1107,8 @@ errlHndl_t FsiDD::write(uint64_t i_address,
* @brief Performs an FSI Read Operation
*/
errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::read(relAddr=0x%.8X,absAddr=0x%.8X)> ", i_addrInfo.relAddr, i_addrInfo.absAddr );
errlHndl_t l_err = NULL;
@@ -1105,7 +1118,22 @@ errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
do {
// setup the OPB command register
- uint64_t fsicmd = i_addrInfo.absAddr | 0x60000000; // 011=Read Full Word
+
+ uint64_t fsicmd = 0;
+
+ if ( i_buflen == 4 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0x60000000; // 011=Read Full Word
+ }
+ else if ( i_buflen == 1 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0x00000000; // 000=Read 1 Byte
+ }
+ else
+ {
+ fsicmd = i_addrInfo.absAddr | 0x20000000; // 001=Read 2 Bytes
+ }
+
fsicmd <<= 32; // Command is in the upper word
// generate the proper OPB SCOM address
@@ -1181,7 +1209,8 @@ errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
* @brief Write FSI Register
*/
errlHndl_t FsiDD::write(FsiAddrInfo_t& i_addrInfo,
- uint32_t* i_buffer)
+ uint32_t* i_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::write(relAddr=0x%.8X,absAddr=0x%.8X)> ", i_addrInfo.relAddr, i_addrInfo.absAddr );
errlHndl_t l_err = NULL;
@@ -1195,7 +1224,22 @@ errlHndl_t FsiDD::write(FsiAddrInfo_t& i_addrInfo,
uint32_t fsidata = *i_buffer;
// setup the OPB command register
- uint64_t fsicmd = i_addrInfo.absAddr | 0xE0000000; // 111=Write Full Word
+
+ uint64_t fsicmd = 0;
+
+ if ( i_buflen == 4 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0xE0000000; // 111=Write Full Word
+ }
+ else if ( i_buflen == 1 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0x80000000; // 100=Write 1 Byte
+ }
+ else
+ {
+ fsicmd = i_addrInfo.absAddr | 0xA0000000; // 101=Write 2 Bytes
+ }
+
fsicmd <<= 32; // Command is in the upper 32-bits
fsicmd |= fsidata; // Data is in the bottom 32-bits
size_t scom_size = sizeof(uint64_t);
@@ -2733,7 +2777,7 @@ errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo,
r++ )
{
l_err = read( i_addrInfo.accessInfo.master,
- MFSI_CONTROL_REG|FSI_MSIEP0_030, &data );
+ MFSI_CONTROL_REG|FSI_MSIEP0_030, &data );
if(l_err) break;
TRACFCOMP( g_trac_fsi, "errorCleanup> %.8X->%.6X = %.8X", TARGETING::get_huid(i_addrInfo.accessInfo.master), grabregs[r], data );
}
diff --git a/src/usr/fsi/fsidd.H b/src/usr/fsi/fsidd.H
index 06c030b57..999b38d02 100644
--- a/src/usr/fsi/fsidd.H
+++ b/src/usr/fsi/fsidd.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2014 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -60,12 +62,14 @@ class FsiDD
* @param[in] i_target Chip target of FSI operation
* @param[in] i_address Address to read (relative to target)
* @param[out] o_buffer Destination buffer for data
+ * @parm[in] i_buflen Length of data to read in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t read(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* o_buffer);
+ uint32_t* o_buffer,
+ size_t i_buflen = 4);
/**
* @brief Performs an FSI Write Operation
@@ -73,12 +77,14 @@ class FsiDD
* @param[in] i_target Chip target of FSI operation
* @param[in] i_address Address to write (relative to target)
* @param[out] i_buffer Source buffer for data
+ * @parm[in] i_buflen Length of data to write in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t write(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* i_buffer);
+ uint32_t* i_buffer,
+ size_t i_buflen = 4);
/**
@@ -160,11 +166,13 @@ class FsiDD
* @param[in] i_address Absolute FSI address to read relative to
* the OPB master processor chip
* @param[out] o_buffer Destination buffer for data
+ * @parm[in] i_buflen Length of data to read in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t read(uint64_t i_address,
- uint32_t* o_buffer);
+ uint32_t* o_buffer,
+ size_t i_buflen = 4);
/**
* @brief Performs an FSI Write Operation to an absolute address
@@ -173,11 +181,13 @@ class FsiDD
* @param[in] i_address Absolute FSI address to write relative to
* the OPB master processor chip
* @param[out] i_buffer Source buffer for data
+ * @parm[in] i_buflen Length of data to write in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t write(uint64_t i_address,
- uint32_t* i_buffer);
+ uint32_t* i_buffer,
+ size_t i_buflen = 4);
/**
* Common id to identify a FSI position to use in error logs and traces
@@ -248,22 +258,26 @@ class FsiDD
*
* @param[in] i_addrInfo Addressing information
* @param[out] o_buffer Destination buffer for data
+ * @parm[in] i_buflen Length of data to read in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t read(FsiAddrInfo_t& i_addrInfo,
- uint32_t* o_buffer);
+ uint32_t* o_buffer,
+ size_t i_buflen = 4);
/**
* @brief Performs an FSI Write Operation to an absolute address
*
* @param[in] i_addrInfo Addressing information
* @param[out] i_buffer Source buffer for data
+ * @parm[in] i_buflen Length of data to write in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t write(FsiAddrInfo_t& i_addrInfo,
- uint32_t* i_buffer);
+ uint32_t* i_buffer,
+ size_t i_buflen = 4);
/**
* @brief Initializes the FSI master control registers
diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C
index 689ba54f0..8523d63a3 100644
--- a/src/usr/hwas/hwasPlat.C
+++ b/src/usr/hwas/hwasPlat.C
@@ -97,6 +97,9 @@ errlHndl_t platReadIDEC(const TargetHandle_t &i_target)
}
else
{
+ // FSI only reads 4 bytes for id_ec
+ op_size = sizeof(uint32_t);
+
errl = DeviceFW::deviceRead(i_target, &id_ec, op_size,
DEVICE_FSI_ADDRESS(0x01028));
}
diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C
index b913665e9..41297cfaf 100755
--- a/src/usr/i2c/eepromdd.C
+++ b/src/usr/i2c/eepromdd.C
@@ -379,7 +379,7 @@ errlHndl_t eepromRead ( TARGETING::Target * i_target,
err_NACK = err;
TRACFCOMP( g_trac_eeprom, ERR_MRK"eepromRead(): "
- "NACK Error rc=0x%X, eid=%d, tgt=0x%X, "
+ "NACK Error rc=0x%X, eid=0x%X, tgt=0x%X, "
"retry/MAX=%d/%d. Save error and retry",
err_NACK->reasonCode(),
err_NACK->eid(),
@@ -1046,8 +1046,9 @@ errlHndl_t eepromReadAttributes ( TARGETING::Target * i_target,
} while( 0 );
- TRACUCOMP(g_trac_eeprom,"eepromReadAttributes() %d/%d/0x%X "
+ TRACUCOMP(g_trac_eeprom,"eepromReadAttributes() tgt=0x%X, %d/%d/0x%X "
"wpw=0x%X, dsKb=0x%X, aS=%d (%d), wct=%d",
+ TARGETING::get_huid(i_target),
o_i2cInfo.port, o_i2cInfo.engine, o_i2cInfo.devAddr,
o_i2cInfo.writePageSize, o_i2cInfo.devSize_KB,
o_i2cInfo.addrSize, eepromData.byteAddrOffset,
@@ -1076,85 +1077,75 @@ errlHndl_t eepromGetI2CMasterTarget ( TARGETING::Target * i_target,
do
{
- if( TARGETING::TYPE_DIMM == i_target->getAttr<TARGETING::ATTR_TYPE>() )
- {
- TARGETING::TargetService& tS = TARGETING::targetService();
-
- // For DIMMs we need to get the parent that contains the
- // I2C Master that talks to the DIMM EEPROM
+ TARGETING::TargetService& tS = TARGETING::targetService();
- // The path was read from the attribute via eepromReadAttributes()
- // and passed to this function in i_i2cInfo
+ // The path from i_target to its I2C Master was read from the
+ // attribute via eepromReadAttributes() and passed to this function
+ // in i_i2cInfo.i2cMasterPath
+ // check that the path exists
+ bool exists = false;
+ tS.exists( i_i2cInfo.i2cMasterPath,
+ exists );
- // check that the path exists
- bool exists = false;
- tS.exists( i_i2cInfo.i2cMasterPath,
- exists );
-
- if( !exists )
- {
- TRACFCOMP( g_trac_eeprom,
- ERR_MRK"eepromGetI2CMasterTarget() - i2cMasterPath attribute path "
- "doesn't exist!" );
+ if( !exists )
+ {
+ TRACFCOMP( g_trac_eeprom,
+ ERR_MRK"eepromGetI2CMasterTarget() - "
+ "i2cMasterPath attribute path doesn't exist!" );
- /*@
- * @errortype
- * @reasoncode EEPROM_DIMM_I2C_MASTER_PATH_ERROR
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid EEPROM_GETI2CMASTERTARGET
- * @userdata1 Attribute Chip Type Enum
- * @userdata2 HUID of target
- * @devdesc DIMM I2C master entity path doesn't exist.
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_GETI2CMASTERTARGET,
- EEPROM_DIMM_I2C_MASTER_PATH_ERROR,
- i_i2cInfo.chip,
- TARGETING::get_huid(i_target),
- true /*Add HB SW Callout*/ );
+ /*@
+ * @errortype
+ * @reasoncode EEPROM_DIMM_I2C_MASTER_PATH_ERROR
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid EEPROM_GETI2CMASTERTARGET
+ * @userdata1 Attribute Chip Type Enum
+ * @userdata2 HUID of target
+ * @devdesc DIMM I2C master entity path doesn't exist.
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_GETI2CMASTERTARGET,
+ EEPROM_DIMM_I2C_MASTER_PATH_ERROR,
+ i_i2cInfo.chip,
+ TARGETING::get_huid(i_target),
+ true /*Add HB SW Callout*/ );
- err->collectTrace( EEPROM_COMP_NAME );
+ err->collectTrace( EEPROM_COMP_NAME );
- break;
- }
+ break;
+ }
- // Since it exists, convert to a target
- o_target = tS.toTarget( i_i2cInfo.i2cMasterPath );
+ // Since it exists, convert to a target
+ o_target = tS.toTarget( i_i2cInfo.i2cMasterPath );
- if( NULL == o_target )
- {
- TRACFCOMP( g_trac_eeprom,
- ERR_MRK"eepromGetI2CMasterTarget() - I2C Master "
- "Path target was NULL!" );
+ if( NULL == o_target )
+ {
+ TRACFCOMP( g_trac_eeprom,
+ ERR_MRK"eepromGetI2CMasterTarget() - I2C Master "
+ "Path target was NULL!" );
- /*@
- * @errortype
- * @reasoncode EEPROM_TARGET_NULL
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid EEPROM_GETI2CMASTERTARGET
- * @userdata1 Attribute Chip Type Enum
- * @userdata2 HUID of target
- * @devdesc I2C master path target is null.
- */
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_GETI2CMASTERTARGET,
- EEPROM_TARGET_NULL,
- i_i2cInfo.chip,
- TARGETING::get_huid(i_target),
- true /*Add HB SW Callout*/ );
+ /*@
+ * @errortype
+ * @reasoncode EEPROM_TARGET_NULL
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid EEPROM_GETI2CMASTERTARGET
+ * @userdata1 Attribute Chip Type Enum
+ * @userdata2 HUID of target
+ * @devdesc I2C master path target is null.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_GETI2CMASTERTARGET,
+ EEPROM_TARGET_NULL,
+ i_i2cInfo.chip,
+ TARGETING::get_huid(i_target),
+ true /*Add HB SW Callout*/ );
- err->collectTrace( EEPROM_COMP_NAME );
+ err->collectTrace( EEPROM_COMP_NAME );
- break;
- }
- }
- else
- {
- // Since current target is not a DIMM, use the target we have
- o_target = i_target;
+ break;
}
+
} while( 0 );
TRACDCOMP( g_trac_eeprom,
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index 4cd4aae7f..5fe216c33 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -81,59 +81,13 @@ TRAC_INIT( & g_trac_i2cr, "I2CR", KILOBYTE );
namespace I2C
{
-/**
- * @brief Addresses for each of the registers in each engine.
- */
-static i2c_addrs_t masterAddrs[] =
-{
- { /* Master 0 */
- I2C_MASTER0_ADDR | 0x4, // FIFO
- I2C_MASTER0_ADDR | 0x5, // Command Register
- I2C_MASTER0_ADDR | 0x6, // Mode Register
- I2C_MASTER0_ADDR | 0x8, // Interrupt Mask Register
- I2C_MASTER0_ADDR | 0xA, // Interrupt Register
- I2C_MASTER0_ADDR | 0xB, // Status Register (Read)
- I2C_MASTER0_ADDR | 0xB, // Reset (Write)
- I2C_MASTER0_ADDR | 0xD, // Set SCL Register (write)
- I2C_MASTER0_ADDR | 0xF, // Reset SCL Register (write)
- I2C_MASTER0_ADDR | 0x10, // Set SDA Register (write)
- I2C_MASTER0_ADDR | 0x11, // Reset SDA Register (write)
- },
- { /* Master 1 */
- I2C_MASTER1_ADDR | 0x4, // FIFO
- I2C_MASTER1_ADDR | 0x5, // Command Register
- I2C_MASTER1_ADDR | 0x6, // Mode Register
- I2C_MASTER1_ADDR | 0x8, // Interrupt Mask Register
- I2C_MASTER1_ADDR | 0xA, // Interrupt Register
- I2C_MASTER1_ADDR | 0xB, // Status Register (Read)
- I2C_MASTER1_ADDR | 0xB, // Reset (Write)
- I2C_MASTER1_ADDR | 0xD, // Set SCL Register (write)
- I2C_MASTER1_ADDR | 0xF, // Reset SCL Register (write)
- I2C_MASTER1_ADDR | 0x10, // Set SDA Register (write)
- I2C_MASTER1_ADDR | 0x11, // Reset SDA Register (write)
- },
- { /* Master 2 */
- I2C_MASTER2_ADDR | 0x4, // FIFO
- I2C_MASTER2_ADDR | 0x5, // Command Register
- I2C_MASTER2_ADDR | 0x6, // Mode Register
- I2C_MASTER2_ADDR | 0x8, // Interrupt Mask Register
- I2C_MASTER2_ADDR | 0xA, // Interrupt Register
- I2C_MASTER2_ADDR | 0xB, // Status Register (Read)
- I2C_MASTER2_ADDR | 0xB, // Reset (Write)
- I2C_MASTER2_ADDR | 0xD, // Set SCL Register (write)
- I2C_MASTER2_ADDR | 0xF, // Reset SCL Register (write)
- I2C_MASTER2_ADDR | 0x10, // Set SDA Register (write)
- I2C_MASTER2_ADDR | 0x11, // Reset SDA Register (write)
- }
-};
-
-// Register the perform Op with the routing code for Procs.
+// Register the generic I2C perform Op with the routing code for Procs.
DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
DeviceFW::I2C,
TARGETING::TYPE_PROC,
i2cPerformOp );
-// Register the perform Op with the routing code for Memory Buffers.
+// Register the generic I2C perform Op with the routing code for Memory Buffers.
DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
DeviceFW::I2C,
TARGETING::TYPE_MEMBUF,
@@ -150,10 +104,72 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
va_list i_args )
{
errlHndl_t err = NULL;
- errlHndl_t err_reset = NULL;
- mutex_t * engineLock = NULL;
- bool mutex_needs_unlock = false;
+ // Get the input args our of the va_list
+ // Address, Port, Engine, Device Addr.
+ // Other args set below
+ misc_args_t args;
+ args.port = va_arg( i_args, uint64_t );
+ args.engine = va_arg( i_args, uint64_t );
+ args.devAddr = va_arg( i_args, uint64_t );
+
+ // These are additional parms in the case an offset is passed in
+ // via va_list, as well
+
+ args.offset_length = va_arg( i_args, uint64_t);
+
+ if ( args.offset_length != 0 )
+ {
+ args.offset_buffer = reinterpret_cast<uint8_t*>
+ (va_arg(i_args, uint64_t));
+ }
+
+ // Set both Host and FSI switches to 0 so that they get set later by
+ // attribute in i2cCommonOp()
+ args.switches.useHostI2C = 0;
+ args.switches.useFsiI2C = 0;
+
+
+ // Call common function
+ err = i2cCommonOp( i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ i_accessType,
+ args );
+
+
+ TRACDCOMP( g_trac_i2c,
+ EXIT_MRK"i2cPerformOp() - %s",
+ ((NULL == err) ? "No Error" : "With Error") );
+
+ return err;
+} // end i2cPerformOp
+
+
+// Register the Host-based I2C perform Op with the routing code for Procs.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::HOSTI2C,
+ TARGETING::TYPE_PROC,
+ host_i2cPerformOp );
+
+// Register the Host-based I2C perform Op with the routing code for Mem Buffers.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::HOSTI2C,
+ TARGETING::TYPE_MEMBUF,
+ host_i2cPerformOp );
+
+// ------------------------------------------------------------------
+// host_i2cPerformOp
+// ------------------------------------------------------------------
+errlHndl_t host_i2cPerformOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args )
+{
+ errlHndl_t err = NULL;
// Get the input args our of the va_list
// Address, Port, Engine, Device Addr.
@@ -163,31 +179,134 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
args.engine = va_arg( i_args, uint64_t );
args.devAddr = va_arg( i_args, uint64_t );
+ // These are additional parms in the case an offset is passed in
+ // via va_list, as well
+
+ args.offset_length = va_arg( i_args, uint64_t);
+
+ if ( args.offset_length != 0 )
+ {
+ args.offset_buffer = reinterpret_cast<uint8_t*>
+ (va_arg(i_args, uint64_t));
+ }
+
+ // Set Host switch to 1 and FSI switch to 0
+ args.switches.useHostI2C = 1;
+ args.switches.useFsiI2C = 0;
+
+
+ // Call common function
+ err = i2cCommonOp( i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ i_accessType,
+ args );
+
+
+ TRACDCOMP( g_trac_i2c,
+ EXIT_MRK"host_i2cPerformOp() - %s",
+ ((NULL == err) ? "No Error" : "With Error") );
+
+ return err;
+} // end host_i2cPerformOp
+
+
+// Register the FSI-based I2C perform Op with the routing code for Procs.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::FSI_I2C,
+ TARGETING::TYPE_PROC,
+ fsi_i2cPerformOp );
+
+// Register the FSI-based I2C perform Op with the routing code for Mem Buffers.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::FSI_I2C,
+ TARGETING::TYPE_MEMBUF,
+ fsi_i2cPerformOp );
+
+// ------------------------------------------------------------------
+// fsi_i2cPerformOp
+// ------------------------------------------------------------------
+errlHndl_t fsi_i2cPerformOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args )
+{
+ errlHndl_t err = NULL;
+
+ // Get the input args our of the va_list
+ // Address, Port, Engine, Device Addr.
+ // Other args set below
+ misc_args_t args;
+ args.port = va_arg( i_args, uint64_t );
+ args.engine = va_arg( i_args, uint64_t );
+ args.devAddr = va_arg( i_args, uint64_t );
// These are additional parms in the case an offset is passed in
// via va_list, as well
- uint64_t l_offset_length = 0;
- uint8_t * l_offset_buffer = NULL;
- l_offset_length = va_arg( i_args, uint64_t);
+ args.offset_length = va_arg( i_args, uint64_t);
- if ( l_offset_length != 0)
+ if ( args.offset_length != 0 )
{
- l_offset_buffer = reinterpret_cast<uint8_t*>(va_arg(i_args, uint64_t));
+ args.offset_buffer = reinterpret_cast<uint8_t*>
+ (va_arg(i_args, uint64_t));
}
+ // Set FSI switch to 1 and Host switch to 0
+ args.switches.useHostI2C = 0;
+ args.switches.useFsiI2C = 1;
+
+
+ // Call common function
+ err = i2cCommonOp( i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ i_accessType,
+ args );
+
+
TRACDCOMP( g_trac_i2c,
- ENTER_MRK"i2cPerformOp(): i_opType=%d, aType=%d, "
+ EXIT_MRK"fsi_i2cPerformOp() - %s",
+ ((NULL == err) ? "No Error" : "With Error") );
+
+ return err;
+} // end fsi_i2cPerformOp
+
+
+
+// ------------------------------------------------------------------
+// i2cCommonOp
+// ------------------------------------------------------------------
+errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ misc_args_t & i_args )
+{
+ errlHndl_t err = NULL;
+ errlHndl_t err_reset = NULL;
+
+ mutex_t * engineLock = NULL;
+ bool mutex_needs_unlock = false;
+
+ TRACDCOMP( g_trac_i2c,
+ ENTER_MRK"i2cCommonOp(): i_opType=%d, aType=%d, "
"p/e/devAddr= %d/%d/0x%X, len=%d, offset=%d/%p",
- (uint64_t) i_opType, i_accessType, args.port, args.engine,
- args.devAddr, io_buflen, l_offset_length, l_offset_buffer);
+ (uint64_t) i_opType, i_accessType, i_args.port, i_args.engine,
+ i_args.devAddr, io_buflen, i_args.offset_length,
+ i_args.offset_buffer);
TRACUCOMP( g_trac_i2c,
- ENTER_MRK"i2cPerformOp(): i_opType=%d, aType=%d, "
+ ENTER_MRK"i2cCommonOp(): i_opType=%d, aType=%d, "
"p/e/devAddr= %d/%d/0x%x, len=%d, offset=%d/%p",
- (uint64_t) i_opType, i_accessType, args.port, args.engine,
- args.devAddr, io_buflen, l_offset_length, l_offset_buffer);
-
+ (uint64_t) i_opType, i_accessType, i_args.port, i_args.engine,
+ i_args.devAddr, io_buflen, i_args.offset_length,
+ i_args.offset_buffer);
do
{
@@ -195,8 +314,8 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
if( TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL == i_target )
{
TRACFCOMP( g_trac_i2c,
- ERR_MRK"i2cPerformOp() - Cannot target Master Sentinel Chip "
- "for an I2C Operation!" );
+ ERR_MRK"i2cCommonOp() - Cannot target Master Sentinel "
+ "Chip for an I2C Operation!" );
/*@
* @errortype
@@ -220,9 +339,22 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
break;
}
+ // Set Host vs FSI switches if both values are zero;
+ // Otherwise, caller should have already set them
+ if ( ( i_args.switches.useHostI2C == 0 ) &&
+ ( i_args.switches.useFsiI2C == 0 ) )
+ {
+ if ( !( i_target->tryGetAttr<TARGETING::ATTR_I2C_SWITCHES>
+ (i_args.switches) ) )
+ {
+ // Default to Host
+ i_args.switches.useHostI2C = 1;
+ i_args.switches.useFsiI2C = 0;
+ }
+ }
// Get the mutex for the requested engine
- switch( args.engine )
+ switch( i_args.engine )
{
case 0:
engineLock = i_target->getHbMutexAttr<TARGETING::ATTR_I2C_ENGINE_MUTEX_0>();
@@ -239,7 +371,7 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
default:
TRACFCOMP( g_trac_i2c,
ERR_MRK"Invalid engine for getting Mutex! "
- "args.engine=%d", args.engine );
+ "i_args.engine=%d", i_args.engine );
// @todo RTC:69113 - Create an error here
break;
};
@@ -247,16 +379,16 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
// Lock on this engine
TRACUCOMP( g_trac_i2c,
INFO_MRK"Obtaining lock for engine: %d",
- args.engine );
+ i_args.engine );
(void)mutex_lock( engineLock );
mutex_needs_unlock = true;
TRACUCOMP( g_trac_i2c,
INFO_MRK"Locked on engine: %d",
- args.engine );
+ i_args.engine );
// Calculate variables related to I2C Bus Speed in 'args' struct
- err = i2cSetBusVariables( i_target, READ_I2C_BUS_ATTRIBUTES, args);
+ err = i2cSetBusVariables( i_target, READ_I2C_BUS_ATTRIBUTES, i_args);
if( err )
{
@@ -273,33 +405,33 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
/* I2C Read with Offset */
/***********************************************/
if( i_opType == DeviceFW::READ &&
- l_offset_length != 0 )
+ i_args.offset_length != 0 )
{
// First WRITE offset to device without a stop
- args.read_not_write = false;
- args.with_stop = false;
- args.skip_mode_setup = false;
+ i_args.read_not_write = false;
+ i_args.with_stop = false;
+ i_args.skip_mode_setup = false;
err = i2cWrite( i_target,
- l_offset_buffer,
- l_offset_length,
- args );
+ i_args.offset_buffer,
+ i_args.offset_length,
+ i_args );
if( err == NULL )
{
// Now do the READ with a stop
- args.read_not_write = true;
- args.with_stop = true;
+ i_args.read_not_write = true;
+ i_args.with_stop = true;
// Skip mode setup on this cmd -
// already set with previous cmd
- args.skip_mode_setup = true;
+ i_args.skip_mode_setup = true;
err = i2cRead( i_target,
io_buffer,
io_buflen,
- args );
+ i_args );
}
}
@@ -307,30 +439,30 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
/* I2C Write with Offset */
/***********************************************/
else if( i_opType == DeviceFW::WRITE &&
- l_offset_length != 0 )
+ i_args.offset_length != 0 )
{
// Add the Offset Information to the start of the data and
// then send as a single write operation
- size_t newBufLen = l_offset_length + io_buflen;
+ size_t newBufLen = i_args.offset_length + io_buflen;
uint8_t * newBuffer = static_cast<uint8_t*>(malloc(newBufLen));
// Add the Offset to the buffer
- memcpy( newBuffer, l_offset_buffer, l_offset_length);
+ memcpy( newBuffer, i_args.offset_buffer, i_args.offset_length);
// Now add the data the user wanted to write
- memcpy( &newBuffer[l_offset_length], io_buffer, io_buflen);
+ memcpy( &newBuffer[i_args.offset_length], io_buffer, io_buflen);
// Write parms:
- args.read_not_write = false;
- args.with_stop = true;
- args.skip_mode_setup = false;
+ i_args.read_not_write = false;
+ i_args.with_stop = true;
+ i_args.skip_mode_setup = false;
err = i2cWrite( i_target,
newBuffer,
newBufLen,
- args );
+ i_args );
free( newBuffer );
@@ -341,17 +473,17 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
/* I2C Read (no offset) */
/***********************************************/
else if ( i_opType == DeviceFW::READ &&
- l_offset_length == 0 )
+ i_args.offset_length == 0 )
{
// Do a direct READ
- args.read_not_write = true;
- args.with_stop = true;
- args.skip_mode_setup = false;
+ i_args.read_not_write = true;
+ i_args.with_stop = true;
+ i_args.skip_mode_setup = false;
err = i2cRead( i_target,
io_buffer,
io_buflen,
- args);
+ i_args);
}
@@ -359,17 +491,17 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
/* I2C Write (no offset) */
/***********************************************/
else if( i_opType == DeviceFW::WRITE &&
- l_offset_length == 0 )
+ i_args.offset_length == 0 )
{
// Do a direct WRITE with a stop
- args.read_not_write = false;
- args.with_stop = true;
- args.skip_mode_setup = false;
+ i_args.read_not_write = false;
+ i_args.with_stop = true;
+ i_args.skip_mode_setup = false;
err = i2cWrite( i_target,
io_buffer,
io_buflen,
- args);
+ i_args);
}
/********************************************************/
@@ -377,13 +509,13 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
/********************************************************/
else
{
- TRACFCOMP( g_trac_i2c, ERR_MRK"i2cPerformOp() - "
+ TRACFCOMP( g_trac_i2c, ERR_MRK"i2cCommonOp() - "
"Unsupported Op/Offset-Type Combination=%d/%d",
- i_opType, l_offset_length );
- uint64_t userdata2 = l_offset_length;
- userdata2 = (userdata2 << 16) | args.port;
- userdata2 = (userdata2 << 16) | args.engine;
- userdata2 = (userdata2 << 16) | args.devAddr;
+ i_opType, i_args.offset_length );
+ uint64_t userdata2 = i_args.offset_length;
+ userdata2 = (userdata2 << 16) | i_args.port;
+ userdata2 = (userdata2 << 16) | i_args.engine;
+ userdata2 = (userdata2 << 16) | i_args.devAddr;
/*@
* @errortype
@@ -426,13 +558,13 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
// Reset the I2C Master
err_reset = i2cReset( i_target,
- args,
+ i_args,
l_reset_level);
if( err_reset )
{
// 2 error logs, so commit the reset log here
- TRACFCOMP( g_trac_i2c, ERR_MRK"i2cPerformOp() - "
+ TRACFCOMP( g_trac_i2c, ERR_MRK"i2cCommonOp() - "
"Previous error (rc=0x%X, eid=0x%X) before "
"i2cReset() failed. Committing reset error "
"(rc=0x%X, eid=0x%X) and returning original error",
@@ -457,27 +589,27 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
(void) mutex_unlock( engineLock );
TRACUCOMP( g_trac_i2c,
INFO_MRK"Unlocked engine: %d",
- args.engine );
+ i_args.engine );
}
// If there is an error, add parameter info to log
if ( err != NULL )
{
-
+ // @todo RTC 114298- update this for new parms/switches
I2C::UdI2CParms( i_opType,
i_target,
io_buflen,
i_accessType,
- args )
+ i_args )
.addToLog(err);
}
TRACDCOMP( g_trac_i2c,
- EXIT_MRK"i2cPerformOp() - %s",
+ EXIT_MRK"i2cCommonOp() - %s",
((NULL == err) ? "No Error" : "With Error") );
return err;
-} // end i2cPerformOp
+} // end i2cCommonOp
// ------------------------------------------------------------------
// i2cRead
@@ -489,8 +621,6 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
{
errlHndl_t err = NULL;
uint64_t bytesRead = 0x0;
- size_t size = sizeof(uint64_t);
-
// Use Local Variables (timeoutCount gets derecmented)
uint64_t interval_ns = i_args.polling_interval_ns;
@@ -614,15 +744,16 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target,
// Read the data from the fifo
fifo.value = 0x0ull;
- err = deviceRead( i_target,
- &fifo.value,
- size,
- DEVICE_SCOM_ADDRESS(
- I2C::masterAddrs[i_args.engine].fifo ) );
+
+ err = i2cRegisterOp( DeviceFW::READ,
+ i_target,
+ &fifo.value,
+ I2C_REG_FIFO,
+ i_args );
TRACUCOMP( g_trac_i2c,
- INFO_MRK"i2cRead() - FIFO[0x%lx] = 0x%016llx",
- masterAddrs[i_args.engine].fifo, fifo.value);
+ INFO_MRK"i2cRead() - FIFO = 0x%016llx",
+ fifo.value);
if( err )
{
@@ -676,7 +807,6 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target,
{
errlHndl_t err = NULL;
uint64_t bytesWritten = 0x0;
- size_t size = sizeof(uint64_t);
// Define regs we'll be using
fifo_reg_t fifo;
@@ -717,11 +847,11 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target,
fifo.value = 0x0ull;
fifo.byte_0 = *((uint8_t*)i_buffer + bytesWritten);
- err = deviceWrite( i_target,
- &fifo.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].fifo ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &fifo.value,
+ I2C_REG_FIFO,
+ i_args );
if( err )
{
@@ -771,7 +901,6 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target,
misc_args_t & i_args)
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
TRACDCOMP( g_trac_i2c,
ENTER_MRK"i2cSetup(): buf_len=%d, r_nw=%d, w_stop=%d, sms=%d",
@@ -810,11 +939,11 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target,
TRACUCOMP( g_trac_i2c,"i2cSetup(): set mode = 0x%lx", mode.value);
- err = deviceWrite( i_target,
- &mode.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].mode));
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &mode.value,
+ I2C_REG_MODE,
+ i_args );
if( err )
{
@@ -845,11 +974,11 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target,
TRACUCOMP( g_trac_i2c,"i2cSetup(): set cmd = 0x%lx", cmd.value);
- err = deviceWrite( i_target,
- &cmd.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].command ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &cmd.value,
+ I2C_REG_COMMAND,
+ i_args );
if( err )
{
@@ -962,7 +1091,6 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target,
status_reg_t & o_statusReg )
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
TRACDCOMP( g_trac_i2c,
ENTER_MRK"i2cReadStatusReg()" );
@@ -970,11 +1098,11 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target,
do
{
// Read the status Reg
- err = deviceRead( i_target,
- &o_statusReg.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].status ) );
+ err = i2cRegisterOp( DeviceFW::READ,
+ i_target,
+ &o_statusReg.value,
+ I2C_REG_STATUS,
+ i_args );
if( err )
{
@@ -982,8 +1110,8 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target,
}
TRACUCOMP(g_trac_i2c,"i2cReadStatusReg(): "
- INFO_MRK"status[0x%lx]: 0x%016llx",
- masterAddrs[i_args.engine].status, o_statusReg.value );
+ INFO_MRK"status: 0x%016llx",
+ o_statusReg.value );
// Check for Errors
@@ -1350,7 +1478,6 @@ errlHndl_t i2cSendStopSignal(TARGETING::Target * i_target,
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
TRACDCOMP( g_trac_i2c,
ENTER_MRK"i2cSendStopSignal" );
@@ -1367,11 +1494,11 @@ errlHndl_t i2cSendStopSignal(TARGETING::Target * i_target,
"clock line 0x%016llx",
clkdataline.value );
- err = deviceWrite( i_target,
- &clkdataline.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].reset_scl ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &clkdataline.value,
+ I2C_REG_RESET_SCL,
+ i_args );
if( err )
{
@@ -1381,11 +1508,11 @@ errlHndl_t i2cSendStopSignal(TARGETING::Target * i_target,
}
//set data low: write 0 to immediate reset sda register
- err = deviceWrite( i_target,
- &clkdataline.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].reset_sda ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &clkdataline.value,
+ I2C_REG_RESET_SDA,
+ i_args );
if( err )
{
@@ -1395,11 +1522,11 @@ errlHndl_t i2cSendStopSignal(TARGETING::Target * i_target,
}
// set clock high: write 0 to immediate set scl register
- err = deviceWrite( i_target,
- &clkdataline.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].set_scl ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &clkdataline.value,
+ I2C_REG_SET_SCL,
+ i_args );
if( err )
{
@@ -1409,11 +1536,11 @@ errlHndl_t i2cSendStopSignal(TARGETING::Target * i_target,
}
//set data high: write 0 to immediate set sda register
- err = deviceWrite( i_target,
- &clkdataline.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].set_sda ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &clkdataline.value,
+ I2C_REG_SET_SDA,
+ i_args );
if( err )
{
@@ -1435,7 +1562,6 @@ errlHndl_t i2cToggleClockLine(TARGETING::Target * i_target,
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
TRACDCOMP( g_trac_i2c,
ENTER_MRK"i2cToggleClockLine()" );
@@ -1452,11 +1578,11 @@ errlHndl_t i2cToggleClockLine(TARGETING::Target * i_target,
"clock line 0x%016llx",
clkline.value );
- err = deviceWrite( i_target,
- &clkline.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].reset_scl ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &clkline.value,
+ I2C_REG_RESET_SCL,
+ i_args );
if( err )
{
@@ -1466,11 +1592,11 @@ errlHndl_t i2cToggleClockLine(TARGETING::Target * i_target,
}
// set clock high: write 0 to immediate set scl register
- err = deviceWrite( i_target,
- &clkline.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].set_scl ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &clkline.value,
+ I2C_REG_SET_SCL,
+ i_args );
if( err )
{
@@ -1493,7 +1619,6 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target,
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
TRACDCOMP( g_trac_i2c,
ENTER_MRK"i2cForceResetAndUnlock()" );
@@ -1513,11 +1638,11 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target,
diagnostic.diag_mode = 0x1;
- err = deviceWrite( i_target,
- &diagnostic.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].mode ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &diagnostic.value,
+ I2C_REG_MODE,
+ i_args );
if( err )
{
@@ -1550,11 +1675,12 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target,
//set bit in mode register
diagnostic.diag_mode = 0x0;
- err = deviceWrite( i_target,
- &diagnostic.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].mode ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &diagnostic.value,
+ I2C_REG_MODE,
+ i_args );
+
if( err )
{
@@ -1577,9 +1703,6 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target,
i2c_reset_level i_reset_level)
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
-
- // Get Args
TRACDCOMP( g_trac_i2c,
ENTER_MRK"i2cReset()" );
@@ -1591,15 +1714,11 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target,
{
reset.value = 0x0;
- TRACUCOMP(g_trac_i2c,"i2cReset() "
- "reset[0x%lx]: 0x%016llx",
- masterAddrs[i_args.engine].reset, reset.value );
-
- err = deviceWrite( i_target,
- &reset.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].reset ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &reset.value,
+ I2C_REG_RESET,
+ i_args );
if( err )
{
@@ -1648,7 +1767,6 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
misc_args_t & i_args)
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
// Master Registers
mode_reg_t mode;
@@ -1662,7 +1780,12 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
// 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
+ // Only do port 0 for FSI I2C
+ if ( ( i_args.switches.useFsiI2C == 1 ) &&
+ ( port != 0 ) )
+ {
+ break;
+ }
mode.value = 0x0ull;
@@ -1671,14 +1794,14 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
mode.bit_rate_div = i_args.bit_rate_divisor;
TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
- "mode[0x%lx]: 0x%016llx",
- masterAddrs[i_args.engine].mode, mode.value );
+ "mode: 0x%016llx",
+ mode.value );
- err = deviceWrite( i_target,
- &mode.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].mode ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &mode.value,
+ I2C_REG_MODE,
+ i_args );
if( err )
{
@@ -1689,14 +1812,14 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
cmd.with_stop = 1;
TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): "
- "cmd[0x%lx]: 0x%016llx",
- masterAddrs[i_args.engine].command, cmd.value );
+ "cmd: 0x%016llx",
+ cmd.value );
- err = deviceWrite( i_target,
- &cmd.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].command ) );
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ i_target,
+ &cmd.value,
+ I2C_REG_COMMAND,
+ i_args );
if( err )
{
@@ -1731,7 +1854,6 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target,
uint64_t & o_intRegValue )
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
// Master Regs
interrupt_reg_t intreg;
@@ -1742,20 +1864,20 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target,
do
{
intreg.value = 0x0;
- err = deviceRead( i_target,
- &intreg.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[i_args.engine].interrupt ) );
+ err = i2cRegisterOp( DeviceFW::READ,
+ i_target,
+ &intreg.value,
+ I2C_REG_INTERRUPT,
+ i_args );
if( err )
{
break;
}
TRACUCOMP(g_trac_i2c,"i2cGetInterrupts(): "
- "interrupt[0x%lx]: 0x%016llx",
- masterAddrs[i_args.engine].interrupt, intreg.value );
+ "interrupt: 0x%016llx",
+ intreg.value );
// Return the data read
o_intRegValue = intreg.value;
@@ -1775,9 +1897,8 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target,
errlHndl_t i2cSetupMasters ( void )
{
errlHndl_t err = NULL;
- size_t size = sizeof(uint64_t);
- misc_args_t io_args;
+ misc_args_t args;
mode_reg_t mode;
@@ -1824,6 +1945,10 @@ errlHndl_t i2cSetupMasters ( void )
continue;
}
+ // Setup Host-based I2C
+ args.switches.useHostI2C = 1;
+ args.switches.useFsiI2C = 0;
+
for( uint32_t engine = 0;
engine < CENTAUR_MASTER_ENGINES;
engine++ )
@@ -1834,7 +1959,7 @@ errlHndl_t i2cSetupMasters ( void )
// Hardcode to 400KHz for PHYP
err = i2cSetBusVariables ( centList[centaur],
SET_I2C_BUS_400KHZ,
- io_args );
+ args );
if( err )
{
@@ -1850,14 +1975,13 @@ errlHndl_t i2cSetupMasters ( void )
continue;
}
- mode.bit_rate_div = io_args.bit_rate_divisor;
+ mode.bit_rate_div = args.bit_rate_divisor;
- size = sizeof(uint64_t);
- err = deviceWrite( centList[centaur],
- &mode.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[engine].mode));
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ centList[centaur],
+ &mode.value,
+ I2C_REG_MODE,
+ args );
if( err )
{
@@ -1916,15 +2040,22 @@ errlHndl_t i2cSetupMasters ( void )
continue;
}
+ // Setup Host-based I2C
+ args.switches.useHostI2C = 1;
+ args.switches.useFsiI2C = 0;
+
+
for( uint32_t engine = 0; engine < P8_MASTER_ENGINES; engine++ )
{
+ args.engine = engine;
+
// Write Mode Register:
mode.value = 0x0ull;
// Hardcode to 400KHz for PHYP
err = i2cSetBusVariables ( procList[proc],
SET_I2C_BUS_400KHZ,
- io_args );
+ args );
if( err )
{
@@ -1941,15 +2072,13 @@ errlHndl_t i2cSetupMasters ( void )
continue;
}
- mode.bit_rate_div = io_args.bit_rate_divisor;
-
- size = sizeof(uint64_t);
- err = deviceWrite( procList[proc],
- &mode.value,
- size,
- DEVICE_SCOM_ADDRESS(
- masterAddrs[engine].mode));
+ mode.bit_rate_div = args.bit_rate_divisor;
+ err = i2cRegisterOp( DeviceFW::WRITE,
+ procList[proc],
+ &mode.value,
+ I2C_REG_MODE,
+ args );
if( err )
{
TRACFCOMP( g_trac_i2c,
@@ -1995,18 +2124,11 @@ errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target,
errlHndl_t err = NULL;
TRACDCOMP( g_trac_i2c,
- ENTER_MRK"i2cSetBusVariables(): nest_freq=%d, i_mode=%d",
- g_I2C_NEST_FREQ_MHZ, i_mode );
+ ENTER_MRK"i2cSetBusVariables(): i_mode=%d",
+ i_mode );
do
{
- // @todo RTC:80614 - sync up reading attributes eventually,
- // but for now, unless requested for 400KHz, default to 1MHz
- if ( i_mode != SET_I2C_BUS_400KHZ )
- {
- i_mode = SET_I2C_BUS_1MHZ;
- }
-
if ( i_mode == SET_I2C_BUS_400KHZ )
{
io_args.bus_speed = I2C_BUS_SPEED_400KHZ;
@@ -2017,12 +2139,27 @@ errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target,
io_args.bus_speed = I2C_BUS_SPEED_1MHZ;
}
- /* @todo RTC:80614 - sync up reading attributes with MRW
+
+ // @todo RTC:80614 - sync up reading attributes with MRW
+ // MRW does not have Host-based processor set at 1MHz
+ // Otherwise, default everything to 400KHZ
else if (i_mode == READ_I2C_BUS_ATTRIBUTES)
{
-
+ // @todo RTC 117430 - Remove when MRWs are updated to have
+ // hostboot SBE Seeproms use 1MHZ speed
+ // Look for Processor and Host I2C mode
+ if ( ( io_args.switches.useHostI2C == 1 ) &&
+ ( i_target->getAttr<TARGETING::ATTR_TYPE>() ==
+ TARGETING::TYPE_PROC )
+ )
+ {
+ io_args.bus_speed = I2C_BUS_SPEED_1MHZ;
+ }
+ else
+ {
+ io_args.bus_speed = I2C_BUS_SPEED_400KHZ;
+ }
}
- */
else
{
@@ -2053,15 +2190,33 @@ errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target,
}
// Set other variables based off of io_args.bus_speed
- io_args.bit_rate_divisor = i2cGetBitRateDivisor(io_args.bus_speed);
io_args.polling_interval_ns = i2cGetPollingInterval(io_args.bus_speed);
io_args.timeout_count = I2C_TIMEOUT_COUNT(io_args.polling_interval_ns);
- } while( 0 );
+ // The Bit-Rate-Divisor set in the I2C Master mode register needs
+ // to know the frequency of the "local bus" serving as a reflock
+ // for the I2C Master
+ uint64_t local_bus_MHZ = 0;
+
+ if ( io_args.switches.useFsiI2C == 1 )
+ {
+ // @todo RTC 117560 - verify correct frequency
+ local_bus_MHZ = g_I2C_NEST_FREQ_MHZ;
+ }
+ else
+ {
+ // For Host I2C use Nest Frequency
+ local_bus_MHZ = g_I2C_NEST_FREQ_MHZ;
+ }
+
+ io_args.bit_rate_divisor = i2cGetBitRateDivisor(io_args.bus_speed,
+ local_bus_MHZ);
+ } while( 0 );
- TRACUCOMP(g_trac_i2c,"i2cSetBusVariables(): e/p/dA=%d/%d/0x%X: "
+ TRACUCOMP(g_trac_i2c,"i2cSetBusVariables(): tgt=0x%X, e/p/dA=%d/%d/0x%X: "
"mode=%d: b_sp=%d, b_r_d=0x%x, p_i=%d, to_c = %d",
+ TARGETING::get_huid(i_target),
io_args.engine, io_args.port, io_args.devAddr,
i_mode, io_args.bus_speed, io_args.bit_rate_divisor,
io_args.polling_interval_ns, io_args.timeout_count);
@@ -2164,6 +2319,11 @@ errlHndl_t i2cResetMasters ( i2cResetType i_resetType )
io_args.engine = engine;
io_args.port = 0; // default to port 0
+
+ // For processors just do Host I2C for now
+ io_args.switches.useHostI2C = 1;
+ io_args.switches.useFsiI2C = 0;
+
// Hardcode to 400KHz - should be a safe speed
err = i2cSetBusVariables ( procList[proc],
SET_I2C_BUS_400KHZ,
@@ -2232,4 +2392,93 @@ errlHndl_t i2cResetMasters ( i2cResetType i_resetType )
return err;
}
+
+
+// ------------------------------------------------------------------
+// i2cRegisterOp
+// ------------------------------------------------------------------
+errlHndl_t i2cRegisterOp ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ uint64_t * io_data_64,
+ i2c_reg_offset_t i_reg,
+ misc_args_t & i_args )
+{
+ errlHndl_t err = NULL;
+
+ TRACDCOMP( g_trac_i2c,
+ ENTER_MRK"i2cRegisterOp()");
+
+ uint64_t op_addr = 0x0;
+ uint64_t op_size = 0x0; // in bytes
+
+ do
+ {
+ // Calculate Register Address and data size based on access type
+ if ( i_args.switches.useHostI2C == 1 )
+ {
+ op_addr = I2C_HOST_MASTER_BASE_ADDR + i_reg +
+ (i_args.engine * 0x20); // engine reg offset
+ op_size=8;
+
+ err = DeviceFW::deviceOp( i_opType,
+ i_target,
+ io_data_64,
+ op_size,
+ DEVICE_SCOM_ADDRESS(op_addr) );
+
+ }
+
+ else // i_args.switches.useFsiI2C == 1
+ {
+ // FSI addresses are at 1-byte offsets, so need to multiply the
+ // i_reg offset by 4 since each I2C register is 4 bytes long.
+ op_addr = I2C_FSI_MASTER_BASE_ADDR + ( i_reg * 4 );
+
+ if ( i_reg == I2C_REG_FIFO )
+ {
+ // Only read/write 1 byte at a time for FIFO register
+ op_size = 1;
+ }
+ else
+ {
+ op_size = 4;
+ }
+
+ // Read or Write, this command should have the data left-justfied
+ err = DeviceFW::deviceOp( i_opType,
+ i_target,
+ io_data_64,
+ op_size,
+ DEVICE_FSI_ADDRESS(op_addr));
+
+ }
+
+ if ( err )
+ {
+ TRACFCOMP(g_trac_i2c,"i2cRegisterOp %s FAIL!: plid=0X%X, rc=0x%X "
+ "tgt=0x%X, reg=%d, addr=0x%.8X, "
+ "data=0x%.16X",
+ ( i_opType == DeviceFW::READ ) ? "read" : "write",
+ err->plid(), err->reasonCode(),
+ TARGETING::get_huid(i_target),
+ i_reg, op_addr, (*io_data_64) );
+ }
+
+ } while( 0 );
+
+ TRACUCOMP(g_trac_i2c,"i2cRegisterOp(%s): tgt=0x%X, h/f=%d/%d(%d) "
+ "i_reg=%d, addr=0x%.8X, data=0x%.16X",
+ ( i_opType == DeviceFW::READ ) ? "r" : "w",
+ TARGETING::get_huid(i_target),
+ i_args.switches.useHostI2C,
+ i_args.switches.useFsiI2C, op_size,
+ i_reg, op_addr, (*io_data_64) );
+
+ TRACDCOMP( g_trac_i2c,
+ EXIT_MRK"i2cRegisterOp()" );
+
+ return err;
+}
+
+
} // end namespace I2C
diff --git a/src/usr/i2c/i2c.H b/src/usr/i2c/i2c.H
index 7834cbd0c..f94e669c3 100755
--- a/src/usr/i2c/i2c.H
+++ b/src/usr/i2c/i2c.H
@@ -77,20 +77,23 @@ ALWAYS_INLINE inline uint64_t i2cGetNestFreq()
};
static uint64_t g_I2C_NEST_FREQ_MHZ = i2cGetNestFreq();
+
/**
* @brief Inline function used to calculate Bit Rate Divisor setting
* based on I2C Bus Speed and Nest Frequency
*
- * @param [in] i_bus_speed_khz Bus Speed in KHz
+ * @param [in] i_bus_speed_khz Bus Speed in KHz
+ * @param [in] i_local_bus_MHZ Local Bus that feeds I2C Master's clock
*
* @return Bit Rate Divisor value
*/
-ALWAYS_INLINE inline uint16_t i2cGetBitRateDivisor(uint64_t i_bus_speed_khz)
+ALWAYS_INLINE inline uint16_t i2cGetBitRateDivisor(uint64_t i_bus_speed_khz,
+ uint64_t i_local_bus_MHZ)
{
- // BRD = ( ( ( NEST_FREQ_MHZ / 16 ) / i_bus_speed_khz ) - 1 ) / 4
+ // BRD = ( ( ( LocalBus_MHZ / 16 ) / i_bus_speed_khz ) - 1 ) / 4
// Use tmp variable to convert everything to KHZ safely
- uint64_t tmp = ( g_I2C_NEST_FREQ_MHZ / 16 ) * 1000;
+ uint64_t tmp = ( i_local_bus_MHZ / 16 ) * 1000;
return ( ( ( tmp / i_bus_speed_khz ) - 1 ) / 4 );
}
@@ -139,48 +142,37 @@ enum i2c_bus_setting_mode_t
#define I2C_BUS_SPEED_1MHZ 1000
-/**
- * @brief I2C Master Base Addresses
- *
- * These addresses will not be needed once there is some solution in
- * the attribute code that can be queried to get the chip base
- * addresses.
- */
-#define I2C_MASTER_BASE_ADDR 0xA0000
-
-/**
- * @brief I2C Master Offset Addresses
- */
-#define I2C_MASTER0_OFFSET 0x00
-#define I2C_MASTER1_OFFSET 0x20
-#define I2C_MASTER2_OFFSET 0x40
+// -----------------------------------------------------------------------
+// NOTE: Host I2C is using the PIB I2C Master 'legacy' registers, which
+// are analagous to the FSI I2C register space.
+// -----------------------------------------------------------------------
/**
- * @brief I2C Master Addresses
+ * @brief I2C Master Base Addresses
*/
-#define I2C_MASTER0_ADDR (I2C_MASTER_BASE_ADDR | I2C_MASTER0_OFFSET)
-#define I2C_MASTER1_ADDR (I2C_MASTER_BASE_ADDR | I2C_MASTER1_OFFSET)
-#define I2C_MASTER2_ADDR (I2C_MASTER_BASE_ADDR | I2C_MASTER2_OFFSET)
+#define I2C_HOST_MASTER_BASE_ADDR 0xA0004
+#define I2C_FSI_MASTER_BASE_ADDR 0x01800
/**
- * @brief I2C Master register structure and address definition
+ * @brief I2C Register Offsets
*/
-struct i2c_addrs_t
+enum i2c_reg_offset_t
{
- uint64_t fifo;
- uint64_t command;
- uint64_t mode;
- uint64_t intmask; // Not Currently used
- uint64_t interrupt;
- uint64_t status;
- uint64_t reset;
- uint64_t set_scl;
- uint32_t reset_scl;
- uint32_t set_sda;
- uint32_t reset_sda;
+ I2C_REG_FIFO = 0,
+ I2C_REG_COMMAND = 1,
+ I2C_REG_MODE = 2,
+ I2C_REG_INTMASK = 4,
+ I2C_REG_INTERRUPT = 6,
+ I2C_REG_STATUS = 7,
+ I2C_REG_RESET = 7,
+ I2C_REG_SET_SCL = 9,
+ I2C_REG_RESET_SCL = 11,
+ I2C_REG_SET_SDA = 12,
+ I2C_REG_RESET_SDA = 13,
};
+
/**
* @brief Structure used to pass important variables between functions
*/
@@ -196,6 +188,10 @@ struct misc_args_t
uint16_t bit_rate_divisor; // uint16_t to match size in mode register
uint64_t polling_interval_ns; // in nanoseconds
uint64_t timeout_count;
+ uint64_t offset_length;
+ uint8_t* offset_buffer;
+
+ TARGETING::I2cSwitches switches;
misc_args_t():port(0xFF),
engine(0xFF),
@@ -206,19 +202,14 @@ struct misc_args_t
bus_speed(0),
bit_rate_divisor(0),
polling_interval_ns(0),
- timeout_count(0){}
-};
+ timeout_count(0),
+ offset_length(0),
+ offset_buffer(NULL){};
-
-// -----------------------------------------------------------------------
-// NOTE: Addressing listed below is from the PIB I2C Master Addressing
-// scheme from the I2C Master specification. Only the Legacy
-// registers are being implemented.
-// -----------------------------------------------------------------------
+};
/**
* @brief I2C FIFO register definition
-* Address 0x04
*/
union fifo_reg_t
{
@@ -232,7 +223,6 @@ union fifo_reg_t
/**
* @brief I2C Command register definition
- * Address 0x05
*/
union command_reg_t
{
@@ -253,7 +243,6 @@ union command_reg_t
/**
* @brief I2C Mode register definition
- * Address 0x06
*/
union mode_reg_t
{
@@ -273,7 +262,6 @@ union mode_reg_t
/**
* @brief Watermark register definition
- * Address 0x07
*/
union watermark_reg_t
{
@@ -291,7 +279,6 @@ union watermark_reg_t
/**
* @brief Interrupt Mask register definition
- * Address 0x08
*/
union interrupt_mask_reg_t
{
@@ -321,7 +308,6 @@ union interrupt_mask_reg_t
/**
* @brief Interrupt Condition register definition
- * Address 0x09
*/
union interrupt_cond_reg_t
{
@@ -351,7 +337,6 @@ union interrupt_cond_reg_t
/**
* @brief Interrupt register definition
- * Address 0x0A
*/
union interrupt_reg_t
{
@@ -381,7 +366,6 @@ union interrupt_reg_t
/**
* @brief Status register definition
- * Address 0x0B
*/
union status_reg_t
{
@@ -412,7 +396,6 @@ union status_reg_t
/**
* @brief Extended Status register definition
- * Address 0x0C
*/
union extended_status_reg_t
{
@@ -440,7 +423,6 @@ union extended_status_reg_t
/**
* @brief Residual Front/Back end length register definition
- * Address 0x0D
*/
union residual_length_reg_t
{
@@ -462,7 +444,7 @@ union residual_length_reg_t
* driver framework.
*
* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
-* driververif.H
+* driverif.H
*
* @param[in] i_target - I2C Master Target device
*
@@ -477,12 +459,10 @@ union residual_length_reg_t
* to be read from target device.
*
* @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
-* usrif.H
+* userif.H
*
* @param [in] i_args - This is an argument list for the device driver
-* framework. This list of arguments consists of the I2C Master
-* engine, which port from the I2C master to use, and the slave's
-* device address.
+* framework. This list of arguments is documented in driverif.H.
*
* @return errlHndl_t - NULL if successful, otherwise a pointer to the
* error log.
@@ -495,6 +475,121 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
int64_t i_accessType,
va_list i_args );
+
+/**
+*
+* @brief Perform a Host-based I2C access operation. It follows a pre-defined
+* prototype function in order to be registered with the device
+* driver framework.
+*
+* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+* driverif.H
+*
+* @param[in] i_target - I2C Master Target device
+*
+* @param [in/out] io_buffer
+* INPUT: Pointer to the data that will be written to the target
+* device.
+* OUTPUT: Pointer to the data that was read from the target device.
+*
+* @param [in/out] io_buflen
+* INPUT: Length of the buffer to be written to target device.
+* OUTPUT: Length of buffer that was written, or length of buffer
+* to be read from target device.
+*
+* @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+* userif.H
+*
+* @param [in] i_args - This is an argument list for the device driver
+* framework. This list of arguments is documented in driverif.H.
+*
+* @return errlHndl_t - NULL if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t host_i2cPerformOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args );
+
+/**
+*
+* @brief Perform a FSI-based I2C access operation. It follows a pre-defined
+* prototype function in order to be registered with the device
+* driver framework.
+*
+* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+* driverif.H
+*
+* @param[in] i_target - I2C Master Target device
+*
+* @param [in/out] io_buffer
+* INPUT: Pointer to the data that will be written to the target
+* device.
+* OUTPUT: Pointer to the data that was read from the target device.
+*
+* @param [in/out] io_buflen
+* INPUT: Length of the buffer to be written to target device.
+* OUTPUT: Length of buffer that was written, or length of buffer
+* to be read from target device.
+*
+* @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+* userif.H
+*
+* @param [in] i_args - This is an argument list for the device driver
+* framework. This list of arguments is documented in driverif.H.
+*
+* @return errlHndl_t - NULL if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t fsi_i2cPerformOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args );
+
+/**
+*
+* @brief Performs the actual I2C operation.
+* NOTE: This function handles the MUTEX used to avoid deadlocks.
+*
+* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+* driverif.H
+*
+* @param[in] i_target - I2C Master Target device
+*
+* @param [in/out] io_buffer
+* INPUT: Pointer to the data that will be written to the target
+* device.
+* OUTPUT: Pointer to the data that was read from the target device.
+*
+* @param [in/out] io_buflen
+* INPUT: Length of the buffer to be written to target device.
+* OUTPUT: Length of buffer that was written, or length of buffer
+* to be read from target device.
+*
+* @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+* userif.H
+*
+* @param[in] i_args - Structure containing arguments needed for a command
+ * transaction.
+*
+* @return errlHndl_t - NULL if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ misc_args_t & i_args );
+
+
/**
* @brief This function will do the real work of reading from the I2C
* device.
@@ -698,6 +793,35 @@ errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target,
i2c_bus_setting_mode_t i_mode,
misc_args_t & io_args );
+/**
+ * @brief This function handles all I2C-related Register operations.
+ * Host (via scom) and FSI operations use different size regisers
+ * and this function converts all data to 64 bits.
+ *
+ * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+ * driververif.H
+ *
+ * @param[in] i_target - I2C Master Target device
+ *
+ * @param [in/out] io_buffer_64
+ * INPUT: Pointer to 64 bits of data to be written to the target
+ * OUTPUT: Pointer to the 64 bits of data that was read from the target
+ *
+ * @param[in] i_reg - The I2C register of the operation
+ *
+ * @param[in/out] i_args - Structure containing arguments needed for a command
+ * transaction.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t i2cRegisterOp ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ uint64_t * io_data_64,
+ i2c_reg_offset_t i_reg,
+ misc_args_t & i_args );
+
+
}; // end I2C namespace
diff --git a/src/usr/i2c/test/i2ctest.H b/src/usr/i2c/test/i2ctest.H
index f33ec1824..e2ef80597 100755
--- a/src/usr/i2c/test/i2ctest.H
+++ b/src/usr/i2c/test/i2ctest.H
@@ -698,11 +698,16 @@ class I2CTest: public CxxTest::TestSuite
{ I2C::SET_I2C_BUS_400KHZ, 400 },
// READ_I2C_BUS_ATTRIBUTES should default to 1MHz
+ // with a processor target using Host I2C
{ I2C::READ_I2C_BUS_ATTRIBUTES, 1000 },
};
uint32_t NUM_CMDS = sizeof(testData)/sizeof(testData[0]);
+ // set Processor Target to Host I2C mode
+ io_args.switches.useHostI2C = 1;
+ io_args.switches.useFsiI2C = 0;
+
for ( uint32_t i = 0; i < NUM_CMDS; i++ )
{
cmds++;
@@ -772,7 +777,9 @@ class I2CTest: public CxxTest::TestSuite
I2C::g_I2C_NEST_FREQ_MHZ = testData_2[i].i_nest_freq_mhz;
cmds++;
- l_brd = I2C::i2cGetBitRateDivisor(testData_2[i].i_bus_speed);
+ l_brd = I2C::i2cGetBitRateDivisor(
+ testData_2[i].i_bus_speed,
+ testData_2[i].i_nest_freq_mhz);
l_pi = I2C::i2cGetPollingInterval(testData_2[i].i_bus_speed);
l_tc = I2C_TIMEOUT_COUNT(l_pi);
OpenPOWER on IntegriCloud