From 56e448b8d5079e418d1be56c31a8e82bf5b95566 Mon Sep 17 00:00:00 2001 From: Kane Chen Date: Mon, 12 Dec 2022 13:15:03 +0800 Subject: drivers/usb/acpi: Add USB _DSM method to enable/disable USB LPM per port This patch supports projects to use _DSM to control USB3 U1/U2 transition per port. More details can be found in https://web.archive.org/web/20230116084819/https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device-specific-method---dsm- The ACPI and USB driver of linux kernel need corresponding functions to support this feature. Please see https://git.kernel.org/pub/scm/linux/kernel/git/mnyman/xhci.git/log/?h=port_check_acpi_dsm BUG=b:253402457 TEST=tested on felwinter and found _DSM method is created. Change-Id: Iffb2498e26352a3f120c097c50587324e311e8ba Signed-off-by: Kane Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/71924 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- src/drivers/usb/acpi/chip.h | 6 ++++++ src/drivers/usb/acpi/usb_acpi.c | 7 +++++++ 2 files changed, 13 insertions(+) (limited to 'src/drivers') diff --git a/src/drivers/usb/acpi/chip.h b/src/drivers/usb/acpi/chip.h index 4adffcf2c0..9acd382c3d 100644 --- a/src/drivers/usb/acpi/chip.h +++ b/src/drivers/usb/acpi/chip.h @@ -72,6 +72,12 @@ struct drivers_usb_acpi_config { * will always return ON. */ bool use_gpio_for_status; + + /* + * Generate _DSM method Function 5 to disable USB U1/U2 transition + * for a port + */ + bool usb_lpm_incapable; }; /* Method to get PLD structure from USB device */ diff --git a/src/drivers/usb/acpi/usb_acpi.c b/src/drivers/usb/acpi/usb_acpi.c index f72129cba8..b95ebc9a60 100644 --- a/src/drivers/usb/acpi/usb_acpi.c +++ b/src/drivers/usb/acpi/usb_acpi.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ static void usb_acpi_fill_ssdt_generator(const struct device *dev) struct drivers_usb_acpi_config *config = dev->chip_info; const char *path = acpi_device_path(dev); struct acpi_pld pld; + struct dsm_usb_config usb_cfg; if (!path || !config) return; @@ -56,6 +58,11 @@ static void usb_acpi_fill_ssdt_generator(const struct device *dev) else printk(BIOS_ERR, "Error retrieving PLD for %s\n", path); + if (config->usb_lpm_incapable) { + usb_cfg.usb_lpm_incapable = 1; + acpigen_write_dsm_usb(&usb_cfg); + } + /* Resources */ if (usb_acpi_add_gpios_to_crs(config) == true) { struct acpi_dp *dsd; -- cgit v1.2.3