[2/5] npu2-opencapi: Rework adapter reset

Message ID 20180412124526.12662-3-fbarrat@linux.ibm.com
State Changes Requested
Headers show
Series
  • npu2-opencapi: Use presence detection and reset
Related show

Commit Message

Frederic Barrat April 12, 2018, 12:45 p.m.
From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>

Rework a bit the code to reset the opencapi adapter:
- make clearer which i2c pin is resetting which device
- break the reset operation in smaller chunks. This is really to
  prepare for a future patch.

No functional changes.

Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
---
 core/platform.c          | 15 ++++++----
 hw/npu2-opencapi.c       | 71 ++++++++++++++++++++++++++++++++++--------------
 include/platform.h       |  6 ++--
 platforms/astbmc/zaius.c | 15 ++++++----
 platforms/ibm-fsp/zz.c   | 15 ++++++----
 5 files changed, 81 insertions(+), 41 deletions(-)

Comments

Andrew Donnellan April 24, 2018, 1:50 a.m. | #1
On 12/04/18 22:45, Frederic Barrat wrote:
> From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> 
> Rework a bit the code to reset the opencapi adapter:
> - make clearer which i2c pin is resetting which device
> - break the reset operation in smaller chunks. This is really to
>    prepare for a future patch.
> 
> No functional changes.
> 
> Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>

This looks good, clearer than my existing approach

Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>

> ---
>   core/platform.c          | 15 ++++++----
>   hw/npu2-opencapi.c       | 71 ++++++++++++++++++++++++++++++++++--------------
>   include/platform.h       |  6 ++--
>   platforms/astbmc/zaius.c | 15 ++++++----
>   platforms/ibm-fsp/zz.c   | 15 ++++++----
>   5 files changed, 81 insertions(+), 41 deletions(-)
> 
> diff --git a/core/platform.c b/core/platform.c
> index 174235d9..b7b048f2 100644
> --- a/core/platform.c
> +++ b/core/platform.c
> @@ -34,6 +34,9 @@ DEFINE_LOG_ENTRY(OPAL_RC_ABNORMAL_REBOOT, OPAL_PLATFORM_ERR_EVT, OPAL_CEC,
>   		 OPAL_CEC_HARDWARE, OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT,
>   		 OPAL_ABNORMAL_POWER_OFF);
>   
> +#define OCAPI_I2C_RESET_ADDR       0x20
> +#define OCAPI_I2C_RESET_BOTTOM     (1 << 1)
> +#define OCAPI_I2C_RESET_TOP        (1 << 6)

my previous comments on use of macros apply here too :D But I don't feel 
very strongly about this.

Patch

diff --git a/core/platform.c b/core/platform.c
index 174235d9..b7b048f2 100644
--- a/core/platform.c
+++ b/core/platform.c
@@ -34,6 +34,9 @@  DEFINE_LOG_ENTRY(OPAL_RC_ABNORMAL_REBOOT, OPAL_PLATFORM_ERR_EVT, OPAL_CEC,
 		 OPAL_CEC_HARDWARE, OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT,
 		 OPAL_ABNORMAL_POWER_OFF);
 
+#define OCAPI_I2C_RESET_ADDR       0x20
+#define OCAPI_I2C_RESET_BOTTOM     (1 << 1)
+#define OCAPI_I2C_RESET_TOP        (1 << 6)
 #define OCAPI_I2C_PRESENCE_ADDR    0x20
 #define OCAPI_I2C_PRESENCE_BOTTOM  (1 << 2)
 #define OCAPI_I2C_PRESENCE_TOP     (1 << 7)
