From d7bf71b42b78fa09da12f764bd3571d0cc446765 Mon Sep 17 00:00:00 2001 From: Scott Collyer Date: Wed, 4 Nov 2020 16:39:19 -0800 Subject: honeybuns: Enable usbc support This CL adds boards specific parts required to enable TCPMv2.0 for both quiche and gingerbread. TCPMv2 configs are included, though, only type-c support is being selected. The reason for this intermediate point is an attempt to have more manageable amounts of changes for CL reviews. BUG=b:167601672 BRANCH=None TEST=verfied type-c attaches properly on quiche Signed-off-by: Scott Collyer Change-Id: I2a4c3bf4089fb3e167d06921b177d8c4e61a021f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2215424 Tested-by: Scott Collyer Commit-Queue: Scott Collyer Reviewed-by: Diana Z Auto-Submit: Scott Collyer --- baseboard/honeybuns/baseboard.h | 50 ++++++++++++++++++++- baseboard/honeybuns/build.mk | 1 + baseboard/honeybuns/usb_pd_policy.c | 73 ++++++++++++++++++++++++++++++ board/gingerbread/board.c | 68 ++++++++++++++++++++++++++++ board/gingerbread/board.h | 12 ++--- board/gingerbread/gpio.inc | 2 + board/quiche/board.c | 89 ++++++++++++++++++++++++++++++++++++- board/quiche/board.h | 5 +++ board/quiche/ec.tasklist | 3 +- board/quiche/gpio.inc | 15 ++++++- 10 files changed, 305 insertions(+), 13 deletions(-) create mode 100644 baseboard/honeybuns/usb_pd_policy.c diff --git a/baseboard/honeybuns/baseboard.h b/baseboard/honeybuns/baseboard.h index 4e2af658c5..a5c64b7402 100644 --- a/baseboard/honeybuns/baseboard.h +++ b/baseboard/honeybuns/baseboard.h @@ -42,6 +42,47 @@ /* USB Type C and USB PD defines */ +#define CONFIG_USB_POWER_DELIVERY +#define CONFIG_USB_PD_TCPMV2 +#define CONFIG_USB_DRP_ACC_TRYSRC +/* No AP on any honeybuns variants */ +#undef CONFIG_USB_PD_HOST_CMD + +/* TODO(b/167711550): Temporarily support type-c mode only */ +#undef CONFIG_USB_PRL_SM +#undef CONFIG_USB_PE_SM + +#define CONFIG_USB_PD_DUAL_ROLE +#define CONFIG_USB_PD_PORT_MAX_COUNT 1 +#define CONFIG_USB_PD_TCPM_MUX +#define CONFIG_USB_PD_TCPM_STM32GX +#define CONFIG_USB_PD_TCPM_TCPCI +#define CONFIG_USB_PD_DECODE_SOP +#define CONFIG_USB_PID 0x5048 + +#define CONFIG_USB_PD_VBUS_DETECT_PPC +#define CONFIG_USB_PD_DISCHARGE_PPC +#define CONFIG_USBC_PPC_SN5S330 +#define CONFIG_USBC_PPC_VCONN +#define CONFIG_USBC_PPC_DEDICATED_INT +#define CONFIG_CMD_PPC_DUMP + +/* TODO(b/167711550): Temporary, will be replaced by correct mux config */ +#define CONFIG_USBC_SS_MUX +#define CONFIG_USB_MUX_VIRTUAL + + +/* Define typical operating power and max power. */ +#define PD_MAX_VOLTAGE_MV 20000 +#define PD_MAX_CURRENT_MA 3000 +#define PD_MAX_POWER_MW 45000 +#define PD_OPERATING_POWER_MW 15000 + +/* TODO(b:147314141): Verify these timings */ +#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ +#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */ +#define PD_VCONN_SWAP_DELAY 5000 /* us */ + /* BC 1.2 */ @@ -52,7 +93,6 @@ #define I2C_PORT_MST 1 #define I2C_PORT_EEPROM 2 - /* * Macros for GPIO signals used in common code that don't match the * schematic names. Signal names in gpio.inc match the schematic and are @@ -73,6 +113,14 @@ struct power_seq { unsigned int delay_ms; /* delay (in msec) after setting gpio_signal */ }; +/* + * This is required as adc_channel is included in adc.h which ends up being + * included when TCPMv2 functions are included + */ +enum adc_channel { + ADC_CH_COUNT +}; + extern const struct power_seq board_power_seq[]; extern const size_t board_power_seq_count; diff --git a/baseboard/honeybuns/build.mk b/baseboard/honeybuns/build.mk index 2a572df114..ca13fcff46 100644 --- a/baseboard/honeybuns/build.mk +++ b/baseboard/honeybuns/build.mk @@ -7,3 +7,4 @@ # baseboard-y=baseboard.o +baseboard-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o diff --git a/baseboard/honeybuns/usb_pd_policy.c b/baseboard/honeybuns/usb_pd_policy.c new file mode 100644 index 0000000000..0bf90995de --- /dev/null +++ b/baseboard/honeybuns/usb_pd_policy.c @@ -0,0 +1,73 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "console.h" +#include "driver/tcpm/tcpci.h" +#include "usb_pd.h" +#include "usbc_ppc.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +/* + * TODO(b/167711550): These 4 functions need to be implemented for honeybuns + * and are required to build with TCPMv2 enabled. Currently, they only allow the + * build to work. They will be implemented in a subsequent CL. + */ + +int pd_check_vconn_swap(int port) +{ + /*TODO: Dock is the Vconn source */ + return 1; +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + prev_en = ppc_is_sourcing_vbus(port); + + /* Disable VBUS. */ + ppc_vbus_source_enable(port, 0); + + /* Enable discharge if we were previously sourcing 5V */ + if (prev_en) + pd_set_vbus_discharge(port, 1); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + /* + * Default operation of buck-boost is 5v/3.6A. + * Turn on the PPC Provide Vbus. + */ + rv = ppc_vbus_source_enable(port, 1); + if (rv) + return rv; + + return EC_SUCCESS; +} + +int pd_snk_is_vbus_provided(int port) +{ + return ppc_is_vbus_present(port); +} + +int board_vbus_source_enabled(int port) +{ + return ppc_is_sourcing_vbus(port); +} + +void pd_set_input_current_limit(int port, uint32_t max_ma, + uint32_t supply_voltage) +{ + +} diff --git a/board/gingerbread/board.c b/board/gingerbread/board.c index 00e7eedc2e..2832f30528 100644 --- a/board/gingerbread/board.c +++ b/board/gingerbread/board.c @@ -6,14 +6,35 @@ /* Gingerbread board-specific configuration */ #include "common.h" +#include "driver/ppc/sn5s330.h" +#include "driver/tcpm/stm32gx.h" +#include "driver/tcpm/tcpci.h" #include "gpio.h" #include "hooks.h" #include "switch.h" #include "system.h" #include "task.h" #include "uart.h" +#include "usb_pd.h" +#include "usbc_ppc.h" #include "util.h" + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) + +static void ppc_interrupt(enum gpio_signal signal) +{ + switch (signal) { + case GPIO_HOST_USBC_PPC_INT_ODL: + sn5s330_interrupt(USB_PD_PORT_HOST); + break; + + default: + break; + } +} + #include "gpio_list.h" /* Must come after other header files. */ /* @@ -49,8 +70,55 @@ const struct power_seq board_power_seq[] = { const size_t board_power_seq_count = ARRAY_SIZE(board_power_seq); + +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + .drv = &stm32gx_tcpm_drv, + }, +}; + +const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + [USB_PD_PORT_HOST] = { + .usb_port = USB_PD_PORT_HOST, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + }, +}; + +/* USB-C PPC Configuration */ +struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { + [USB_PD_PORT_HOST] = { + .i2c_port = 2, + .i2c_addr_flags = SN5S330_ADDR0_FLAGS, + .drv = &sn5s330_drv + }, +}; +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +/* Power Delivery and charging functions */ +void board_tcpc_init(void) +{ + /* Enable PPC interrupts. */ + gpio_enable_interrupt(GPIO_HOST_USBC_PPC_INT_ODL); +} +DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1); + static void board_init(void) { /* TODO */ } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +int ppc_get_alert_status(int port) +{ + if (port == USB_PD_PORT_HOST) + return gpio_get_level(GPIO_HOST_USBC_PPC_INT_ODL) == 0; + + return 0; +} + +void board_overcurrent_event(int port, int is_overcurrented) +{ + /* TODO: b/ - check correct operation for honeybuns */ +} diff --git a/board/gingerbread/board.h b/board/gingerbread/board.h index c3052f3f59..ccabbcf579 100644 --- a/board/gingerbread/board.h +++ b/board/gingerbread/board.h @@ -17,20 +17,16 @@ #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 -/* Keyboard features */ - -/* Sensors */ - /* USB Type C and USB PD defines */ +#define USB_PD_PORT_HOST 0 +#define USB_PD_PORT_DP 1 +#define CONFIG_USB_PD_PORT_MAX_COUNT 1 + /* USB Type A Features */ /* BC 1.2 */ -/* Volume Button feature */ - -/* Fan features */ - /* * Macros for GPIO signals used in common code that don't match the * schematic names. Signal names in gpio.inc match the schematic and are diff --git a/board/gingerbread/gpio.inc b/board/gingerbread/gpio.inc index 052124289c..77a3e52ced 100644 --- a/board/gingerbread/gpio.inc +++ b/board/gingerbread/gpio.inc @@ -8,6 +8,8 @@ /* Declare symbolic names for all the GPIOs that we care about. * Note: Those with interrupt handlers must be declared first. */ +GPIO_INT(HOST_USBC_PPC_INT_ODL, PIN(B, 0), GPIO_INT_FALLING, ppc_interrupt) + /* Power sequencing interrupts */ GPIO(PWR_BTN, PIN(A, 0), GPIO_INPUT) GPIO(EN_AC_JACK, PIN(A, 1), GPIO_OUT_LOW) diff --git a/board/quiche/board.c b/board/quiche/board.c index 46a19f4b5e..afcd9b1443 100644 --- a/board/quiche/board.c +++ b/board/quiche/board.c @@ -5,8 +5,35 @@ /* Quiche board-specific configuration */ +#include "common.h" +#include "driver/ppc/sn5s330.h" +#include "driver/tcpm/ps8xxx.h" +#include "driver/tcpm/stm32gx.h" +#include "driver/tcpm/tcpci.h" +#include "gpio.h" #include "hooks.h" #include "switch.h" +#include "system.h" +#include "task.h" +#include "uart.h" +#include "usb_pd.h" +#include "usbc_ppc.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) + +static void ppc_interrupt(enum gpio_signal signal) +{ + switch (signal) { + case GPIO_HOST_USBC_PPC_INT_ODL: + sn5s330_interrupt(USB_PD_PORT_HOST); + break; + + default: + break; + } +} #include "gpio_list.h" /* Must come after other header files. */ @@ -42,8 +69,68 @@ const struct power_seq board_power_seq[] = { const size_t board_power_seq_count = ARRAY_SIZE(board_power_seq); +/* TCPCs */ +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + .drv = &stm32gx_tcpm_drv, + }, +}; + +const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + [USB_PD_PORT_HOST] = { + .usb_port = USB_PD_PORT_HOST, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + }, +}; + +/* USB-C PPC Configuration */ +struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { + [USB_PD_PORT_HOST] = { + .i2c_port = I2C_PORT_USBC, + .i2c_addr_flags = SN5S330_ADDR0_FLAGS, + .drv = &sn5s330_drv + }, +}; +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +/* Power Delivery and charging functions */ +void board_tcpc_init(void) +{ + /* Enable PPC interrupts. */ + gpio_enable_interrupt(GPIO_HOST_USBC_PPC_INT_ODL); +} +DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1); + +static void board_select_drp_mode(void) +{ + /* + * Host port should operate as a dual role port. If it attaches as a + * sink, then it will trigger a PRS to end up as a SRC UFP. The port's + * DRP state only needs to be set once, after it's initialized in TCPMv2 + * as the default role of sink only. + */ + pd_set_dual_role(USB_PD_PORT_HOST, PD_DRP_TOGGLE_ON); + CPRINTS("ucpd: set drp toggle on"); +} +DECLARE_DEFERRED(board_select_drp_mode); + static void board_init(void) { - /* TODO */ + hook_call_deferred(&board_select_drp_mode_data, 50 * MSEC); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +int ppc_get_alert_status(int port) +{ + if (port == USB_PD_PORT_HOST) + return gpio_get_level(GPIO_HOST_USBC_PPC_INT_ODL) == 0; + + return 0; +} + +void board_overcurrent_event(int port, int is_overcurrented) +{ + /* TODO(b/174825406): check correct operation for honeybuns */ +} diff --git a/board/quiche/board.h b/board/quiche/board.h index 48422e7a50..d5eb046424 100644 --- a/board/quiche/board.h +++ b/board/quiche/board.h @@ -15,6 +15,8 @@ #define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands while in dev. */ /* USB Type C and USB PD defines */ +#define USB_PD_PORT_HOST 0 +#define USB_PD_PORT_DP 1 /* USB Type A Features */ @@ -25,6 +27,9 @@ #include "registers.h" +#define GPIO_TRIGGER_1 GPIO_USB3_A3_CDP_EN +#define GPIO_TRIGGER_2 GPIO_USB3_A4_CDP_EN + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/quiche/ec.tasklist b/board/quiche/ec.tasklist index c272906fc7..fb51fe2088 100644 --- a/board/quiche/ec.tasklist +++ b/board/quiche/ec.tasklist @@ -9,4 +9,5 @@ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \ - TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) + TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) diff --git a/board/quiche/gpio.inc b/board/quiche/gpio.inc index e6264c741e..1b90bf9e1e 100644 --- a/board/quiche/gpio.inc +++ b/board/quiche/gpio.inc @@ -8,6 +8,8 @@ /* Declare symbolic names for all the GPIOs that we care about. * Note: Those with interrupt handlers must be declared first. */ +GPIO_INT(HOST_USBC_PPC_INT_ODL, PIN(D, 9), GPIO_INT_FALLING | GPIO_PULL_UP, ppc_interrupt) + /* Power sequencing signals */ GPIO(PWR_BTN, PIN(A, 0), GPIO_INPUT) GPIO(EN_AC_JACK, PIN(A, 1), GPIO_OUT_LOW) @@ -38,8 +40,17 @@ GPIO(USBC_DP_PD_RST_L, PIN(E, 9), GPIO_ODR_LOW) GPIO(USBC_UF_RESET_L, PIN(D, 2), GPIO_ODR_LOW) /* USB Hubs signals */ -GPIO(EC_HUB2_RESET_L, PIN(C, 5), GPIO_ODR_LOW) -GPIO(EC_HUB3_RESET_L, PIN(C, 10), GPIO_ODR_LOW) +GPIO(EC_HUB2_RESET_L, PIN(C, 5), GPIO_ODR_HIGH) +GPIO(EC_HUB3_RESET_L, PIN(C, 10), GPIO_ODR_HIGH) + +/* USB-A Current limit switches, set default to 1.5A */ + +GPIO(USB3_A1_CDP_EN, PIN(C, 3), GPIO_OUT_LOW) +GPIO(USB3_A2_CDP_EN, PIN(C, 2), GPIO_OUT_LOW) +GPIO(USB3_A3_CDP_EN, PIN(C, 0), GPIO_OUT_LOW) +GPIO(USB3_A4_CDP_EN, PIN(C, 1), GPIO_OUT_LOW) +GPIO(USB3_A5_CDP_EN, PIN(B, 9), GPIO_OUT_LOW) +GPIO(USB3_A6_CDP_EN, PIN(C, 13), GPIO_OUT_LOW) /* Write protect */ GPIO(EC_FLASH_WP_ODL, PIN(A, 3), GPIO_ODR_HIGH) -- cgit v1.2.1