xref: /aosp_15_r20/external/coreboot/src/soc/intel/xeon_sp/chip_common.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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