blob: 17cd8f4ab82e6b781c5f37215f380a44a6283810 [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Uwe Hermannb80dbf02007-04-22 19:08:13 +00003 *
4 * It was originally based on the Linux kernel (arch/i386/kernel/pci-pc.c).
5 *
6 * Modifications are:
7 * Copyright (C) 2003 Eric Biederman <ebiederm@xmission.com>
8 * Copyright (C) 2003-2004 Linux Networx
9 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
10 * Copyright (C) 2003 Ronald G. Minnich <rminnich@gmail.com>
11 * Copyright (C) 2004-2005 Li-Ta Lo <ollie@lanl.gov>
12 * Copyright (C) 2005-2006 Tyan
13 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
14 * Copyright (C) 2005-2006 Stefan Reinauer <stepan@openbios.org>
Myles Watson29cc9ed2009-07-02 18:56:24 +000015 * Copyright (C) 2009 Myles Watson <mylesgw@gmail.com>
Martin Rothbb5953d2016-04-11 20:53:39 -060016 * Copyright (c) 1999--2000 Martin Mares <mj@suse.cz>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; version 2 of the License.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
Eric Biederman8ca8d762003-04-22 19:02:15 +000026 */
Uwe Hermanne4870472010-11-04 23:23:47 +000027
28/*
29 * Lots of mods by Ron Minnich <rminnich@lanl.gov>, with
30 * the final architecture guidance from Tom Merritt <tjm@codegen.com>.
31 *
Myles Watson032a9652009-05-11 22:24:53 +000032 * In particular, we changed from the one-pass original version to
33 * Tom's recommended multiple-pass version. I wasn't sure about doing
Eric Biederman8ca8d762003-04-22 19:02:15 +000034 * it with multiple passes, until I actually started doing it and saw
Uwe Hermanne4870472010-11-04 23:23:47 +000035 * the wisdom of Tom's recommendations...
Eric Biederman8ca8d762003-04-22 19:02:15 +000036 *
37 * Lots of cleanups by Eric Biederman to handle bridges, and to
Uwe Hermanne4870472010-11-04 23:23:47 +000038 * handle resource allocation for non-PCI devices.
Eric Biederman8ca8d762003-04-22 19:02:15 +000039 */
40
41#include <console/console.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000042#include <device/device.h>
Kyösti Mälkki318066f2014-02-12 14:18:50 +020043#include <device/pci_def.h>
Li-Ta Lo54f05f62004-05-14 17:20:29 +000044#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000045#include <stdlib.h>
46#include <string.h>
Eric Biederman03acab62004-10-14 21:25:53 +000047#include <smp/spinlock.h>
Julius Wernercd49cce2019-03-05 16:53:33 -080048#if CONFIG(ARCH_X86)
Duncan Laurieb4aaaa72012-01-17 09:03:11 -080049#include <arch/ebda.h>
50#endif
Aaron Durbin05294292013-04-30 15:41:13 -050051#include <timer.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000052
Li-Ta Loe5266692004-03-23 21:28:05 +000053/** Pointer to the last device */
Myles Watson70679a02010-09-01 21:03:03 +000054extern struct device *last_dev;
Myles Watsonc25cc112010-05-21 14:33:48 +000055/** Linked list of free resources */
56struct resource *free_resources = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +000057
Nico Huberacd7d952012-07-25 10:33:05 +020058/**
59 * Initialize all chips of statically known devices.
60 *
61 * Will be called before bus enumeration to initialize chips stated in the
62 * device tree.
63 */
64void dev_initialize_chips(void)
65{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +020066 const struct device *dev;
Nico Huberacd7d952012-07-25 10:33:05 +020067
68 for (dev = all_devices; dev; dev = dev->next) {
69 /* Initialize chip if we haven't yet. */
70 if (dev->chip_ops && dev->chip_ops->init &&
71 !dev->chip_ops->initialized) {
Duncan Laurie8adf7a22013-06-10 10:34:20 -070072 post_log_path(dev);
Nico Huberacd7d952012-07-25 10:33:05 +020073 dev->chip_ops->init(dev->chip_info);
74 dev->chip_ops->initialized = 1;
75 }
76 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -070077 post_log_clear();
Nico Huberacd7d952012-07-25 10:33:05 +020078}
79
Marc Jones2a58ecd2013-10-29 17:32:00 -060080/**
81 * Finalize all chips of statically known devices.
82 *
83 * This is the last call before calling the payload. This is a good place
84 * to lock registers or other final cleanup.
85 */
86void dev_finalize_chips(void)
87{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +020088 const struct device *dev;
Marc Jones2a58ecd2013-10-29 17:32:00 -060089
90 for (dev = all_devices; dev; dev = dev->next) {
91 /* Initialize chip if we haven't yet. */
92 if (dev->chip_ops && dev->chip_ops->final &&
93 !dev->chip_ops->finalized) {
94 dev->chip_ops->final(dev->chip_info);
95 dev->chip_ops->finalized = 1;
96 }
97 }
98}
99
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000100DECLARE_SPIN_LOCK(dev_lock)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000101
Julius Wernercd49cce2019-03-05 16:53:33 -0800102#if CONFIG(GFXUMA)
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +0300103/* IGD UMA memory */
104uint64_t uma_memory_base = 0;
105uint64_t uma_memory_size = 0;
Kyösti Mälkkib25374c2012-08-01 08:05:22 +0300106#endif
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +0300107
Li-Ta Loe5266692004-03-23 21:28:05 +0000108/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000109 * Allocate a new device structure.
Myles Watson032a9652009-05-11 22:24:53 +0000110 *
Martin Roth63373ed2013-07-08 16:24:19 -0600111 * Allocate a new device structure and attach it to the device tree as a
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000112 * child of the parent bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000113 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000114 * @param parent Parent bus the newly created device should be attached to.
115 * @param path Path to the device to be created.
116 * @return Pointer to the newly created device structure.
Li-Ta Loe5266692004-03-23 21:28:05 +0000117 *
118 * @see device_path
Eric Biederman8ca8d762003-04-22 19:02:15 +0000119 */
Elyes HAOUASd34a7852018-09-17 10:44:14 +0200120static struct device *__alloc_dev(struct bus *parent, struct device_path *path)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000121{
Elyes HAOUASe3480662018-05-06 20:32:23 +0200122 struct device *dev, *child;
Li-Ta Loe5266692004-03-23 21:28:05 +0000123
Myles Watson29cc9ed2009-07-02 18:56:24 +0000124 /* Find the last child of our parent. */
Elyes HAOUASa342f392018-10-17 10:56:26 +0200125 for (child = parent->children; child && child->sibling; /* */)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000126 child = child->sibling;
Li-Ta Lo3a812852004-12-03 22:39:34 +0000127
Eric Biedermane9a271e32003-09-02 03:36:25 +0000128 dev = malloc(sizeof(*dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000129 if (dev == 0)
Uwe Hermanne4870472010-11-04 23:23:47 +0000130 die("alloc_dev(): out of memory.\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000131
Eric Biedermane9a271e32003-09-02 03:36:25 +0000132 memset(dev, 0, sizeof(*dev));
133 memcpy(&dev->path, path, sizeof(*path));
134
Myles Watson29cc9ed2009-07-02 18:56:24 +0000135 /* By default devices are enabled. */
Eric Biederman03acab62004-10-14 21:25:53 +0000136 dev->enabled = 1;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000137
Eric Biedermanb78c1972004-10-14 20:54:17 +0000138 /* Add the new device to the list of children of the bus. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000139 dev->bus = parent;
Uwe Hermanne4870472010-11-04 23:23:47 +0000140 if (child)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000141 child->sibling = dev;
Uwe Hermanne4870472010-11-04 23:23:47 +0000142 else
Eric Biedermane9a271e32003-09-02 03:36:25 +0000143 parent->children = dev;
Li-Ta Loe5266692004-03-23 21:28:05 +0000144
Eric Biederman03acab62004-10-14 21:25:53 +0000145 /* Append a new device to the global device list.
146 * The list is used to find devices once everything is set up.
147 */
Myles Watson70679a02010-09-01 21:03:03 +0000148 last_dev->next = dev;
149 last_dev = dev;
Eric Biederman03acab62004-10-14 21:25:53 +0000150
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300151 return dev;
152}
153
Elyes HAOUASd34a7852018-09-17 10:44:14 +0200154struct device *alloc_dev(struct bus *parent, struct device_path *path)
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300155{
Elyes HAOUASe3480662018-05-06 20:32:23 +0200156 struct device *dev;
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300157 spin_lock(&dev_lock);
158 dev = __alloc_dev(parent, path);
Eric Biederman03acab62004-10-14 21:25:53 +0000159 spin_unlock(&dev_lock);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000160 return dev;
161}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000162
Li-Ta Loe5266692004-03-23 21:28:05 +0000163/**
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300164 * See if a device structure already exists and if not allocate it.
165 *
166 * @param parent The bus to find the device on.
167 * @param path The relative path from the bus to the appropriate device.
168 * @return Pointer to a device structure for the device on bus at path.
169 */
Elyes HAOUASd34a7852018-09-17 10:44:14 +0200170struct device *alloc_find_dev(struct bus *parent, struct device_path *path)
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300171{
Elyes HAOUASe3480662018-05-06 20:32:23 +0200172 struct device *child;
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300173 spin_lock(&dev_lock);
174 child = find_dev_path(parent, path);
175 if (!child)
176 child = __alloc_dev(parent, path);
177 spin_unlock(&dev_lock);
178 return child;
179}
180
181/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000182 * Round a number up to an alignment.
183 *
184 * @param val The starting value.
Martin Roth32bc6b62015-01-04 16:54:35 -0700185 * @param pow Alignment as a power of two.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000186 * @return Rounded up number.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000187 */
Eric Biederman448bd632004-10-14 22:52:15 +0000188static resource_t round(resource_t val, unsigned long pow)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000189{
Eric Biederman448bd632004-10-14 22:52:15 +0000190 resource_t mask;
191 mask = (1ULL << pow) - 1ULL;
192 val += mask;
193 val &= ~mask;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000194 return val;
195}
196
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +0200197static const char *resource2str(struct resource *res)
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200198{
199 if (res->flags & IORESOURCE_IO)
200 return "io";
201 if (res->flags & IORESOURCE_PREFETCH)
202 return "prefmem";
203 if (res->flags & IORESOURCE_MEM)
204 return "mem";
205 return "undefined";
206}
207
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000208/**
209 * Read the resources on all devices of a given bus.
210 *
211 * @param bus Bus to read the resources on.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000212 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000213static void read_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000214{
215 struct device *curdev;
216
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000217 printk(BIOS_SPEW, "%s %s bus %x link: %d\n", dev_path(bus->dev),
218 __func__, bus->secondary, bus->link_num);
Eric Biederman448bd632004-10-14 22:52:15 +0000219
Myles Watson29cc9ed2009-07-02 18:56:24 +0000220 /* Walk through all devices and find which resources they need. */
221 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Myles Watson894a3472010-06-09 22:41:35 +0000222 struct bus *link;
Uwe Hermanne4870472010-11-04 23:23:47 +0000223
224 if (!curdev->enabled)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000225 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000226
Eric Biedermane9a271e32003-09-02 03:36:25 +0000227 if (!curdev->ops || !curdev->ops->read_resources) {
Martin Roth7bc74ab2015-11-18 20:23:02 -0700228 if (curdev->path.type != DEVICE_PATH_APIC)
229 printk(BIOS_ERR, "%s missing read_resources\n",
230 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000231 continue;
232 }
Duncan Laurie7ed39762013-07-09 10:46:52 -0700233 post_log_path(curdev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000234 curdev->ops->read_resources(curdev);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000235
236 /* Read in the resources behind the current device's links. */
Myles Watson894a3472010-06-09 22:41:35 +0000237 for (link = curdev->link_list; link; link = link->next)
238 read_resources(link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000239 }
Duncan Laurie7ed39762013-07-09 10:46:52 -0700240 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000241 printk(BIOS_SPEW, "%s read_resources bus %d link: %d done\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000242 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000243}
244
Eric Biedermane9a271e32003-09-02 03:36:25 +0000245struct pick_largest_state {
246 struct resource *last;
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200247 const struct device *result_dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000248 struct resource *result;
249 int seen_last;
250};
251
Myles Watson29cc9ed2009-07-02 18:56:24 +0000252static void pick_largest_resource(void *gp, struct device *dev,
253 struct resource *resource)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000254{
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000255 struct pick_largest_state *state = gp;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000256 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000257
Eric Biedermane9a271e32003-09-02 03:36:25 +0000258 last = state->last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000259
260 /* Be certain to pick the successor to last. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000261 if (resource == last) {
262 state->seen_last = 1;
263 return;
264 }
Myles Watson032a9652009-05-11 22:24:53 +0000265 if (resource->flags & IORESOURCE_FIXED)
Uwe Hermanne4870472010-11-04 23:23:47 +0000266 return; /* Skip it. */
Myles Watson032a9652009-05-11 22:24:53 +0000267 if (last && ((last->align < resource->align) ||
268 ((last->align == resource->align) &&
269 (last->size < resource->size)) ||
270 ((last->align == resource->align) &&
271 (last->size == resource->size) && (!state->seen_last)))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000272 return;
273 }
Myles Watson032a9652009-05-11 22:24:53 +0000274 if (!state->result ||
275 (state->result->align < resource->align) ||
276 ((state->result->align == resource->align) &&
Myles Watson29cc9ed2009-07-02 18:56:24 +0000277 (state->result->size < resource->size))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000278 state->result_dev = dev;
279 state->result = resource;
Myles Watson032a9652009-05-11 22:24:53 +0000280 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000281}
282
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200283static const struct device *largest_resource(struct bus *bus,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000284 struct resource **result_res,
285 unsigned long type_mask,
286 unsigned long type)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000287{
288 struct pick_largest_state state;
289
290 state.last = *result_res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000291 state.result_dev = NULL;
292 state.result = NULL;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000293 state.seen_last = 0;
294
Myles Watson032a9652009-05-11 22:24:53 +0000295 search_bus_resources(bus, type_mask, type, pick_largest_resource,
296 &state);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000297
298 *result_res = state.result;
299 return state.result_dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000300}
301
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000302/**
Uwe Hermanne4870472010-11-04 23:23:47 +0000303 * This function is the guts of the resource allocator.
Myles Watson032a9652009-05-11 22:24:53 +0000304 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000305 * The problem.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000306 * - Allocate resource locations for every device.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000307 * - Don't overlap, and follow the rules of bridges.
308 * - Don't overlap with resources in fixed locations.
309 * - Be efficient so we don't have ugly strategies.
310 *
311 * The strategy.
312 * - Devices that have fixed addresses are the minority so don't
Myles Watson29cc9ed2009-07-02 18:56:24 +0000313 * worry about them too much. Instead only use part of the address
314 * space for devices with programmable addresses. This easily handles
Eric Biederman8ca8d762003-04-22 19:02:15 +0000315 * everything except bridges.
316 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000317 * - PCI devices are required to have their sizes and their alignments
318 * equal. In this case an optimal solution to the packing problem
319 * exists. Allocate all devices from highest alignment to least
320 * alignment or vice versa. Use this.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000321 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000322 * - So we can handle more than PCI run two allocation passes on bridges. The
323 * first to see how large the resources are behind the bridge, and what
324 * their alignment requirements are. The second to assign a safe address to
325 * the devices behind the bridge. This allows us to treat a bridge as just
326 * a device with a couple of resources, and not need to special case it in
327 * the allocator. Also this allows handling of other types of bridges.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000328 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000329 * @param bus The bus we are traversing.
330 * @param bridge The bridge resource which must contain the bus' resources.
331 * @param type_mask This value gets ANDed with the resource type.
332 * @param type This value must match the result of the AND.
333 * @return TODO
Eric Biederman8ca8d762003-04-22 19:02:15 +0000334 */
Myles Watson54913b92009-10-13 20:00:09 +0000335static void compute_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000336 unsigned long type_mask, unsigned long type)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000337{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200338 const struct device *dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000339 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000340 resource_t base;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000341 base = round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000342
John Zhao2deb5fb2019-05-29 18:12:01 -0700343 if (!bus)
344 return;
345
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200346 printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d"
347 " limit: %llx\n", dev_path(bus->dev), resource2str(bridge),
348 base, bridge->size, bridge->align,
Uwe Hermanne4870472010-11-04 23:23:47 +0000349 bridge->gran, bridge->limit);
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000350
Uwe Hermanne4870472010-11-04 23:23:47 +0000351 /* For each child which is a bridge, compute the resource needs. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000352 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000353 struct resource *child_bridge;
354
Myles Watson894a3472010-06-09 22:41:35 +0000355 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000356 continue;
357
358 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000359 for (child_bridge = dev->resource_list; child_bridge;
360 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000361 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000362
Uwe Hermanne4870472010-11-04 23:23:47 +0000363 if (!(child_bridge->flags & IORESOURCE_BRIDGE)
364 || (child_bridge->flags & type_mask) != type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000365 continue;
366
Uwe Hermanne4870472010-11-04 23:23:47 +0000367 /*
368 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000369 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000370 * and non-prefetchable memory. Bridges below them need
371 * it separated. Add the PREFETCH flag to the type_mask
372 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000373 */
Myles Watson894a3472010-06-09 22:41:35 +0000374 link = dev->link_list;
375 while (link && link->link_num !=
376 IOINDEX_LINK(child_bridge->index))
377 link = link->next;
Uwe Hermanne4870472010-11-04 23:23:47 +0000378
379 if (link == NULL) {
Myles Watson894a3472010-06-09 22:41:35 +0000380 printk(BIOS_ERR, "link %ld not found on %s\n",
381 IOINDEX_LINK(child_bridge->index),
382 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000383 }
384
Myles Watson894a3472010-06-09 22:41:35 +0000385 compute_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000386 type_mask | IORESOURCE_PREFETCH,
387 type | (child_bridge->flags &
388 IORESOURCE_PREFETCH));
389 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000390 }
391
Myles Watson29cc9ed2009-07-02 18:56:24 +0000392 /* Remember we haven't found anything yet. */
393 resource = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000394
Uwe Hermanne4870472010-11-04 23:23:47 +0000395 /*
396 * Walk through all the resources on the current bus and compute the
397 * amount of address space taken by them. Take granularity and
Myles Watson29cc9ed2009-07-02 18:56:24 +0000398 * alignment into account.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000399 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000400 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000401
Myles Watson29cc9ed2009-07-02 18:56:24 +0000402 /* Size 0 resources can be skipped. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000403 if (!resource->size)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000404 continue;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000405
Myles Watson29cc9ed2009-07-02 18:56:24 +0000406 /* Propagate the resource alignment to the bridge resource. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000407 if (resource->align > bridge->align)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000408 bridge->align = resource->align;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000409
410 /* Propagate the resource limit to the bridge register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000411 if (bridge->limit > resource->limit)
Eric Biedermandbec2d42004-10-21 10:44:08 +0000412 bridge->limit = resource->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000413
414 /* Warn if it looks like APICs aren't declared. */
415 if ((resource->limit == 0xffffffff) &&
416 (resource->flags & IORESOURCE_ASSIGNED)) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000417 printk(BIOS_ERR,
418 "Resource limit looks wrong! (no APIC?)\n");
Patrick Georgi51615092012-03-11 19:31:03 +0100419 printk(BIOS_ERR, "%s %02lx limit %08llx\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000420 dev_path(dev), resource->index, resource->limit);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000421 }
Stefan Reinauer51754a32008-08-01 12:28:38 +0000422
Eric Biederman8ca8d762003-04-22 19:02:15 +0000423 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000424 /*
425 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000426 * expansion card addresses. The legacy PCI decodes
427 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
428 * 0x00 - 0xff can be used out of each 0x400 block of
429 * I/O space.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000430 */
Eric Biedermanbbb6d102003-08-04 19:54:48 +0000431 if ((base & 0x300) != 0) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000432 base = (base & ~0x3ff) + 0x400;
433 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000434 /*
435 * Don't allow allocations in the VGA I/O range.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000436 * PCI has special cases for that.
437 */
438 else if ((base >= 0x3b0) && (base <= 0x3df)) {
439 base = 0x3e0;
440 }
441 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000442 /* Base must be aligned. */
443 base = round(base, resource->align);
444 resource->base = base;
445 base += resource->size;
Myles Watson032a9652009-05-11 22:24:53 +0000446
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000447 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000448 dev_path(dev), resource->index, resource->base,
449 resource->base + resource->size - 1,
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200450 resource2str(resource));
Eric Biederman8ca8d762003-04-22 19:02:15 +0000451 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000452
453 /*
454 * A PCI bridge resource does not need to be a power of two size, but
455 * it does have a minimum granularity. Round the size up to that
456 * minimum granularity so we know not to place something else at an
Martin Roth63373ed2013-07-08 16:24:19 -0600457 * address positively decoded by the bridge.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000458 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000459 bridge->size = round(base, bridge->gran) -
460 round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000461
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200462 printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d"
463 " limit: %llx done\n", dev_path(bus->dev),
464 resource2str(bridge),
Uwe Hermanne4870472010-11-04 23:23:47 +0000465 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000466}
467
468/**
469 * This function is the second part of the resource allocator.
470 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000471 * See the compute_resources function for a more detailed explanation.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000472 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000473 * This function assigns the resources a value.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000474 *
475 * @param bus The bus we are traversing.
476 * @param bridge The bridge resource which must contain the bus' resources.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000477 * @param type_mask This value gets ANDed with the resource type.
478 * @param type This value must match the result of the AND.
Uwe Hermanne4870472010-11-04 23:23:47 +0000479 *
480 * @see compute_resources
Myles Watson29cc9ed2009-07-02 18:56:24 +0000481 */
Myles Watson54913b92009-10-13 20:00:09 +0000482static void allocate_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000483 unsigned long type_mask, unsigned long type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000484{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200485 const struct device *dev;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000486 struct resource *resource;
487 resource_t base;
488 base = bridge->base;
489
John Zhao2deb5fb2019-05-29 18:12:01 -0700490 if (!bus)
491 return;
492
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200493 printk(BIOS_SPEW, "%s %s: base:%llx size:%llx align:%d gran:%d "
494 "limit:%llx\n", dev_path(bus->dev),
495 resource2str(bridge),
Myles Watson29cc9ed2009-07-02 18:56:24 +0000496 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
497
498 /* Remember we haven't found anything yet. */
499 resource = NULL;
500
Uwe Hermanne4870472010-11-04 23:23:47 +0000501 /*
502 * Walk through all the resources on the current bus and allocate them
Myles Watson29cc9ed2009-07-02 18:56:24 +0000503 * address space.
504 */
505 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
506
507 /* Propagate the bridge limit to the resource register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000508 if (resource->limit > bridge->limit)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000509 resource->limit = bridge->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000510
511 /* Size 0 resources can be skipped. */
512 if (!resource->size) {
513 /* Set the base to limit so it doesn't confuse tolm. */
514 resource->base = resource->limit;
515 resource->flags |= IORESOURCE_ASSIGNED;
516 continue;
517 }
518
519 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000520 /*
521 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000522 * expansion card addresses. The legacy PCI decodes
523 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
524 * 0x00 - 0xff can be used out of each 0x400 block of
525 * I/O space.
526 */
527 if ((base & 0x300) != 0) {
528 base = (base & ~0x3ff) + 0x400;
529 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000530 /*
531 * Don't allow allocations in the VGA I/O range.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000532 * PCI has special cases for that.
533 */
534 else if ((base >= 0x3b0) && (base <= 0x3df)) {
535 base = 0x3e0;
536 }
537 }
538
539 if ((round(base, resource->align) + resource->size - 1) <=
540 resource->limit) {
541 /* Base must be aligned. */
542 base = round(base, resource->align);
543 resource->base = base;
Kyösti Mälkki134b6162015-03-23 19:58:23 +0200544 resource->limit = resource->base + resource->size - 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000545 resource->flags |= IORESOURCE_ASSIGNED;
546 resource->flags &= ~IORESOURCE_STORED;
547 base += resource->size;
548 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000549 printk(BIOS_ERR, "!! Resource didn't fit !!\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000550 printk(BIOS_ERR, " aligned base %llx size %llx "
551 "limit %llx\n", round(base, resource->align),
552 resource->size, resource->limit);
553 printk(BIOS_ERR, " %llx needs to be <= %llx "
554 "(limit)\n", (round(base, resource->align) +
Myles Watson29cc9ed2009-07-02 18:56:24 +0000555 resource->size) - 1, resource->limit);
Uwe Hermanne4870472010-11-04 23:23:47 +0000556 printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx]"
557 " %s\n", (resource->flags & IORESOURCE_ASSIGNED)
558 ? "Assigned: " : "", dev_path(dev),
559 resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000560 resource->base + resource->size - 1,
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200561 resource2str(resource));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000562 }
563
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200564 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
565 dev_path(dev), resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000566 resource->size ? resource->base + resource->size - 1 :
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200567 resource->base, resource2str(resource));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000568 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000569
570 /*
571 * A PCI bridge resource does not need to be a power of two size, but
Myles Watson29cc9ed2009-07-02 18:56:24 +0000572 * it does have a minimum granularity. Round the size up to that
573 * minimum granularity so we know not to place something else at an
574 * address positively decoded by the bridge.
575 */
576
577 bridge->flags |= IORESOURCE_ASSIGNED;
578
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200579 printk(BIOS_SPEW, "%s %s: next_base: %llx size: %llx align: %d "
580 "gran: %d done\n", dev_path(bus->dev),
581 resource2str(bridge), base, bridge->size, bridge->align,
Uwe Hermanne4870472010-11-04 23:23:47 +0000582 bridge->gran);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000583
584 /* For each child which is a bridge, allocate_resources. */
585 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000586 struct resource *child_bridge;
587
Myles Watson894a3472010-06-09 22:41:35 +0000588 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000589 continue;
590
591 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000592 for (child_bridge = dev->resource_list; child_bridge;
593 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000594 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000595
596 if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
597 (child_bridge->flags & type_mask) != type)
598 continue;
599
Uwe Hermanne4870472010-11-04 23:23:47 +0000600 /*
601 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000602 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000603 * and non-prefetchable memory. Bridges below them need
604 * it separated. Add the PREFETCH flag to the type_mask
605 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000606 */
Myles Watson894a3472010-06-09 22:41:35 +0000607 link = dev->link_list;
608 while (link && link->link_num !=
609 IOINDEX_LINK(child_bridge->index))
610 link = link->next;
611 if (link == NULL)
612 printk(BIOS_ERR, "link %ld not found on %s\n",
613 IOINDEX_LINK(child_bridge->index),
614 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000615
Myles Watson894a3472010-06-09 22:41:35 +0000616 allocate_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000617 type_mask | IORESOURCE_PREFETCH,
618 type | (child_bridge->flags &
619 IORESOURCE_PREFETCH));
620 }
621 }
622}
623
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200624static int resource_is(struct resource *res, u32 type)
625{
626 return (res->flags & IORESOURCE_TYPE_MASK) == type;
627}
Myles Watson29cc9ed2009-07-02 18:56:24 +0000628
629struct constraints {
Kyösti Mälkkifcbebb62015-03-17 06:42:54 +0200630 struct resource io, mem;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000631};
632
Elyes HAOUASe3480662018-05-06 20:32:23 +0200633static struct resource *resource_limit(struct constraints *limits,
634 struct resource *res)
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200635{
636 struct resource *lim = NULL;
637
638 /* MEM, or I/O - skip any others. */
639 if (resource_is(res, IORESOURCE_MEM))
640 lim = &limits->mem;
641 else if (resource_is(res, IORESOURCE_IO))
642 lim = &limits->io;
643
644 return lim;
645}
646
Elyes HAOUASe3480662018-05-06 20:32:23 +0200647static void constrain_resources(const struct device *dev,
648 struct constraints* limits)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000649{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200650 const struct device *child;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000651 struct resource *res;
652 struct resource *lim;
Myles Watson894a3472010-06-09 22:41:35 +0000653 struct bus *link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000654
Myles Watson29cc9ed2009-07-02 18:56:24 +0000655 /* Constrain limits based on the fixed resources of this device. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000656 for (res = dev->resource_list; res; res = res->next) {
Patrick Georgi18c585b2009-08-28 12:48:02 +0000657 if (!(res->flags & IORESOURCE_FIXED))
658 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000659 if (!res->size) {
660 /* It makes no sense to have 0-sized, fixed resources.*/
Uwe Hermanne4870472010-11-04 23:23:47 +0000661 printk(BIOS_ERR, "skipping %s@%lx fixed resource, "
662 "size=0!\n", dev_path(dev), res->index);
Patrick Georgi6bd93f42009-08-19 17:29:41 +0000663 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000664 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000665
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200666 lim = resource_limit(limits, res);
667 if (!lim)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000668 continue;
669
Uwe Hermanne4870472010-11-04 23:23:47 +0000670 /*
671 * Is it a fixed resource outside the current known region?
672 * If so, we don't have to consider it - it will be handled
673 * correctly and doesn't affect current region's limits.
674 */
675 if (((res->base + res->size -1) < lim->base)
676 || (res->base > lim->limit))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000677 continue;
678
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200679 printk(BIOS_SPEW, "%s: %s %02lx base %08llx limit %08llx %s (fixed)\n",
680 __func__, dev_path(dev), res->index, res->base,
681 res->base + res->size - 1, resource2str(res));
682
Uwe Hermanne4870472010-11-04 23:23:47 +0000683 /*
684 * Choose to be above or below fixed resources. This check is
685 * signed so that "negative" amounts of space are handled
686 * correctly.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000687 */
Uwe Hermanne4870472010-11-04 23:23:47 +0000688 if ((signed long long)(lim->limit - (res->base + res->size -1))
689 > (signed long long)(res->base - lim->base))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000690 lim->base = res->base + res->size;
691 else
692 lim->limit = res->base -1;
693 }
694
695 /* Descend into every enabled child and look for fixed resources. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000696 for (link = dev->link_list; link; link = link->next) {
697 for (child = link->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000698 if (child->enabled)
699 constrain_resources(child, limits);
Uwe Hermanne4870472010-11-04 23:23:47 +0000700 }
701 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000702}
703
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200704static void avoid_fixed_resources(const struct device *dev)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000705{
706 struct constraints limits;
707 struct resource *res;
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200708 struct resource *lim;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000709
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000710 printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000711
Uwe Hermanne4870472010-11-04 23:23:47 +0000712 /* Initialize constraints to maximum size. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000713 limits.io.base = 0;
714 limits.io.limit = 0xffffffffffffffffULL;
715 limits.mem.base = 0;
716 limits.mem.limit = 0xffffffffffffffffULL;
717
718 /* Constrain the limits to dev's initial resources. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000719 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000720 if ((res->flags & IORESOURCE_FIXED))
721 continue;
Patrick Georgi51615092012-03-11 19:31:03 +0100722 printk(BIOS_SPEW, "%s:@%s %02lx limit %08llx\n", __func__,
Uwe Hermanne4870472010-11-04 23:23:47 +0000723 dev_path(dev), res->index, res->limit);
Kyösti Mälkkifcbebb62015-03-17 06:42:54 +0200724
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200725 lim = resource_limit(&limits, res);
726 if (!lim)
727 continue;
728
729 if (res->base > lim->base)
730 lim->base = res->base;
Elyes HAOUAS1943f372018-05-04 16:30:39 +0200731 if (res->limit < lim->limit)
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200732 lim->limit = res->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000733 }
734
735 /* Look through the tree for fixed resources and update the limits. */
736 constrain_resources(dev, &limits);
737
738 /* Update dev's resources with new limits. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000739 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000740 if ((res->flags & IORESOURCE_FIXED))
741 continue;
742
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200743 lim = resource_limit(&limits, res);
744 if (!lim)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000745 continue;
746
Myles Watson29cc9ed2009-07-02 18:56:24 +0000747 /* Is the resource outside the limits? */
748 if (lim->base > res->base)
749 res->base = lim->base;
750 if (res->limit > lim->limit)
751 res->limit = lim->limit;
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200752
Kyösti Mälkki634899c2015-03-23 14:22:22 +0200753 /* MEM resources need to start at the highest address manageable. */
754 if (res->flags & IORESOURCE_MEM)
755 res->base = resource_max(res);
756
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200757 printk(BIOS_SPEW, "%s:@%s %02lx base %08llx limit %08llx\n",
758 __func__, dev_path(dev), res->index, res->base, res->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000759 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000760}
arch import user (historical)dc811182005-07-06 17:16:09 +0000761
Elyes HAOUASe3480662018-05-06 20:32:23 +0200762struct device *vga_pri = NULL;
Myles Watsonc7233e02009-07-02 19:02:33 +0000763static void set_vga_bridge_bits(void)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000764{
Uwe Hermann312673c2009-10-27 21:49:33 +0000765 /*
Martin Roth63373ed2013-07-08 16:24:19 -0600766 * FIXME: Modify set_vga_bridge() so it is less PCI-centric!
Uwe Hermann312673c2009-10-27 21:49:33 +0000767 * This function knows too much about PCI stuff, it should be just
768 * an iterator/visitor.
769 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000770
Myles Watson29cc9ed2009-07-02 18:56:24 +0000771 /* FIXME: Handle the VGA palette snooping. */
Patrick Georgi557ecf22012-07-20 12:16:17 +0200772 struct device *dev, *vga, *vga_onboard;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000773 struct bus *bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000774
Eric Biedermanb78c1972004-10-14 20:54:17 +0000775 bus = 0;
776 vga = 0;
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000777 vga_onboard = 0;
Uwe Hermanne4870472010-11-04 23:23:47 +0000778
Patrick Georgi557ecf22012-07-20 12:16:17 +0200779 dev = NULL;
780 while ((dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev))) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000781 if (!dev->enabled)
782 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000783
Patrick Georgi557ecf22012-07-20 12:16:17 +0200784 printk(BIOS_DEBUG, "found VGA at %s\n", dev_path(dev));
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000785
Patrick Georgi557ecf22012-07-20 12:16:17 +0200786 if (dev->on_mainboard) {
787 vga_onboard = dev;
Kostr1f0d3792012-10-06 13:27:58 +0400788 } else {
Patrick Georgi557ecf22012-07-20 12:16:17 +0200789 vga = dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000790 }
Myles Watson032a9652009-05-11 22:24:53 +0000791
Patrick Georgi557ecf22012-07-20 12:16:17 +0200792 /* It isn't safe to enable all VGA cards. */
793 dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Patrick Georgi594473d2012-07-25 08:55:53 +0200794 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000795
Uwe Hermanne4870472010-11-04 23:23:47 +0000796 if (!vga)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000797 vga = vga_onboard;
Patrick Georgi557ecf22012-07-20 12:16:17 +0200798
Julius Werner5d1f9a02019-03-07 17:07:26 -0800799 if (CONFIG(ONBOARD_VGA_IS_PRIMARY) && vga_onboard)
Patrick Georgi557ecf22012-07-20 12:16:17 +0200800 vga = vga_onboard;
Myles Watson032a9652009-05-11 22:24:53 +0000801
Patrick Georgi5869fa22012-07-20 12:29:33 +0200802 /* If we prefer plugin VGA over chipset VGA, the chipset might
803 want to know. */
Julius Werner5d1f9a02019-03-07 17:07:26 -0800804 if (!CONFIG(ONBOARD_VGA_IS_PRIMARY) && (vga != vga_onboard) &&
Patrick Georgi5869fa22012-07-20 12:29:33 +0200805 vga_onboard && vga_onboard->ops && vga_onboard->ops->disable) {
806 printk(BIOS_DEBUG, "Use plugin graphics over integrated.\n");
807 vga_onboard->ops->disable(vga_onboard);
808 }
809
arch import user (historical)dc811182005-07-06 17:16:09 +0000810 if (vga) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000811 /* VGA is first add-on card or the only onboard VGA. */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000812 printk(BIOS_DEBUG, "Setting up VGA for %s\n", dev_path(vga));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000813 /* All legacy VGA cards have MEM & I/O space registers. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000814 vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
815 vga_pri = vga;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000816 bus = vga->bus;
817 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000818
Myles Watson29cc9ed2009-07-02 18:56:24 +0000819 /* Now walk up the bridges setting the VGA enable. */
820 while (bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000821 printk(BIOS_DEBUG, "Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000822 dev_path(bus->dev));
Li-Ta Lodb7f47c2004-01-08 21:15:49 +0000823 bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000824 bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus;
Myles Watson032a9652009-05-11 22:24:53 +0000825 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000826}
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000827
Li-Ta Lo04930692004-11-25 17:37:19 +0000828/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000829 * Assign the computed resources to the devices on the bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000830 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000831 * Use the device specific set_resources() method to store the computed
Li-Ta Lo04930692004-11-25 17:37:19 +0000832 * resources to hardware. For bridge devices, the set_resources() method
833 * has to recurse into every down stream buses.
834 *
835 * Mutual recursion:
836 * assign_resources() -> device_operation::set_resources()
837 * device_operation::set_resources() -> assign_resources()
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000838 *
839 * @param bus Pointer to the structure for this bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000840 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000841void assign_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000842{
843 struct device *curdev;
844
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000845 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000846 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000847
Myles Watson29cc9ed2009-07-02 18:56:24 +0000848 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000849 if (!curdev->enabled || !curdev->resource_list)
Eric Biederman03acab62004-10-14 21:25:53 +0000850 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000851
Eric Biedermane9a271e32003-09-02 03:36:25 +0000852 if (!curdev->ops || !curdev->ops->set_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000853 printk(BIOS_ERR, "%s missing set_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000854 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000855 continue;
856 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700857 post_log_path(curdev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000858 curdev->ops->set_resources(curdev);
859 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700860 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000861 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000862 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000863}
864
Li-Ta Lo5782d272004-04-26 17:51:20 +0000865/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000866 * Enable the resources for devices on a link.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000867 *
868 * Enable resources of the device by calling the device specific
869 * enable_resources() method.
870 *
871 * The parent's resources should be enabled first to avoid having enabling
872 * order problem. This is done by calling the parent's enable_resources()
Martin Roth63373ed2013-07-08 16:24:19 -0600873 * method before its children's enable_resources() methods.
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000874 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000875 * @param link The link whose devices' resources are to be enabled.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000876 */
Myles Watson7eac4452010-06-17 16:16:56 +0000877static void enable_resources(struct bus *link)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000878{
Myles Watson7eac4452010-06-17 16:16:56 +0000879 struct device *dev;
880 struct bus *c_link;
881
882 for (dev = link->children; dev; dev = dev->sibling) {
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700883 if (dev->enabled && dev->ops && dev->ops->enable_resources) {
884 post_log_path(dev);
Myles Watson7eac4452010-06-17 16:16:56 +0000885 dev->ops->enable_resources(dev);
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700886 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000887 }
Myles Watson7eac4452010-06-17 16:16:56 +0000888
889 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000890 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +0000891 enable_resources(c_link);
Eric Biederman83b991a2003-10-11 06:20:25 +0000892 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700893 post_log_clear();
Eric Biederman8ca8d762003-04-22 19:02:15 +0000894}
895
Myles Watson032a9652009-05-11 22:24:53 +0000896/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000897 * Reset all of the devices on a bus and clear the bus's reset_needed flag.
898 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000899 * @param bus Pointer to the bus structure.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000900 * @return 1 if the bus was successfully reset, 0 otherwise.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000901 */
902int reset_bus(struct bus *bus)
903{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000904 if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000905 bus->dev->ops->reset_bus(bus);
906 bus->reset_needed = 0;
907 return 1;
908 }
909 return 0;
910}
911
Myles Watson032a9652009-05-11 22:24:53 +0000912/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000913 * Scan for devices on a bus.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000914 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000915 * If there are bridges on the bus, recursively scan the buses behind the
916 * bridges. If the setting up and tuning of the bus causes a reset to be
917 * required, reset the bus and scan it again.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000918 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000919 * @param busdev Pointer to the bus device.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000920 */
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200921static void scan_bus(struct device *busdev)
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000922{
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000923 int do_scan_bus;
Paul Menzel662380f2015-10-20 10:21:08 +0200924 struct stopwatch sw;
925
926 stopwatch_init(&sw);
Uwe Hermanne4870472010-11-04 23:23:47 +0000927
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200928 if (!busdev->enabled)
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200929 return;
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200930
931 printk(BIOS_SPEW, "%s scanning...\n", dev_path(busdev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000932
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700933 post_log_path(busdev);
934
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000935 do_scan_bus = 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000936 while (do_scan_bus) {
Myles Watson894a3472010-06-09 22:41:35 +0000937 struct bus *link;
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200938 busdev->ops->scan_bus(busdev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000939 do_scan_bus = 0;
Myles Watson894a3472010-06-09 22:41:35 +0000940 for (link = busdev->link_list; link; link = link->next) {
941 if (link->reset_needed) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000942 if (reset_bus(link))
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000943 do_scan_bus = 1;
Uwe Hermanne4870472010-11-04 23:23:47 +0000944 else
Myles Watson29cc9ed2009-07-02 18:56:24 +0000945 busdev->bus->reset_needed = 1;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000946 }
947 }
948 }
Paul Menzel662380f2015-10-20 10:21:08 +0200949
950 printk(BIOS_DEBUG, "%s: scanning of bus %s took %ld usecs\n",
951 __func__, dev_path(busdev), stopwatch_duration_usecs(&sw));
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000952}
953
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200954void scan_bridges(struct bus *bus)
955{
956 struct device *child;
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200957
958 for (child = bus->children; child; child = child->sibling) {
959 if (!child->ops || !child->ops->scan_bus)
960 continue;
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200961 scan_bus(child);
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200962 }
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200963}
964
Li-Ta Loe5266692004-03-23 21:28:05 +0000965/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000966 * Determine the existence of devices and extend the device tree.
Li-Ta Lo04930692004-11-25 17:37:19 +0000967 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000968 * Most of the devices in the system are listed in the mainboard devicetree.cb
Li-Ta Lo04930692004-11-25 17:37:19 +0000969 * file. The device structures for these devices are generated at compile
970 * time by the config tool and are organized into the device tree. This
971 * function determines if the devices created at compile time actually exist
972 * in the physical system.
973 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000974 * For devices in the physical system but not listed in devicetree.cb,
Li-Ta Lo04930692004-11-25 17:37:19 +0000975 * the device structures have to be created at run time and attached to the
Li-Ta Loe5266692004-03-23 21:28:05 +0000976 * device tree.
977 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000978 * This function starts from the root device 'dev_root', scans the buses in
979 * the system recursively, and modifies the device tree according to the
980 * result of the probe.
Li-Ta Loe5266692004-03-23 21:28:05 +0000981 *
Li-Ta Lo5782d272004-04-26 17:51:20 +0000982 * This function has no idea how to scan and probe buses and devices at all.
983 * It depends on the bus/device specific scan_bus() method to do it. The
Li-Ta Lo04930692004-11-25 17:37:19 +0000984 * scan_bus() method also has to create the device structure and attach
Myles Watson032a9652009-05-11 22:24:53 +0000985 * it to the device tree.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000986 */
987void dev_enumerate(void)
988{
989 struct device *root;
Uwe Hermanne4870472010-11-04 23:23:47 +0000990
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000991 printk(BIOS_INFO, "Enumerating buses...\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000992
Eric Biederman8ca8d762003-04-22 19:02:15 +0000993 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000994
Uwe Hermanne4870472010-11-04 23:23:47 +0000995 show_all_devs(BIOS_SPEW, "Before device enumeration.");
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000996 printk(BIOS_SPEW, "Compare with tree...\n");
Kyösti Mälkki3d3c8c32016-08-15 10:04:21 +0300997 show_devs_tree(root, BIOS_SPEW, 0);
Myles Watsoncd5d7562009-05-12 13:43:34 +0000998
Stefan Reinauera675d492012-08-07 14:50:47 -0700999 if (root->chip_ops && root->chip_ops->enable_dev)
1000 root->chip_ops->enable_dev(root);
Uwe Hermanne4870472010-11-04 23:23:47 +00001001
Eric Biedermanb78c1972004-10-14 20:54:17 +00001002 if (!root->ops || !root->ops->scan_bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001003 printk(BIOS_ERR, "dev_root missing scan_bus operation");
Eric Biedermanb78c1972004-10-14 20:54:17 +00001004 return;
1005 }
Kyösti Mälkki580e7222015-03-19 21:04:23 +02001006 scan_bus(root);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001007 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001008 printk(BIOS_INFO, "done\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001009}
1010
Li-Ta Loe5266692004-03-23 21:28:05 +00001011/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001012 * Configure devices on the devices tree.
Myles Watson032a9652009-05-11 22:24:53 +00001013 *
Li-Ta Lo04930692004-11-25 17:37:19 +00001014 * Starting at the root of the device tree, travel it recursively in two
1015 * passes. In the first pass, we compute and allocate resources (ranges)
Martin Roth63373ed2013-07-08 16:24:19 -06001016 * required by each device. In the second pass, the resources ranges are
Li-Ta Lo04930692004-11-25 17:37:19 +00001017 * relocated to their final position and stored to the hardware.
Li-Ta Lo5782d272004-04-26 17:51:20 +00001018 *
Myles Watson29cc9ed2009-07-02 18:56:24 +00001019 * I/O resources grow upward. MEM resources grow downward.
Li-Ta Lo5782d272004-04-26 17:51:20 +00001020 *
1021 * Since the assignment is hierarchical we set the values into the dev_root
Myles Watson032a9652009-05-11 22:24:53 +00001022 * struct.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001023 */
1024void dev_configure(void)
1025{
Myles Watson29cc9ed2009-07-02 18:56:24 +00001026 struct resource *res;
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +02001027 const struct device *root;
1028 const struct device *child;
Li-Ta Loe5266692004-03-23 21:28:05 +00001029
Marc Jones80bd74c2012-02-21 17:44:35 +01001030 set_vga_bridge_bits();
Marc Jones80bd74c2012-02-21 17:44:35 +01001031
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001032 printk(BIOS_INFO, "Allocating resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001033
Eric Biedermanb78c1972004-10-14 20:54:17 +00001034 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +00001035
Uwe Hermanne4870472010-11-04 23:23:47 +00001036 /*
1037 * Each domain should create resources which contain the entire address
Myles Watson29cc9ed2009-07-02 18:56:24 +00001038 * space for IO, MEM, and PREFMEM resources in the domain. The
1039 * allocation of device resources will be done from this address space.
1040 */
Myles Watsoncd5d7562009-05-12 13:43:34 +00001041
Myles Watson29cc9ed2009-07-02 18:56:24 +00001042 /* Read the resources for the entire tree. */
Li-Ta Lo04930692004-11-25 17:37:19 +00001043
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001044 printk(BIOS_INFO, "Reading resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001045 read_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001046 printk(BIOS_INFO, "Done reading resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001047
Stefan Reinauer39e72292009-10-26 16:47:05 +00001048 print_resource_tree(root, BIOS_SPEW, "After reading.");
Myles Watsoncd5d7562009-05-12 13:43:34 +00001049
Myles Watson29cc9ed2009-07-02 18:56:24 +00001050 /* Compute resources for all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001051 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001052 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001053 continue;
Duncan Laurie7ed39762013-07-09 10:46:52 -07001054 post_log_path(child);
Myles Watsonc25cc112010-05-21 14:33:48 +00001055 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001056 if (res->flags & IORESOURCE_FIXED)
1057 continue;
Myles Watson29cc9ed2009-07-02 18:56:24 +00001058 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001059 compute_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001060 res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001061 continue;
1062 }
1063 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001064 compute_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001065 res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001066 continue;
1067 }
1068 }
1069 }
1070
1071 /* For all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001072 for (child = root->link_list->children; child; child=child->sibling)
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001073 if (child->path.type == DEVICE_PATH_DOMAIN)
Myles Watson29cc9ed2009-07-02 18:56:24 +00001074 avoid_fixed_resources(child);
1075
Eric Biedermanb78c1972004-10-14 20:54:17 +00001076 /* Store the computed resource allocations into device registers ... */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001077 printk(BIOS_INFO, "Setting resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001078 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001079 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001080 continue;
Duncan Laurie7ed39762013-07-09 10:46:52 -07001081 post_log_path(child);
Myles Watsonc25cc112010-05-21 14:33:48 +00001082 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001083 if (res->flags & IORESOURCE_FIXED)
1084 continue;
Myles Watson29cc9ed2009-07-02 18:56:24 +00001085 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001086 allocate_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001087 res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001088 continue;
1089 }
1090 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001091 allocate_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001092 res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001093 continue;
1094 }
1095 }
1096 }
Myles Watson894a3472010-06-09 22:41:35 +00001097 assign_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001098 printk(BIOS_INFO, "Done setting resources.\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001099 print_resource_tree(root, BIOS_SPEW, "After assigning values.");
Eric Biederman03acab62004-10-14 21:25:53 +00001100
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001101 printk(BIOS_INFO, "Done allocating resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001102}
1103
Li-Ta Loe5266692004-03-23 21:28:05 +00001104/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001105 * Enable devices on the device tree.
Li-Ta Loe5266692004-03-23 21:28:05 +00001106 *
1107 * Starting at the root, walk the tree and enable all devices/bridges by
1108 * calling the device's enable_resources() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001109 */
1110void dev_enable(void)
1111{
Myles Watson7eac4452010-06-17 16:16:56 +00001112 struct bus *link;
1113
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001114 printk(BIOS_INFO, "Enabling resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001115
Uwe Hermanne4870472010-11-04 23:23:47 +00001116 /* Now enable everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001117 for (link = dev_root.link_list; link; link = link->next)
1118 enable_resources(link);
Li-Ta Loe5266692004-03-23 21:28:05 +00001119
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001120 printk(BIOS_INFO, "done.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001121}
1122
Li-Ta Loe5266692004-03-23 21:28:05 +00001123/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001124 * Initialize a specific device.
Myles Watson7eac4452010-06-17 16:16:56 +00001125 *
Uwe Hermanne4870472010-11-04 23:23:47 +00001126 * The parent should be initialized first to avoid having an ordering problem.
Martin Roth63373ed2013-07-08 16:24:19 -06001127 * This is done by calling the parent's init() method before its children's
Uwe Hermanne4870472010-11-04 23:23:47 +00001128 * init() methods.
Myles Watson7eac4452010-06-17 16:16:56 +00001129 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001130 * @param dev The device to be initialized.
Myles Watson7eac4452010-06-17 16:16:56 +00001131 */
1132static void init_dev(struct device *dev)
1133{
Uwe Hermanne4870472010-11-04 23:23:47 +00001134 if (!dev->enabled)
Myles Watson7eac4452010-06-17 16:16:56 +00001135 return;
Myles Watson7eac4452010-06-17 16:16:56 +00001136
1137 if (!dev->initialized && dev->ops && dev->ops->init) {
Julius Wernercd49cce2019-03-05 16:53:33 -08001138#if CONFIG(HAVE_MONOTONIC_TIMER)
Aaron Durbin46ba4802014-09-23 16:34:40 -05001139 struct stopwatch sw;
1140 stopwatch_init(&sw);
Aaron Durbin05294292013-04-30 15:41:13 -05001141#endif
Myles Watson7eac4452010-06-17 16:16:56 +00001142 if (dev->path.type == DEVICE_PATH_I2C) {
1143 printk(BIOS_DEBUG, "smbus: %s[%d]->",
1144 dev_path(dev->bus->dev), dev->bus->link_num);
1145 }
1146
Paul Menzeldb232152015-06-07 20:28:17 +02001147 printk(BIOS_DEBUG, "%s init ...\n", dev_path(dev));
Myles Watson7eac4452010-06-17 16:16:56 +00001148 dev->initialized = 1;
1149 dev->ops->init(dev);
Julius Wernercd49cce2019-03-05 16:53:33 -08001150#if CONFIG(HAVE_MONOTONIC_TIMER)
Paul Menzeldb232152015-06-07 20:28:17 +02001151 printk(BIOS_DEBUG, "%s init finished in %ld usecs\n", dev_path(dev),
Aaron Durbin46ba4802014-09-23 16:34:40 -05001152 stopwatch_duration_usecs(&sw));
Aaron Durbin05294292013-04-30 15:41:13 -05001153#endif
Myles Watson7eac4452010-06-17 16:16:56 +00001154 }
1155}
1156
1157static void init_link(struct bus *link)
1158{
1159 struct device *dev;
1160 struct bus *c_link;
1161
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001162 for (dev = link->children; dev; dev = dev->sibling) {
Duncan Lauriecb73a842013-06-10 10:41:04 -07001163 post_code(POST_BS_DEV_INIT);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001164 post_log_path(dev);
Myles Watson7eac4452010-06-17 16:16:56 +00001165 init_dev(dev);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001166 }
Myles Watson7eac4452010-06-17 16:16:56 +00001167
1168 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +00001169 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +00001170 init_link(c_link);
Myles Watson7eac4452010-06-17 16:16:56 +00001171 }
1172}
1173
1174/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001175 * Initialize all devices in the global device tree.
Myles Watson7eac4452010-06-17 16:16:56 +00001176 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001177 * Starting at the root device, call the device's init() method to do
1178 * device-specific setup, then call each child's init() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001179 */
1180void dev_initialize(void)
1181{
Myles Watson7eac4452010-06-17 16:16:56 +00001182 struct bus *link;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001183
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001184 printk(BIOS_INFO, "Initializing devices...\n");
Myles Watson7eac4452010-06-17 16:16:56 +00001185
Julius Wernercd49cce2019-03-05 16:53:33 -08001186#if CONFIG(ARCH_X86)
Subrata Banikc7590cd2017-09-04 18:44:38 +05301187 /*
1188 * Initialize EBDA area in ramstage if early
1189 * initialization is not done.
1190 */
Julius Wernercd49cce2019-03-05 16:53:33 -08001191 if (!CONFIG(EARLY_EBDA_INIT))
Subrata Banikc7590cd2017-09-04 18:44:38 +05301192 /* Ensure EBDA is prepared before Option ROMs. */
1193 setup_default_ebda();
Duncan Laurieb4aaaa72012-01-17 09:03:11 -08001194#endif
1195
Myles Watson1bd3fb72010-08-16 16:25:23 +00001196 /* First call the mainboard init. */
1197 init_dev(&dev_root);
1198
Uwe Hermanne4870472010-11-04 23:23:47 +00001199 /* Now initialize everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001200 for (link = dev_root.link_list; link; link = link->next)
1201 init_link(link);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001202 post_log_clear();
Myles Watson7eac4452010-06-17 16:16:56 +00001203
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001204 printk(BIOS_INFO, "Devices initialized\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001205 show_all_devs(BIOS_SPEW, "After init.");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001206}
Marc Jones2a58ecd2013-10-29 17:32:00 -06001207
1208/**
1209 * Finalize a specific device.
1210 *
1211 * The parent should be finalized first to avoid having an ordering problem.
1212 * This is done by calling the parent's final() method before its childrens'
1213 * final() methods.
1214 *
1215 * @param dev The device to be initialized.
1216 */
1217static void final_dev(struct device *dev)
1218{
1219 if (!dev->enabled)
1220 return;
1221
1222 if (dev->ops && dev->ops->final) {
1223 printk(BIOS_DEBUG, "%s final\n", dev_path(dev));
1224 dev->ops->final(dev);
1225 }
1226}
1227
1228static void final_link(struct bus *link)
1229{
1230 struct device *dev;
1231 struct bus *c_link;
1232
1233 for (dev = link->children; dev; dev = dev->sibling)
1234 final_dev(dev);
1235
1236 for (dev = link->children; dev; dev = dev->sibling) {
1237 for (c_link = dev->link_list; c_link; c_link = c_link->next)
1238 final_link(c_link);
1239 }
1240}
1241/**
1242 * Finalize all devices in the global device tree.
1243 *
1244 * Starting at the root device, call the device's final() method to do
1245 * device-specific cleanup, then call each child's final() method.
1246 */
1247void dev_finalize(void)
1248{
1249 struct bus *link;
1250
1251 printk(BIOS_INFO, "Finalize devices...\n");
1252
1253 /* First call the mainboard finalize. */
1254 final_dev(&dev_root);
1255
1256 /* Now finalize everything. */
1257 for (link = dev_root.link_list; link; link = link->next)
1258 final_link(link);
1259
1260 printk(BIOS_INFO, "Devices finalized\n");
1261}