diff options
author | Mike Baiocchi <mbaiocch@us.ibm.com> | 2018-01-25 09:53:29 -0600 |
---|---|---|
committer | William G. Hoffa <wghoffa@us.ibm.com> | 2018-01-26 17:03:43 -0500 |
commit | 079068a0dd84a877e3aa9b382b4dcaebecfa5f37 (patch) | |
tree | 54aa28b9d03bd20838147ed12d88f02d4576c964 /src/usr/i2c | |
parent | c9a86977d3eb0902e16c51338da83069117d4b7d (diff) | |
download | talos-hostboot-079068a0dd84a877e3aa9b382b4dcaebecfa5f37.tar.gz talos-hostboot-079068a0dd84a877e3aa9b382b4dcaebecfa5f37.zip |
I2C Reset Path: Add Poll of SCL High Before Issuing Stop Command
At the end of the I2C reset sequence, a 'stop' command is sent to
each port on the master that was reset. Before sending this 'stop'
command, a poll has been added such to check that SCL (clock line)
is high. This addresses a known issue with current TPMs.
Change-Id: I13b199f5b4d10d7224d3ccc5d1a8baaecb4f2326
CQ: SW405816
Backport: release-fips910
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/52636
Reviewed-by: Christopher J. Engel <cjengel@us.ibm.com>
Reviewed-by: Timothy R. Block <block@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr/i2c')
-rwxr-xr-x | src/usr/i2c/i2c.C | 55 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.H | 5 |
2 files changed, 57 insertions, 3 deletions
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C index 762d66ec2..61256f3bd 100755 --- a/src/usr/i2c/i2c.C +++ b/src/usr/i2c/i2c.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -80,6 +80,9 @@ TRAC_INIT( & g_trac_i2cr, "I2CR", KILOBYTE ); // Defines // ---------------------------------------------- #define I2C_RESET_DELAY_NS (5 * NS_PER_MSEC) // Sleep for 5 ms after reset +#define I2C_RESET_POLL_DELAY_NS (500 * 1000) // Sleep for 500usec per poll +#define I2C_RESET_POLL_DELAY_TOTAL_NS (500 * NS_PER_MSEC) // Total time to poll + #define P9_MASTER_PORTS 13 // Number of Ports used in P9 #define CENTAUR_MASTER_ENGINES 1 // Number of Engines in a Centaur #define MAX_NACK_RETRIES 3 @@ -2791,6 +2794,7 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, // Master Registers mode_reg_t mode; command_reg_t cmd; + status_reg_t status_reg; uint64_t l_speed = I2C_BUS_SPEED_FROM_MRW; // I2C Bus Speed Array @@ -2897,6 +2901,55 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, continue; } + // Look for Clock Line (SCL) High such that 'stop' cmd will work + status_reg.value = 0x0ull; + size_t delay_ns = 0; + for ( ; + delay_ns <= I2C_RESET_POLL_DELAY_TOTAL_NS; + delay_ns += I2C_RESET_POLL_DELAY_NS) + { + err = i2cRegisterOp( DeviceFW::READ, + i_target, + &status_reg.value, + I2C_REG_STATUS, + i_args ); + + if( err ) + { + TRACFCOMP( g_trac_i2c, + ERR_MRK"Reading I2C Status Reg Failed!!" ); + break; + } + + if ( status_reg.scl_input_level != 0 ) + { + break; + } + + // Sleep before polling again + nanosleep( 0, I2C_RESET_POLL_DELAY_NS ); + + } + + if ( err ) + { + // We still need to send the slave stop to the other ports + // on this I2C engine + errlCommit( err, I2C_COMP_ID ); + continue; + } + + if ( delay_ns > I2C_RESET_POLL_DELAY_TOTAL_NS ) + { + // Even though we don't see the Clock Line High, just + // trace a warning here and continue to send the 'stop' cmd + TRACFCOMP( g_trac_i2c, INFO_MRK"i2cSendSlaveStop(): " + "Not seeing SCL High 0x%.16llX after 0x%X ns of " + "polling (max=0x%X)", + status_reg.value, delay_ns, + I2C_RESET_POLL_DELAY_TOTAL_NS ); + } + cmd.value = 0x0ull; cmd.with_stop = 1; diff --git a/src/usr/i2c/i2c.H b/src/usr/i2c/i2c.H index d644eae74..d2ba23009 100755 --- a/src/usr/i2c/i2c.H +++ b/src/usr/i2c/i2c.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -359,7 +359,8 @@ union status_reg_t uint64_t stop_error : 1; uint64_t upper_threshold : 7; uint64_t any_i2c_interrupt : 1; - uint64_t reserved0 : 2; + uint64_t waiting_for_i2c_busy : 1; + uint64_t error_in : 1; uint64_t i2c_port_history_busy : 1; uint64_t scl_input_level : 1; uint64_t sda_inupt_level : 1; |