summaryrefslogtreecommitdiffstats
path: root/src/sbefw/sbeirq.C
diff options
context:
space:
mode:
authorspashabk-in <shakeebbk@in.ibm.com>2017-12-12 04:53:44 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2017-12-21 23:24:22 -0500
commite808b5c476c73fd1207e41dc9e7893c458c59969 (patch)
tree4719fe108067f56d75319e50c147c93728403ff7 /src/sbefw/sbeirq.C
parent1c909df08fcfe011621618f4350b2c04abbe0806 (diff)
downloadtalos-sbe-e808b5c476c73fd1207e41dc9e7893c458c59969.tar.gz
talos-sbe-e808b5c476c73fd1207e41dc9e7893c458c59969.zip
I2C reset sequence
i2c reset sequence as a C function Change-Id: Ia14523765c5b4d4a7073f40e7dbf614197f5b825 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50796 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Sandeep Korrapati <sakorrap@in.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/sbefw/sbeirq.C')
-rw-r--r--src/sbefw/sbeirq.C132
1 files changed, 127 insertions, 5 deletions
diff --git a/src/sbefw/sbeirq.C b/src/sbefw/sbeirq.C
index b5c2328b..d7ce601c 100644
--- a/src/sbefw/sbeirq.C
+++ b/src/sbefw/sbeirq.C
@@ -34,6 +34,8 @@
#include "sbetrace.H"
#include "assert.h"
#include "sbeglobals.H"
+#include "ppe42_scom.h"
+#include "p9_misc_scom_addresses.H"
////////////////////////////////////////////////////////////////
// @brief: SBE control loop ISR:
@@ -150,6 +152,80 @@ int sbeIRQSetup (void)
#undef SBE_FUNC
}
+// SBE I2C reset sequence
+uint32_t __max_i2c_reset_retrials = 3;
+
+// bit 0
+#define I2CM_RESET_BIT (0x8000000000000000ull)
+// bit 7
+#define I2C_CMD_COMPLETE_BIT (0x0100000000000000ull)
+// bit 3
+#define I2C_STOP_BIT (0x1000000000000000ull)
+// bit 16-21
+#define I2C_MODE_REG_PORT_BITS (0xFFFF03FFFFFFFFFFull)
+// bit 8
+#define I2C_MODE_FGAT_BIT (0x8000000000000000ull)
+
+#define POLL_BEFORE_I2C_RESET (25600)
+#define I2C_CMD_COMPLETE_POLL (0x00003FFF)
+
+extern "C" void i2c_reset()
+{
+ // empty cycles before i2c reset
+ for (auto i = POLL_BEFORE_I2C_RESET; i > 0; --i) {
+ // Force compiler not to optimize for loop
+ asm("");
+ }
+
+ uint32_t reg_address = 0;
+ uint64_t value = 0ull;
+
+ // reset I2CM register - 0x000A0001
+ reg_address = PU_RESET_REGISTER_B;
+ value = I2CM_RESET_BIT;
+ PPE_STVD( reg_address, value);
+
+ // forcefully reset port busy register - 0x000A000E
+ reg_address = PU_I2C_BUSY_REGISTER_B;
+ value = I2CM_RESET_BIT;
+ PPE_STVD( reg_address, value);
+
+ // clear bit 16-21 of mode register
+ SBE_GLOBAL->i2cModeRegister &= I2C_MODE_REG_PORT_BITS;
+ // set enchanced mode - fgat bit - 28
+ SBE_GLOBAL->i2cModeRegister |= I2C_MODE_FGAT_BIT;
+
+ for( auto port=0; port < 2; port++ )
+ {
+ // write mode register - 0x000A0006
+ reg_address = PU_MODE_REGISTER_B;
+ SBE_GLOBAL->i2cModeRegister |= ((uint64_t)port << 42);
+ PPE_STVD( reg_address, SBE_GLOBAL->i2cModeRegister );
+
+ // write command control register - 0x000A0005
+ reg_address = PU_COMMAND_REGISTER_B;
+ value = I2C_STOP_BIT;
+ PPE_STVD( reg_address, value );
+
+ // poll cmd complete register 0x000A000B
+ uint64_t status = 0;
+ for( auto i=0; i < I2C_CMD_COMPLETE_POLL; i--)
+ {
+ reg_address = PU_IMM_RESET_I2C_B;
+ PPE_LVD( reg_address, status );
+ if( status & I2C_CMD_COMPLETE_BIT )
+ {
+ // cmd complete
+ break;
+ }
+ }
+ if(!( status & I2C_CMD_COMPLETE_BIT ))
+ {
+ pk_halt();
+ }
+ }
+}
+
////////////////////////////////////////////////////////////////
// SBE handler for the PPE machine check interrupt
////////////////////////////////////////////////////////////////
@@ -159,10 +235,31 @@ int sbeIRQSetup (void)
extern "C" void __sbe_machine_check_handler()
{
asm(
- "# Save r4 to stack, since it is going to be used by\n"
+ "# reclaim function callstack\n"
+ "lwz %r0,12(%r1)\n"
+ "mtlr %r0\n"
+ "addi %r1,%r1,8\n"
+
+ "# Save r0, r1, r2, r3,r4, r5, r6, r7, r8, r9, r10, r13, r28, r29, r30, r31\n"
+ "# lr to stack, since it is going to be used by\n"
"# this handler\n"
- "stwu %r1, -8(%r1)\n"
- "stw %r4, 0(%r1)\n"
+ "stwu %r1, -68(%r1)\n"
+ "stw %r0, 0(%r1)\n"
+ "stw %r2, 4(%r1)\n"
+ "stw %r3, 8(%r1)\n"
+ "stw %r4, 12(%r1)\n"
+ "stw %r5, 16(%r1)\n"
+ "stw %r6, 20(%r1)\n"
+ "stw %r7, 24(%r1)\n"
+ "stw %r8, 28(%r1)\n"
+ "stw %r9, 32(%r1)\n"
+ "stw %r10, 36(%r1)\n"
+ "stw %r13, 40(%r1)\n"
+ "stw %r28, 44(%r1)\n"
+ "stw %r29, 48(%r1)\n"
+ "stw %r30, 52(%r1)\n"
+ "stw %r31, 56(%r1)\n"
+
"# Check the MCS bits (29:31) in the ISR to determine the cause for the machine check\n"
"# For a data machine check, the MCS should be 0x001 to 0x011\n"
"mfisr %r4\n"
@@ -187,8 +284,33 @@ extern "C" void __sbe_machine_check_handler()
"mfsrr0 %r4\n"
"addi %r4, %r4, 4\n"
"mtsrr0 %r4\n"
- "lwz %r4, 0(%r1)\n"
- "addi %r1, %r1, 8\n"
+ "b __exit\n"
+ "__sbe_i2c_reset_sequence:\n"
+ "mflr %r0\n"
+ "stw %r0, 60(%r1)\n");
+ i2c_reset();
+ asm(
+ "lwz %r0, 60(%r1)\n"
+ "mtlr %r0\n"
+ "stw %r10, __max_i2c_reset_retrials@sda21(0)\n"
+ "__exit:\n"
+ "lwz %r0, 0(%r1)\n"
+ "lwz %r2, 4(%r1)\n"
+ "lwz %r3, 8(%r1)\n"
+ "lwz %r4, 12(%r1)\n"
+ "lwz %r5, 16(%r1)\n"
+ "lwz %r6, 20(%r1)\n"
+ "lwz %r7, 24(%r1)\n"
+ "lwz %r8, 28(%r1)\n"
+ "lwz %r9, 32(%r1)\n"
+ "lwz %r10, 36(%r1)\n"
+ "lwz %r13, 40(%r1)\n"
+ "lwz %r28, 44(%r1)\n"
+ "lwz %r29, 48(%r1)\n"
+ "lwz %r30, 52(%r1)\n"
+ "lwz %r31, 56(%r1)\n"
+ "addi %r1, %r1, 68\n"
+
"rfi\n"
);
}
OpenPOWER on IntegriCloud