Update vboot submodule to upstream master
[coreboot.git] / src / device / hypertransport.c
bloba9f922fdf38839a3b458ccfd4c1eea22ed143160
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/path.h>
6 #include <device/pci.h>
7 #include <device/pci_ops.h>
8 #include <device/pci_ids.h>
9 #include <device/hypertransport.h>
11 struct ht_link {
12 struct device *dev;
13 unsigned int pos;
14 unsigned char ctrl_off, config_off, freq_off, freq_cap_off;
17 static struct device *ht_scan_get_devs(struct device **old_devices)
19 struct device *first, *last;
21 first = *old_devices;
22 last = first;
25 * Extract the chain of devices to (first through last) for the next
26 * hypertransport device.
28 while (last && last->sibling &&
29 (last->sibling->path.type == DEVICE_PATH_PCI) &&
30 (last->sibling->path.pci.devfn > last->path.pci.devfn))
32 last = last->sibling;
35 if (first) {
36 struct device *child;
38 /* Unlink the chain from the list of old devices. */
39 *old_devices = last->sibling;
40 last->sibling = 0;
42 /* Now add the device to the list of devices on the bus. */
43 /* Find the last child of our parent. */
44 for (child = first->bus->children; child && child->sibling;)
45 child = child->sibling;
47 /* Place the chain on the list of children of their parent. */
48 if (child)
49 child->sibling = first;
50 else
51 first->bus->children = first;
53 return first;
56 static int ht_setup_link(struct ht_link *prev, struct device *dev, unsigned int pos)
58 struct ht_link cur[1];
59 int linkb_to_host;
61 /* Set the hypertransport link width and frequency. */
64 * See which side of the device our previous write to set the unitid
65 * came from.
67 cur->dev = dev;
68 cur->pos = pos;
69 linkb_to_host =
70 (pci_read_config16(cur->dev, cur->pos + PCI_CAP_FLAGS) >> 10) & 1;
72 if (!linkb_to_host) {
73 cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL0;
74 cur->config_off = PCI_HT_CAP_SLAVE_WIDTH0;
75 cur->freq_off = PCI_HT_CAP_SLAVE_FREQ0;
76 cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
77 } else {
78 cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL1;
79 cur->config_off = PCI_HT_CAP_SLAVE_WIDTH1;
80 cur->freq_off = PCI_HT_CAP_SLAVE_FREQ1;
81 cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
85 * Remember the current link as the previous link, but look at the
86 * other offsets.
88 prev->dev = cur->dev;
89 prev->pos = cur->pos;
90 if (cur->ctrl_off == PCI_HT_CAP_SLAVE_CTRL0) {
91 prev->ctrl_off = PCI_HT_CAP_SLAVE_CTRL1;
92 prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1;
93 prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1;
94 prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
95 } else {
96 prev->ctrl_off = PCI_HT_CAP_SLAVE_CTRL0;
97 prev->config_off = PCI_HT_CAP_SLAVE_WIDTH0;
98 prev->freq_off = PCI_HT_CAP_SLAVE_FREQ0;
99 prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
102 return 0;
105 static unsigned int ht_lookup_slave_capability(struct device *dev)
107 unsigned int pos;
109 pos = 0;
110 do {
111 pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos);
112 if (pos) {
113 u16 flags;
114 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
115 printk(BIOS_SPEW, "flags: 0x%04x\n", flags);
116 if ((flags >> 13) == 0) {
117 /* Entry is a slave secondary, success... */
118 break;
121 } while (pos);
123 return pos;
126 static void ht_collapse_early_enumeration(struct bus *bus,
127 unsigned int offset_unitid)
129 unsigned int devfn;
130 struct ht_link prev;
131 u16 ctrl;
133 /* Initialize the hypertransport enumeration state. */
134 prev.dev = bus->dev;
135 prev.pos = bus->cap;
136 prev.ctrl_off = PCI_HT_CAP_HOST_CTRL;
137 prev.config_off = PCI_HT_CAP_HOST_WIDTH;
138 prev.freq_off = PCI_HT_CAP_HOST_FREQ;
139 prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;
141 /* Wait until the link initialization is complete. */
142 do {
143 ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off);
145 /* Is this the end of the hypertransport chain? */
146 if (ctrl & (1 << 6))
147 return;
149 /* Has the link failed? */
150 if (ctrl & (1 << 4)) {
152 * Either the link has failed, or we have a CRC error.
153 * Sometimes this can happen due to link retrain, so
154 * lets knock it down and see if its transient.
156 ctrl |= ((1 << 4) | (1 << 8)); /* Link fail + CRC */
157 pci_write_config16(prev.dev, prev.pos + prev.ctrl_off,
158 ctrl);
159 ctrl = pci_read_config16(prev.dev,
160 prev.pos + prev.ctrl_off);
161 if (ctrl & ((1 << 4) | (1 << 8))) {
162 printk(BIOS_ALERT, "Detected error on "
163 "Hypertransport link\n");
164 return;
167 } while ((ctrl & (1 << 5)) == 0);
169 /* Actually, only for one HT device HT chain, and unitid is 0. */
170 #if !CONFIG_HT_CHAIN_UNITID_BASE
171 if (offset_unitid)
172 return;
173 #endif
175 /* Check if is already collapsed. */
176 if ((!offset_unitid) || (offset_unitid
177 && (!((CONFIG_HT_CHAIN_END_UNITID_BASE == 0)
178 && (CONFIG_HT_CHAIN_END_UNITID_BASE
179 < CONFIG_HT_CHAIN_UNITID_BASE))))) {
181 struct device dummy;
182 u32 id;
184 dummy.bus = bus;
185 dummy.path.type = DEVICE_PATH_PCI;
186 dummy.path.pci.devfn = PCI_DEVFN(0, 0);
188 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
189 if (!((id == 0xffffffff) || (id == 0x00000000)
190 || (id == 0x0000ffff) || (id == 0xffff0000))) {
191 return;
195 /* Spin through the devices and collapse any early HT enumeration. */
196 for (devfn = PCI_DEVFN(1, 0); devfn <= 0xff; devfn += 8) {
197 struct device dummy;
198 u32 id;
199 unsigned int pos, flags;
201 dummy.bus = bus;
202 dummy.path.type = DEVICE_PATH_PCI;
203 dummy.path.pci.devfn = devfn;
205 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
206 if ((id == 0xffffffff) || (id == 0x00000000)
207 || (id == 0x0000ffff) || (id == 0xffff0000)) {
208 continue;
211 dummy.vendor = id & 0xffff;
212 dummy.device = (id >> 16) & 0xffff;
213 dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE);
215 pos = ht_lookup_slave_capability(&dummy);
216 if (!pos)
217 continue;
219 /* Clear the unitid. */
220 flags = pci_read_config16(&dummy, pos + PCI_CAP_FLAGS);
221 flags &= ~0x1f;
222 pci_write_config16(&dummy, pos + PCI_CAP_FLAGS, flags);
223 printk(BIOS_SPEW, "Collapsing %s [%04x/%04x]\n",
224 dev_path(&dummy), dummy.vendor, dummy.device);
228 static unsigned int do_hypertransport_scan_chain(struct bus *bus, unsigned int min_devfn,
229 unsigned int max_devfn,
230 unsigned int *ht_unitid_base,
231 unsigned int offset_unitid)
234 * Even CONFIG_HT_CHAIN_UNITID_BASE == 0, we still can go through this
235 * function, because of end_of_chain check. Also, we need it to
236 * optimize link.
238 unsigned int next_unitid, last_unitid, min_unitid, max_unitid;
239 struct device *old_devices, *dev, *func, *last_func = NULL;
240 struct ht_link prev;
241 int ht_dev_num = 0;
243 printk(BIOS_SPEW, "%s for bus %02x\n", __func__, bus->secondary);
245 min_unitid = (offset_unitid) ? CONFIG_HT_CHAIN_UNITID_BASE : 1;
247 #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
249 * Let's record the device of last HT device, so we can set the unitid
250 * to CONFIG_HT_CHAIN_END_UNITID_BASE.
252 unsigned int real_last_unitid = 0, end_used = 0;
253 u8 real_last_pos = 0;
254 struct device *real_last_dev = NULL;
255 #endif
257 /* Restore the hypertransport chain to it's uninitialized state. */
258 ht_collapse_early_enumeration(bus, offset_unitid);
260 /* See which static device nodes I have. */
261 old_devices = bus->children;
262 bus->children = 0;
264 /* Initialize the hypertransport enumeration state. */
265 prev.dev = bus->dev;
266 prev.pos = bus->cap;
268 prev.ctrl_off = PCI_HT_CAP_HOST_CTRL;
269 prev.config_off = PCI_HT_CAP_HOST_WIDTH;
270 prev.freq_off = PCI_HT_CAP_HOST_FREQ;
271 prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;
273 /* If present, assign unitid to a hypertransport chain. */
274 max_unitid = next_unitid = min_unitid;
275 do {
276 u8 pos;
277 u16 flags, ctrl;
278 unsigned int count, static_count;
280 last_unitid = next_unitid;
282 /* Wait until the link initialization is complete. */
283 do {
284 ctrl = pci_read_config16(prev.dev,
285 prev.pos + prev.ctrl_off);
287 /* End of chain? */
288 if (ctrl & (1 << 6))
289 goto end_of_chain;
291 if (ctrl & ((1 << 4) | (1 << 8))) {
293 * Either the link has failed, or we have a CRC
294 * error. Sometimes this can happen due to link
295 * retrain, so lets knock it down and see if
296 * it's transient.
298 ctrl |= ((1 << 4) | (1 <<8)); // Link fail + CRC
299 pci_write_config16(prev.dev,
300 prev.pos + prev.ctrl_off, ctrl);
301 ctrl = pci_read_config16(prev.dev,
302 prev.pos + prev.ctrl_off);
303 if (ctrl & ((1 << 4) | (1 << 8))) {
304 printk(BIOS_ALERT, "Detected error on "
305 "hypertransport link\n");
306 goto end_of_chain;
309 } while ((ctrl & (1 << 5)) == 0);
312 /* Get and setup the device_structure. */
313 dev = ht_scan_get_devs(&old_devices);
315 /* See if a device is present and setup the device structure. */
316 dev = pci_probe_dev(dev, bus, 0);
317 if (!dev || !dev->enabled)
318 break;
320 /* Find the hypertransport link capability. */
321 pos = ht_lookup_slave_capability(dev);
322 if (pos == 0) {
323 printk(BIOS_ERR, "%s Hypertransport link capability "
324 "not found", dev_path(dev));
325 break;
328 /* Update the unitid of the current device. */
329 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
332 * If the device has a unitid set and is at devfn 0 we are
333 * done. This can happen with shadow hypertransport devices,
334 * or if we have reached the bottom of a HT device chain.
336 if (flags & 0x1f)
337 break;
339 flags &= ~0x1f; /* Mask out base Unit ID. */
341 count = (flags >> 5) & 0x1f; /* Het unit count. */
343 #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
344 if (offset_unitid) {
345 /* max_devfn will be (0x17<<3)|7 or (0x1f<<3)|7. */
346 if (next_unitid > (max_devfn >> 3)) {
347 if (!end_used) {
348 next_unitid =
349 CONFIG_HT_CHAIN_END_UNITID_BASE;
350 end_used = 1;
351 } else {
352 goto end_of_chain;
356 #endif
358 flags |= next_unitid & 0x1f;
359 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
361 /* Update the unitid in the device structure. */
362 static_count = 1;
363 for (func = dev; func; func = func->sibling) {
364 func->path.pci.devfn += (next_unitid << 3);
365 static_count = (func->path.pci.devfn >> 3)
366 - (dev->path.pci.devfn >> 3) + 1;
367 last_func = func;
370 /* Compute the number of unitids consumed. */
371 printk(BIOS_SPEW, "%s count: %04x static_count: %04x\n",
372 dev_path(dev), count, static_count);
373 if (count < static_count)
374 count = static_count;
376 /* Update the unitid of the next device. */
377 ht_unitid_base[ht_dev_num] = next_unitid;
378 ht_dev_num++;
380 #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
381 if (offset_unitid) {
382 real_last_pos = pos;
383 real_last_unitid = next_unitid;
384 real_last_dev = dev;
386 #endif
387 next_unitid += count;
388 if (next_unitid > max_unitid)
389 max_unitid = next_unitid;
391 /* Setup the hypertransport link. */
392 bus->reset_needed |= ht_setup_link(&prev, dev, pos);
394 printk(BIOS_DEBUG, "%s [%04x/%04x] %s next_unitid: %04x\n",
395 dev_path(dev), dev->vendor, dev->device,
396 (dev->enabled? "enabled" : "disabled"), next_unitid);
398 } while (last_unitid != next_unitid);
400 end_of_chain:
402 #if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
403 if (offset_unitid && (ht_dev_num > 1)
404 && (real_last_unitid != CONFIG_HT_CHAIN_END_UNITID_BASE)
405 && !end_used) {
406 u16 flags;
407 flags = pci_read_config16(real_last_dev,
408 real_last_pos + PCI_CAP_FLAGS);
409 flags &= ~0x1f;
410 flags |= CONFIG_HT_CHAIN_END_UNITID_BASE & 0x1f;
411 pci_write_config16(real_last_dev,
412 real_last_pos + PCI_CAP_FLAGS, flags);
414 for (func = real_last_dev; func; func = func->sibling) {
415 func->path.pci.devfn -= ((real_last_unitid
416 - CONFIG_HT_CHAIN_END_UNITID_BASE) << 3);
417 last_func = func;
420 /* Update last one. */
421 ht_unitid_base[ht_dev_num-1] = CONFIG_HT_CHAIN_END_UNITID_BASE;
423 printk(BIOS_DEBUG, " unitid: %04x --> %04x\n",
424 real_last_unitid, CONFIG_HT_CHAIN_END_UNITID_BASE);
426 #endif
427 next_unitid = max_unitid;
429 if (next_unitid > 0x20)
430 next_unitid = 0x20;
432 if ((bus->secondary == 0) && (next_unitid > 0x18))
433 next_unitid = 0x18; /* Avoid K8 on bus 0. */
436 * Die if any leftover static devices are are found. There's probably
437 * a problem in devicetree.cb.
439 if (old_devices) {
440 struct device *left;
441 for (left = old_devices; left; left = left->sibling)
442 printk(BIOS_DEBUG, "%s\n", dev_path(left));
444 printk(BIOS_ERR, "HT: Leftover static devices. "
445 "Check your devicetree.cb\n");
448 * Put back the leftover static device, and let pci_scan_bus()
449 * disable it.
451 if (last_func && !last_func->sibling)
452 last_func->sibling = old_devices;
455 return next_unitid;
459 * Scan a PCI bridge and the buses behind the bridge.
461 * Determine the existence of buses behind the bridge. Set up the bridge
462 * according to the result of the scan.
464 * This function is the default scan_bus() method for PCI bridge devices.
466 * @param bus TODO
467 * @param min_devfn TODO
468 * @param max_devfn TODO
470 static void hypertransport_scan_chain_x(struct bus *bus,
471 unsigned int min_devfn, unsigned int max_devfn)
473 unsigned int ht_unitid_base[4];
474 unsigned int offset_unitid = 1;
476 unsigned int next_unitid = do_hypertransport_scan_chain(bus, min_devfn, max_devfn,
477 ht_unitid_base, offset_unitid);
479 /* Now that nothing is overlapping it is safe to scan the children. */
480 pci_scan_bus(bus, 0x00, ((next_unitid - 1) << 3) | 7);
483 static void ht_scan_bridge(struct device *dev)
485 do_pci_scan_bridge(dev, hypertransport_scan_chain_x);
488 /** Default device operations for hypertransport bridges */
489 static struct pci_operations ht_bus_ops_pci = {
490 .set_subsystem = 0,
493 struct device_operations default_ht_ops_bus = {
494 .read_resources = pci_bus_read_resources,
495 .set_resources = pci_dev_set_resources,
496 .enable_resources = pci_bus_enable_resources,
497 .scan_bus = ht_scan_bridge,
498 .reset_bus = pci_bus_reset,
499 .ops_pci = &ht_bus_ops_pci,