Raul Rangel has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41900 )
Change subject: soc/amd/common/blocks/xhci: Add an AMD block to generate xHCI ACPI nodes ......................................................................
soc/amd/common/blocks/xhci: Add an AMD block to generate xHCI ACPI nodes
We can use xhci_for_each_ext_cap to inspect the xHC so we generate the correct number of device nodes.
BUG=b:154756391 TEST=Boot trembyle and look at ACPI table. See all xHCI nodes.
Signed-off-by: Raul E Rangel rrangel@chromium.org Change-Id: I44ebaef342e45923bc181ceebef882358d33f0d1 --- A src/soc/amd/common/block/xhci/Kconfig A src/soc/amd/common/block/xhci/Makefile.inc A src/soc/amd/common/block/xhci/xhci.c 3 files changed, 128 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/00/41900/1
diff --git a/src/soc/amd/common/block/xhci/Kconfig b/src/soc/amd/common/block/xhci/Kconfig new file mode 100644 index 0000000..5751907 --- /dev/null +++ b/src/soc/amd/common/block/xhci/Kconfig @@ -0,0 +1,5 @@ +config SOC_AMD_COMMON_BLOCK_XHCI + bool + default n + help + Select this option to use AMD common xhci driver support. diff --git a/src/soc/amd/common/block/xhci/Makefile.inc b/src/soc/amd/common/block/xhci/Makefile.inc new file mode 100644 index 0000000..2387450 --- /dev/null +++ b/src/soc/amd/common/block/xhci/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_XHCI) += xhci.c diff --git a/src/soc/amd/common/block/xhci/xhci.c b/src/soc/amd/common/block/xhci/xhci.c new file mode 100644 index 0000000..72bb9bb --- /dev/null +++ b/src/soc/amd/common/block/xhci/xhci.c @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpigen.h> +#include <amdblocks/gpio_banks.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pci_ehci.h> +#include <soc/acpi.h> +#include <soc/pci_devs.h> +#include <soc/smi.h> +#include <soc/southbridge.h> +#include <amdblocks/acpimmio.h> +#include <device/xhci.h> + +#define XHCI_GEVENT GEVENT_31 + +struct port_counts { + unsigned int high_speed; + unsigned int super_speed; +}; + +static void handle_xhci_ext_cap(void *context, const struct xhci_ext_cap *cap) +{ + const struct xhci_supported_protocol *data; + const char *format; + char buf[16]; + struct port_counts *counts = context; + unsigned int *dev_num; + + if (cap->cap_id != XHCI_ECP_CAP_ID_SUPP) + return; + + data = &cap->supported_protocol; + + if (memcmp(data->name, "USB ", 4)) { + printk(BIOS_INFO, "%s: Unknown Protocol: %.*s\n", __func__, + (int)sizeof(data->name), data->name); + return; + } + + if (data->major_rev == 3) { + format = "SS%02d"; + dev_num = &counts->super_speed; + } else if (data->major_rev == 2) { + format = "HS%02d"; + dev_num = &counts->high_speed; + } else { + printk(BIOS_INFO, "%s: Unknown USB Version: %#x\n", __func__, data->major_rev); + return; + } + + for (unsigned int i = 0; i < data->port_count; ++i) { + snprintf(buf, sizeof(buf), format, ++(*dev_num)); + acpigen_write_device(buf); + acpigen_write_name_byte("_ADR", data->port_offset + i); + acpigen_pop_len(); + } +} + +static void xhci_add_devices(const struct device *device) +{ + struct port_counts counts = {0, 0}; + + acpigen_write_device("RHUB"); + acpigen_write_name_integer("_ADR", 0x00000000); + + xhci_for_each_ext_cap(device, &counts, handle_xhci_ext_cap); + + /* Exit RHUB device */ + acpigen_pop_len(); +} + +static void xhci_fill_ssdt_generator(const struct device *device) +{ + printk(BIOS_INFO, "xHCI SSDT generation\n"); + + /* Write SSDT entry for xHCI controller */ + acpigen_write_scope(acpi_device_scope(device)); + acpigen_write_device(acpi_device_name(device)); + acpigen_write_ADR_pci_device(device); + acpigen_write_STA(acpi_device_status(device)); + acpigen_write_PRW(XHCI_GEVENT, 3); + + xhci_add_devices(device); + + acpigen_write_name_integer("_S0W", 0); + acpigen_write_name_integer("_S3W", 4); + acpigen_write_name_integer("_S4W", 4); + + acpigen_pop_len(); // xHCI device + + acpigen_pop_len(); // Bridge scope +} + +static struct pci_operations lops_pci = { + .set_subsystem = pci_dev_set_subsystem, +}; + +static struct device_operations usb_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .scan_bus = scan_static_bus, + .ops_pci = &lops_pci, + .acpi_fill_ssdt = xhci_fill_ssdt_generator, +}; + +static const unsigned short pci_device_ids[] = { + PCI_DEVICE_ID_AMD_FAM17H_MODEL18H_XHCI0, + PCI_DEVICE_ID_AMD_FAM17H_MODEL18H_XHCI1, + PCI_DEVICE_ID_AMD_FAM17H_MODEL20H_XHCI0, + 0 +}; + +static const struct pci_driver usb_0_driver __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_AMD, + .devices = pci_device_ids, +};