1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include <acpi/acpigen_pci.h>
4 #include <assert.h>
5 #include <console/console.h>
6 #include <device/pci.h>
7 #include <intelblocks/acpi.h>
8 #include <soc/acpi.h>
9 #include <soc/chip_common.h>
10 #include <soc/soc_util.h>
11 #include <soc/util.h>
12
13 /**
14 * Find all device of a given vendor and type for the specified socket.
15 * The function iterates over all PCI domains of the specified socket
16 * and matches the PCI vendor and device ID.
17 *
18 * @param socket The socket where to search for the device.
19 * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
20 * @param device A PCI device ID.
21 * @param from The device pointer to start search from.
22 *
23 * @return Pointer to the device struct. When there are multiple device
24 * instances, the caller should continue search upon a non-NULL match.
25 */
dev_find_all_devices_on_socket(uint8_t socket,u16 vendor,u16 device,struct device * from)26 struct device *dev_find_all_devices_on_socket(uint8_t socket, u16 vendor, u16 device,
27 struct device *from)
28 {
29 return dev_find_all_devices_on_stack(socket, XEONSP_STACK_MAX, vendor, device, from);
30 }
31
32 /*
33 * Find device of a given vendor and type for the specified socket.
34 * The function will return at the 1st match.
35 */
dev_find_device_on_socket(uint8_t socket,u16 vendor,u16 device)36 struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device)
37 {
38 return dev_find_all_devices_on_socket(socket, vendor, device, NULL);
39 }
40
filter_device_on_stack(struct device * dev,uint8_t socket,uint8_t stack,u16 vendor,u16 device)41 static int filter_device_on_stack(struct device *dev, uint8_t socket, uint8_t stack,
42 u16 vendor, u16 device)
43 {
44 if (dev->path.type != DEVICE_PATH_PCI)
45 return 0;
46
47 const struct device *domain = dev_get_domain(dev);
48 if (!domain)
49 return 0;
50
51 union xeon_domain_path dn;
52 dn.domain_path = domain->path.domain.domain;
53
54 if (socket != XEONSP_SOCKET_MAX && dn.socket != socket)
55 return 0;
56 if (stack != XEONSP_STACK_MAX && dn.stack != stack)
57 return 0;
58 if (vendor != XEONSP_VENDOR_MAX && dev->vendor != vendor)
59 return 0;
60 if (device != XEONSP_DEVICE_MAX && dev->device != device)
61 return 0;
62
63 return 1;
64 };
65
66 /**
67 * Find all device of a given vendor and type for the specified socket and stack.
68 *
69 * @param socket The socket where to search for the device.
70 * XEONSP_SOCKET_MAX indicates any socket.
71 * @param stack The stack where to search for the device.
72 * XEONSP_STACK_MAX indicates any stack.
73 * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
74 * XEONSP_VENDOR_MAX indicates any vendor.
75 * @param device A PCI device ID.
76 * XEONSP_DEVICE_MAX indicates any device.
77 * @param from The device pointer to start search from.
78 *
79 * @return Pointer to the device struct. When there are multiple device
80 * instances, the caller should continue search upon a non-NULL match.
81 */
dev_find_all_devices_on_stack(uint8_t socket,uint8_t stack,u16 vendor,u16 device,struct device * from)82 struct device *dev_find_all_devices_on_stack(uint8_t socket, uint8_t stack,
83 u16 vendor, u16 device, struct device *from)
84 {
85 if (!from)
86 from = all_devices;
87 else
88 from = from->next;
89
90 while (from && (!filter_device_on_stack(from, socket, stack,
91 vendor, device)))
92 from = from->next;
93
94 return from;
95 }
96
97 /**
98 * Find all device of a given vendor and type for the specific domain
99 * Only the direct child of the input domain is iterated
100 *
101 * @param domain Pointer to the input domain
102 * @param vendor A PCI vendor ID
103 * XEONSP_VENDOR_MAX indicates any vendor
104 * @param vendor A PCI device ID
105 * XEONSP_DEVICE_MAX indicates any vendor
106 * @param from The device pointer to start search from.
107 *
108 * @return Pointer to the device struct. When there are multiple device
109 * instances, the caller should continue search upon a non-NULL match.
110 */
dev_find_all_devices_on_domain(struct device * domain,u16 vendor,u16 device,struct device * from)111 struct device *dev_find_all_devices_on_domain(struct device *domain, u16 vendor,
112 u16 device, struct device *from)
113 {
114 struct device *dev = from;
115 while ((dev = dev_bus_each_child(domain->downstream, dev))) {
116 if (vendor != XEONSP_VENDOR_MAX && dev->vendor != vendor)
117 continue;
118 if (device != XEONSP_DEVICE_MAX && dev->device != device)
119 continue;
120 break;
121 }
122
123 return dev;
124 }
125
126 /**
127 * Returns the socket ID where the specified device is connected to.
128 * This is an integer in the range [0, CONFIG_MAX_SOCKET).
129 *
130 * @param dev The device to look up
131 *
132 * @return Socket ID the device is attached to, negative number on error.
133 */
iio_pci_domain_socket_from_dev(const struct device * dev)134 int iio_pci_domain_socket_from_dev(const struct device *dev)
135 {
136 const struct device *domain;
137 union xeon_domain_path dn;
138
139 domain = dev_get_domain(dev);
140 if (!domain)
141 return -1;
142
143 dn.domain_path = domain->path.domain.domain;
144
145 return dn.socket;
146 }
147
148 /**
149 * Returns the stack ID where the specified device is connected to.
150 * This is an integer in the range [0, MAX_IIO_STACK).
151 *
152 * @param dev The device to look up
153 *
154 * @return Stack ID the device is attached to, negative number on error.
155 */
iio_pci_domain_stack_from_dev(const struct device * dev)156 int iio_pci_domain_stack_from_dev(const struct device *dev)
157 {
158 const struct device *domain;
159 union xeon_domain_path dn;
160
161 domain = dev_get_domain(dev);
162 if (!domain)
163 return -1;
164
165 dn.domain_path = domain->path.domain.domain;
166
167 return dn.stack;
168 }
169
create_domain(const union xeon_domain_path dp,struct bus * upstream,int bus_base,int bus_limit,const char * type,struct device_operations * ops,const size_t pci_segment_group)170 void create_domain(const union xeon_domain_path dp, struct bus *upstream,
171 int bus_base, int bus_limit, const char *type,
172 struct device_operations *ops,
173 const size_t pci_segment_group)
174 {
175 struct device_path path;
176 init_xeon_domain_path(&path, dp.socket, dp.stack, bus_base);
177
178 struct device *const domain = alloc_find_dev(upstream, &path);
179 if (!domain)
180 die("%s: out of memory.\n", __func__);
181
182 domain->ops = ops;
183 iio_domain_set_acpi_name(domain, type);
184
185 struct bus *const bus = alloc_bus(domain);
186 bus->secondary = bus_base;
187 bus->subordinate = bus_base;
188 bus->max_subordinate = bus_limit;
189 bus->segment_group = pci_segment_group;
190 }
191
192 /* Attach stack as domains */
attach_iio_stacks(void)193 void attach_iio_stacks(void)
194 {
195 const IIO_UDS *hob = get_iio_uds();
196 union xeon_domain_path dn = { .domain_path = 0 };
197 if (!hob)
198 return;
199
200 struct bus *root_bus = dev_root.downstream;
201 for (int s = 0; s < CONFIG_MAX_SOCKET; ++s) {
202 if (!soc_cpu_is_enabled(s))
203 continue;
204 for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) {
205 const xSTACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x];
206 const size_t seg = hob->PlatformData.CpuQpiInfo[s].PcieSegment;
207
208 if (ri->BusBase > ri->BusLimit)
209 continue;
210
211 /* Prepare domain path */
212 dn.socket = s;
213 dn.stack = x;
214
215 create_xeonsp_domains(dn, root_bus, ri, seg);
216 }
217 }
218 }
219
is_pcie_domain(const struct device * dev)220 bool is_pcie_domain(const struct device *dev)
221 {
222 if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
223 return false;
224
225 return strstr(dev->name, DOMAIN_TYPE_PCIE);
226 }
227
is_ioat_domain(const struct device * dev)228 bool is_ioat_domain(const struct device *dev)
229 {
230 if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
231 return false;
232
233 return (strstr(dev->name, DOMAIN_TYPE_CPM0) ||
234 strstr(dev->name, DOMAIN_TYPE_CPM1) ||
235 strstr(dev->name, DOMAIN_TYPE_DINO) ||
236 strstr(dev->name, DOMAIN_TYPE_HQM0) ||
237 strstr(dev->name, DOMAIN_TYPE_HQM1));
238 }
239
is_ubox_domain(const struct device * dev)240 bool is_ubox_domain(const struct device *dev)
241 {
242 if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
243 return false;
244
245 return (strstr(dev->name, DOMAIN_TYPE_UBX0) ||
246 strstr(dev->name, DOMAIN_TYPE_UBX1));
247 }
248
is_cxl_domain(const struct device * dev)249 bool is_cxl_domain(const struct device *dev)
250 {
251 if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
252 return false;
253
254 return strstr(dev->name, DOMAIN_TYPE_CXL);
255 }
256