Include Must-Fix Hostboot Items for 1.1 Release
diff --git a/openpower/package/hostboot/hostboot-0017-Fix-I2C-Reset-to-resolve-I2C-Bus-Arbitration-Lost-Er.patch b/openpower/package/hostboot/hostboot-0017-Fix-I2C-Reset-to-resolve-I2C-Bus-Arbitration-Lost-Er.patch
new file mode 100644
index 0000000..757f701
--- /dev/null
+++ b/openpower/package/hostboot/hostboot-0017-Fix-I2C-Reset-to-resolve-I2C-Bus-Arbitration-Lost-Er.patch
@@ -0,0 +1,306 @@
+From 3f630837040bae961612214307d2903e65af9e5d Mon Sep 17 00:00:00 2001
+From: Mike Baiocchi <baiocchi@us.ibm.com>
+Date: Thu, 2 Apr 2015 13:42:00 -0500
+Subject: [PATCH 05/10] Fix I2C Reset to resolve I2C Bus Arbitration Lost
+ Errors
+
+This commit fixes 2 bugs where the full "Force Reset and Unlock"
+I2C reset procedure used to both avoid and recover from I2C Bus
+Arbitration Lost errors was not being performed correctly on any
+ports but port 0.
+
+Change-Id: Ie967d81917e9b942d5cb516856075ebdb5029487
+CQ: SW297864
+(cherry picked from commit 01ee7107170c867d25af2485b75307e3bfa87339)
+---
+ src/include/usr/i2c/i2creasoncodes.H | 1 +
+ src/usr/i2c/i2c.C | 182 ++++++++++++++++++++++++-----------
+ src/usr/i2c/i2c.H | 4 +-
+ 3 files changed, 130 insertions(+), 57 deletions(-)
+
+diff --git a/src/include/usr/i2c/i2creasoncodes.H b/src/include/usr/i2c/i2creasoncodes.H
+index a63e8d5..454ef15 100644
+--- a/src/include/usr/i2c/i2creasoncodes.H
++++ b/src/include/usr/i2c/i2creasoncodes.H
+@@ -58,6 +58,7 @@ enum i2cModuleId
+ I2C_SETUP_MASTERS = 0x08,
+ I2C_SEND_SLAVE_STOP = 0x09,
+ I2C_PROCESS_ACTIVE_MASTERS = 0x0A,
++ I2C_FORCE_RESET_AND_UNLOCK = 0x0B,
+ };
+
+
+diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
+index bc4bb7b..ee7e5e3 100755
+--- a/src/usr/i2c/i2c.C
++++ b/src/usr/i2c/i2c.C
+@@ -1925,6 +1925,11 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target,
+ {
+
+ errlHndl_t err = NULL;
++ mode_reg_t mode;
++ uint64_t l_speed = I2C_BUS_SPEED_FROM_MRW;
++
++ // I2C Bus Speed Array
++ TARGETING::ATTR_I2C_BUS_SPEED_ARRAY_type speed_array;
+
+ TRACDCOMP( g_trac_i2c,
+ ENTER_MRK"i2cForceResetAndUnlock()" );
+@@ -1932,62 +1937,122 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target,
+ do
+ {
+
+- // enable diagnostic mode
+- // set bit in mode register
+- mode_reg_t diagnostic;
+-
+- diagnostic.diag_mode = 0x1;
+-
+- err = i2cRegisterOp( DeviceFW::WRITE,
+- i_target,
+- &diagnostic.value,
+- I2C_REG_MODE,
+- i_args );
+-
+- if( err )
++ // Get I2C Bus Speed Array attribute. It will be used to determine
++ // which engine/port combinations have devices on them
++ if ( !( i_target->tryGetAttr<TARGETING::ATTR_I2C_BUS_SPEED_ARRAY>
++ (speed_array) ) )
+ {
+ TRACFCOMP( g_trac_i2c,
+- ERR_MRK"I2C Enable Diagnostic mode Failed!!" );
++ ERR_MRK"i2cForceResetAndUnlock() - Cannot find "
++ "ATTR_I2C_BUS_SPEED_ARRAY needed for operation");
++ /*@
++ * @errortype
++ * @reasoncode I2C_ATTRIBUTE_NOT_FOUND
++ * @severity ERRORLOG_SEV_UNRECOVERABLE
++ * @moduleid I2C_FORCE_RESET_AND_UNLOCK
++ * @userdata1 Target for the attribute
++ * @userdata2 <UNUSED>
++ * @devdesc ATTR_I2C_BUS_SPEED_ARRAY not found
++ * @custdesc I2C configuration data missing
++ */
++ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
++ I2C_FORCE_RESET_AND_UNLOCK,
++ I2C_ATTRIBUTE_NOT_FOUND,
++ TARGETING::get_huid(i_target),
++ 0x0,
++ true /*Add HB SW Callout*/ );
++
++ err->collectTrace( I2C_COMP_NAME, 256);
++
+ break;
+ }
+
++ // Need to send slave stop to all ports with a device on the engine
++ for( uint32_t port = 0; port < P8_MASTER_PORTS; port++ )
++ {
+
+- //toggle clock line
+- err = i2cToggleClockLine( i_target,
+- i_args );
++ // Only send stop to a port if there are devices on it
++ l_speed = speed_array[i_args.engine][port];
++ if ( l_speed == 0 )
++ {
++ continue;
++ }
+
+- if( err )
+- {
+- break;
+- }
++ TRACUCOMP( g_trac_i2c,
++ INFO_MRK"i2cForceResetAndUnlock() - Performing op on "
++ "engine=%d, port=%d",
++ i_args.engine, port);
+
+- //manually send stop signal
+- err = i2cSendStopSignal( i_target,
+- i_args );
++ // Clear mode register
++ mode.value = 0x0ull;
+
+- if( err )
+- {
+- break;
+- }
++ // set port in mode register
++ mode.port_num = port;
+
+- //disable diagnostic mode
+- //set bit in mode register
+- diagnostic.diag_mode = 0x0;
++ // enable diagnostic mode in mode register
++ mode.diag_mode = 0x1;
+
+- err = i2cRegisterOp( DeviceFW::WRITE,
+- i_target,
+- &diagnostic.value,
+- I2C_REG_MODE,
+- i_args );
++ err = i2cRegisterOp( DeviceFW::WRITE,
++ i_target,
++ &mode.value,
++ I2C_REG_MODE,
++ i_args );
+
++ if( err )
++ {
++ TRACFCOMP( g_trac_i2c,
++ ERR_MRK"I2C Enable Diagnostic mode Failed!!" );
+
+- if( err )
+- {
+- TRACFCOMP( g_trac_i2c,
+- ERR_MRK"I2C disable Diagnostic mode Failed!!" );
+- break;
+- }
+
++ // We still need to reset the other ports on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
++ }
++
++
++ //toggle clock line
++ err = i2cToggleClockLine( i_target,
++ i_args );
++
++ if( err )
++ {
++ // We still need to reset the other ports on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
++ }
++
++ //manually send stop signal
++ err = i2cSendStopSignal( i_target,
++ i_args );
++
++ if( err )
++ {
++ // We still need to reset the other ports on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
++ }
++
++ // disable diagnostic mode in mode register
++ mode.diag_mode = 0x0;
++
++ err = i2cRegisterOp( DeviceFW::WRITE,
++ i_target,
++ &mode.value,
++ I2C_REG_MODE,
++ i_args );
++
++
++ if( err )
++ {
++ TRACFCOMP( g_trac_i2c,
++ ERR_MRK"I2C disable Diagnostic mode Failed!!" );
++ // We still need to reset the other ports on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
++ }
++
++
++ } // end of port for loop
+
+ }while(0);
+
+@@ -2036,8 +2101,10 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target,
+
+ if( err )
+ {
+- //error trying to force a reset break
+- break;
++ // We still want to send the slave stop command since the
++ // initial reset completed above.
++ // So just commit the log here and let the function continue.
++ errlCommit( err, I2C_COMP_ID );
+ }
+ }
+
+@@ -2114,13 +2181,6 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
+ // Need to send slave stop to all ports with a device on the engine
+ for( uint32_t port = 0; port < P8_MASTER_PORTS; port++ )
+ {
+- // Only do port 0 for FSI I2C
+- if ( ( i_args.switches.useFsiI2C == 1 ) &&
+- ( port != 0 ) )
+- {
+- break;
+- }
+-
+ // Only send stop to a port if there are devices on it
+ l_speed = speed_array[i_args.engine][port];
+ if ( l_speed == 0 )
+@@ -2139,7 +2199,10 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
+ i_args );
+ if( err )
+ {
+- break;
++ // We still need to send the slave stop to the other ports
++ // on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
+ }
+
+ mode.bit_rate_div = i_args.bit_rate_divisor;
+@@ -2156,7 +2219,10 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
+
+ if( err )
+ {
+- break;
++ // We still need to send the slave stop to the other ports
++ // on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
+ }
+
+ cmd.value = 0x0ull;
+@@ -2174,7 +2240,10 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
+
+ if( err )
+ {
+- break;
++ // We still need to send the slave stop to the other ports
++ // on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
+ }
+
+ // Now wait for cmd Complete
+@@ -2183,7 +2252,10 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target,
+
+ if( err )
+ {
+- break;
++ // We still need to send the slave stop to the other ports
++ // on this I2C engine
++ errlCommit( err, I2C_COMP_ID );
++ continue;
+ }
+
+ } // end of port for-loop
+diff --git a/src/usr/i2c/i2c.H b/src/usr/i2c/i2c.H
+index c3e5278..4a74663 100755
+--- a/src/usr/i2c/i2c.H
++++ b/src/usr/i2c/i2c.H
+@@ -723,8 +723,8 @@ errlHndl_t i2cSendStopSignal(TARGETING::Target * i_target,
+
+ /**
+ * @brief This function will reset the I2C Master engine specified
+- * by the args. It will also then initiate a Stop cmd to the
+- * slave device.
++ * by the args. It will also end the sequence by initiating a Stop
++ * cmd to all ports on the engine that have a slave device.
+ *
+ * @param[in] i_target - The I2C master target.
+ *
+--
+1.8.2.2
+