From 0f7e08622984f9c749b4d4327e22bdaa25cd0f0c Mon Sep 17 00:00:00 2001 From: Maulik V Vaghela Date: Tue, 29 Jun 2021 17:16:49 +0530 Subject: drivers/intel/usb4/retimer: Update code to assign correct port number Since TBT controller can have maximum 2 ports per controller, our code will loop over DFP structure twice and determine port number. Retimer driver used to assign port number as below: 1. Check if power GPIO is assigned for particular DFP entry or not 2. If entry is there, assign loop count as port number Since loop count is 2, retimer will never assign port number = 2 even if it's present. In case of more than 1 controller, port number assigned will still be 0 or 1 even though actual port index might be 2 or 3. This will create an issue where even if you do transaction on device on controller 2 (port index 2 or 3), EC will route it on port 0 or 1 due to incorrect port index. Update the driver flow as per below to handle this scenario: 1. Check if power GPIO is assigned for particular DFP entry or not 2. Get USB port number from config since it's stored in usb port information under devicetree 3. Pass the port number to ACPI SSDT and EC code Above changes will ensure that we're assigning correct port number as per calculation and EC will use correct port index. BUG=b:189476816 BRANCH=None TEST=Checked that retimer firmware update works on both ports and update happens on correct port index. Change-Id: Ib11637ae39046e0afdacd33bc34e8a59e6f2bfb1 Signed-off-by: Maulik V Vaghela Reviewed-on: https://review.coreboot.org/c/coreboot/+/55945 Tested-by: build bot (Jenkins) Reviewed-by: Tim Wawrzynczak --- src/drivers/intel/usb4/retimer/chip.h | 2 ++ src/drivers/intel/usb4/retimer/retimer.c | 35 ++++++++++++++++++++------------ 2 files changed, 24 insertions(+), 13 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/intel/usb4/retimer/chip.h b/src/drivers/intel/usb4/retimer/chip.h index 5b1c76f53c..46bd77ab94 100644 --- a/src/drivers/intel/usb4/retimer/chip.h +++ b/src/drivers/intel/usb4/retimer/chip.h @@ -16,6 +16,8 @@ struct drivers_intel_usb4_retimer_config { struct acpi_gpio power_gpio; /* _PLD setting */ struct acpi_pld_group group; + /* Type-C port associated with retimer */ + DEVTREE_CONST struct device *typec_port; } dfp[DFP_NUM_MAX]; }; diff --git a/src/drivers/intel/usb4/retimer/retimer.c b/src/drivers/intel/usb4/retimer/retimer.c index e84d29b6c6..e54952598c 100644 --- a/src/drivers/intel/usb4/retimer/retimer.c +++ b/src/drivers/intel/usb4/retimer/retimer.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include "chip.h" @@ -336,9 +337,10 @@ static void usb4_retimer_write_dsm(uint8_t port, const char *uuid, static void usb4_retimer_fill_ssdt(const struct device *dev) { struct drivers_intel_usb4_retimer_config *config = dev->chip_info; + const struct device *usb_device; static char dfp[DEVICE_PATH_MAX]; struct acpi_pld pld; - uint8_t port; + uint8_t dfp_port, usb_port; usb4_retimer_scope = acpi_device_scope(dev); if (!usb4_retimer_scope || !config) @@ -352,24 +354,31 @@ static void usb4_retimer_fill_ssdt(const struct device *dev) acpigen_write_ADR(0); acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); - for (port = 0; port < DFP_NUM_MAX; port++) { - if (!config->dfp[port].power_gpio.pin_count) { - printk(BIOS_ERR, "%s: No DFP%1d power GPIO for %s\n", __func__, - port, dev_path(dev)); + for (dfp_port = 0; dfp_port < DFP_NUM_MAX; dfp_port++) { + + if (!config->dfp[dfp_port].power_gpio.pin_count) { + printk(BIOS_ERR, "%s: No DFP%1d power GPIO for %s\n", + __func__, dfp_port, dev_path(dev)); continue; } + usb_device = config->dfp[dfp_port].typec_port; + usb_port = usb_device->path.usb.port_id; + /* DFPx */ - snprintf(dfp, sizeof(dfp), "DFP%1d", port); + snprintf(dfp, sizeof(dfp), "DFP%1d", usb_port); acpigen_write_device(dfp); /* _ADR part is for the lane adapter */ - acpigen_write_ADR(port*2 + 1); + acpigen_write_ADR(dfp_port*2 + 1); /* Fill _PLD with the same USB 3.x object on the Type-C connector */ - acpi_pld_fill_usb(&pld, UPC_TYPE_PROPRIETARY, &config->dfp[port].group); - pld.shape = PLD_SHAPE_OVAL; - pld.visible = 1; - acpigen_write_pld(&pld); + if (CONFIG(DRIVERS_USB_ACPI)) { + if (usb_acpi_get_pld(usb_device, &pld)) + acpigen_write_pld(&pld); + else + printk(BIOS_ERR, "Error retrieving PLD for USB Type-C %d\n", + usb_port); + } /* Power online reference counter(_PWR) */ acpigen_write_name("PWR"); @@ -387,9 +396,9 @@ static void usb4_retimer_fill_ssdt(const struct device *dev) /* Return (Buffer (One) { 0x0 }) */ acpigen_write_return_singleton_buffer(0x0); acpigen_pop_len(); - usb4_retimer_write_dsm(port, INTEL_USB4_RETIMER_DSM_UUID, + usb4_retimer_write_dsm(usb_port, INTEL_USB4_RETIMER_DSM_UUID, usb4_retimer_callbacks, ARRAY_SIZE(usb4_retimer_callbacks), - (void *)&config->dfp[port].power_gpio); + (void *)&config->dfp[dfp_port].power_gpio); /* Default case: Return (Buffer (One) { 0x0 }) */ acpigen_write_return_singleton_buffer(0x0); -- cgit v1.2.3