blob: 81496ce70ad8e42b7af203b4fb39c6494a07d140 [file] [log] [blame]
Duncan Lauriece3a9742020-08-13 16:17:57 -07001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3#include <acpi/acpigen.h>
4#include <console/console.h>
5#include <device/device.h>
6#include <device/path.h>
Duncan Lauriece3a9742020-08-13 16:17:57 -07007#include <string.h>
Duncan Lauriece3a9742020-08-13 16:17:57 -07008#include "chip.h"
9
10#define PCI_HOTPLUG_IN_D3_UUID "6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"
11#define PCI_EXTERNAL_PORT_UUID "EFCC06CC-73AC-4BC3-BFF0-76143807C389"
12
13#if CONFIG(HAVE_ACPI_TABLES)
Duncan Laurie389cb302020-10-18 15:01:22 -070014static void usb4_pcie_acpi_fill_ssdt(const struct device *dev)
Duncan Lauriece3a9742020-08-13 16:17:57 -070015{
16 const struct soc_intel_common_block_usb4_config *config;
17 const struct device *parent;
18 struct acpi_dp *dsd, *pkg;
19 const char *usb4_path;
20 int port_id;
21
22 /* Get parent PCI device */
23 parent = dev->bus->dev;
24 if (!parent) {
25 printk(BIOS_ERR, "%s: Unable to find parent device\n", __func__);
26 return;
27 }
28
Karthikeyan Ramasubramaniand1c0f952020-11-02 16:26:52 -070029 if (!parent->enabled)
Duncan Lauriece3a9742020-08-13 16:17:57 -070030 return;
31
32 config = config_of(dev);
33 if (!config->usb4_port) {
34 printk(BIOS_ERR, "%s: Unable to find reference to usb4_port\n", __func__);
35 return;
36 }
37
38 /* Get ACPI path to USB4 device. */
39 usb4_path = acpi_device_path(config->usb4_port);
40 if (!usb4_path) {
Duncan Laurie389cb302020-10-18 15:01:22 -070041 printk(BIOS_ERR, "%s: Unable to find ACPI path for usb4_port %s\n",
42 __func__, dev_path(config->usb4_port));
Duncan Lauriece3a9742020-08-13 16:17:57 -070043 return;
44 }
45
46 usb4_path = strdup(usb4_path);
47 port_id = dev->path.generic.id;
48
Duncan Laurie389cb302020-10-18 15:01:22 -070049 acpigen_write_scope(acpi_device_path(parent));
Duncan Lauriece3a9742020-08-13 16:17:57 -070050
51 /* Add pointer to USB4 port controller. */
52 dsd = acpi_dp_new_table("_DSD");
53 acpi_dp_add_reference(dsd, "usb4-host-interface", usb4_path);
54 acpi_dp_add_integer(dsd, "usb4-port-number", port_id);
55
56 /* Indicate that device supports hotplug in D3. */
57 pkg = acpi_dp_new_table(PCI_HOTPLUG_IN_D3_UUID);
58 acpi_dp_add_integer(pkg, "HotPlugSupportInD3", 1);
59 acpi_dp_add_package(dsd, pkg);
60
61 /* Indicate that port is external. */
62 pkg = acpi_dp_new_table(PCI_EXTERNAL_PORT_UUID);
63 acpi_dp_add_integer(pkg, "ExternalFacingPort", 1);
Duncan Lauriece3a9742020-08-13 16:17:57 -070064
65 acpi_dp_add_package(dsd, pkg);
66 acpi_dp_write(dsd);
67
68 acpigen_pop_len(); /* Scope */
69
Duncan Laurie389cb302020-10-18 15:01:22 -070070 printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(parent),
71 config->desc ? : dev->chip_ops->name, dev_path(parent));
Duncan Lauriece3a9742020-08-13 16:17:57 -070072}
73#endif
74
Duncan Laurie389cb302020-10-18 15:01:22 -070075static struct device_operations usb4_pcie_acpi_dev_ops = {
76 .read_resources = noop_read_resources,
77 .set_resources = noop_set_resources,
Duncan Lauriece3a9742020-08-13 16:17:57 -070078#if CONFIG(HAVE_ACPI_TABLES)
Duncan Laurie389cb302020-10-18 15:01:22 -070079 .acpi_fill_ssdt = usb4_pcie_acpi_fill_ssdt,
Duncan Lauriece3a9742020-08-13 16:17:57 -070080#endif
81};
82
Duncan Laurie389cb302020-10-18 15:01:22 -070083static void usb4_pcie_acpi_enable(struct device *dev)
Duncan Lauriece3a9742020-08-13 16:17:57 -070084{
Duncan Laurie389cb302020-10-18 15:01:22 -070085 dev->ops = &usb4_pcie_acpi_dev_ops;
Duncan Lauriece3a9742020-08-13 16:17:57 -070086}
87
88struct chip_operations soc_intel_common_block_usb4_ops = {
Duncan Laurie389cb302020-10-18 15:01:22 -070089 CHIP_NAME("Intel USB4 PCIe Root Port")
90 .enable_dev = usb4_pcie_acpi_enable
Duncan Lauriece3a9742020-08-13 16:17:57 -070091};