blob: 236b7684d73f543fe9016f6ffd4af1ca649adfbe [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 *
Martin Rothbb5953d2016-04-11 20:53:39 -06004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
Eric Biederman8ca8d762003-04-22 19:02:15 +000012 */
Uwe Hermanne4870472010-11-04 23:23:47 +000013
14/*
Martin Roth99f83bb2019-09-15 20:57:18 -070015 * Originally based on the Linux kernel (arch/i386/kernel/pci-pc.c).
Eric Biederman8ca8d762003-04-22 19:02:15 +000016 */
17
18#include <console/console.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000019#include <device/device.h>
Kyösti Mälkki318066f2014-02-12 14:18:50 +020020#include <device/pci_def.h>
Li-Ta Lo54f05f62004-05-14 17:20:29 +000021#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000022#include <stdlib.h>
23#include <string.h>
Eric Biederman03acab62004-10-14 21:25:53 +000024#include <smp/spinlock.h>
Julius Wernercd49cce2019-03-05 16:53:33 -080025#if CONFIG(ARCH_X86)
Duncan Laurieb4aaaa72012-01-17 09:03:11 -080026#include <arch/ebda.h>
27#endif
Aaron Durbin05294292013-04-30 15:41:13 -050028#include <timer.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000029
Li-Ta Loe5266692004-03-23 21:28:05 +000030/** Pointer to the last device */
Myles Watson70679a02010-09-01 21:03:03 +000031extern struct device *last_dev;
Myles Watsonc25cc112010-05-21 14:33:48 +000032/** Linked list of free resources */
33struct resource *free_resources = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +000034
Nico Huberacd7d952012-07-25 10:33:05 +020035/**
36 * Initialize all chips of statically known devices.
37 *
38 * Will be called before bus enumeration to initialize chips stated in the
39 * device tree.
40 */
41void dev_initialize_chips(void)
42{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +020043 const struct device *dev;
Nico Huberacd7d952012-07-25 10:33:05 +020044
45 for (dev = all_devices; dev; dev = dev->next) {
46 /* Initialize chip if we haven't yet. */
47 if (dev->chip_ops && dev->chip_ops->init &&
48 !dev->chip_ops->initialized) {
Duncan Laurie8adf7a22013-06-10 10:34:20 -070049 post_log_path(dev);
Nico Huberacd7d952012-07-25 10:33:05 +020050 dev->chip_ops->init(dev->chip_info);
51 dev->chip_ops->initialized = 1;
52 }
53 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -070054 post_log_clear();
Nico Huberacd7d952012-07-25 10:33:05 +020055}
56
Marc Jones2a58ecd2013-10-29 17:32:00 -060057/**
58 * Finalize all chips of statically known devices.
59 *
60 * This is the last call before calling the payload. This is a good place
61 * to lock registers or other final cleanup.
62 */
63void dev_finalize_chips(void)
64{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +020065 const struct device *dev;
Marc Jones2a58ecd2013-10-29 17:32:00 -060066
67 for (dev = all_devices; dev; dev = dev->next) {
68 /* Initialize chip if we haven't yet. */
69 if (dev->chip_ops && dev->chip_ops->final &&
70 !dev->chip_ops->finalized) {
71 dev->chip_ops->final(dev->chip_info);
72 dev->chip_ops->finalized = 1;
73 }
74 }
75}
76
Uwe Hermannc1ee4292010-10-17 19:01:48 +000077DECLARE_SPIN_LOCK(dev_lock)
Eric Biederman8ca8d762003-04-22 19:02:15 +000078
Julius Wernercd49cce2019-03-05 16:53:33 -080079#if CONFIG(GFXUMA)
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +030080/* IGD UMA memory */
81uint64_t uma_memory_base = 0;
82uint64_t uma_memory_size = 0;
Kyösti Mälkkib25374c2012-08-01 08:05:22 +030083#endif
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +030084
Li-Ta Loe5266692004-03-23 21:28:05 +000085/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +000086 * Allocate a new device structure.
Myles Watson032a9652009-05-11 22:24:53 +000087 *
Martin Roth63373ed2013-07-08 16:24:19 -060088 * Allocate a new device structure and attach it to the device tree as a
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +000089 * child of the parent bus.
Li-Ta Loe5266692004-03-23 21:28:05 +000090 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +000091 * @param parent Parent bus the newly created device should be attached to.
92 * @param path Path to the device to be created.
93 * @return Pointer to the newly created device structure.
Li-Ta Loe5266692004-03-23 21:28:05 +000094 *
95 * @see device_path
Eric Biederman8ca8d762003-04-22 19:02:15 +000096 */
Elyes HAOUASd34a7852018-09-17 10:44:14 +020097static struct device *__alloc_dev(struct bus *parent, struct device_path *path)
Eric Biederman8ca8d762003-04-22 19:02:15 +000098{
Elyes HAOUASe3480662018-05-06 20:32:23 +020099 struct device *dev, *child;
Li-Ta Loe5266692004-03-23 21:28:05 +0000100
Myles Watson29cc9ed2009-07-02 18:56:24 +0000101 /* Find the last child of our parent. */
Elyes HAOUASa342f392018-10-17 10:56:26 +0200102 for (child = parent->children; child && child->sibling; /* */)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000103 child = child->sibling;
Li-Ta Lo3a812852004-12-03 22:39:34 +0000104
Eric Biedermane9a271e32003-09-02 03:36:25 +0000105 dev = malloc(sizeof(*dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000106 if (dev == 0)
Uwe Hermanne4870472010-11-04 23:23:47 +0000107 die("alloc_dev(): out of memory.\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000108
Eric Biedermane9a271e32003-09-02 03:36:25 +0000109 memset(dev, 0, sizeof(*dev));
110 memcpy(&dev->path, path, sizeof(*path));
111
Myles Watson29cc9ed2009-07-02 18:56:24 +0000112 /* By default devices are enabled. */
Eric Biederman03acab62004-10-14 21:25:53 +0000113 dev->enabled = 1;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000114
Eric Biedermanb78c1972004-10-14 20:54:17 +0000115 /* Add the new device to the list of children of the bus. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000116 dev->bus = parent;
Uwe Hermanne4870472010-11-04 23:23:47 +0000117 if (child)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000118 child->sibling = dev;
Uwe Hermanne4870472010-11-04 23:23:47 +0000119 else
Eric Biedermane9a271e32003-09-02 03:36:25 +0000120 parent->children = dev;
Li-Ta Loe5266692004-03-23 21:28:05 +0000121
Eric Biederman03acab62004-10-14 21:25:53 +0000122 /* Append a new device to the global device list.
123 * The list is used to find devices once everything is set up.
124 */
Myles Watson70679a02010-09-01 21:03:03 +0000125 last_dev->next = dev;
126 last_dev = dev;
Eric Biederman03acab62004-10-14 21:25:53 +0000127
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300128 return dev;
129}
130
Elyes HAOUASd34a7852018-09-17 10:44:14 +0200131struct device *alloc_dev(struct bus *parent, struct device_path *path)
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300132{
Elyes HAOUASe3480662018-05-06 20:32:23 +0200133 struct device *dev;
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300134 spin_lock(&dev_lock);
135 dev = __alloc_dev(parent, path);
Eric Biederman03acab62004-10-14 21:25:53 +0000136 spin_unlock(&dev_lock);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000137 return dev;
138}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000139
Li-Ta Loe5266692004-03-23 21:28:05 +0000140/**
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300141 * See if a device structure already exists and if not allocate it.
142 *
143 * @param parent The bus to find the device on.
144 * @param path The relative path from the bus to the appropriate device.
145 * @return Pointer to a device structure for the device on bus at path.
146 */
Elyes HAOUASd34a7852018-09-17 10:44:14 +0200147struct device *alloc_find_dev(struct bus *parent, struct device_path *path)
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300148{
Elyes HAOUASe3480662018-05-06 20:32:23 +0200149 struct device *child;
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300150 spin_lock(&dev_lock);
151 child = find_dev_path(parent, path);
152 if (!child)
153 child = __alloc_dev(parent, path);
154 spin_unlock(&dev_lock);
155 return child;
156}
157
158/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000159 * Round a number up to an alignment.
160 *
161 * @param val The starting value.
Martin Roth32bc6b62015-01-04 16:54:35 -0700162 * @param pow Alignment as a power of two.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000163 * @return Rounded up number.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000164 */
Eric Biederman448bd632004-10-14 22:52:15 +0000165static resource_t round(resource_t val, unsigned long pow)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000166{
Eric Biederman448bd632004-10-14 22:52:15 +0000167 resource_t mask;
168 mask = (1ULL << pow) - 1ULL;
169 val += mask;
170 val &= ~mask;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000171 return val;
172}
173
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +0200174static const char *resource2str(struct resource *res)
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200175{
176 if (res->flags & IORESOURCE_IO)
177 return "io";
178 if (res->flags & IORESOURCE_PREFETCH)
179 return "prefmem";
180 if (res->flags & IORESOURCE_MEM)
181 return "mem";
182 return "undefined";
183}
184
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000185/**
186 * Read the resources on all devices of a given bus.
187 *
188 * @param bus Bus to read the resources on.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000189 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000190static void read_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000191{
192 struct device *curdev;
193
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000194 printk(BIOS_SPEW, "%s %s bus %x link: %d\n", dev_path(bus->dev),
195 __func__, bus->secondary, bus->link_num);
Eric Biederman448bd632004-10-14 22:52:15 +0000196
Myles Watson29cc9ed2009-07-02 18:56:24 +0000197 /* Walk through all devices and find which resources they need. */
198 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Myles Watson894a3472010-06-09 22:41:35 +0000199 struct bus *link;
Uwe Hermanne4870472010-11-04 23:23:47 +0000200
201 if (!curdev->enabled)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000202 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000203
Eric Biedermane9a271e32003-09-02 03:36:25 +0000204 if (!curdev->ops || !curdev->ops->read_resources) {
Martin Roth7bc74ab2015-11-18 20:23:02 -0700205 if (curdev->path.type != DEVICE_PATH_APIC)
206 printk(BIOS_ERR, "%s missing read_resources\n",
207 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000208 continue;
209 }
Duncan Laurie7ed39762013-07-09 10:46:52 -0700210 post_log_path(curdev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000211 curdev->ops->read_resources(curdev);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000212
213 /* Read in the resources behind the current device's links. */
Myles Watson894a3472010-06-09 22:41:35 +0000214 for (link = curdev->link_list; link; link = link->next)
215 read_resources(link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000216 }
Duncan Laurie7ed39762013-07-09 10:46:52 -0700217 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000218 printk(BIOS_SPEW, "%s read_resources bus %d link: %d done\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000219 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000220}
221
Eric Biedermane9a271e32003-09-02 03:36:25 +0000222struct pick_largest_state {
223 struct resource *last;
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200224 const struct device *result_dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000225 struct resource *result;
226 int seen_last;
227};
228
Myles Watson29cc9ed2009-07-02 18:56:24 +0000229static void pick_largest_resource(void *gp, struct device *dev,
230 struct resource *resource)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000231{
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000232 struct pick_largest_state *state = gp;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000233 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000234
Eric Biedermane9a271e32003-09-02 03:36:25 +0000235 last = state->last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000236
237 /* Be certain to pick the successor to last. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000238 if (resource == last) {
239 state->seen_last = 1;
240 return;
241 }
Myles Watson032a9652009-05-11 22:24:53 +0000242 if (resource->flags & IORESOURCE_FIXED)
Uwe Hermanne4870472010-11-04 23:23:47 +0000243 return; /* Skip it. */
Myles Watson032a9652009-05-11 22:24:53 +0000244 if (last && ((last->align < resource->align) ||
245 ((last->align == resource->align) &&
246 (last->size < resource->size)) ||
247 ((last->align == resource->align) &&
248 (last->size == resource->size) && (!state->seen_last)))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000249 return;
250 }
Myles Watson032a9652009-05-11 22:24:53 +0000251 if (!state->result ||
252 (state->result->align < resource->align) ||
253 ((state->result->align == resource->align) &&
Myles Watson29cc9ed2009-07-02 18:56:24 +0000254 (state->result->size < resource->size))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000255 state->result_dev = dev;
256 state->result = resource;
Myles Watson032a9652009-05-11 22:24:53 +0000257 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000258}
259
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200260static const struct device *largest_resource(struct bus *bus,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000261 struct resource **result_res,
262 unsigned long type_mask,
263 unsigned long type)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000264{
265 struct pick_largest_state state;
266
267 state.last = *result_res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000268 state.result_dev = NULL;
269 state.result = NULL;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000270 state.seen_last = 0;
271
Myles Watson032a9652009-05-11 22:24:53 +0000272 search_bus_resources(bus, type_mask, type, pick_largest_resource,
273 &state);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000274
275 *result_res = state.result;
276 return state.result_dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000277}
278
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000279/**
Uwe Hermanne4870472010-11-04 23:23:47 +0000280 * This function is the guts of the resource allocator.
Myles Watson032a9652009-05-11 22:24:53 +0000281 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000282 * The problem.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000283 * - Allocate resource locations for every device.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000284 * - Don't overlap, and follow the rules of bridges.
285 * - Don't overlap with resources in fixed locations.
286 * - Be efficient so we don't have ugly strategies.
287 *
288 * The strategy.
289 * - Devices that have fixed addresses are the minority so don't
Myles Watson29cc9ed2009-07-02 18:56:24 +0000290 * worry about them too much. Instead only use part of the address
291 * space for devices with programmable addresses. This easily handles
Eric Biederman8ca8d762003-04-22 19:02:15 +0000292 * everything except bridges.
293 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000294 * - PCI devices are required to have their sizes and their alignments
295 * equal. In this case an optimal solution to the packing problem
296 * exists. Allocate all devices from highest alignment to least
297 * alignment or vice versa. Use this.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000298 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000299 * - So we can handle more than PCI run two allocation passes on bridges. The
300 * first to see how large the resources are behind the bridge, and what
301 * their alignment requirements are. The second to assign a safe address to
302 * the devices behind the bridge. This allows us to treat a bridge as just
303 * a device with a couple of resources, and not need to special case it in
304 * the allocator. Also this allows handling of other types of bridges.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000305 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000306 * @param bus The bus we are traversing.
307 * @param bridge The bridge resource which must contain the bus' resources.
308 * @param type_mask This value gets ANDed with the resource type.
309 * @param type This value must match the result of the AND.
310 * @return TODO
Eric Biederman8ca8d762003-04-22 19:02:15 +0000311 */
Myles Watson54913b92009-10-13 20:00:09 +0000312static void compute_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000313 unsigned long type_mask, unsigned long type)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000314{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200315 const struct device *dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000316 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000317 resource_t base;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000318 base = round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000319
John Zhao2deb5fb2019-05-29 18:12:01 -0700320 if (!bus)
321 return;
322
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200323 printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d"
324 " limit: %llx\n", dev_path(bus->dev), resource2str(bridge),
325 base, bridge->size, bridge->align,
Uwe Hermanne4870472010-11-04 23:23:47 +0000326 bridge->gran, bridge->limit);
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000327
Uwe Hermanne4870472010-11-04 23:23:47 +0000328 /* For each child which is a bridge, compute the resource needs. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000329 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000330 struct resource *child_bridge;
331
Myles Watson894a3472010-06-09 22:41:35 +0000332 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000333 continue;
334
335 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000336 for (child_bridge = dev->resource_list; child_bridge;
337 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000338 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000339
Uwe Hermanne4870472010-11-04 23:23:47 +0000340 if (!(child_bridge->flags & IORESOURCE_BRIDGE)
341 || (child_bridge->flags & type_mask) != type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000342 continue;
343
Uwe Hermanne4870472010-11-04 23:23:47 +0000344 /*
345 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000346 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000347 * and non-prefetchable memory. Bridges below them need
348 * it separated. Add the PREFETCH flag to the type_mask
349 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000350 */
Myles Watson894a3472010-06-09 22:41:35 +0000351 link = dev->link_list;
352 while (link && link->link_num !=
353 IOINDEX_LINK(child_bridge->index))
354 link = link->next;
Uwe Hermanne4870472010-11-04 23:23:47 +0000355
356 if (link == NULL) {
Myles Watson894a3472010-06-09 22:41:35 +0000357 printk(BIOS_ERR, "link %ld not found on %s\n",
358 IOINDEX_LINK(child_bridge->index),
359 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000360 }
361
Myles Watson894a3472010-06-09 22:41:35 +0000362 compute_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000363 type_mask | IORESOURCE_PREFETCH,
364 type | (child_bridge->flags &
365 IORESOURCE_PREFETCH));
366 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000367 }
368
Myles Watson29cc9ed2009-07-02 18:56:24 +0000369 /* Remember we haven't found anything yet. */
370 resource = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000371
Uwe Hermanne4870472010-11-04 23:23:47 +0000372 /*
373 * Walk through all the resources on the current bus and compute the
374 * amount of address space taken by them. Take granularity and
Myles Watson29cc9ed2009-07-02 18:56:24 +0000375 * alignment into account.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000376 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000377 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000378
Myles Watson29cc9ed2009-07-02 18:56:24 +0000379 /* Size 0 resources can be skipped. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000380 if (!resource->size)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000381 continue;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000382
Myles Watson29cc9ed2009-07-02 18:56:24 +0000383 /* Propagate the resource alignment to the bridge resource. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000384 if (resource->align > bridge->align)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000385 bridge->align = resource->align;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000386
387 /* Propagate the resource limit to the bridge register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000388 if (bridge->limit > resource->limit)
Eric Biedermandbec2d42004-10-21 10:44:08 +0000389 bridge->limit = resource->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000390
391 /* Warn if it looks like APICs aren't declared. */
392 if ((resource->limit == 0xffffffff) &&
393 (resource->flags & IORESOURCE_ASSIGNED)) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000394 printk(BIOS_ERR,
395 "Resource limit looks wrong! (no APIC?)\n");
Patrick Georgi51615092012-03-11 19:31:03 +0100396 printk(BIOS_ERR, "%s %02lx limit %08llx\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000397 dev_path(dev), resource->index, resource->limit);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000398 }
Stefan Reinauer51754a32008-08-01 12:28:38 +0000399
Eric Biederman8ca8d762003-04-22 19:02:15 +0000400 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000401 /*
402 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000403 * expansion card addresses. The legacy PCI decodes
404 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
405 * 0x00 - 0xff can be used out of each 0x400 block of
406 * I/O space.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000407 */
Eric Biedermanbbb6d102003-08-04 19:54:48 +0000408 if ((base & 0x300) != 0) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000409 base = (base & ~0x3ff) + 0x400;
410 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000411 /*
412 * Don't allow allocations in the VGA I/O range.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000413 * PCI has special cases for that.
414 */
415 else if ((base >= 0x3b0) && (base <= 0x3df)) {
416 base = 0x3e0;
417 }
418 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000419 /* Base must be aligned. */
420 base = round(base, resource->align);
421 resource->base = base;
422 base += resource->size;
Myles Watson032a9652009-05-11 22:24:53 +0000423
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000424 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000425 dev_path(dev), resource->index, resource->base,
426 resource->base + resource->size - 1,
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200427 resource2str(resource));
Eric Biederman8ca8d762003-04-22 19:02:15 +0000428 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000429
430 /*
431 * A PCI bridge resource does not need to be a power of two size, but
432 * it does have a minimum granularity. Round the size up to that
433 * minimum granularity so we know not to place something else at an
Martin Roth63373ed2013-07-08 16:24:19 -0600434 * address positively decoded by the bridge.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000435 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000436 bridge->size = round(base, bridge->gran) -
437 round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000438
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200439 printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d"
440 " limit: %llx done\n", dev_path(bus->dev),
441 resource2str(bridge),
Uwe Hermanne4870472010-11-04 23:23:47 +0000442 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000443}
444
445/**
446 * This function is the second part of the resource allocator.
447 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000448 * See the compute_resources function for a more detailed explanation.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000449 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000450 * This function assigns the resources a value.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000451 *
452 * @param bus The bus we are traversing.
453 * @param bridge The bridge resource which must contain the bus' resources.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000454 * @param type_mask This value gets ANDed with the resource type.
455 * @param type This value must match the result of the AND.
Uwe Hermanne4870472010-11-04 23:23:47 +0000456 *
457 * @see compute_resources
Myles Watson29cc9ed2009-07-02 18:56:24 +0000458 */
Myles Watson54913b92009-10-13 20:00:09 +0000459static void allocate_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000460 unsigned long type_mask, unsigned long type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000461{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200462 const struct device *dev;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000463 struct resource *resource;
464 resource_t base;
465 base = bridge->base;
466
John Zhao2deb5fb2019-05-29 18:12:01 -0700467 if (!bus)
468 return;
469
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200470 printk(BIOS_SPEW, "%s %s: base:%llx size:%llx align:%d gran:%d "
471 "limit:%llx\n", dev_path(bus->dev),
472 resource2str(bridge),
Myles Watson29cc9ed2009-07-02 18:56:24 +0000473 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
474
475 /* Remember we haven't found anything yet. */
476 resource = NULL;
477
Uwe Hermanne4870472010-11-04 23:23:47 +0000478 /*
479 * Walk through all the resources on the current bus and allocate them
Myles Watson29cc9ed2009-07-02 18:56:24 +0000480 * address space.
481 */
482 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
483
484 /* Propagate the bridge limit to the resource register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000485 if (resource->limit > bridge->limit)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000486 resource->limit = bridge->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000487
488 /* Size 0 resources can be skipped. */
489 if (!resource->size) {
490 /* Set the base to limit so it doesn't confuse tolm. */
491 resource->base = resource->limit;
492 resource->flags |= IORESOURCE_ASSIGNED;
493 continue;
494 }
495
496 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000497 /*
498 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000499 * expansion card addresses. The legacy PCI decodes
500 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
501 * 0x00 - 0xff can be used out of each 0x400 block of
502 * I/O space.
503 */
504 if ((base & 0x300) != 0) {
505 base = (base & ~0x3ff) + 0x400;
506 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000507 /*
508 * Don't allow allocations in the VGA I/O range.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000509 * PCI has special cases for that.
510 */
511 else if ((base >= 0x3b0) && (base <= 0x3df)) {
512 base = 0x3e0;
513 }
514 }
515
516 if ((round(base, resource->align) + resource->size - 1) <=
517 resource->limit) {
518 /* Base must be aligned. */
519 base = round(base, resource->align);
520 resource->base = base;
Kyösti Mälkki134b6162015-03-23 19:58:23 +0200521 resource->limit = resource->base + resource->size - 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000522 resource->flags |= IORESOURCE_ASSIGNED;
523 resource->flags &= ~IORESOURCE_STORED;
524 base += resource->size;
525 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000526 printk(BIOS_ERR, "!! Resource didn't fit !!\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000527 printk(BIOS_ERR, " aligned base %llx size %llx "
528 "limit %llx\n", round(base, resource->align),
529 resource->size, resource->limit);
530 printk(BIOS_ERR, " %llx needs to be <= %llx "
531 "(limit)\n", (round(base, resource->align) +
Myles Watson29cc9ed2009-07-02 18:56:24 +0000532 resource->size) - 1, resource->limit);
Uwe Hermanne4870472010-11-04 23:23:47 +0000533 printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx]"
534 " %s\n", (resource->flags & IORESOURCE_ASSIGNED)
535 ? "Assigned: " : "", dev_path(dev),
536 resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000537 resource->base + resource->size - 1,
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200538 resource2str(resource));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000539 }
540
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200541 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
542 dev_path(dev), resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000543 resource->size ? resource->base + resource->size - 1 :
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200544 resource->base, resource2str(resource));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000545 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000546
547 /*
548 * A PCI bridge resource does not need to be a power of two size, but
Myles Watson29cc9ed2009-07-02 18:56:24 +0000549 * it does have a minimum granularity. Round the size up to that
550 * minimum granularity so we know not to place something else at an
551 * address positively decoded by the bridge.
552 */
553
554 bridge->flags |= IORESOURCE_ASSIGNED;
555
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200556 printk(BIOS_SPEW, "%s %s: next_base: %llx size: %llx align: %d "
557 "gran: %d done\n", dev_path(bus->dev),
558 resource2str(bridge), base, bridge->size, bridge->align,
Uwe Hermanne4870472010-11-04 23:23:47 +0000559 bridge->gran);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000560
561 /* For each child which is a bridge, allocate_resources. */
562 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000563 struct resource *child_bridge;
564
Myles Watson894a3472010-06-09 22:41:35 +0000565 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000566 continue;
567
568 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000569 for (child_bridge = dev->resource_list; child_bridge;
570 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000571 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000572
573 if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
574 (child_bridge->flags & type_mask) != type)
575 continue;
576
Uwe Hermanne4870472010-11-04 23:23:47 +0000577 /*
578 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000579 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000580 * and non-prefetchable memory. Bridges below them need
581 * it separated. Add the PREFETCH flag to the type_mask
582 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000583 */
Myles Watson894a3472010-06-09 22:41:35 +0000584 link = dev->link_list;
585 while (link && link->link_num !=
586 IOINDEX_LINK(child_bridge->index))
587 link = link->next;
588 if (link == NULL)
589 printk(BIOS_ERR, "link %ld not found on %s\n",
590 IOINDEX_LINK(child_bridge->index),
591 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000592
Myles Watson894a3472010-06-09 22:41:35 +0000593 allocate_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000594 type_mask | IORESOURCE_PREFETCH,
595 type | (child_bridge->flags &
596 IORESOURCE_PREFETCH));
597 }
598 }
599}
600
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200601static int resource_is(struct resource *res, u32 type)
602{
603 return (res->flags & IORESOURCE_TYPE_MASK) == type;
604}
Myles Watson29cc9ed2009-07-02 18:56:24 +0000605
606struct constraints {
Kyösti Mälkkifcbebb62015-03-17 06:42:54 +0200607 struct resource io, mem;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000608};
609
Elyes HAOUASe3480662018-05-06 20:32:23 +0200610static struct resource *resource_limit(struct constraints *limits,
611 struct resource *res)
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200612{
613 struct resource *lim = NULL;
614
615 /* MEM, or I/O - skip any others. */
616 if (resource_is(res, IORESOURCE_MEM))
617 lim = &limits->mem;
618 else if (resource_is(res, IORESOURCE_IO))
619 lim = &limits->io;
620
621 return lim;
622}
623
Elyes HAOUASe3480662018-05-06 20:32:23 +0200624static void constrain_resources(const struct device *dev,
625 struct constraints* limits)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000626{
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200627 const struct device *child;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000628 struct resource *res;
629 struct resource *lim;
Myles Watson894a3472010-06-09 22:41:35 +0000630 struct bus *link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000631
Myles Watson29cc9ed2009-07-02 18:56:24 +0000632 /* Constrain limits based on the fixed resources of this device. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000633 for (res = dev->resource_list; res; res = res->next) {
Patrick Georgi18c585b2009-08-28 12:48:02 +0000634 if (!(res->flags & IORESOURCE_FIXED))
635 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000636 if (!res->size) {
637 /* It makes no sense to have 0-sized, fixed resources.*/
Uwe Hermanne4870472010-11-04 23:23:47 +0000638 printk(BIOS_ERR, "skipping %s@%lx fixed resource, "
639 "size=0!\n", dev_path(dev), res->index);
Patrick Georgi6bd93f42009-08-19 17:29:41 +0000640 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000641 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000642
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200643 lim = resource_limit(limits, res);
644 if (!lim)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000645 continue;
646
Uwe Hermanne4870472010-11-04 23:23:47 +0000647 /*
648 * Is it a fixed resource outside the current known region?
649 * If so, we don't have to consider it - it will be handled
650 * correctly and doesn't affect current region's limits.
651 */
652 if (((res->base + res->size -1) < lim->base)
653 || (res->base > lim->limit))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000654 continue;
655
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200656 printk(BIOS_SPEW, "%s: %s %02lx base %08llx limit %08llx %s (fixed)\n",
657 __func__, dev_path(dev), res->index, res->base,
658 res->base + res->size - 1, resource2str(res));
659
Uwe Hermanne4870472010-11-04 23:23:47 +0000660 /*
661 * Choose to be above or below fixed resources. This check is
662 * signed so that "negative" amounts of space are handled
663 * correctly.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000664 */
Uwe Hermanne4870472010-11-04 23:23:47 +0000665 if ((signed long long)(lim->limit - (res->base + res->size -1))
666 > (signed long long)(res->base - lim->base))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000667 lim->base = res->base + res->size;
668 else
669 lim->limit = res->base -1;
670 }
671
672 /* Descend into every enabled child and look for fixed resources. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000673 for (link = dev->link_list; link; link = link->next) {
674 for (child = link->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000675 if (child->enabled)
676 constrain_resources(child, limits);
Uwe Hermanne4870472010-11-04 23:23:47 +0000677 }
678 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000679}
680
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +0200681static void avoid_fixed_resources(const struct device *dev)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000682{
683 struct constraints limits;
684 struct resource *res;
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200685 struct resource *lim;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000686
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000687 printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000688
Uwe Hermanne4870472010-11-04 23:23:47 +0000689 /* Initialize constraints to maximum size. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000690 limits.io.base = 0;
691 limits.io.limit = 0xffffffffffffffffULL;
692 limits.mem.base = 0;
693 limits.mem.limit = 0xffffffffffffffffULL;
694
695 /* Constrain the limits to dev's initial resources. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000696 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000697 if ((res->flags & IORESOURCE_FIXED))
698 continue;
Patrick Georgi51615092012-03-11 19:31:03 +0100699 printk(BIOS_SPEW, "%s:@%s %02lx limit %08llx\n", __func__,
Uwe Hermanne4870472010-11-04 23:23:47 +0000700 dev_path(dev), res->index, res->limit);
Kyösti Mälkkifcbebb62015-03-17 06:42:54 +0200701
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200702 lim = resource_limit(&limits, res);
703 if (!lim)
704 continue;
705
706 if (res->base > lim->base)
707 lim->base = res->base;
Elyes HAOUAS1943f372018-05-04 16:30:39 +0200708 if (res->limit < lim->limit)
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200709 lim->limit = res->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000710 }
711
712 /* Look through the tree for fixed resources and update the limits. */
713 constrain_resources(dev, &limits);
714
715 /* Update dev's resources with new limits. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000716 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000717 if ((res->flags & IORESOURCE_FIXED))
718 continue;
719
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200720 lim = resource_limit(&limits, res);
721 if (!lim)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000722 continue;
723
Myles Watson29cc9ed2009-07-02 18:56:24 +0000724 /* Is the resource outside the limits? */
725 if (lim->base > res->base)
726 res->base = lim->base;
727 if (res->limit > lim->limit)
728 res->limit = lim->limit;
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200729
Kyösti Mälkki634899c2015-03-23 14:22:22 +0200730 /* MEM resources need to start at the highest address manageable. */
731 if (res->flags & IORESOURCE_MEM)
732 res->base = resource_max(res);
733
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200734 printk(BIOS_SPEW, "%s:@%s %02lx base %08llx limit %08llx\n",
735 __func__, dev_path(dev), res->index, res->base, res->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000736 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000737}
arch import user (historical)dc811182005-07-06 17:16:09 +0000738
Elyes HAOUASe3480662018-05-06 20:32:23 +0200739struct device *vga_pri = NULL;
Myles Watsonc7233e02009-07-02 19:02:33 +0000740static void set_vga_bridge_bits(void)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000741{
Uwe Hermann312673c2009-10-27 21:49:33 +0000742 /*
Martin Roth63373ed2013-07-08 16:24:19 -0600743 * FIXME: Modify set_vga_bridge() so it is less PCI-centric!
Uwe Hermann312673c2009-10-27 21:49:33 +0000744 * This function knows too much about PCI stuff, it should be just
745 * an iterator/visitor.
746 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000747
Myles Watson29cc9ed2009-07-02 18:56:24 +0000748 /* FIXME: Handle the VGA palette snooping. */
Patrick Georgi557ecf22012-07-20 12:16:17 +0200749 struct device *dev, *vga, *vga_onboard;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000750 struct bus *bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000751
Eric Biedermanb78c1972004-10-14 20:54:17 +0000752 bus = 0;
753 vga = 0;
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000754 vga_onboard = 0;
Uwe Hermanne4870472010-11-04 23:23:47 +0000755
Patrick Georgi557ecf22012-07-20 12:16:17 +0200756 dev = NULL;
757 while ((dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev))) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000758 if (!dev->enabled)
759 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000760
Patrick Georgi557ecf22012-07-20 12:16:17 +0200761 printk(BIOS_DEBUG, "found VGA at %s\n", dev_path(dev));
Nico Huber061b9052019-09-21 15:58:23 +0200762 if (dev->bus->no_vga16) {
763 printk(BIOS_WARNING,
764 "A bridge on the path doesn't support 16-bit VGA decoding!");
765 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000766
Patrick Georgi557ecf22012-07-20 12:16:17 +0200767 if (dev->on_mainboard) {
768 vga_onboard = dev;
Kostr1f0d3792012-10-06 13:27:58 +0400769 } else {
Patrick Georgi557ecf22012-07-20 12:16:17 +0200770 vga = dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000771 }
Myles Watson032a9652009-05-11 22:24:53 +0000772
Patrick Georgi557ecf22012-07-20 12:16:17 +0200773 /* It isn't safe to enable all VGA cards. */
774 dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Patrick Georgi594473d2012-07-25 08:55:53 +0200775 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000776
Uwe Hermanne4870472010-11-04 23:23:47 +0000777 if (!vga)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000778 vga = vga_onboard;
Patrick Georgi557ecf22012-07-20 12:16:17 +0200779
Julius Werner5d1f9a02019-03-07 17:07:26 -0800780 if (CONFIG(ONBOARD_VGA_IS_PRIMARY) && vga_onboard)
Patrick Georgi557ecf22012-07-20 12:16:17 +0200781 vga = vga_onboard;
Myles Watson032a9652009-05-11 22:24:53 +0000782
Patrick Georgi5869fa22012-07-20 12:29:33 +0200783 /* If we prefer plugin VGA over chipset VGA, the chipset might
784 want to know. */
Julius Werner5d1f9a02019-03-07 17:07:26 -0800785 if (!CONFIG(ONBOARD_VGA_IS_PRIMARY) && (vga != vga_onboard) &&
Patrick Georgi5869fa22012-07-20 12:29:33 +0200786 vga_onboard && vga_onboard->ops && vga_onboard->ops->disable) {
787 printk(BIOS_DEBUG, "Use plugin graphics over integrated.\n");
788 vga_onboard->ops->disable(vga_onboard);
789 }
790
arch import user (historical)dc811182005-07-06 17:16:09 +0000791 if (vga) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000792 /* VGA is first add-on card or the only onboard VGA. */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000793 printk(BIOS_DEBUG, "Setting up VGA for %s\n", dev_path(vga));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000794 /* All legacy VGA cards have MEM & I/O space registers. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000795 vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
796 vga_pri = vga;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000797 bus = vga->bus;
798 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000799
Myles Watson29cc9ed2009-07-02 18:56:24 +0000800 /* Now walk up the bridges setting the VGA enable. */
801 while (bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000802 printk(BIOS_DEBUG, "Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000803 dev_path(bus->dev));
Nico Huber061b9052019-09-21 15:58:23 +0200804 bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA | PCI_BRIDGE_CTL_VGA16;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000805 bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus;
Myles Watson032a9652009-05-11 22:24:53 +0000806 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000807}
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000808
Li-Ta Lo04930692004-11-25 17:37:19 +0000809/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000810 * Assign the computed resources to the devices on the bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000811 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000812 * Use the device specific set_resources() method to store the computed
Li-Ta Lo04930692004-11-25 17:37:19 +0000813 * resources to hardware. For bridge devices, the set_resources() method
814 * has to recurse into every down stream buses.
815 *
816 * Mutual recursion:
817 * assign_resources() -> device_operation::set_resources()
818 * device_operation::set_resources() -> assign_resources()
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000819 *
820 * @param bus Pointer to the structure for this bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000821 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000822void assign_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000823{
824 struct device *curdev;
825
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000826 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000827 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000828
Myles Watson29cc9ed2009-07-02 18:56:24 +0000829 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000830 if (!curdev->enabled || !curdev->resource_list)
Eric Biederman03acab62004-10-14 21:25:53 +0000831 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000832
Eric Biedermane9a271e32003-09-02 03:36:25 +0000833 if (!curdev->ops || !curdev->ops->set_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000834 printk(BIOS_ERR, "%s missing set_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000835 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000836 continue;
837 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700838 post_log_path(curdev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000839 curdev->ops->set_resources(curdev);
840 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700841 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000842 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000843 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000844}
845
Li-Ta Lo5782d272004-04-26 17:51:20 +0000846/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000847 * Enable the resources for devices on a link.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000848 *
849 * Enable resources of the device by calling the device specific
850 * enable_resources() method.
851 *
852 * The parent's resources should be enabled first to avoid having enabling
853 * order problem. This is done by calling the parent's enable_resources()
Martin Roth63373ed2013-07-08 16:24:19 -0600854 * method before its children's enable_resources() methods.
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000855 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000856 * @param link The link whose devices' resources are to be enabled.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000857 */
Myles Watson7eac4452010-06-17 16:16:56 +0000858static void enable_resources(struct bus *link)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000859{
Myles Watson7eac4452010-06-17 16:16:56 +0000860 struct device *dev;
861 struct bus *c_link;
862
863 for (dev = link->children; dev; dev = dev->sibling) {
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700864 if (dev->enabled && dev->ops && dev->ops->enable_resources) {
865 post_log_path(dev);
Myles Watson7eac4452010-06-17 16:16:56 +0000866 dev->ops->enable_resources(dev);
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700867 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000868 }
Myles Watson7eac4452010-06-17 16:16:56 +0000869
870 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000871 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +0000872 enable_resources(c_link);
Eric Biederman83b991a2003-10-11 06:20:25 +0000873 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700874 post_log_clear();
Eric Biederman8ca8d762003-04-22 19:02:15 +0000875}
876
Myles Watson032a9652009-05-11 22:24:53 +0000877/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000878 * Reset all of the devices on a bus and clear the bus's reset_needed flag.
879 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000880 * @param bus Pointer to the bus structure.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000881 * @return 1 if the bus was successfully reset, 0 otherwise.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000882 */
883int reset_bus(struct bus *bus)
884{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000885 if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000886 bus->dev->ops->reset_bus(bus);
887 bus->reset_needed = 0;
888 return 1;
889 }
890 return 0;
891}
892
Myles Watson032a9652009-05-11 22:24:53 +0000893/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000894 * Scan for devices on a bus.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000895 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000896 * If there are bridges on the bus, recursively scan the buses behind the
897 * bridges. If the setting up and tuning of the bus causes a reset to be
898 * required, reset the bus and scan it again.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000899 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000900 * @param busdev Pointer to the bus device.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000901 */
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200902static void scan_bus(struct device *busdev)
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000903{
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000904 int do_scan_bus;
Paul Menzel662380f2015-10-20 10:21:08 +0200905 struct stopwatch sw;
Kyösti Mälkkie3d9d672019-12-01 12:27:44 +0200906 long scan_time;
Uwe Hermanne4870472010-11-04 23:23:47 +0000907
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200908 if (!busdev->enabled)
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200909 return;
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200910
Kyösti Mälkkie3d9d672019-12-01 12:27:44 +0200911 printk(BIOS_DEBUG, "%s scanning...\n", dev_path(busdev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000912
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700913 post_log_path(busdev);
914
Kyösti Mälkkie3d9d672019-12-01 12:27:44 +0200915 stopwatch_init(&sw);
916
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000917 do_scan_bus = 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000918 while (do_scan_bus) {
Myles Watson894a3472010-06-09 22:41:35 +0000919 struct bus *link;
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200920 busdev->ops->scan_bus(busdev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000921 do_scan_bus = 0;
Myles Watson894a3472010-06-09 22:41:35 +0000922 for (link = busdev->link_list; link; link = link->next) {
923 if (link->reset_needed) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000924 if (reset_bus(link))
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000925 do_scan_bus = 1;
Uwe Hermanne4870472010-11-04 23:23:47 +0000926 else
Myles Watson29cc9ed2009-07-02 18:56:24 +0000927 busdev->bus->reset_needed = 1;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000928 }
929 }
930 }
Paul Menzel662380f2015-10-20 10:21:08 +0200931
Kyösti Mälkkie3d9d672019-12-01 12:27:44 +0200932 scan_time = stopwatch_duration_msecs(&sw);
933 printk(BIOS_DEBUG, "%s: bus %s finished in %ld msecs\n", __func__,
934 dev_path(busdev), scan_time);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000935}
936
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200937void scan_bridges(struct bus *bus)
938{
939 struct device *child;
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200940
941 for (child = bus->children; child; child = child->sibling) {
942 if (!child->ops || !child->ops->scan_bus)
943 continue;
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200944 scan_bus(child);
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200945 }
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200946}
947
Li-Ta Loe5266692004-03-23 21:28:05 +0000948/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000949 * Determine the existence of devices and extend the device tree.
Li-Ta Lo04930692004-11-25 17:37:19 +0000950 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000951 * Most of the devices in the system are listed in the mainboard devicetree.cb
Li-Ta Lo04930692004-11-25 17:37:19 +0000952 * file. The device structures for these devices are generated at compile
953 * time by the config tool and are organized into the device tree. This
954 * function determines if the devices created at compile time actually exist
955 * in the physical system.
956 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000957 * For devices in the physical system but not listed in devicetree.cb,
Li-Ta Lo04930692004-11-25 17:37:19 +0000958 * the device structures have to be created at run time and attached to the
Li-Ta Loe5266692004-03-23 21:28:05 +0000959 * device tree.
960 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000961 * This function starts from the root device 'dev_root', scans the buses in
962 * the system recursively, and modifies the device tree according to the
963 * result of the probe.
Li-Ta Loe5266692004-03-23 21:28:05 +0000964 *
Li-Ta Lo5782d272004-04-26 17:51:20 +0000965 * This function has no idea how to scan and probe buses and devices at all.
966 * It depends on the bus/device specific scan_bus() method to do it. The
Li-Ta Lo04930692004-11-25 17:37:19 +0000967 * scan_bus() method also has to create the device structure and attach
Myles Watson032a9652009-05-11 22:24:53 +0000968 * it to the device tree.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000969 */
970void dev_enumerate(void)
971{
972 struct device *root;
Uwe Hermanne4870472010-11-04 23:23:47 +0000973
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000974 printk(BIOS_INFO, "Enumerating buses...\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000975
Eric Biederman8ca8d762003-04-22 19:02:15 +0000976 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000977
Uwe Hermanne4870472010-11-04 23:23:47 +0000978 show_all_devs(BIOS_SPEW, "Before device enumeration.");
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000979 printk(BIOS_SPEW, "Compare with tree...\n");
Kyösti Mälkki3d3c8c32016-08-15 10:04:21 +0300980 show_devs_tree(root, BIOS_SPEW, 0);
Myles Watsoncd5d7562009-05-12 13:43:34 +0000981
Stefan Reinauera675d492012-08-07 14:50:47 -0700982 if (root->chip_ops && root->chip_ops->enable_dev)
983 root->chip_ops->enable_dev(root);
Uwe Hermanne4870472010-11-04 23:23:47 +0000984
Eric Biedermanb78c1972004-10-14 20:54:17 +0000985 if (!root->ops || !root->ops->scan_bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000986 printk(BIOS_ERR, "dev_root missing scan_bus operation");
Eric Biedermanb78c1972004-10-14 20:54:17 +0000987 return;
988 }
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200989 scan_bus(root);
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700990 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000991 printk(BIOS_INFO, "done\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000992}
993
Li-Ta Loe5266692004-03-23 21:28:05 +0000994/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000995 * Configure devices on the devices tree.
Myles Watson032a9652009-05-11 22:24:53 +0000996 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000997 * Starting at the root of the device tree, travel it recursively in two
998 * passes. In the first pass, we compute and allocate resources (ranges)
Martin Roth63373ed2013-07-08 16:24:19 -0600999 * required by each device. In the second pass, the resources ranges are
Li-Ta Lo04930692004-11-25 17:37:19 +00001000 * relocated to their final position and stored to the hardware.
Li-Ta Lo5782d272004-04-26 17:51:20 +00001001 *
Myles Watson29cc9ed2009-07-02 18:56:24 +00001002 * I/O resources grow upward. MEM resources grow downward.
Li-Ta Lo5782d272004-04-26 17:51:20 +00001003 *
1004 * Since the assignment is hierarchical we set the values into the dev_root
Myles Watson032a9652009-05-11 22:24:53 +00001005 * struct.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001006 */
1007void dev_configure(void)
1008{
Myles Watson29cc9ed2009-07-02 18:56:24 +00001009 struct resource *res;
Lubomir Rintel9ba8f7c2018-04-26 00:00:22 +02001010 const struct device *root;
1011 const struct device *child;
Li-Ta Loe5266692004-03-23 21:28:05 +00001012
Marc Jones80bd74c2012-02-21 17:44:35 +01001013 set_vga_bridge_bits();
Marc Jones80bd74c2012-02-21 17:44:35 +01001014
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001015 printk(BIOS_INFO, "Allocating resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001016
Eric Biedermanb78c1972004-10-14 20:54:17 +00001017 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +00001018
Uwe Hermanne4870472010-11-04 23:23:47 +00001019 /*
1020 * Each domain should create resources which contain the entire address
Myles Watson29cc9ed2009-07-02 18:56:24 +00001021 * space for IO, MEM, and PREFMEM resources in the domain. The
1022 * allocation of device resources will be done from this address space.
1023 */
Myles Watsoncd5d7562009-05-12 13:43:34 +00001024
Myles Watson29cc9ed2009-07-02 18:56:24 +00001025 /* Read the resources for the entire tree. */
Li-Ta Lo04930692004-11-25 17:37:19 +00001026
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001027 printk(BIOS_INFO, "Reading resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001028 read_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001029 printk(BIOS_INFO, "Done reading resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001030
Stefan Reinauer39e72292009-10-26 16:47:05 +00001031 print_resource_tree(root, BIOS_SPEW, "After reading.");
Myles Watsoncd5d7562009-05-12 13:43:34 +00001032
Myles Watson29cc9ed2009-07-02 18:56:24 +00001033 /* Compute resources for all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001034 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001035 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001036 continue;
Duncan Laurie7ed39762013-07-09 10:46:52 -07001037 post_log_path(child);
Myles Watsonc25cc112010-05-21 14:33:48 +00001038 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001039 if (res->flags & IORESOURCE_FIXED)
1040 continue;
Myles Watson29cc9ed2009-07-02 18:56:24 +00001041 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001042 compute_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001043 res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001044 continue;
1045 }
1046 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001047 compute_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001048 res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001049 continue;
1050 }
1051 }
1052 }
1053
1054 /* For all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001055 for (child = root->link_list->children; child; child=child->sibling)
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001056 if (child->path.type == DEVICE_PATH_DOMAIN)
Myles Watson29cc9ed2009-07-02 18:56:24 +00001057 avoid_fixed_resources(child);
1058
Eric Biedermanb78c1972004-10-14 20:54:17 +00001059 /* Store the computed resource allocations into device registers ... */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001060 printk(BIOS_INFO, "Setting resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001061 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001062 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001063 continue;
Duncan Laurie7ed39762013-07-09 10:46:52 -07001064 post_log_path(child);
Myles Watsonc25cc112010-05-21 14:33:48 +00001065 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001066 if (res->flags & IORESOURCE_FIXED)
1067 continue;
Myles Watson29cc9ed2009-07-02 18:56:24 +00001068 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001069 allocate_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001070 res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001071 continue;
1072 }
1073 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001074 allocate_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001075 res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001076 continue;
1077 }
1078 }
1079 }
Myles Watson894a3472010-06-09 22:41:35 +00001080 assign_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001081 printk(BIOS_INFO, "Done setting resources.\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001082 print_resource_tree(root, BIOS_SPEW, "After assigning values.");
Eric Biederman03acab62004-10-14 21:25:53 +00001083
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001084 printk(BIOS_INFO, "Done allocating resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001085}
1086
Li-Ta Loe5266692004-03-23 21:28:05 +00001087/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001088 * Enable devices on the device tree.
Li-Ta Loe5266692004-03-23 21:28:05 +00001089 *
1090 * Starting at the root, walk the tree and enable all devices/bridges by
1091 * calling the device's enable_resources() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001092 */
1093void dev_enable(void)
1094{
Myles Watson7eac4452010-06-17 16:16:56 +00001095 struct bus *link;
1096
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001097 printk(BIOS_INFO, "Enabling resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001098
Uwe Hermanne4870472010-11-04 23:23:47 +00001099 /* Now enable everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001100 for (link = dev_root.link_list; link; link = link->next)
1101 enable_resources(link);
Li-Ta Loe5266692004-03-23 21:28:05 +00001102
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001103 printk(BIOS_INFO, "done.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001104}
1105
Li-Ta Loe5266692004-03-23 21:28:05 +00001106/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001107 * Initialize a specific device.
Myles Watson7eac4452010-06-17 16:16:56 +00001108 *
Uwe Hermanne4870472010-11-04 23:23:47 +00001109 * The parent should be initialized first to avoid having an ordering problem.
Martin Roth63373ed2013-07-08 16:24:19 -06001110 * This is done by calling the parent's init() method before its children's
Uwe Hermanne4870472010-11-04 23:23:47 +00001111 * init() methods.
Myles Watson7eac4452010-06-17 16:16:56 +00001112 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001113 * @param dev The device to be initialized.
Myles Watson7eac4452010-06-17 16:16:56 +00001114 */
1115static void init_dev(struct device *dev)
1116{
Uwe Hermanne4870472010-11-04 23:23:47 +00001117 if (!dev->enabled)
Myles Watson7eac4452010-06-17 16:16:56 +00001118 return;
Myles Watson7eac4452010-06-17 16:16:56 +00001119
1120 if (!dev->initialized && dev->ops && dev->ops->init) {
Aaron Durbin46ba4802014-09-23 16:34:40 -05001121 struct stopwatch sw;
Kyösti Mälkkie3d9d672019-12-01 12:27:44 +02001122 long init_time;
1123
Myles Watson7eac4452010-06-17 16:16:56 +00001124 if (dev->path.type == DEVICE_PATH_I2C) {
1125 printk(BIOS_DEBUG, "smbus: %s[%d]->",
1126 dev_path(dev->bus->dev), dev->bus->link_num);
1127 }
1128
Kyösti Mälkkie3d9d672019-12-01 12:27:44 +02001129 printk(BIOS_DEBUG, "%s init\n", dev_path(dev));
1130
1131 stopwatch_init(&sw);
Myles Watson7eac4452010-06-17 16:16:56 +00001132 dev->initialized = 1;
1133 dev->ops->init(dev);
Kyösti Mälkkie3d9d672019-12-01 12:27:44 +02001134
1135 init_time = stopwatch_duration_msecs(&sw);
1136 printk(BIOS_DEBUG, "%s init finished in %ld msecs\n", dev_path(dev),
1137 init_time);
Myles Watson7eac4452010-06-17 16:16:56 +00001138 }
1139}
1140
1141static void init_link(struct bus *link)
1142{
1143 struct device *dev;
1144 struct bus *c_link;
1145
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001146 for (dev = link->children; dev; dev = dev->sibling) {
Duncan Lauriecb73a842013-06-10 10:41:04 -07001147 post_code(POST_BS_DEV_INIT);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001148 post_log_path(dev);
Myles Watson7eac4452010-06-17 16:16:56 +00001149 init_dev(dev);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001150 }
Myles Watson7eac4452010-06-17 16:16:56 +00001151
1152 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +00001153 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +00001154 init_link(c_link);
Myles Watson7eac4452010-06-17 16:16:56 +00001155 }
1156}
1157
1158/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001159 * Initialize all devices in the global device tree.
Myles Watson7eac4452010-06-17 16:16:56 +00001160 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001161 * Starting at the root device, call the device's init() method to do
1162 * device-specific setup, then call each child's init() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001163 */
1164void dev_initialize(void)
1165{
Myles Watson7eac4452010-06-17 16:16:56 +00001166 struct bus *link;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001167
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001168 printk(BIOS_INFO, "Initializing devices...\n");
Myles Watson7eac4452010-06-17 16:16:56 +00001169
Julius Wernercd49cce2019-03-05 16:53:33 -08001170#if CONFIG(ARCH_X86)
Arthur Heymans8b7cd432019-10-26 20:31:41 +02001171 /* Ensure EBDA is prepared before Option ROMs. */
1172 setup_default_ebda();
Duncan Laurieb4aaaa72012-01-17 09:03:11 -08001173#endif
1174
Myles Watson1bd3fb72010-08-16 16:25:23 +00001175 /* First call the mainboard init. */
1176 init_dev(&dev_root);
1177
Uwe Hermanne4870472010-11-04 23:23:47 +00001178 /* Now initialize everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001179 for (link = dev_root.link_list; link; link = link->next)
1180 init_link(link);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001181 post_log_clear();
Myles Watson7eac4452010-06-17 16:16:56 +00001182
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001183 printk(BIOS_INFO, "Devices initialized\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001184 show_all_devs(BIOS_SPEW, "After init.");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001185}
Marc Jones2a58ecd2013-10-29 17:32:00 -06001186
1187/**
1188 * Finalize a specific device.
1189 *
1190 * The parent should be finalized first to avoid having an ordering problem.
1191 * This is done by calling the parent's final() method before its childrens'
1192 * final() methods.
1193 *
1194 * @param dev The device to be initialized.
1195 */
1196static void final_dev(struct device *dev)
1197{
1198 if (!dev->enabled)
1199 return;
1200
1201 if (dev->ops && dev->ops->final) {
1202 printk(BIOS_DEBUG, "%s final\n", dev_path(dev));
1203 dev->ops->final(dev);
1204 }
1205}
1206
1207static void final_link(struct bus *link)
1208{
1209 struct device *dev;
1210 struct bus *c_link;
1211
1212 for (dev = link->children; dev; dev = dev->sibling)
1213 final_dev(dev);
1214
1215 for (dev = link->children; dev; dev = dev->sibling) {
1216 for (c_link = dev->link_list; c_link; c_link = c_link->next)
1217 final_link(c_link);
1218 }
1219}
1220/**
1221 * Finalize all devices in the global device tree.
1222 *
1223 * Starting at the root device, call the device's final() method to do
1224 * device-specific cleanup, then call each child's final() method.
1225 */
1226void dev_finalize(void)
1227{
1228 struct bus *link;
1229
1230 printk(BIOS_INFO, "Finalize devices...\n");
1231
1232 /* First call the mainboard finalize. */
1233 final_dev(&dev_root);
1234
1235 /* Now finalize everything. */
1236 for (link = dev_root.link_list; link; link = link->next)
1237 final_link(link);
1238
1239 printk(BIOS_INFO, "Devices finalized\n");
1240}