summaryrefslogtreecommitdiff
path: root/board/servo_v4p1
diff options
context:
space:
mode:
authorJan Dabros <jsd@semihalf.com>2021-01-12 10:25:28 +0100
committerCommit Bot <commit-bot@chromium.org>2021-02-09 10:35:20 +0000
commit50ebbad974c5c9916721ecf2e42ca07dd6df691b (patch)
treef247ee0bf6e5aad942a66794fe35c2f9887616ab /board/servo_v4p1
parenta57b6020ae50c474886f7ed591a6e0dbdb1bc950 (diff)
downloadchrome-ec-50ebbad974c5c9916721ecf2e42ca07dd6df691b.tar.gz
servo_v4p1: Allow host hub to manage USB PWREN signals
Starting from REV2 of servo_v4p1, host hub is capable of managing power enable signals for USB ports. This hub with its I2C interface is used as a kind of ioexpander. Configure routing of signals so that hub is now managing ports power instead of the EC. By allowing the hub to steer PWREN signals, it is now possible to handle FAULT signals directly there without extra EC interactions. During init move the code for enabling power to ports at the time when we are sure GL3590 I2C interface is up and running. BUG=b:169929627 BRANCH=main TEST=Verify that servo_v4p1 has all USB ports working after reset. In general behavior of hub ports in normal conditions should be the same as previously. With usage of gl3590 tool, verify that one can enable/disable power to all 3 available USB ports (two stacked and uServo). Signed-off-by: Jan Dabros <jsd@semihalf.com> Change-Id: I1fc1c6f8718a46984eb486919dfbe463363a2587 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2624472 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'board/servo_v4p1')
-rw-r--r--board/servo_v4p1/board.c11
-rw-r--r--board/servo_v4p1/board.h3
-rw-r--r--board/servo_v4p1/ioexpanders.c63
-rw-r--r--board/servo_v4p1/ioexpanders.h23
-rw-r--r--board/servo_v4p1/pathsel.c23
5 files changed, 106 insertions, 17 deletions
diff --git a/board/servo_v4p1/board.c b/board/servo_v4p1/board.c
index 6e0264d913..448d852844 100644
--- a/board/servo_v4p1/board.c
+++ b/board/servo_v4p1/board.c
@@ -187,7 +187,11 @@ static void dut_pwr_evt(enum gpio_signal signal)
static void init_uservo_port(void)
{
/* Enable USERVO_POWER_EN */
- uservo_power_en(1);
+ if (board_id_det() <= BOARD_ID_REV1)
+ ec_uservo_power_en(1);
+
+ gl3590_enable_ports(0, GL3590_DFP4, 1);
+
/* Connect uservo to host hub */
uservo_fastboot_mux_sel(0);
}
@@ -425,6 +429,9 @@ static void evaluate_input_power_def(void)
gl3590_init(HOST_HUB);
evaluate_input_power();
+
+ init_uservo_port();
+ init_pathsel();
}
#endif
@@ -459,8 +466,6 @@ static void board_init(void)
atmel_reset_l(1);
#ifdef SECTION_IS_RO
- init_uservo_port();
- init_pathsel();
init_ina231s();
init_fusb302b(1);
diff --git a/board/servo_v4p1/board.h b/board/servo_v4p1/board.h
index 8d930fe0d8..98a5fcc6a1 100644
--- a/board/servo_v4p1/board.h
+++ b/board/servo_v4p1/board.h
@@ -225,6 +225,9 @@
/* Add the raw option to the i2c_xfer command */
#define CONFIG_CMD_I2C_XFER_RAW
+
+/* Enable command for managing host hub */
+#define CONFIG_CMD_GL3590
#else
#undef CONFIG_CMD_I2C_XFER
#undef CONFIG_USB_POWER_DELIVERY
diff --git a/board/servo_v4p1/ioexpanders.c b/board/servo_v4p1/ioexpanders.c
index b55c8647a9..323db8dec3 100644
--- a/board/servo_v4p1/ioexpanders.c
+++ b/board/servo_v4p1/ioexpanders.c
@@ -32,15 +32,15 @@ int init_ioexpanders(void)
* BIT-2 (SBU_FLIP_SEL) | O | 1
* BIT-3 (USB3_A0_MUX_SEL) | O | 0
* BIT-4 (USB3_A0_MUX_EN_L) | O | 0
- * BIT-5 (USB3_A0_PWR_EN) | O | 0
+ * BIT-5 (USB3_A0_PWR_EN) | I | x
* BIT-6 (UART_18_SEL) | O | 0
- * BIT-7 (USERVO_POWER_EN) | O | 0
+ * BIT-7 (USERVO_POWER_EN) | I | x
*/
ret = tca6416a_write_byte(1, TCA6416A_OUT_PORT_0, 0x04);
if (ret != EC_SUCCESS)
return ret;
- ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_0, 0x00);
+ ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_0, 0xa0);
if (ret != EC_SUCCESS)
return ret;
@@ -49,7 +49,7 @@ int init_ioexpanders(void)
* NAME | DIR | Initial setting
* -------------------------------------------------------
* BIT-0 (USERVO_FASTBOOT_MUX_SEL) | O | 0
- * BIT-1 (USB3_A1_PWR_EN) | O | 0
+ * BIT-1 (USB3_A1_PWR_EN) | I | x
* BIT-2 (USB3_A1_MUX_SEL) | O | 0
* BIT-3 (BOARD_ID) | I | x
* BIT-4 (BOARD ID) | I | x
@@ -61,7 +61,7 @@ int init_ioexpanders(void)
if (ret != EC_SUCCESS)
return ret;
- ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_1, 0xb8);
+ ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_1, 0xba);
if (ret != EC_SUCCESS)
return ret;
@@ -124,6 +124,13 @@ int init_ioexpanders(void)
if (ret != EC_SUCCESS)
return ret;
+ /*
+ * Now we are able to read board revision, let EC manage USB ports power
+ * for REV0 and REV1 boards.
+ */
+ if (board_id_det() <= BOARD_ID_REV1)
+ ec_manage_usb_pwr();
+
/* Clear any faults and other IRQs*/
read_faults();
read_irqs();
@@ -189,6 +196,34 @@ int irq_ioexpanders(void)
return 0;
}
+int ec_manage_usb_pwr(void)
+{
+ int ret;
+
+ /*
+ * Configure USB3_A0_PWR_EN & USERVO_POWER_EN as outputs with initial
+ * value 0.
+ */
+ ret = tca6416a_write_byte(1, TCA6416A_OUT_PORT_0, 0x04);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_0, 0x0);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ /* Configure USB3_A1_PWR_EN as output with initial value 0. */
+ ret = tca6416a_write_byte(1, TCA6416A_OUT_PORT_1, 0x0);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_1, 0xb8);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ return ret;
+}
+
inline int sbu_uart_sel(int en)
{
return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 0, en);
@@ -214,7 +249,11 @@ inline int usb3_a0_mux_en_l(int en)
return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 4, en);
}
-inline int usb3_a0_pwr_en(int en)
+/*
+ * Warning: This method works only on REV0 & REV1 revisions! For REV2 host hub
+ * manages power to USB ports.
+ */
+inline int ec_usb3_a0_pwr_en(int en)
{
return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 5, en);
}
@@ -224,7 +263,11 @@ inline int uart_18_sel(int en)
return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 6, en);
}
-inline int uservo_power_en(int en)
+/*
+ * Warning: This method works only on REV0 & REV1 revisions! For REV2 host hub
+ * manages power to USB ports.
+ */
+inline int ec_uservo_power_en(int en)
{
return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 7, en);
}
@@ -234,7 +277,11 @@ inline int uservo_fastboot_mux_sel(enum uservo_fastboot_mux_sel_t sel)
return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 0, sel);
}
-inline int usb3_a1_pwr_en(int en)
+/*
+ * Warning: This method works only on REV0 & REV1 revisions! For REV2 host hub
+ * manages power to USB ports.
+ */
+inline int ec_usb3_a1_pwr_en(int en)
{
return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 1, en);
}
diff --git a/board/servo_v4p1/ioexpanders.h b/board/servo_v4p1/ioexpanders.h
index b6aded8654..12f692b9fa 100644
--- a/board/servo_v4p1/ioexpanders.h
+++ b/board/servo_v4p1/ioexpanders.h
@@ -23,6 +23,15 @@ int init_ioexpanders(void);
int irq_ioexpanders(void);
/**
+ * Reconfigure ioexpanders to allow EC manage USB ports power
+ *
+ * In the never servo_v4p1 designs host hub manages USB ports PWREN signals by
+ * default, however electrical design is flexible and allow to return to old
+ * behaviour.
+ */
+int ec_manage_usb_pwr(void);
+
+/**
* SBU Crosspoint select
*
* @param en 0 - HOST SBU to DUT SBU connected
@@ -68,13 +77,15 @@ int usb3_a0_mux_sel(int en);
int usb3_a0_mux_en_l(int en);
/**
- * Controls load switches for 5V to general USB type A
+ * Controls load switches for 5V to general USB type A.
+ * Warning: This method works only on REVO & REV1 revisions! For REV2 host hub
+ * manages power to USB ports.
*
* @param en 0 - Disable power
* 1 - Enable power
* @return EC_SUCCESS or EC_xxx on error
*/
-int usb3_a0_pwr_en(int en);
+int ec_usb3_a0_pwr_en(int en);
/**
* Controls logic to select 1.8V or 3.3V UART from STM to DUT on SBU lines
@@ -87,12 +98,14 @@ int uart_18_sel(int en);
/**
* Controls load switches for 5V to uservo USB type A port
+ * Warning: This method works only on REVO & REV1 revisions! For REV2 host hub
+ * manages power to USB ports.
*
* @param en 0 - Disable power
* 1 - Enable power
* @return EC_SUCCESS or EC_xxx on error
*/
-int uservo_power_en(int en);
+int ec_uservo_power_en(int en);
/**
* USB data path enable from host hub to downstream userv or DUT peripheral
@@ -105,12 +118,14 @@ int uservo_fastboot_mux_sel(enum uservo_fastboot_mux_sel_t sel);
/**
* Controls load switches for 5V to general USB type A second port
+ * Warning: This method works only on REVO & REV1 revisions! For REV2 host hub
+ * manages power to USB ports.
*
* @param en 0 - power off
* 1 - power enabled
* @return EC_SUCCESS or EC_xxx on error
*/
-int usb3_a1_pwr_en(int en);
+int ec_usb3_a1_pwr_en(int en);
/**
* USB data path for general USB type A port, second on J2
diff --git a/board/servo_v4p1/pathsel.c b/board/servo_v4p1/pathsel.c
index 5121d69ac6..ee9f61eb51 100644
--- a/board/servo_v4p1/pathsel.c
+++ b/board/servo_v4p1/pathsel.c
@@ -3,25 +3,44 @@
* found in the LICENSE file.
*/
+#include "gl3590.h"
#include "gpio.h"
#include "ioexpanders.h"
#include "pathsel.h"
+static void hh_usb3_a0_pwr_en(int en)
+{
+ gl3590_enable_ports(0, GL3590_DFP2, en);
+}
+
+static void hh_usb3_a1_pwr_en(int en)
+{
+ gl3590_enable_ports(0, GL3590_DFP1, en);
+}
+
void init_pathsel(void)
{
/* Connect TypeA port to DUT hub */
usb3_a0_to_dut();
/* Connect data lines */
usb3_a0_mux_en_l(0);
+
/* Enable power */
- usb3_a0_pwr_en(1);
+ if (board_id_det() <= BOARD_ID_REV1)
+ ec_usb3_a0_pwr_en(1);
+
+ hh_usb3_a0_pwr_en(1);
/* Connect TypeA port to DUT hub */
usb3_a1_to_dut();
/* Connect data lines */
gpio_set_level(GPIO_USB3_A1_MUX_EN_L, 0);
+
/* Enable power */
- usb3_a1_pwr_en(1);
+ if (board_id_det() <= BOARD_ID_REV1)
+ ec_usb3_a1_pwr_en(1);
+
+ hh_usb3_a1_pwr_en(1);
}
void usb3_a0_to_dut(void)