@@ -174,11 +177,11 @@  static int generic_start_preload_resource(enum resource_id id, uint32_t subid,
 
 /* These values will work for a ZZ booted using BML */
 const struct platform_ocapi generic_ocapi = {
-	.i2c_engine	= 1,
-	.i2c_port	= 4,
-	.i2c_offset	= { 0x3, 0x1, 0x1 },
-	.i2c_odl0_data	= { 0xFD, 0xFD, 0xFF },
-	.i2c_odl1_data	= { 0xBF, 0xBF, 0xFF },
+	.i2c_engine        = 1,
+	.i2c_port          = 4,
+	.i2c_reset_addr    = OCAPI_I2C_RESET_ADDR,
+	.i2c_reset_odl0    = OCAPI_I2C_RESET_BOTTOM,
+	.i2c_reset_odl1    = OCAPI_I2C_RESET_TOP,
 	.i2c_presence_addr = OCAPI_I2C_PRESENCE_ADDR,
 	.i2c_presence_odl0 = OCAPI_I2C_PRESENCE_BOTTOM,
 	.i2c_presence_odl1 = OCAPI_I2C_PRESENCE_TOP,
@@ -187,7 +190,7 @@  const struct platform_ocapi generic_ocapi = {
 	 * force the presence until all our systems are upgraded
 	 */
 	.force_presence    = true,
-	.odl_phy_swap   = true,
+	.odl_phy_swap      = true,
 };
 
 static struct bmc_platform generic_bmc = {
diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c
index b2bc0628..be0707ea 100644
--- a/hw/npu2-opencapi.c
+++ b/hw/npu2-opencapi.c
@@ -794,39 +794,70 @@  static void otl_enabletx(uint32_t gcid, uint32_t scom_base, uint64_t index)
 
 static void reset_ocapi_device(struct npu2_dev *dev)
 {
-	uint8_t data[3];
+	uint8_t pin, data;
 	int rc;
-	int i;
 
 	switch (dev->index) {
 	case 2:
 	case 4:
-		memcpy(data, platform.ocapi->i2c_odl0_data, sizeof(data));
+		pin = platform.ocapi->i2c_reset_odl0;
 		break;
 	case 3:
 	case 5:
-		memcpy(data, platform.ocapi->i2c_odl1_data, sizeof(data));
+		pin = platform.ocapi->i2c_reset_odl1;
 		break;
 	default:
 		assert(false);
 	}
 
-	for (i = 0; i < 3; i++) {
-		rc = i2c_request_send(dev->i2c_port_id_ocapi, 0x20, SMBUS_WRITE,
-				      platform.ocapi->i2c_offset[i], 1,
-				      &data[i], sizeof(data[i]), 120);
-		if (rc) {
-			/**
-			 * @fwts-label OCAPIDeviceResetFailed
-			 * @fwts-advice There was an error attempting to send
-			 * a reset signal over I2C to the OpenCAPI device.
-			 */
-			prlog(PR_ERR, "OCAPI: Error writing I2C reset signal: %d\n", rc);
-			break;
-		}
-		if (i != 0)
-			time_wait_ms(5);
-	}
+	/*
+	 * set the i2c reset pin in output mode
+	 *
+	 * On the 9554 device, register 3 is the configuration
+	 * register and a pin is in output mode if its value is 0
+	 */
+	data = ~pin;
+	rc = i2c_request_send(dev->i2c_port_id_ocapi,
+			platform.ocapi->i2c_reset_addr, SMBUS_WRITE,
+			0x3, 1,
+			&data, sizeof(data), 120);
+	if (rc)
+		goto err;
+
+	/*
+	 * assert i2c reset for 5ms
+	 * register 1 controls the signal, reset is active low
+	 */
+	data = ~pin;
+	rc = i2c_request_send(dev->i2c_port_id_ocapi,
+			platform.ocapi->i2c_reset_addr, SMBUS_WRITE,
+			0x1, 1,
+			&data, sizeof(data), 120);
+	if (rc)
+		goto err;
+	time_wait_ms(5);
+
+	/*
+	 * deassert i2c reset and wait 5ms
+	 */
+	data = 0xFF;
+	rc = i2c_request_send(dev->i2c_port_id_ocapi,
+			platform.ocapi->i2c_reset_addr, SMBUS_WRITE,
+			0x1, 1,
+			&data, sizeof(data), 120);
+	if (rc)
+		goto err;
+	time_wait_ms(5);
+
+	return;
+
+err:
+	/**
+	 * @fwts-label OCAPIDeviceResetFailed
+	 * @fwts-advice There was an error attempting to send
+	 * a reset signal over I2C to the OpenCAPI device.
+	 */
+	prlog(PR_ERR, "OCAPI: Error writing I2C reset signal: %d\n", rc);
 }
 
 static bool i2c_presence_detect(struct npu2_dev *dev)
diff --git a/include/platform.h b/include/platform.h
index 9a04ab37..d71fae78 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -48,9 +48,9 @@  struct bmc_platform {
 struct platform_ocapi {
 	uint8_t i2c_engine;		/* I2C engine number */
 	uint8_t i2c_port;		/* I2C port number */
-	uint32_t i2c_offset[3];		/* Offsets on I2C device */
-	uint8_t i2c_odl0_data[3];	/* Data to reset ODL0 */
-	uint8_t i2c_odl1_data[3];	/* Data to reset ODL1 */
+	uint8_t i2c_reset_addr;		/* I2C address for reset */
+	uint8_t i2c_reset_odl0;		/* I2C pin to write to reset ODL0 */
+	uint8_t i2c_reset_odl1;		/* I2C pin to write to reset ODL1 */
 	uint8_t i2c_presence_addr;	/* I2C address for presence detection */
 	uint8_t i2c_presence_odl0;	/* I2C pin to read to detect ODL0 */
 	uint8_t i2c_presence_odl1;	/* I2C pin to read to detect ODL1 */
diff --git a/platforms/astbmc/zaius.c b/platforms/astbmc/zaius.c
index 279fbf8b..170d828f 100644
--- a/platforms/astbmc/zaius.c
+++ b/platforms/astbmc/zaius.c
@@ -24,20 +24,23 @@ 
 
 #include "astbmc.h"
 
+#define OCAPI_I2C_RESET_ADDR       0x20
+#define OCAPI_I2C_RESET_BOTTOM     (1 << 1)
+#define OCAPI_I2C_RESET_TOP        (1 << 6)
 #define OCAPI_I2C_PRESENCE_ADDR    0x20
 #define OCAPI_I2C_PRESENCE_BOTTOM  (1 << 2)
 #define OCAPI_I2C_PRESENCE_TOP     (1 << 7)
 
 const struct platform_ocapi zaius_ocapi = {
-	.i2c_engine	= 1,
-	.i2c_port	= 4,
-	.i2c_offset	= { 0x3, 0x1, 0x1 },
-	.i2c_odl0_data	= { 0xFD, 0xFD, 0xFF },
-	.i2c_odl1_data	= { 0xBF, 0xBF, 0xFF },
+	.i2c_engine        = 1,
+	.i2c_port          = 4,
+	.i2c_reset_addr    = OCAPI_I2C_RESET_ADDR,
+	.i2c_reset_odl0    = OCAPI_I2C_RESET_BOTTOM,
+	.i2c_reset_odl1    = OCAPI_I2C_RESET_TOP,
 	.i2c_presence_addr = OCAPI_I2C_PRESENCE_ADDR,
 	.i2c_presence_odl0 = OCAPI_I2C_PRESENCE_BOTTOM,
 	.i2c_presence_odl1 = OCAPI_I2C_PRESENCE_TOP,
-	.odl_phy_swap   = true,
+	.odl_phy_swap      = true,
 };
 
 #define NPU_BASE 0x5011000
diff --git a/platforms/ibm-fsp/zz.c b/platforms/ibm-fsp/zz.c
index 66f29d44..d6920110 100644
--- a/platforms/ibm-fsp/zz.c
+++ b/platforms/ibm-fsp/zz.c
@@ -27,17 +27,20 @@ 
 #include "ibm-fsp.h"
 #include "lxvpd.h"
 
+#define OCAPI_I2C_RESET_ADDR       0x20
+#define OCAPI_I2C_RESET_BOTTOM     (1 << 1)
+#define OCAPI_I2C_RESET_TOP        (1 << 6)
 #define OCAPI_I2C_PRESENCE_ADDR    0x20
 #define OCAPI_I2C_PRESENCE_BOTTOM  (1 << 2)
 #define OCAPI_I2C_PRESENCE_TOP     (1 << 7)
 
 /* We don't yet create NPU device nodes on ZZ, but these values are correct */
 const struct platform_ocapi zz_ocapi = {
-	.i2c_engine	= 1,
-	.i2c_port	= 4,
-	.i2c_offset	= { 0x3, 0x1, 0x1 },
-	.i2c_odl0_data	= { 0xFD, 0xFD, 0xFF },
-	.i2c_odl1_data	= { 0xBF, 0xBF, 0xFF },
+	.i2c_engine        = 1,
+	.i2c_port          = 4,
+	.i2c_reset_addr    = OCAPI_I2C_RESET_ADDR,
+	.i2c_reset_odl0    = OCAPI_I2C_RESET_BOTTOM,
+	.i2c_reset_odl1    = OCAPI_I2C_RESET_TOP,
 	.i2c_presence_addr = OCAPI_I2C_PRESENCE_ADDR,
 	.i2c_presence_odl0 = OCAPI_I2C_PRESENCE_BOTTOM,
 	.i2c_presence_odl1 = OCAPI_I2C_PRESENCE_TOP,
@@ -46,7 +49,7 @@  const struct platform_ocapi zz_ocapi = {
 	 * force the presence until all our systems are upgraded
 	 */
 	.force_presence    = true,
-	.odl_phy_swap   = true,
+	.odl_phy_swap      = true,
 };
 
 static bool zz_probe(void)