From b149d72f08edb528914d17d36435500cf497e792 Mon Sep 17 00:00:00 2001 From: Caveh Jalali Date: Mon, 13 Jan 2020 20:10:35 -0800 Subject: volteer: add USB3 daughterboard support The USB3 daughterboard uses a ps8815 TCPC. If the CBI FW_CONFIG tag indicates that such a daughterboard is present, set up the ps8815 as the 2nd TCPC in the system. BRANCH=none BUG=b:144397088 TEST=in combination with additional patches, was able to update TCPC firmware Change-Id: I50ee57f5aa2efa0b6dbc562f968587f4fe03236c Signed-off-by: Caveh Jalali Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2013656 Reviewed-by: Jett Rink Reviewed-by: Keith Short --- baseboard/volteer/baseboard.c | 82 +++++++++++++++++++++++++++++++++++++++---- baseboard/volteer/baseboard.h | 3 ++ board/volteer/gpio.inc | 4 +-- driver/tcpm/ps8xxx.h | 16 +++++++++ 4 files changed, 97 insertions(+), 8 deletions(-) diff --git a/baseboard/volteer/baseboard.c b/baseboard/volteer/baseboard.c index f8bba377b6..5206ba9cc3 100644 --- a/baseboard/volteer/baseboard.c +++ b/baseboard/volteer/baseboard.c @@ -12,6 +12,7 @@ #include "driver/bc12/pi3usb9201.h" #include "driver/ppc/sn5s330.h" #include "driver/ppc/syv682x.h" +#include "driver/tcpm/ps8xxx.h" #include "driver/tcpm/tusb422.h" #include "driver/temp_sensor/thermistor.h" #include "fan.h" @@ -22,6 +23,7 @@ #include "keyboard_scan.h" #include "pwm.h" #include "pwm_chip.h" +#include "system.h" #include "task.h" #include "temp_sensor.h" #include "usbc_ppc.h" @@ -329,7 +331,7 @@ BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT); /******************************************************************************/ /* USBC TCPC configuration */ -const struct tcpc_config_t tcpc_config[] = { +struct tcpc_config_t tcpc_config[] = { [USBC_PORT_C0] = { .bus_type = EC_BUS_TYPE_I2C, .i2c_info = { @@ -352,6 +354,20 @@ const struct tcpc_config_t tcpc_config[] = { BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT); BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT); +/* USBC TCPC configuration for port 1 on USB3 board */ +static const struct tcpc_config_t tcpc_config_p1_usb3 = { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1, + .addr_flags = PS8751_I2C_ADDR1_FLAGS, + }, + .flags = TCPC_FLAGS_TCPCI_V2_0, + .drv = &ps8xxx_tcpm_drv, + .usb23 = USBC_PORT_1_USB2_NUM | (USBC_PORT_1_USB3_NUM << 4), +}; + +static enum usb_db_id usb_db_type = USB_DB_NONE; + /******************************************************************************/ /* USBC PPC configuration */ struct ppc_config_t ppc_chips[] = { @@ -410,6 +426,10 @@ BUILD_ASSERT(ARRAY_SIZE(usb_retimers) == USBC_PORT_COUNT); static void baseboard_tcpc_init(void) { + /* Only reset TCPC if not sysjump */ + if (!system_jumped_to_this_image()) + board_reset_pd_mcu(); + /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL); @@ -422,7 +442,7 @@ static void baseboard_tcpc_init(void) gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL); gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_ODL); } -DECLARE_HOOK(HOOK_INIT, baseboard_tcpc_init, HOOK_PRIO_INIT_I2C + 1); +DECLARE_HOOK(HOOK_INIT, baseboard_tcpc_init, HOOK_PRIO_INIT_CHIPSET); /******************************************************************************/ /* PPC support routines */ @@ -440,9 +460,42 @@ void ppc_interrupt(enum gpio_signal signal) /******************************************************************************/ /* TCPC support routines */ +static void ps8815_reset(void) +{ + int val; + + gpio_set_level(GPIO_USB_C1_RT_RST_ODL, 0); + msleep(GENERIC_MAX(PS8XXX_RESET_DELAY_MS, + PS8815_PWR_H_RST_H_DELAY_MS)); + gpio_set_level(GPIO_USB_C1_RT_RST_ODL, 1); + msleep(PS8815_FW_INIT_DELAY_MS); + + /* + * b/144397088 + * ps8815 firmware 0x01 needs special configuration + */ + + CPRINTS("%s: patching ps8815 registers", __func__); + + if (i2c_read8(I2C_PORT_USB_C1, + PS8751_I2C_ADDR1_P2_FLAGS, 0x0f, &val) == EC_SUCCESS) + CPRINTS("ps8815: reg 0x0f was %02x", val); + + if (i2c_write8(I2C_PORT_USB_C1, + PS8751_I2C_ADDR1_P2_FLAGS, 0x0f, 0x31) == EC_SUCCESS) + CPRINTS("ps8815: reg 0x0f set to 0x31"); + + if (i2c_read8(I2C_PORT_USB_C1, + PS8751_I2C_ADDR1_P2_FLAGS, 0x0f, &val) == EC_SUCCESS) + CPRINTS("ps8815: reg 0x0f now %02x", val); +} + void board_reset_pd_mcu(void) { /* No reset available for TCPC on port 0 */ + /* Daughterboard specific reset for port 1 */ + if (usb_db_type == USB_DB_USB3) + ps8815_reset(); } uint16_t tcpc_get_alert_status(void) @@ -586,8 +639,21 @@ static void baseboard_init(void) } DECLARE_HOOK(HOOK_INIT, baseboard_init, HOOK_PRIO_DEFAULT); +/* + * Set up support for the USB3 daughterboard: + * Parade PS8815 TCPC (integrated retimer) + * Diodes PI3USB9201 BC 1.2 chip (same as USB4 board) + * Silergy SYV682A PPC (same as USB4 board) + */ +static void config_db_usb3(void) +{ + tcpc_config[USBC_PORT_C1] = tcpc_config_p1_usb3; + /* USB-C port 1 has an integrated retimer */ + memset(&usb_retimers[USBC_PORT_C1], 0, + sizeof(usb_retimers[USBC_PORT_C1])); +} + static uint8_t board_id; -static enum usb_db_id usb_db_type = USB_DB_NONE; uint8_t get_board_id(void) { @@ -609,8 +675,8 @@ static void cbi_init(void) if (cbi_get_board_version(&cbi_val) != EC_SUCCESS || cbi_val > UINT8_MAX) CPRINTS("CBI: Read Board ID failed"); - - board_id = cbi_val; + else + board_id = cbi_val; CPRINTS("Board ID: %d", board_id); @@ -630,10 +696,14 @@ static void cbi_init(void) case USB_DB_USB4: CPRINTS("Daughterboard type: USB4"); break; + case USB_DB_USB3: + config_db_usb3(); + CPRINTS("Daughterboard type: USB3"); + break; default: CPRINTS("Daughterboard ID %d not supported", usb_db_val); usb_db_val = USB_DB_NONE; } usb_db_type = usb_db_val; } -DECLARE_HOOK(HOOK_INIT, cbi_init, HOOK_PRIO_INIT_I2C + 1); +DECLARE_HOOK(HOOK_INIT, cbi_init, HOOK_PRIO_FIRST); diff --git a/baseboard/volteer/baseboard.h b/baseboard/volteer/baseboard.h index 5e30e60e86..6930edeca5 100644 --- a/baseboard/volteer/baseboard.h +++ b/baseboard/volteer/baseboard.h @@ -159,10 +159,13 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_MAX_COUNT 2 +#define CONFIG_USB_PD_TCPC_RUNTIME_CONFIG /* TODO: b/145250123: Enabling low-power mode breaks USB SNK detection */ #undef CONFIG_USB_PD_TCPC_LOW_POWER #define CONFIG_USB_PD_TCPM_TCPCI #define CONFIG_USB_PD_TCPM_TUSB422 /* USBC port C0 */ +#define CONFIG_USB_PD_TCPM_PS8815 /* USBC port USB3 DB */ +#define CONFIG_USB_PD_TCPM_MUX #define CONFIG_CMD_PD_CONTROL /* Needed for TCPC FW update */ #define CONFIG_USB_PD_TRY_SRC diff --git a/board/volteer/gpio.inc b/board/volteer/gpio.inc index a2c47951ce..d4cbfcaa47 100644 --- a/board/volteer/gpio.inc +++ b/board/volteer/gpio.inc @@ -95,8 +95,8 @@ GPIO(EC_PCH_INT_ODL, PIN(D, 6), GPIO_ODR_HIGH) /* TODO - b/140557015 - /* USB and USBC Signals */ -/* TODO - b/145560203 route USB_C1_RT_RST_ODL to EC */ -UNIMPLEMENTED(USB_C1_RT_RST_ODL) +/* TODO(b/148243971): update PIN for next build */ +GPIO(USB_C1_RT_RST_ODL, PIN(3, 2), GPIO_ODR_LOW) /* USB_C1 Reset */ /* Don't have a load switch for retimer */ UNIMPLEMENTED(USB_C1_LS_EN) /* Retimer Force Power enable is connected to AP */ diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h index 08399aba2d..ff78a74041 100644 --- a/driver/tcpm/ps8xxx.h +++ b/driver/tcpm/ps8xxx.h @@ -10,6 +10,7 @@ /* I2C interface */ #define PS8751_I2C_ADDR1_P1_FLAGS 0x09 +#define PS8751_I2C_ADDR1_P2_FLAGS 0x0a #define PS8751_I2C_ADDR1_FLAGS 0x0B #define PS8751_I2C_ADDR2_FLAGS 0x1B #define PS8751_I2C_ADDR3_FLAGS 0x2B @@ -21,6 +22,21 @@ /* Delay between releasing reset and the first I2C read */ #define PS8805_FW_INIT_DELAY_MS 10 +/* Delay from power on to reset de-asserted */ +#define PS8815_PWR_H_RST_H_DELAY_MS 20 +/* + * Delay between releasing reset and the first I2C read + * + * If the delay is too short, I2C fails. + * If the delay is marginal I2C reads return garbage. + * + * With firmware 0x03: + * 10ms is too short + * 20ms is marginal + * 25ms is OK + */ +#define PS8815_FW_INIT_DELAY_MS 40 + #define PS8751_BIST_TIMER_FREQ 15000000 #define PS8751_BIST_DELAY_MS 50 -- cgit v1.2.1