blob: 144dba16652f7138aab3cf2b6ad470f39de0b4cb [file] [log] [blame]
Marc Jones1f500842020-10-15 14:32:51 -06001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3#include <assert.h>
4#include <console/console.h>
5#include <post.h>
6#include <device/pci.h>
7#include <soc/chip_common.h>
8#include <soc/soc_util.h>
9#include <soc/util.h>
10#include <stdlib.h>
11
Arthur Heymans550f55e2022-08-24 14:44:26 +020012static const STACK_RES *domain_to_stack_res(const struct device *dev)
Marc Jones1f500842020-10-15 14:32:51 -060013{
Arthur Heymans550f55e2022-08-24 14:44:26 +020014 assert(dev->path.type == DEVICE_PATH_DOMAIN);
Patrick Rudolph8c99ebc2024-01-19 17:28:47 +010015 const union xeon_domain_path dn = {
16 .domain_path = dev->path.domain.domain
17 };
Arthur Heymans550f55e2022-08-24 14:44:26 +020018
19 const IIO_UDS *hob = get_iio_uds();
20 assert(hob != NULL);
21
Patrick Rudolph8c99ebc2024-01-19 17:28:47 +010022 return &hob->PlatformData.IIO_resource[dn.socket].StackRes[dn.stack];
Marc Jones1f500842020-10-15 14:32:51 -060023}
24
Arthur Heymans550f55e2022-08-24 14:44:26 +020025void iio_pci_domain_read_resources(struct device *dev)
Marc Jones1f500842020-10-15 14:32:51 -060026{
27 struct resource *res;
Arthur Heymans550f55e2022-08-24 14:44:26 +020028 const STACK_RES *sr = domain_to_stack_res(dev);
29
30 if (!sr)
Marc Jones1f500842020-10-15 14:32:51 -060031 return;
32
Arthur Heymans550f55e2022-08-24 14:44:26 +020033 int index = 0;
Marc Jones1f500842020-10-15 14:32:51 -060034
Arthur Heymans550f55e2022-08-24 14:44:26 +020035 if (dev->path.domain.domain == 0) {
36 /* The 0 - 0xfff IO range is not reported by the HOB but still gets decoded */
37 res = new_resource(dev, index++);
38 res->base = 0;
39 res->size = 0x1000;
40 res->limit = 0xfff;
41 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
42 }
Marc Jones1f500842020-10-15 14:32:51 -060043
Arthur Heymans550f55e2022-08-24 14:44:26 +020044 if (sr->PciResourceIoBase < sr->PciResourceIoLimit) {
45 res = new_resource(dev, index++);
46 res->base = sr->PciResourceIoBase;
47 res->limit = sr->PciResourceIoLimit;
48 res->size = res->limit - res->base + 1;
49 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED;
50 }
Marc Jones1f500842020-10-15 14:32:51 -060051
Arthur Heymans550f55e2022-08-24 14:44:26 +020052 if (sr->PciResourceMem32Base < sr->PciResourceMem32Limit) {
53 res = new_resource(dev, index++);
54 res->base = sr->PciResourceMem32Base;
55 res->limit = sr->PciResourceMem32Limit;
56 res->size = res->limit - res->base + 1;
57 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
58 }
59
60 if (sr->PciResourceMem64Base < sr->PciResourceMem64Limit) {
61 res = new_resource(dev, index++);
62 res->base = sr->PciResourceMem64Base;
63 res->limit = sr->PciResourceMem64Limit;
64 res->size = res->limit - res->base + 1;
65 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
Marc Jones1f500842020-10-15 14:32:51 -060066 }
67}
68
Arthur Heymans550f55e2022-08-24 14:44:26 +020069void iio_pci_domain_scan_bus(struct device *dev)
Marc Jones1f500842020-10-15 14:32:51 -060070{
Arthur Heymans550f55e2022-08-24 14:44:26 +020071 const STACK_RES *sr = domain_to_stack_res(dev);
72 if (!sr)
73 return;
Marc Jones1f500842020-10-15 14:32:51 -060074
Arthur Heymans3e99ba02024-01-25 22:26:07 +010075 struct bus *bus = alloc_bus(dev);
Arthur Heymans550f55e2022-08-24 14:44:26 +020076 bus->secondary = sr->BusBase;
77 bus->subordinate = sr->BusBase;
78 bus->max_subordinate = sr->BusLimit;
79
80 printk(BIOS_SPEW, "Scanning IIO stack %d: busses %x-%x\n", dev->path.domain.domain,
Arthur Heymans7fcd4d52023-08-24 15:12:19 +020081 dev->downstream->secondary, dev->downstream->max_subordinate);
Arthur Heymans550f55e2022-08-24 14:44:26 +020082 pci_host_bridge_scan_bus(dev);
Marc Jones1f500842020-10-15 14:32:51 -060083}
84
Jonathan Zhanga63ea892023-01-25 11:16:58 -080085/*
Arthur Heymans550f55e2022-08-24 14:44:26 +020086 * Used by IIO stacks for PCIe bridges. Those contain 1 PCI host bridges,
87 * all the bus numbers on the IIO stack can be used for this bridge
Jonathan Zhanga63ea892023-01-25 11:16:58 -080088 */
Arthur Heymans550f55e2022-08-24 14:44:26 +020089static struct device_operations iio_pcie_domain_ops = {
90 .read_resources = iio_pci_domain_read_resources,
91 .set_resources = pci_domain_set_resources,
92 .scan_bus = iio_pci_domain_scan_bus,
93};
Arthur Heymans165893b2020-11-06 12:15:41 +010094
Arthur Heymans550f55e2022-08-24 14:44:26 +020095/* Attach IIO stack as domains */
Marc Jones1f500842020-10-15 14:32:51 -060096void attach_iio_stacks(struct device *dev)
97{
Arthur Heymans550f55e2022-08-24 14:44:26 +020098 const IIO_UDS *hob = get_iio_uds();
Patrick Rudolph8c99ebc2024-01-19 17:28:47 +010099 union xeon_domain_path dn = { .domain_path = 0 };
Arthur Heymans550f55e2022-08-24 14:44:26 +0200100 if (!hob)
101 return;
Marc Jones1f500842020-10-15 14:32:51 -0600102
Arthur Heymans550f55e2022-08-24 14:44:26 +0200103 for (int s = 0; s < hob->PlatformData.numofIIO; ++s) {
104 for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) {
105 if (s == 0 && x == 0)
106 continue;
Marc Jones1f500842020-10-15 14:32:51 -0600107
Arthur Heymans550f55e2022-08-24 14:44:26 +0200108 const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x];
Arthur Heymans470f1d32023-08-31 18:19:09 +0200109 if (ri->BusBase > ri->BusLimit)
Arthur Heymans550f55e2022-08-24 14:44:26 +0200110 continue;
Jonathan Zhang532e8c02023-01-25 11:28:49 -0800111
Patrick Rudolph8c99ebc2024-01-19 17:28:47 +0100112 /* Prepare domain path */
113 dn.socket = s;
114 dn.stack = x;
115 dn.bus = ri->BusBase;
116
Arthur Heymans550f55e2022-08-24 14:44:26 +0200117 if (!is_pcie_iio_stack_res(ri)) {
118 if (CONFIG(HAVE_IOAT_DOMAINS))
Arthur Heymans7fcd4d52023-08-24 15:12:19 +0200119 soc_create_ioat_domains(dn, dev->upstream, ri);
Jonathan Zhang532e8c02023-01-25 11:28:49 -0800120 continue;
121 }
122
Arthur Heymans550f55e2022-08-24 14:44:26 +0200123 struct device_path path;
124 path.type = DEVICE_PATH_DOMAIN;
Patrick Rudolph8c99ebc2024-01-19 17:28:47 +0100125 path.domain.domain = dn.domain_path;
Arthur Heymans7fcd4d52023-08-24 15:12:19 +0200126 struct device *iio_domain = alloc_dev(dev->upstream, &path);
Arthur Heymans550f55e2022-08-24 14:44:26 +0200127 if (iio_domain == NULL)
Jonathan Zhang532e8c02023-01-25 11:28:49 -0800128 die("%s: out of memory.\n", __func__);
Arthur Heymans550f55e2022-08-24 14:44:26 +0200129 iio_domain->ops = &iio_pcie_domain_ops;
Marc Jones1f500842020-10-15 14:32:51 -0600130 }
131 }
Marc Jones1f500842020-10-15 14:32:51 -0600132}