blob: f2414ccb12e584aaa6140769c8de742aae0a5325 [file] [log] [blame]
Duncan Lauriece3a9742020-08-13 16:17:57 -07001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
Elyes Haouas8ed58352022-10-22 22:17:28 +02003#include <acpi/acpi_device.h>
Duncan Lauriece3a9742020-08-13 16:17:57 -07004#include <acpi/acpigen.h>
5#include <console/console.h>
6#include <device/device.h>
7#include <device/path.h>
Duncan Lauriece3a9742020-08-13 16:17:57 -07008#include <string.h>
Elyes Haouas8ed58352022-10-22 22:17:28 +02009
Duncan Lauriece3a9742020-08-13 16:17:57 -070010#include "chip.h"
11
Duncan Lauriece3a9742020-08-13 16:17:57 -070012#if CONFIG(HAVE_ACPI_TABLES)
Duncan Laurie389cb302020-10-18 15:01:22 -070013static void usb4_pcie_acpi_fill_ssdt(const struct device *dev)
Duncan Lauriece3a9742020-08-13 16:17:57 -070014{
15 const struct soc_intel_common_block_usb4_config *config;
16 const struct device *parent;
Kapil Porwal65bcb572022-11-28 18:53:40 +053017 struct acpi_dp *dsd;
Duncan Lauriece3a9742020-08-13 16:17:57 -070018 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 Ramasubramaniand1c0f952020-11-02 16:26:52 -070028 if (!parent->enabled)
Duncan Lauriece3a9742020-08-13 16:17:57 -070029 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 Laurie389cb302020-10-18 15:01:22 -070040 printk(BIOS_ERR, "%s: Unable to find ACPI path for usb4_port %s\n",
41 __func__, dev_path(config->usb4_port));
Duncan Lauriece3a9742020-08-13 16:17:57 -070042 return;
43 }
44
45 usb4_path = strdup(usb4_path);
46 port_id = dev->path.generic.id;
47
Duncan Laurie389cb302020-10-18 15:01:22 -070048 acpigen_write_scope(acpi_device_path(parent));
Duncan Lauriece3a9742020-08-13 16:17:57 -070049
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 Porwal65bcb572022-11-28 18:53:40 +053056 acpi_device_add_hotplug_support_in_d3(dsd);
Duncan Lauriece3a9742020-08-13 16:17:57 -070057
58 /* Indicate that port is external. */
Kapil Porwal65bcb572022-11-28 18:53:40 +053059 acpi_device_add_external_facing_port(dsd);
Duncan Lauriece3a9742020-08-13 16:17:57 -070060
Duncan Lauriece3a9742020-08-13 16:17:57 -070061 acpi_dp_write(dsd);
62
63 acpigen_pop_len(); /* Scope */
64
Duncan Laurie389cb302020-10-18 15:01:22 -070065 printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(parent),
66 config->desc ? : dev->chip_ops->name, dev_path(parent));
Duncan Lauriece3a9742020-08-13 16:17:57 -070067}
68#endif
69
Duncan Laurie389cb302020-10-18 15:01:22 -070070static struct device_operations usb4_pcie_acpi_dev_ops = {
71 .read_resources = noop_read_resources,
72 .set_resources = noop_set_resources,
Duncan Lauriece3a9742020-08-13 16:17:57 -070073#if CONFIG(HAVE_ACPI_TABLES)
Duncan Laurie389cb302020-10-18 15:01:22 -070074 .acpi_fill_ssdt = usb4_pcie_acpi_fill_ssdt,
Duncan Lauriece3a9742020-08-13 16:17:57 -070075#endif
76};
77
Duncan Laurie389cb302020-10-18 15:01:22 -070078static void usb4_pcie_acpi_enable(struct device *dev)
Duncan Lauriece3a9742020-08-13 16:17:57 -070079{
Duncan Laurie389cb302020-10-18 15:01:22 -070080 dev->ops = &usb4_pcie_acpi_dev_ops;
Duncan Lauriece3a9742020-08-13 16:17:57 -070081}
82
83struct chip_operations soc_intel_common_block_usb4_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +090084 .name = "Intel USB4 PCIe Root Port",
Duncan Laurie389cb302020-10-18 15:01:22 -070085 .enable_dev = usb4_pcie_acpi_enable
Duncan Lauriece3a9742020-08-13 16:17:57 -070086};