From 46b79b2f8c93db90cc0ecf5b7c555f05966afd01 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Wed, 29 Nov 2023 11:49:32 -0700 Subject: [PATCH 1/4] include/device: Add missing headers to usbc_mux.h Add the headers for using bool and uint8_t. Change-Id: Ie1a2a482145a7ca02fb306e385538894807a6ad6 Signed-off-by: Tim Crawford --- src/include/device/usbc_mux.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/device/usbc_mux.h b/src/include/device/usbc_mux.h index cf109b7fe8..814e82509f 100644 --- a/src/include/device/usbc_mux.h +++ b/src/include/device/usbc_mux.h @@ -3,6 +3,9 @@ #ifndef __USBC_MUX_H__ #define __USBC_MUX_H__ +#include +#include + /* struct to hold all USB-C mux related variables */ struct usbc_mux_info { bool dp; /* DP connected */ From e42d01544e4d2c10d5d7cac8799d4a12e9989581 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Wed, 29 Nov 2023 12:06:59 -0700 Subject: [PATCH 2/4] [WIP] ec/system76/ec: Implement usbc_get_ops Change-Id: Icee0661ec0d0c949b73503e639dd8a461c05235a Signed-off-by: Tim Crawford --- src/ec/system76/ec/Makefile.mk | 1 + src/ec/system76/ec/usbc_mux.c | 99 ++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/ec/system76/ec/usbc_mux.c diff --git a/src/ec/system76/ec/Makefile.mk b/src/ec/system76/ec/Makefile.mk index 02fcda537c..2f5496bec4 100644 --- a/src/ec/system76/ec/Makefile.mk +++ b/src/ec/system76/ec/Makefile.mk @@ -5,6 +5,7 @@ all-y += system76_ec.c ramstage-y += smbios.c ramstage-$(CONFIG_EC_SYSTEM76_EC_LOCKDOWN) += lockdown.c +ramstage-y += usbc_mux.c smm-$(CONFIG_DEBUG_SMI) += system76_ec.c diff --git a/src/ec/system76/ec/usbc_mux.c b/src/ec/system76/ec/usbc_mux.c new file mode 100644 index 0000000000..3cfc5d1061 --- /dev/null +++ b/src/ec/system76/ec/usbc_mux.c @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "system76_ec.h" +#include +#include +#include +#include + +#define CMD_USBC_MUX_INFO 23 + +enum usbc_mux_flags { + USBC_MUX_DP = BIT(0), + USBC_MUX_USB = BIT(1), + USBC_MUX_CABLE = BIT(2), + USBC_MUX_POLARITY = BIT(3), + USBC_MUX_HPD_LVL = BIT(4), + USBC_MUX_HPD_IRQ = BIT(5), + USBC_MUX_UFP = BIT(6), + USBC_MUX_DBG_ACC = BIT(7), +}; + +static int system76_ec_get_mux_info(int port, struct usbc_mux_info *info) +{ + uint8_t request[1] = { port }; + uint8_t reply[3] = { 0 }; + uint8_t flags; + uint8_t pin_mode; + bool res; + + if (!info) + return -1; + + res = system76_ec_cmd(CMD_USBC_MUX_INFO, request, ARRAY_SIZE(request), + reply, ARRAY_SIZE(reply)); + if (!res) + return -1; + + flags = reply[1]; + pin_mode = reply[2]; + + info->dp = !!(flags & USBC_MUX_DP); + info->usb = !!(flags & USBC_MUX_USB); + info->cable = !!(flags & USBC_MUX_CABLE); + info->polarity = !!(flags & USBC_MUX_POLARITY); + info->hpd_lvl = !!(flags & USBC_MUX_HPD_LVL); + info->hpd_irq = !!(flags & USBC_MUX_HPD_IRQ); + info->ufp = !!(flags & USBC_MUX_UFP); + info->dbg_acc = !!(flags & USBC_MUX_DBG_ACC); + info->dp_pin_mode = pin_mode; + + printk(BIOS_SPEW, "%s: dp=%u, usb=%u\n", __func__, info->dp, info->usb); + printk(BIOS_SPEW, "%s: cable=%u, polarity=%u\n", __func__, info->cable, info->polarity); + printk(BIOS_SPEW, "%s: hpd_lvl=%u, hpd_irq=%u\n", __func__, info->hpd_lvl, info->hpd_irq); + printk(BIOS_SPEW, "%s: ufp=%u, dbg_acc=%u\n", __func__, info->ufp, info->dbg_acc); + printk(BIOS_SPEW, "%s: pin_mode=0x%x\n", __func__, info->dp_pin_mode); + + return 0; +} + +static int system76_ec_wait_for_connection(long timeout_ms) +{ + // TODO + return 0; +} + +static int system76_ec_enter_dp_mode(int port) +{ + // TODO + return -1; +} + +static int system76_ec_wait_for_dp_mode_entry(int port, long timeout_ms) +{ + // TODO + return -1; +} + +static int system76_ec_wait_for_hpd(int port, long timeout_ms) +{ + // TODO + return -1; +} + +static const struct usbc_ops system76_ec_usbc_ops = { + .mux_ops = { + .get_mux_info = system76_ec_get_mux_info, + }, + .dp_ops = { + .wait_for_connection = system76_ec_wait_for_connection, + .enter_dp_mode = system76_ec_enter_dp_mode, + .wait_for_dp_mode_entry = system76_ec_wait_for_dp_mode_entry, + .wait_for_hpd = system76_ec_wait_for_hpd, + }, +}; + +const struct usbc_ops *usbc_get_ops(void) +{ + return &system76_ec_usbc_ops; +} From e0b3e3208a1d9f1675ba3f4d565dfd2783af9663 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Wed, 29 Nov 2023 12:08:10 -0700 Subject: [PATCH 3/4] mb/system76/adl,rpl: Enable TCSS USB/Display detection Change-Id: I9d06c1e4e84655cb78175a7b011bbca2e01403a9 Signed-off-by: Tim Crawford --- src/mainboard/system76/adl/Kconfig | 2 ++ src/mainboard/system76/rpl/Kconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/mainboard/system76/adl/Kconfig b/src/mainboard/system76/adl/Kconfig index 1bb3fd2304..d760b4ce76 100644 --- a/src/mainboard/system76/adl/Kconfig +++ b/src/mainboard/system76/adl/Kconfig @@ -11,6 +11,8 @@ config BOARD_SYSTEM76_ADL_COMMON select DRIVERS_INTEL_USB4_RETIMER select EC_SYSTEM76_EC select EC_SYSTEM76_EC_LOCKDOWN + select ENABLE_TCSS_DISPLAY_DETECTION + select ENABLE_TCSS_USB_DETECTION select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index d5683dd987..285ffce52f 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -9,6 +9,8 @@ config BOARD_SYSTEM76_RPL_COMMON select DRIVERS_I2C_HID select EC_SYSTEM76_EC select EC_SYSTEM76_EC_LOCKDOWN + select ENABLE_TCSS_DISPLAY_DETECTION + select ENABLE_TCSS_USB_DETECTION select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT From 6ad24ae0361eac13e403c53be5e4e32bb1452a02 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 14 Dec 2023 12:49:02 -0700 Subject: [PATCH 4/4] [WIP] ec/system76/ec: Implement USB-C DP HPD Change-Id: I0487b761a5a83b0a1897c92416d0d81219303341 Signed-off-by: Tim Crawford --- src/ec/system76/ec/usbc_mux.c | 45 ++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/ec/system76/ec/usbc_mux.c b/src/ec/system76/ec/usbc_mux.c index 3cfc5d1061..bac5ad31ff 100644 --- a/src/ec/system76/ec/usbc_mux.c +++ b/src/ec/system76/ec/usbc_mux.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #define CMD_USBC_MUX_INFO 23 @@ -60,25 +61,57 @@ static int system76_ec_get_mux_info(int port, struct usbc_mux_info *info) static int system76_ec_wait_for_connection(long timeout_ms) { // TODO - return 0; + return 1; } static int system76_ec_enter_dp_mode(int port) { // TODO - return -1; + return 0; } static int system76_ec_wait_for_dp_mode_entry(int port, long timeout_ms) { - // TODO - return -1; + struct usbc_mux_info info; + + if (system76_ec_get_mux_info(port, &info) < 0) { + printk(BIOS_WARNING, "%s: could not get usbc mux info\n", __func__); + return -1; + } + + if (!info.dp) { + printk(BIOS_WARNING, "DP mode not ready\n"); + return -1; + } + + return 0; } static int system76_ec_wait_for_hpd(int port, long timeout_ms) { - // TODO - return -1; + struct usbc_mux_info info; + struct stopwatch sw; + + stopwatch_init_msecs_expire(&sw, timeout_ms); + while (1) { + if (system76_ec_get_mux_info(port, &info) < 0) { + printk(BIOS_WARNING, "%s: could not get usbc mux info\n", __func__); + return -1; + } + + if (info.hpd_lvl) + break; + + if (stopwatch_expired(&sw)) { + printk(BIOS_WARNING, "HPD not ready after %ldms\n", timeout_ms); + return -1; + } + + mdelay(100); + } + + printk(BIOS_INFO, "HPD ready after %lldms\n", stopwatch_duration_msecs(&sw)); + return 0; } static const struct usbc_ops system76_ec_usbc_ops = {