diff options
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/errl/errludlogregister.C | 9 | ||||
-rw-r--r-- | src/usr/errl/test/errluserdetailtest.H | 2 | ||||
-rw-r--r-- | src/usr/fsi/fsidd.C | 92 | ||||
-rw-r--r-- | src/usr/fsi/fsidd.H | 28 | ||||
-rw-r--r-- | src/usr/hwas/hwasPlat.C | 3 | ||||
-rwxr-xr-x | src/usr/i2c/eepromdd.C | 129 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.C | 767 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.H | 242 | ||||
-rwxr-xr-x | src/usr/i2c/test/i2ctest.H | 9 |
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, ®2_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, ®3_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); |