Jeremy Soller has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35946 )
Change subject: driver/thunderbolt: Driver for allocating hotplug resources ......................................................................
driver/thunderbolt: Driver for allocating hotplug resources
This adds a new driver which can be selected with DRIVERS_THUNDERBOLT that, by default, adds 32 PCI subordinate numbers, 256 MiB of both prefetchable and non-prefetchable memory, and 8 KiB of I/O space to matching devices. It currently supports the JHL7540 Thunderbolt 3 bridge, but other devices can be added easily.
In order to support the allocation of hotplugged PCI buses, a new field was added to struct device called hotplug_buses. This is defaulted to zero, but when set, it adds the hotplug_buses value to the subordinate value of the PCI bridge. This allows devices to be plugged in and unplugged after boot.
This code was tested on the System76 Darter Pro (darp6). Before this change, there are not enough resources allocated to the Thunderbolt PCI bridge to allow plugging in new devices after boot. This can be worked around in the Linux kernel by passing a boot param such as: pci=assign-buses,hpbussize=32,realloc
This change makes it possible to use Thunderbolt hotplugging without kernel parameters, and attempts to match closely what our motherboard manufacturer's firmware does by default.
Signed-off-by: Jeremy Soller jeremy@system76.com Change-Id: I500191626584b83e6a8ae38417fd324b5e803afc --- M src/device/pci_device.c A src/drivers/thunderbolt/Kconfig A src/drivers/thunderbolt/Makefile.inc A src/drivers/thunderbolt/thunderbolt.c M src/include/device/device.h 5 files changed, 117 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/46/35946/1
diff --git a/src/device/pci_device.c b/src/device/pci_device.c index c043dd6..1796d81 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -1217,7 +1217,7 @@
if (state == PCI_ROUTE_SCAN) { link->secondary = parent->subordinate + 1; - link->subordinate = link->secondary; + link->subordinate = link->secondary + dev->hotplug_buses; }
if (state == PCI_ROUTE_CLOSE) { diff --git a/src/drivers/thunderbolt/Kconfig b/src/drivers/thunderbolt/Kconfig new file mode 100644 index 0000000..f64e6cb --- /dev/null +++ b/src/drivers/thunderbolt/Kconfig @@ -0,0 +1,4 @@ +config DRIVERS_THUNDERBOLT + bool + help + Thunderbolt support diff --git a/src/drivers/thunderbolt/Makefile.inc b/src/drivers/thunderbolt/Makefile.inc new file mode 100644 index 0000000..623b897 --- /dev/null +++ b/src/drivers/thunderbolt/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_DRIVERS_THUNDERBOLT) += thunderbolt.c diff --git a/src/drivers/thunderbolt/thunderbolt.c b/src/drivers/thunderbolt/thunderbolt.c new file mode 100644 index 0000000..db463e0e --- /dev/null +++ b/src/drivers/thunderbolt/thunderbolt.c @@ -0,0 +1,110 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 System76. + * Copyright (C) 2017-2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pciexp.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> + +static void slot_dev_read_resources(struct device *dev) +{ + struct resource *resource; + + // Add 256 MiB of memory space + resource = new_resource(dev, 0x10); + resource->size = 1 << 28; + resource->align = 22; + resource->gran = 22; + resource->limit = 0xffffffff; + resource->flags |= IORESOURCE_MEM; + + // Add 256 MiB of prefetchable memory space + resource = new_resource(dev, 0x14); + resource->size = 1 << 28; + resource->align = 22; + resource->gran = 22; + resource->limit = 0xffffffff; + resource->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; + + // Add 8 KiB of I/O space + resource = new_resource(dev, 0x18); + resource->size = 1 << 13; + resource->align = 12; + resource->gran = 12; + resource->limit = 0xffff; + resource->flags |= IORESOURCE_IO; +} + +static struct device_operations slot_dev_ops = { + .read_resources = slot_dev_read_resources, +}; + +static bool tbt_is_hotplug_bridge(struct device *dev) { + return PCI_SLOT(dev->path.pci.devfn) == 1; +} + +static void tbt_pciexp_scan_bridge(struct device *dev) { + printk(BIOS_DEBUG, "%s: %s: scan bridge\n", __func__, dev_path(dev)); + + bool is_hotplug = tbt_is_hotplug_bridge(dev); + if (is_hotplug) { + /* Add hotplug buses, must happen before bus scan */ + printk(BIOS_DEBUG, "%s: %s: add hotplug buses\n", __func__, dev_path(dev)); + dev->hotplug_buses = 32; + } + + /* Normal PCIe Scan */ + pciexp_scan_bridge(dev); + + if (is_hotplug) { + /* Add dummy slot to preserve resources, must happen after bus scan */ + printk(BIOS_DEBUG, "%s: %s: add dummy device\n", __func__, dev_path(dev)); + struct device *slot; + struct device_path slot_path = { .type = DEVICE_PATH_NONE }; + slot = alloc_dev(dev->link_list, &slot_path); + slot->ops = &slot_dev_ops; + } +} + +static struct pci_operations pcie_ops = { + .set_subsystem = pci_dev_set_subsystem, +}; + +static struct device_operations device_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = 0, + .scan_bus = tbt_pciexp_scan_bridge, + .enable = 0, + .reset_bus = pci_bus_reset, + .ops_pci = &pcie_ops, +}; + +static const unsigned short pcie_device_ids[] = { + // JHL7540 Thunderbolt 3 Bridge + 0x15e7, + 0 +}; + +static const struct pci_driver tbt_pcie __pci_driver = { + .ops = &device_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pcie_device_ids, +}; diff --git a/src/include/device/device.h b/src/include/device/device.h index cb37c09..f22bed5 100644 --- a/src/include/device/device.h +++ b/src/include/device/device.h @@ -129,6 +129,7 @@ unsigned int disable_pcie_aspm : 1; unsigned int hidden : 1; /* set if we should hide from UI */ u8 command; + uint16_t hotplug_buses; /* hotplug buses to allocate */
/* Base registers for this device. I/O, MEM and Expansion ROM */ DEVTREE_CONST struct resource *resource_list;