Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | |
Elyes Haouas | 8ed5835 | 2022-10-22 22:17:28 +0200 | [diff] [blame] | 3 | #include <acpi/acpi_device.h> |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 4 | #include <acpi/acpigen.h> |
| 5 | #include <console/console.h> |
| 6 | #include <device/device.h> |
| 7 | #include <device/path.h> |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 8 | #include <string.h> |
Elyes Haouas | 8ed5835 | 2022-10-22 22:17:28 +0200 | [diff] [blame] | 9 | |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 10 | #include "chip.h" |
| 11 | |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 12 | #if CONFIG(HAVE_ACPI_TABLES) |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 13 | static void usb4_pcie_acpi_fill_ssdt(const struct device *dev) |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 14 | { |
| 15 | const struct soc_intel_common_block_usb4_config *config; |
| 16 | const struct device *parent; |
Kapil Porwal | 65bcb57 | 2022-11-28 18:53:40 +0530 | [diff] [blame^] | 17 | struct acpi_dp *dsd; |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 18 | const char *usb4_path; |
| 19 | int port_id; |
| 20 | |
| 21 | /* Get parent PCI device */ |
| 22 | parent = dev->bus->dev; |
| 23 | if (!parent) { |
| 24 | printk(BIOS_ERR, "%s: Unable to find parent device\n", __func__); |
| 25 | return; |
| 26 | } |
| 27 | |
Karthikeyan Ramasubramanian | d1c0f95 | 2020-11-02 16:26:52 -0700 | [diff] [blame] | 28 | if (!parent->enabled) |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 29 | return; |
| 30 | |
| 31 | config = config_of(dev); |
| 32 | if (!config->usb4_port) { |
| 33 | printk(BIOS_ERR, "%s: Unable to find reference to usb4_port\n", __func__); |
| 34 | return; |
| 35 | } |
| 36 | |
| 37 | /* Get ACPI path to USB4 device. */ |
| 38 | usb4_path = acpi_device_path(config->usb4_port); |
| 39 | if (!usb4_path) { |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 40 | printk(BIOS_ERR, "%s: Unable to find ACPI path for usb4_port %s\n", |
| 41 | __func__, dev_path(config->usb4_port)); |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 42 | return; |
| 43 | } |
| 44 | |
| 45 | usb4_path = strdup(usb4_path); |
| 46 | port_id = dev->path.generic.id; |
| 47 | |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 48 | acpigen_write_scope(acpi_device_path(parent)); |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 49 | |
| 50 | /* Add pointer to USB4 port controller. */ |
| 51 | dsd = acpi_dp_new_table("_DSD"); |
| 52 | acpi_dp_add_reference(dsd, "usb4-host-interface", usb4_path); |
| 53 | acpi_dp_add_integer(dsd, "usb4-port-number", port_id); |
| 54 | |
| 55 | /* Indicate that device supports hotplug in D3. */ |
Kapil Porwal | 65bcb57 | 2022-11-28 18:53:40 +0530 | [diff] [blame^] | 56 | acpi_device_add_hotplug_support_in_d3(dsd); |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 57 | |
| 58 | /* Indicate that port is external. */ |
Kapil Porwal | 65bcb57 | 2022-11-28 18:53:40 +0530 | [diff] [blame^] | 59 | acpi_device_add_external_facing_port(dsd); |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 60 | |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 61 | acpi_dp_write(dsd); |
| 62 | |
| 63 | acpigen_pop_len(); /* Scope */ |
| 64 | |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 65 | printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(parent), |
| 66 | config->desc ? : dev->chip_ops->name, dev_path(parent)); |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 67 | } |
| 68 | #endif |
| 69 | |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 70 | static struct device_operations usb4_pcie_acpi_dev_ops = { |
| 71 | .read_resources = noop_read_resources, |
| 72 | .set_resources = noop_set_resources, |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 73 | #if CONFIG(HAVE_ACPI_TABLES) |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 74 | .acpi_fill_ssdt = usb4_pcie_acpi_fill_ssdt, |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 75 | #endif |
| 76 | }; |
| 77 | |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 78 | static void usb4_pcie_acpi_enable(struct device *dev) |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 79 | { |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 80 | dev->ops = &usb4_pcie_acpi_dev_ops; |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 81 | } |
| 82 | |
| 83 | struct chip_operations soc_intel_common_block_usb4_ops = { |
Duncan Laurie | 389cb30 | 2020-10-18 15:01:22 -0700 | [diff] [blame] | 84 | CHIP_NAME("Intel USB4 PCIe Root Port") |
| 85 | .enable_dev = usb4_pcie_acpi_enable |
Duncan Laurie | ce3a974 | 2020-08-13 16:17:57 -0700 | [diff] [blame] | 86 | }; |