blob: cf418eb4d19a25ce9e41e4414195517083978c88 [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>
Uwe Hermannb80dbf02007-04-22 19:08:13 +000016 */
17
18/*
Eric Biederman8ca8d762003-04-22 19:02:15 +000019 * (c) 1999--2000 Martin Mares <mj@suse.cz>
Eric Biederman8ca8d762003-04-22 19:02:15 +000020 */
Uwe Hermanne4870472010-11-04 23:23:47 +000021
22/*
23 * Lots of mods by Ron Minnich <rminnich@lanl.gov>, with
24 * the final architecture guidance from Tom Merritt <tjm@codegen.com>.
25 *
Myles Watson032a9652009-05-11 22:24:53 +000026 * In particular, we changed from the one-pass original version to
27 * Tom's recommended multiple-pass version. I wasn't sure about doing
Eric Biederman8ca8d762003-04-22 19:02:15 +000028 * it with multiple passes, until I actually started doing it and saw
Uwe Hermanne4870472010-11-04 23:23:47 +000029 * the wisdom of Tom's recommendations...
Eric Biederman8ca8d762003-04-22 19:02:15 +000030 *
31 * Lots of cleanups by Eric Biederman to handle bridges, and to
Uwe Hermanne4870472010-11-04 23:23:47 +000032 * handle resource allocation for non-PCI devices.
Eric Biederman8ca8d762003-04-22 19:02:15 +000033 */
34
35#include <console/console.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000036#include <arch/io.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000037#include <device/device.h>
Kyösti Mälkki318066f2014-02-12 14:18:50 +020038#include <device/pci_def.h>
Li-Ta Lo54f05f62004-05-14 17:20:29 +000039#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000040#include <stdlib.h>
41#include <string.h>
Eric Biederman03acab62004-10-14 21:25:53 +000042#include <smp/spinlock.h>
Duncan Laurieb4aaaa72012-01-17 09:03:11 -080043#if CONFIG_ARCH_X86
44#include <arch/ebda.h>
45#endif
Aaron Durbin05294292013-04-30 15:41:13 -050046#include <timer.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000047
Li-Ta Loe5266692004-03-23 21:28:05 +000048/** Linked list of ALL devices */
Eric Biederman5cd81732004-03-11 15:01:31 +000049struct device *all_devices = &dev_root;
Li-Ta Loe5266692004-03-23 21:28:05 +000050/** Pointer to the last device */
Myles Watson70679a02010-09-01 21:03:03 +000051extern struct device *last_dev;
Myles Watsonc25cc112010-05-21 14:33:48 +000052/** Linked list of free resources */
53struct resource *free_resources = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +000054
Nico Huberacd7d952012-07-25 10:33:05 +020055/**
56 * Initialize all chips of statically known devices.
57 *
58 * Will be called before bus enumeration to initialize chips stated in the
59 * device tree.
60 */
61void dev_initialize_chips(void)
62{
63 struct device *dev;
64
65 for (dev = all_devices; dev; dev = dev->next) {
66 /* Initialize chip if we haven't yet. */
67 if (dev->chip_ops && dev->chip_ops->init &&
68 !dev->chip_ops->initialized) {
Duncan Laurie8adf7a22013-06-10 10:34:20 -070069 post_log_path(dev);
Nico Huberacd7d952012-07-25 10:33:05 +020070 dev->chip_ops->init(dev->chip_info);
71 dev->chip_ops->initialized = 1;
72 }
73 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -070074 post_log_clear();
Nico Huberacd7d952012-07-25 10:33:05 +020075}
76
Marc Jones2a58ecd2013-10-29 17:32:00 -060077/**
78 * Finalize all chips of statically known devices.
79 *
80 * This is the last call before calling the payload. This is a good place
81 * to lock registers or other final cleanup.
82 */
83void dev_finalize_chips(void)
84{
85 struct device *dev;
86
87 for (dev = all_devices; dev; dev = dev->next) {
88 /* Initialize chip if we haven't yet. */
89 if (dev->chip_ops && dev->chip_ops->final &&
90 !dev->chip_ops->finalized) {
91 dev->chip_ops->final(dev->chip_info);
92 dev->chip_ops->finalized = 1;
93 }
94 }
95}
96
Uwe Hermannc1ee4292010-10-17 19:01:48 +000097DECLARE_SPIN_LOCK(dev_lock)
Eric Biederman8ca8d762003-04-22 19:02:15 +000098
Kyösti Mälkkib25374c2012-08-01 08:05:22 +030099#if CONFIG_GFXUMA
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +0300100/* IGD UMA memory */
101uint64_t uma_memory_base = 0;
102uint64_t uma_memory_size = 0;
Kyösti Mälkkib25374c2012-08-01 08:05:22 +0300103#endif
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +0300104
Li-Ta Loe5266692004-03-23 21:28:05 +0000105/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000106 * Allocate a new device structure.
Myles Watson032a9652009-05-11 22:24:53 +0000107 *
Martin Roth63373ed2013-07-08 16:24:19 -0600108 * Allocate a new device structure and attach it to the device tree as a
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000109 * child of the parent bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000110 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000111 * @param parent Parent bus the newly created device should be attached to.
112 * @param path Path to the device to be created.
113 * @return Pointer to the newly created device structure.
Li-Ta Loe5266692004-03-23 21:28:05 +0000114 *
115 * @see device_path
Eric Biederman8ca8d762003-04-22 19:02:15 +0000116 */
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300117static device_t __alloc_dev(struct bus *parent, struct device_path *path)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000118{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000119 device_t dev, child;
Li-Ta Loe5266692004-03-23 21:28:05 +0000120
Myles Watson29cc9ed2009-07-02 18:56:24 +0000121 /* Find the last child of our parent. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000122 for (child = parent->children; child && child->sibling; /* */ )
Eric Biedermane9a271e32003-09-02 03:36:25 +0000123 child = child->sibling;
Li-Ta Lo3a812852004-12-03 22:39:34 +0000124
Eric Biedermane9a271e32003-09-02 03:36:25 +0000125 dev = malloc(sizeof(*dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000126 if (dev == 0)
Uwe Hermanne4870472010-11-04 23:23:47 +0000127 die("alloc_dev(): out of memory.\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000128
Eric Biedermane9a271e32003-09-02 03:36:25 +0000129 memset(dev, 0, sizeof(*dev));
130 memcpy(&dev->path, path, sizeof(*path));
131
Myles Watson29cc9ed2009-07-02 18:56:24 +0000132 /* By default devices are enabled. */
Eric Biederman03acab62004-10-14 21:25:53 +0000133 dev->enabled = 1;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000134
Eric Biedermanb78c1972004-10-14 20:54:17 +0000135 /* Add the new device to the list of children of the bus. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000136 dev->bus = parent;
Uwe Hermanne4870472010-11-04 23:23:47 +0000137 if (child)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000138 child->sibling = dev;
Uwe Hermanne4870472010-11-04 23:23:47 +0000139 else
Eric Biedermane9a271e32003-09-02 03:36:25 +0000140 parent->children = dev;
Li-Ta Loe5266692004-03-23 21:28:05 +0000141
Eric Biederman03acab62004-10-14 21:25:53 +0000142 /* Append a new device to the global device list.
143 * The list is used to find devices once everything is set up.
144 */
Myles Watson70679a02010-09-01 21:03:03 +0000145 last_dev->next = dev;
146 last_dev = dev;
Eric Biederman03acab62004-10-14 21:25:53 +0000147
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300148 return dev;
149}
150
151device_t alloc_dev(struct bus *parent, struct device_path *path)
152{
153 device_t dev;
154 spin_lock(&dev_lock);
155 dev = __alloc_dev(parent, path);
Eric Biederman03acab62004-10-14 21:25:53 +0000156 spin_unlock(&dev_lock);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000157 return dev;
158}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000159
Li-Ta Loe5266692004-03-23 21:28:05 +0000160/**
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300161 * See if a device structure already exists and if not allocate it.
162 *
163 * @param parent The bus to find the device on.
164 * @param path The relative path from the bus to the appropriate device.
165 * @return Pointer to a device structure for the device on bus at path.
166 */
167device_t alloc_find_dev(struct bus *parent, struct device_path *path)
168{
169 device_t child;
170 spin_lock(&dev_lock);
171 child = find_dev_path(parent, path);
172 if (!child)
173 child = __alloc_dev(parent, path);
174 spin_unlock(&dev_lock);
175 return child;
176}
177
178/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000179 * Round a number up to an alignment.
180 *
181 * @param val The starting value.
Martin Roth32bc6b62015-01-04 16:54:35 -0700182 * @param pow Alignment as a power of two.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000183 * @return Rounded up number.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000184 */
Eric Biederman448bd632004-10-14 22:52:15 +0000185static resource_t round(resource_t val, unsigned long pow)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000186{
Eric Biederman448bd632004-10-14 22:52:15 +0000187 resource_t mask;
188 mask = (1ULL << pow) - 1ULL;
189 val += mask;
190 val &= ~mask;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000191 return val;
192}
193
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200194static const char * resource2str(struct resource *res)
195{
196 if (res->flags & IORESOURCE_IO)
197 return "io";
198 if (res->flags & IORESOURCE_PREFETCH)
199 return "prefmem";
200 if (res->flags & IORESOURCE_MEM)
201 return "mem";
202 return "undefined";
203}
204
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000205/**
206 * Read the resources on all devices of a given bus.
207 *
208 * @param bus Bus to read the resources on.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000209 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000210static void read_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000211{
212 struct device *curdev;
213
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000214 printk(BIOS_SPEW, "%s %s bus %x link: %d\n", dev_path(bus->dev),
215 __func__, bus->secondary, bus->link_num);
Eric Biederman448bd632004-10-14 22:52:15 +0000216
Myles Watson29cc9ed2009-07-02 18:56:24 +0000217 /* Walk through all devices and find which resources they need. */
218 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Myles Watson894a3472010-06-09 22:41:35 +0000219 struct bus *link;
Uwe Hermanne4870472010-11-04 23:23:47 +0000220
221 if (!curdev->enabled)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000222 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000223
Eric Biedermane9a271e32003-09-02 03:36:25 +0000224 if (!curdev->ops || !curdev->ops->read_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000225 printk(BIOS_ERR, "%s missing read_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000226 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000227 continue;
228 }
Duncan Laurie7ed39762013-07-09 10:46:52 -0700229 post_log_path(curdev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000230 curdev->ops->read_resources(curdev);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000231
232 /* Read in the resources behind the current device's links. */
Myles Watson894a3472010-06-09 22:41:35 +0000233 for (link = curdev->link_list; link; link = link->next)
234 read_resources(link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000235 }
Duncan Laurie7ed39762013-07-09 10:46:52 -0700236 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000237 printk(BIOS_SPEW, "%s read_resources bus %d link: %d done\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000238 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000239}
240
Eric Biedermane9a271e32003-09-02 03:36:25 +0000241struct pick_largest_state {
242 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000243 struct device *result_dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000244 struct resource *result;
245 int seen_last;
246};
247
Myles Watson29cc9ed2009-07-02 18:56:24 +0000248static void pick_largest_resource(void *gp, struct device *dev,
249 struct resource *resource)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000250{
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000251 struct pick_largest_state *state = gp;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000252 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000253
Eric Biedermane9a271e32003-09-02 03:36:25 +0000254 last = state->last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000255
256 /* Be certain to pick the successor to last. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000257 if (resource == last) {
258 state->seen_last = 1;
259 return;
260 }
Myles Watson032a9652009-05-11 22:24:53 +0000261 if (resource->flags & IORESOURCE_FIXED)
Uwe Hermanne4870472010-11-04 23:23:47 +0000262 return; /* Skip it. */
Myles Watson032a9652009-05-11 22:24:53 +0000263 if (last && ((last->align < resource->align) ||
264 ((last->align == resource->align) &&
265 (last->size < resource->size)) ||
266 ((last->align == resource->align) &&
267 (last->size == resource->size) && (!state->seen_last)))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000268 return;
269 }
Myles Watson032a9652009-05-11 22:24:53 +0000270 if (!state->result ||
271 (state->result->align < resource->align) ||
272 ((state->result->align == resource->align) &&
Myles Watson29cc9ed2009-07-02 18:56:24 +0000273 (state->result->size < resource->size))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000274 state->result_dev = dev;
275 state->result = resource;
Myles Watson032a9652009-05-11 22:24:53 +0000276 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000277}
278
Myles Watson29cc9ed2009-07-02 18:56:24 +0000279static struct device *largest_resource(struct bus *bus,
280 struct resource **result_res,
281 unsigned long type_mask,
282 unsigned long type)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000283{
284 struct pick_largest_state state;
285
286 state.last = *result_res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000287 state.result_dev = NULL;
288 state.result = NULL;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000289 state.seen_last = 0;
290
Myles Watson032a9652009-05-11 22:24:53 +0000291 search_bus_resources(bus, type_mask, type, pick_largest_resource,
292 &state);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000293
294 *result_res = state.result;
295 return state.result_dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000296}
297
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000298/**
Uwe Hermanne4870472010-11-04 23:23:47 +0000299 * This function is the guts of the resource allocator.
Myles Watson032a9652009-05-11 22:24:53 +0000300 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000301 * The problem.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000302 * - Allocate resource locations for every device.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000303 * - Don't overlap, and follow the rules of bridges.
304 * - Don't overlap with resources in fixed locations.
305 * - Be efficient so we don't have ugly strategies.
306 *
307 * The strategy.
308 * - Devices that have fixed addresses are the minority so don't
Myles Watson29cc9ed2009-07-02 18:56:24 +0000309 * worry about them too much. Instead only use part of the address
310 * space for devices with programmable addresses. This easily handles
Eric Biederman8ca8d762003-04-22 19:02:15 +0000311 * everything except bridges.
312 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000313 * - PCI devices are required to have their sizes and their alignments
314 * equal. In this case an optimal solution to the packing problem
315 * exists. Allocate all devices from highest alignment to least
316 * alignment or vice versa. Use this.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000317 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000318 * - So we can handle more than PCI run two allocation passes on bridges. The
319 * first to see how large the resources are behind the bridge, and what
320 * their alignment requirements are. The second to assign a safe address to
321 * the devices behind the bridge. This allows us to treat a bridge as just
322 * a device with a couple of resources, and not need to special case it in
323 * the allocator. Also this allows handling of other types of bridges.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000324 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000325 * @param bus The bus we are traversing.
326 * @param bridge The bridge resource which must contain the bus' resources.
327 * @param type_mask This value gets ANDed with the resource type.
328 * @param type This value must match the result of the AND.
329 * @return TODO
Eric Biederman8ca8d762003-04-22 19:02:15 +0000330 */
Myles Watson54913b92009-10-13 20:00:09 +0000331static void compute_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000332 unsigned long type_mask, unsigned long type)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000333{
334 struct device *dev;
335 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000336 resource_t base;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000337 base = round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000338
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200339 printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d"
340 " limit: %llx\n", dev_path(bus->dev), resource2str(bridge),
341 base, bridge->size, bridge->align,
Uwe Hermanne4870472010-11-04 23:23:47 +0000342 bridge->gran, bridge->limit);
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000343
Uwe Hermanne4870472010-11-04 23:23:47 +0000344 /* For each child which is a bridge, compute the resource needs. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000345 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000346 struct resource *child_bridge;
347
Myles Watson894a3472010-06-09 22:41:35 +0000348 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000349 continue;
350
351 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000352 for (child_bridge = dev->resource_list; child_bridge;
353 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000354 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000355
Uwe Hermanne4870472010-11-04 23:23:47 +0000356 if (!(child_bridge->flags & IORESOURCE_BRIDGE)
357 || (child_bridge->flags & type_mask) != type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000358 continue;
359
Uwe Hermanne4870472010-11-04 23:23:47 +0000360 /*
361 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000362 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000363 * and non-prefetchable memory. Bridges below them need
364 * it separated. Add the PREFETCH flag to the type_mask
365 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000366 */
Myles Watson894a3472010-06-09 22:41:35 +0000367 link = dev->link_list;
368 while (link && link->link_num !=
369 IOINDEX_LINK(child_bridge->index))
370 link = link->next;
Uwe Hermanne4870472010-11-04 23:23:47 +0000371
372 if (link == NULL) {
Myles Watson894a3472010-06-09 22:41:35 +0000373 printk(BIOS_ERR, "link %ld not found on %s\n",
374 IOINDEX_LINK(child_bridge->index),
375 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000376 }
377
Myles Watson894a3472010-06-09 22:41:35 +0000378 compute_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000379 type_mask | IORESOURCE_PREFETCH,
380 type | (child_bridge->flags &
381 IORESOURCE_PREFETCH));
382 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000383 }
384
Myles Watson29cc9ed2009-07-02 18:56:24 +0000385 /* Remember we haven't found anything yet. */
386 resource = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000387
Uwe Hermanne4870472010-11-04 23:23:47 +0000388 /*
389 * Walk through all the resources on the current bus and compute the
390 * amount of address space taken by them. Take granularity and
Myles Watson29cc9ed2009-07-02 18:56:24 +0000391 * alignment into account.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000392 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000393 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000394
Myles Watson29cc9ed2009-07-02 18:56:24 +0000395 /* Size 0 resources can be skipped. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000396 if (!resource->size)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000397 continue;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000398
Myles Watson29cc9ed2009-07-02 18:56:24 +0000399 /* Propagate the resource alignment to the bridge resource. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000400 if (resource->align > bridge->align)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000401 bridge->align = resource->align;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000402
403 /* Propagate the resource limit to the bridge register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000404 if (bridge->limit > resource->limit)
Eric Biedermandbec2d42004-10-21 10:44:08 +0000405 bridge->limit = resource->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000406
407 /* Warn if it looks like APICs aren't declared. */
408 if ((resource->limit == 0xffffffff) &&
409 (resource->flags & IORESOURCE_ASSIGNED)) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000410 printk(BIOS_ERR,
411 "Resource limit looks wrong! (no APIC?)\n");
Patrick Georgi51615092012-03-11 19:31:03 +0100412 printk(BIOS_ERR, "%s %02lx limit %08llx\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000413 dev_path(dev), resource->index, resource->limit);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000414 }
Stefan Reinauer51754a32008-08-01 12:28:38 +0000415
Eric Biederman8ca8d762003-04-22 19:02:15 +0000416 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000417 /*
418 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000419 * expansion card addresses. The legacy PCI decodes
420 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
421 * 0x00 - 0xff can be used out of each 0x400 block of
422 * I/O space.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000423 */
Eric Biedermanbbb6d102003-08-04 19:54:48 +0000424 if ((base & 0x300) != 0) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000425 base = (base & ~0x3ff) + 0x400;
426 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000427 /*
428 * Don't allow allocations in the VGA I/O range.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000429 * PCI has special cases for that.
430 */
431 else if ((base >= 0x3b0) && (base <= 0x3df)) {
432 base = 0x3e0;
433 }
434 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000435 /* Base must be aligned. */
436 base = round(base, resource->align);
437 resource->base = base;
438 base += resource->size;
Myles Watson032a9652009-05-11 22:24:53 +0000439
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000440 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000441 dev_path(dev), resource->index, resource->base,
442 resource->base + resource->size - 1,
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200443 resource2str(resource));
Eric Biederman8ca8d762003-04-22 19:02:15 +0000444 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000445
446 /*
447 * A PCI bridge resource does not need to be a power of two size, but
448 * it does have a minimum granularity. Round the size up to that
449 * minimum granularity so we know not to place something else at an
Martin Roth63373ed2013-07-08 16:24:19 -0600450 * address positively decoded by the bridge.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000451 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000452 bridge->size = round(base, bridge->gran) -
453 round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000454
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200455 printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d"
456 " limit: %llx done\n", dev_path(bus->dev),
457 resource2str(bridge),
Uwe Hermanne4870472010-11-04 23:23:47 +0000458 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000459}
460
461/**
462 * This function is the second part of the resource allocator.
463 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000464 * See the compute_resources function for a more detailed explanation.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000465 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000466 * This function assigns the resources a value.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000467 *
468 * @param bus The bus we are traversing.
469 * @param bridge The bridge resource which must contain the bus' resources.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000470 * @param type_mask This value gets ANDed with the resource type.
471 * @param type This value must match the result of the AND.
Uwe Hermanne4870472010-11-04 23:23:47 +0000472 *
473 * @see compute_resources
Myles Watson29cc9ed2009-07-02 18:56:24 +0000474 */
Myles Watson54913b92009-10-13 20:00:09 +0000475static void allocate_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000476 unsigned long type_mask, unsigned long type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000477{
478 struct device *dev;
479 struct resource *resource;
480 resource_t base;
481 base = bridge->base;
482
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200483 printk(BIOS_SPEW, "%s %s: base:%llx size:%llx align:%d gran:%d "
484 "limit:%llx\n", dev_path(bus->dev),
485 resource2str(bridge),
Myles Watson29cc9ed2009-07-02 18:56:24 +0000486 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
487
488 /* Remember we haven't found anything yet. */
489 resource = NULL;
490
Uwe Hermanne4870472010-11-04 23:23:47 +0000491 /*
492 * Walk through all the resources on the current bus and allocate them
Myles Watson29cc9ed2009-07-02 18:56:24 +0000493 * address space.
494 */
495 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
496
497 /* Propagate the bridge limit to the resource register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000498 if (resource->limit > bridge->limit)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000499 resource->limit = bridge->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000500
501 /* Size 0 resources can be skipped. */
502 if (!resource->size) {
503 /* Set the base to limit so it doesn't confuse tolm. */
504 resource->base = resource->limit;
505 resource->flags |= IORESOURCE_ASSIGNED;
506 continue;
507 }
508
509 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000510 /*
511 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000512 * expansion card addresses. The legacy PCI decodes
513 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
514 * 0x00 - 0xff can be used out of each 0x400 block of
515 * I/O space.
516 */
517 if ((base & 0x300) != 0) {
518 base = (base & ~0x3ff) + 0x400;
519 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000520 /*
521 * Don't allow allocations in the VGA I/O range.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000522 * PCI has special cases for that.
523 */
524 else if ((base >= 0x3b0) && (base <= 0x3df)) {
525 base = 0x3e0;
526 }
527 }
528
529 if ((round(base, resource->align) + resource->size - 1) <=
530 resource->limit) {
531 /* Base must be aligned. */
532 base = round(base, resource->align);
533 resource->base = base;
Kyösti Mälkki134b6162015-03-23 19:58:23 +0200534 resource->limit = resource->base + resource->size - 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000535 resource->flags |= IORESOURCE_ASSIGNED;
536 resource->flags &= ~IORESOURCE_STORED;
537 base += resource->size;
538 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000539 printk(BIOS_ERR, "!! Resource didn't fit !!\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000540 printk(BIOS_ERR, " aligned base %llx size %llx "
541 "limit %llx\n", round(base, resource->align),
542 resource->size, resource->limit);
543 printk(BIOS_ERR, " %llx needs to be <= %llx "
544 "(limit)\n", (round(base, resource->align) +
Myles Watson29cc9ed2009-07-02 18:56:24 +0000545 resource->size) - 1, resource->limit);
Uwe Hermanne4870472010-11-04 23:23:47 +0000546 printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx]"
547 " %s\n", (resource->flags & IORESOURCE_ASSIGNED)
548 ? "Assigned: " : "", dev_path(dev),
549 resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000550 resource->base + resource->size - 1,
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200551 resource2str(resource));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000552 }
553
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200554 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
555 dev_path(dev), resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000556 resource->size ? resource->base + resource->size - 1 :
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200557 resource->base, resource2str(resource));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000558 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000559
560 /*
561 * A PCI bridge resource does not need to be a power of two size, but
Myles Watson29cc9ed2009-07-02 18:56:24 +0000562 * it does have a minimum granularity. Round the size up to that
563 * minimum granularity so we know not to place something else at an
564 * address positively decoded by the bridge.
565 */
566
567 bridge->flags |= IORESOURCE_ASSIGNED;
568
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200569 printk(BIOS_SPEW, "%s %s: next_base: %llx size: %llx align: %d "
570 "gran: %d done\n", dev_path(bus->dev),
571 resource2str(bridge), base, bridge->size, bridge->align,
Uwe Hermanne4870472010-11-04 23:23:47 +0000572 bridge->gran);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000573
574 /* For each child which is a bridge, allocate_resources. */
575 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000576 struct resource *child_bridge;
577
Myles Watson894a3472010-06-09 22:41:35 +0000578 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000579 continue;
580
581 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000582 for (child_bridge = dev->resource_list; child_bridge;
583 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000584 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000585
586 if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
587 (child_bridge->flags & type_mask) != type)
588 continue;
589
Uwe Hermanne4870472010-11-04 23:23:47 +0000590 /*
591 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000592 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000593 * and non-prefetchable memory. Bridges below them need
594 * it separated. Add the PREFETCH flag to the type_mask
595 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000596 */
Myles Watson894a3472010-06-09 22:41:35 +0000597 link = dev->link_list;
598 while (link && link->link_num !=
599 IOINDEX_LINK(child_bridge->index))
600 link = link->next;
601 if (link == NULL)
602 printk(BIOS_ERR, "link %ld not found on %s\n",
603 IOINDEX_LINK(child_bridge->index),
604 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000605
Myles Watson894a3472010-06-09 22:41:35 +0000606 allocate_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000607 type_mask | IORESOURCE_PREFETCH,
608 type | (child_bridge->flags &
609 IORESOURCE_PREFETCH));
610 }
611 }
612}
613
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200614static int resource_is(struct resource *res, u32 type)
615{
616 return (res->flags & IORESOURCE_TYPE_MASK) == type;
617}
Myles Watson29cc9ed2009-07-02 18:56:24 +0000618
619struct constraints {
Kyösti Mälkkifcbebb62015-03-17 06:42:54 +0200620 struct resource io, mem;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000621};
622
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200623static struct resource * resource_limit(struct constraints *limits, struct resource *res)
624{
625 struct resource *lim = NULL;
626
627 /* MEM, or I/O - skip any others. */
628 if (resource_is(res, IORESOURCE_MEM))
629 lim = &limits->mem;
630 else if (resource_is(res, IORESOURCE_IO))
631 lim = &limits->io;
632
633 return lim;
634}
635
Myles Watson29cc9ed2009-07-02 18:56:24 +0000636static void constrain_resources(struct device *dev, struct constraints* limits)
637{
638 struct device *child;
639 struct resource *res;
640 struct resource *lim;
Myles Watson894a3472010-06-09 22:41:35 +0000641 struct bus *link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000642
Myles Watson29cc9ed2009-07-02 18:56:24 +0000643 /* Constrain limits based on the fixed resources of this device. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000644 for (res = dev->resource_list; res; res = res->next) {
Patrick Georgi18c585b2009-08-28 12:48:02 +0000645 if (!(res->flags & IORESOURCE_FIXED))
646 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000647 if (!res->size) {
648 /* It makes no sense to have 0-sized, fixed resources.*/
Uwe Hermanne4870472010-11-04 23:23:47 +0000649 printk(BIOS_ERR, "skipping %s@%lx fixed resource, "
650 "size=0!\n", dev_path(dev), res->index);
Patrick Georgi6bd93f42009-08-19 17:29:41 +0000651 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000652 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000653
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200654 lim = resource_limit(limits, res);
655 if (!lim)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000656 continue;
657
Uwe Hermanne4870472010-11-04 23:23:47 +0000658 /*
659 * Is it a fixed resource outside the current known region?
660 * If so, we don't have to consider it - it will be handled
661 * correctly and doesn't affect current region's limits.
662 */
663 if (((res->base + res->size -1) < lim->base)
664 || (res->base > lim->limit))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000665 continue;
666
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200667 printk(BIOS_SPEW, "%s: %s %02lx base %08llx limit %08llx %s (fixed)\n",
668 __func__, dev_path(dev), res->index, res->base,
669 res->base + res->size - 1, resource2str(res));
670
Uwe Hermanne4870472010-11-04 23:23:47 +0000671 /*
672 * Choose to be above or below fixed resources. This check is
673 * signed so that "negative" amounts of space are handled
674 * correctly.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000675 */
Uwe Hermanne4870472010-11-04 23:23:47 +0000676 if ((signed long long)(lim->limit - (res->base + res->size -1))
677 > (signed long long)(res->base - lim->base))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000678 lim->base = res->base + res->size;
679 else
680 lim->limit = res->base -1;
681 }
682
683 /* Descend into every enabled child and look for fixed resources. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000684 for (link = dev->link_list; link; link = link->next) {
685 for (child = link->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000686 if (child->enabled)
687 constrain_resources(child, limits);
Uwe Hermanne4870472010-11-04 23:23:47 +0000688 }
689 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000690}
691
692static void avoid_fixed_resources(struct device *dev)
693{
694 struct constraints limits;
695 struct resource *res;
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200696 struct resource *lim;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000697
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000698 printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000699
Uwe Hermanne4870472010-11-04 23:23:47 +0000700 /* Initialize constraints to maximum size. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000701 limits.io.base = 0;
702 limits.io.limit = 0xffffffffffffffffULL;
703 limits.mem.base = 0;
704 limits.mem.limit = 0xffffffffffffffffULL;
705
706 /* Constrain the limits to dev's initial resources. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000707 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000708 if ((res->flags & IORESOURCE_FIXED))
709 continue;
Patrick Georgi51615092012-03-11 19:31:03 +0100710 printk(BIOS_SPEW, "%s:@%s %02lx limit %08llx\n", __func__,
Uwe Hermanne4870472010-11-04 23:23:47 +0000711 dev_path(dev), res->index, res->limit);
Kyösti Mälkkifcbebb62015-03-17 06:42:54 +0200712
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200713 lim = resource_limit(&limits, res);
714 if (!lim)
715 continue;
716
717 if (res->base > lim->base)
718 lim->base = res->base;
719 if (res->limit < lim->limit)
720 lim->limit = res->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000721 }
722
723 /* Look through the tree for fixed resources and update the limits. */
724 constrain_resources(dev, &limits);
725
726 /* Update dev's resources with new limits. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000727 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000728 if ((res->flags & IORESOURCE_FIXED))
729 continue;
730
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +0200731 lim = resource_limit(&limits, res);
732 if (!lim)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000733 continue;
734
Myles Watson29cc9ed2009-07-02 18:56:24 +0000735 /* Is the resource outside the limits? */
736 if (lim->base > res->base)
737 res->base = lim->base;
738 if (res->limit > lim->limit)
739 res->limit = lim->limit;
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200740
Kyösti Mälkki634899c2015-03-23 14:22:22 +0200741 /* MEM resources need to start at the highest address manageable. */
742 if (res->flags & IORESOURCE_MEM)
743 res->base = resource_max(res);
744
Kyösti Mälkkie6a9290f2015-03-23 19:37:38 +0200745 printk(BIOS_SPEW, "%s:@%s %02lx base %08llx limit %08llx\n",
746 __func__, dev_path(dev), res->index, res->base, res->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000747 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000748}
arch import user (historical)dc811182005-07-06 17:16:09 +0000749
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000750device_t vga_pri = 0;
Myles Watsonc7233e02009-07-02 19:02:33 +0000751static void set_vga_bridge_bits(void)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000752{
Uwe Hermann312673c2009-10-27 21:49:33 +0000753 /*
Martin Roth63373ed2013-07-08 16:24:19 -0600754 * FIXME: Modify set_vga_bridge() so it is less PCI-centric!
Uwe Hermann312673c2009-10-27 21:49:33 +0000755 * This function knows too much about PCI stuff, it should be just
756 * an iterator/visitor.
757 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000758
Myles Watson29cc9ed2009-07-02 18:56:24 +0000759 /* FIXME: Handle the VGA palette snooping. */
Patrick Georgi557ecf22012-07-20 12:16:17 +0200760 struct device *dev, *vga, *vga_onboard;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000761 struct bus *bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000762
Eric Biedermanb78c1972004-10-14 20:54:17 +0000763 bus = 0;
764 vga = 0;
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000765 vga_onboard = 0;
Uwe Hermanne4870472010-11-04 23:23:47 +0000766
Patrick Georgi557ecf22012-07-20 12:16:17 +0200767 dev = NULL;
768 while ((dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev))) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000769 if (!dev->enabled)
770 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000771
Patrick Georgi557ecf22012-07-20 12:16:17 +0200772 printk(BIOS_DEBUG, "found VGA at %s\n", dev_path(dev));
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000773
Patrick Georgi557ecf22012-07-20 12:16:17 +0200774 if (dev->on_mainboard) {
775 vga_onboard = dev;
Kostr1f0d3792012-10-06 13:27:58 +0400776 } else {
Patrick Georgi557ecf22012-07-20 12:16:17 +0200777 vga = dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000778 }
Myles Watson032a9652009-05-11 22:24:53 +0000779
Patrick Georgi557ecf22012-07-20 12:16:17 +0200780 /* It isn't safe to enable all VGA cards. */
781 dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Patrick Georgi594473d2012-07-25 08:55:53 +0200782 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000783
Uwe Hermanne4870472010-11-04 23:23:47 +0000784 if (!vga)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000785 vga = vga_onboard;
Patrick Georgi557ecf22012-07-20 12:16:17 +0200786
787 if (CONFIG_ONBOARD_VGA_IS_PRIMARY && vga_onboard)
788 vga = vga_onboard;
Myles Watson032a9652009-05-11 22:24:53 +0000789
Patrick Georgi5869fa22012-07-20 12:29:33 +0200790 /* If we prefer plugin VGA over chipset VGA, the chipset might
791 want to know. */
792 if (!CONFIG_ONBOARD_VGA_IS_PRIMARY && (vga != vga_onboard) &&
793 vga_onboard && vga_onboard->ops && vga_onboard->ops->disable) {
794 printk(BIOS_DEBUG, "Use plugin graphics over integrated.\n");
795 vga_onboard->ops->disable(vga_onboard);
796 }
797
arch import user (historical)dc811182005-07-06 17:16:09 +0000798 if (vga) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000799 /* VGA is first add-on card or the only onboard VGA. */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000800 printk(BIOS_DEBUG, "Setting up VGA for %s\n", dev_path(vga));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000801 /* All legacy VGA cards have MEM & I/O space registers. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000802 vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
803 vga_pri = vga;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000804 bus = vga->bus;
805 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000806
Myles Watson29cc9ed2009-07-02 18:56:24 +0000807 /* Now walk up the bridges setting the VGA enable. */
808 while (bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000809 printk(BIOS_DEBUG, "Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000810 dev_path(bus->dev));
Li-Ta Lodb7f47c2004-01-08 21:15:49 +0000811 bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000812 bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus;
Myles Watson032a9652009-05-11 22:24:53 +0000813 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000814}
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000815
Li-Ta Lo04930692004-11-25 17:37:19 +0000816/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000817 * Assign the computed resources to the devices on the bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000818 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000819 * Use the device specific set_resources() method to store the computed
Li-Ta Lo04930692004-11-25 17:37:19 +0000820 * resources to hardware. For bridge devices, the set_resources() method
821 * has to recurse into every down stream buses.
822 *
823 * Mutual recursion:
824 * assign_resources() -> device_operation::set_resources()
825 * device_operation::set_resources() -> assign_resources()
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000826 *
827 * @param bus Pointer to the structure for this bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000828 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000829void assign_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000830{
831 struct device *curdev;
832
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000833 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000834 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000835
Myles Watson29cc9ed2009-07-02 18:56:24 +0000836 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000837 if (!curdev->enabled || !curdev->resource_list)
Eric Biederman03acab62004-10-14 21:25:53 +0000838 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000839
Eric Biedermane9a271e32003-09-02 03:36:25 +0000840 if (!curdev->ops || !curdev->ops->set_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000841 printk(BIOS_ERR, "%s missing set_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000842 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000843 continue;
844 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700845 post_log_path(curdev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000846 curdev->ops->set_resources(curdev);
847 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700848 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000849 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000850 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000851}
852
Li-Ta Lo5782d272004-04-26 17:51:20 +0000853/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000854 * Enable the resources for devices on a link.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000855 *
856 * Enable resources of the device by calling the device specific
857 * enable_resources() method.
858 *
859 * The parent's resources should be enabled first to avoid having enabling
860 * order problem. This is done by calling the parent's enable_resources()
Martin Roth63373ed2013-07-08 16:24:19 -0600861 * method before its children's enable_resources() methods.
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000862 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000863 * @param link The link whose devices' resources are to be enabled.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000864 */
Myles Watson7eac4452010-06-17 16:16:56 +0000865static void enable_resources(struct bus *link)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000866{
Myles Watson7eac4452010-06-17 16:16:56 +0000867 struct device *dev;
868 struct bus *c_link;
869
870 for (dev = link->children; dev; dev = dev->sibling) {
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700871 if (dev->enabled && dev->ops && dev->ops->enable_resources) {
872 post_log_path(dev);
Myles Watson7eac4452010-06-17 16:16:56 +0000873 dev->ops->enable_resources(dev);
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700874 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000875 }
Myles Watson7eac4452010-06-17 16:16:56 +0000876
877 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000878 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +0000879 enable_resources(c_link);
Eric Biederman83b991a2003-10-11 06:20:25 +0000880 }
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700881 post_log_clear();
Eric Biederman8ca8d762003-04-22 19:02:15 +0000882}
883
Myles Watson032a9652009-05-11 22:24:53 +0000884/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000885 * Reset all of the devices on a bus and clear the bus's reset_needed flag.
886 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000887 * @param bus Pointer to the bus structure.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000888 * @return 1 if the bus was successfully reset, 0 otherwise.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000889 */
890int reset_bus(struct bus *bus)
891{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000892 if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000893 bus->dev->ops->reset_bus(bus);
894 bus->reset_needed = 0;
895 return 1;
896 }
897 return 0;
898}
899
Myles Watson032a9652009-05-11 22:24:53 +0000900/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000901 * Scan for devices on a bus.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000902 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000903 * If there are bridges on the bus, recursively scan the buses behind the
904 * bridges. If the setting up and tuning of the bus causes a reset to be
905 * required, reset the bus and scan it again.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000906 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000907 * @param busdev Pointer to the bus device.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000908 */
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200909static void scan_bus(struct device *busdev)
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000910{
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000911 int do_scan_bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000912
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200913 if (!busdev->enabled)
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200914 return;
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200915
916 printk(BIOS_SPEW, "%s scanning...\n", dev_path(busdev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000917
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700918 post_log_path(busdev);
919
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000920 do_scan_bus = 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000921 while (do_scan_bus) {
Myles Watson894a3472010-06-09 22:41:35 +0000922 struct bus *link;
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200923 busdev->ops->scan_bus(busdev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000924 do_scan_bus = 0;
Myles Watson894a3472010-06-09 22:41:35 +0000925 for (link = busdev->link_list; link; link = link->next) {
926 if (link->reset_needed) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000927 if (reset_bus(link))
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000928 do_scan_bus = 1;
Uwe Hermanne4870472010-11-04 23:23:47 +0000929 else
Myles Watson29cc9ed2009-07-02 18:56:24 +0000930 busdev->bus->reset_needed = 1;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000931 }
932 }
933 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000934}
935
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200936void scan_bridges(struct bus *bus)
937{
938 struct device *child;
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200939
940 for (child = bus->children; child; child = child->sibling) {
941 if (!child->ops || !child->ops->scan_bus)
942 continue;
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200943 scan_bus(child);
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200944 }
Kyösti Mälkki2d2367c2015-02-20 21:28:31 +0200945}
946
Li-Ta Loe5266692004-03-23 21:28:05 +0000947/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000948 * Determine the existence of devices and extend the device tree.
Li-Ta Lo04930692004-11-25 17:37:19 +0000949 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000950 * Most of the devices in the system are listed in the mainboard devicetree.cb
Li-Ta Lo04930692004-11-25 17:37:19 +0000951 * file. The device structures for these devices are generated at compile
952 * time by the config tool and are organized into the device tree. This
953 * function determines if the devices created at compile time actually exist
954 * in the physical system.
955 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000956 * For devices in the physical system but not listed in devicetree.cb,
Li-Ta Lo04930692004-11-25 17:37:19 +0000957 * the device structures have to be created at run time and attached to the
Li-Ta Loe5266692004-03-23 21:28:05 +0000958 * device tree.
959 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000960 * This function starts from the root device 'dev_root', scans the buses in
961 * the system recursively, and modifies the device tree according to the
962 * result of the probe.
Li-Ta Loe5266692004-03-23 21:28:05 +0000963 *
Li-Ta Lo5782d272004-04-26 17:51:20 +0000964 * This function has no idea how to scan and probe buses and devices at all.
965 * It depends on the bus/device specific scan_bus() method to do it. The
Li-Ta Lo04930692004-11-25 17:37:19 +0000966 * scan_bus() method also has to create the device structure and attach
Myles Watson032a9652009-05-11 22:24:53 +0000967 * it to the device tree.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000968 */
969void dev_enumerate(void)
970{
971 struct device *root;
Uwe Hermanne4870472010-11-04 23:23:47 +0000972
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000973 printk(BIOS_INFO, "Enumerating buses...\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000974
Eric Biederman8ca8d762003-04-22 19:02:15 +0000975 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000976
Uwe Hermanne4870472010-11-04 23:23:47 +0000977 show_all_devs(BIOS_SPEW, "Before device enumeration.");
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000978 printk(BIOS_SPEW, "Compare with tree...\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +0000979 show_devs_tree(root, BIOS_SPEW, 0, 0);
Myles Watsoncd5d7562009-05-12 13:43:34 +0000980
Stefan Reinauera675d492012-08-07 14:50:47 -0700981 if (root->chip_ops && root->chip_ops->enable_dev)
982 root->chip_ops->enable_dev(root);
Uwe Hermanne4870472010-11-04 23:23:47 +0000983
Eric Biedermanb78c1972004-10-14 20:54:17 +0000984 if (!root->ops || !root->ops->scan_bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000985 printk(BIOS_ERR, "dev_root missing scan_bus operation");
Eric Biedermanb78c1972004-10-14 20:54:17 +0000986 return;
987 }
Kyösti Mälkki580e7222015-03-19 21:04:23 +0200988 scan_bus(root);
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700989 post_log_clear();
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000990 printk(BIOS_INFO, "done\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000991}
992
Li-Ta Loe5266692004-03-23 21:28:05 +0000993/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000994 * Configure devices on the devices tree.
Myles Watson032a9652009-05-11 22:24:53 +0000995 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000996 * Starting at the root of the device tree, travel it recursively in two
997 * passes. In the first pass, we compute and allocate resources (ranges)
Martin Roth63373ed2013-07-08 16:24:19 -0600998 * required by each device. In the second pass, the resources ranges are
Li-Ta Lo04930692004-11-25 17:37:19 +0000999 * relocated to their final position and stored to the hardware.
Li-Ta Lo5782d272004-04-26 17:51:20 +00001000 *
Myles Watson29cc9ed2009-07-02 18:56:24 +00001001 * I/O resources grow upward. MEM resources grow downward.
Li-Ta Lo5782d272004-04-26 17:51:20 +00001002 *
1003 * Since the assignment is hierarchical we set the values into the dev_root
Myles Watson032a9652009-05-11 22:24:53 +00001004 * struct.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001005 */
1006void dev_configure(void)
1007{
Myles Watson29cc9ed2009-07-02 18:56:24 +00001008 struct resource *res;
Eric Biedermanb78c1972004-10-14 20:54:17 +00001009 struct device *root;
Myles Watson29cc9ed2009-07-02 18:56:24 +00001010 struct device *child;
Li-Ta Loe5266692004-03-23 21:28:05 +00001011
Marc Jones80bd74c2012-02-21 17:44:35 +01001012 set_vga_bridge_bits();
Marc Jones80bd74c2012-02-21 17:44:35 +01001013
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001014 printk(BIOS_INFO, "Allocating resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001015
Eric Biedermanb78c1972004-10-14 20:54:17 +00001016 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +00001017
Uwe Hermanne4870472010-11-04 23:23:47 +00001018 /*
1019 * Each domain should create resources which contain the entire address
Myles Watson29cc9ed2009-07-02 18:56:24 +00001020 * space for IO, MEM, and PREFMEM resources in the domain. The
1021 * allocation of device resources will be done from this address space.
1022 */
Myles Watsoncd5d7562009-05-12 13:43:34 +00001023
Myles Watson29cc9ed2009-07-02 18:56:24 +00001024 /* Read the resources for the entire tree. */
Li-Ta Lo04930692004-11-25 17:37:19 +00001025
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001026 printk(BIOS_INFO, "Reading resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001027 read_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001028 printk(BIOS_INFO, "Done reading resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001029
Stefan Reinauer39e72292009-10-26 16:47:05 +00001030 print_resource_tree(root, BIOS_SPEW, "After reading.");
Myles Watsoncd5d7562009-05-12 13:43:34 +00001031
Myles Watson29cc9ed2009-07-02 18:56:24 +00001032 /* Compute resources for all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001033 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001034 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001035 continue;
Duncan Laurie7ed39762013-07-09 10:46:52 -07001036 post_log_path(child);
Myles Watsonc25cc112010-05-21 14:33:48 +00001037 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001038 if (res->flags & IORESOURCE_FIXED)
1039 continue;
Myles Watson29cc9ed2009-07-02 18:56:24 +00001040 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001041 compute_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001042 res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001043 continue;
1044 }
1045 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001046 compute_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001047 res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001048 continue;
1049 }
1050 }
1051 }
1052
1053 /* For all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001054 for (child = root->link_list->children; child; child=child->sibling)
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001055 if (child->path.type == DEVICE_PATH_DOMAIN)
Myles Watson29cc9ed2009-07-02 18:56:24 +00001056 avoid_fixed_resources(child);
1057
Eric Biedermanb78c1972004-10-14 20:54:17 +00001058 /* Store the computed resource allocations into device registers ... */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001059 printk(BIOS_INFO, "Setting resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001060 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001061 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001062 continue;
Duncan Laurie7ed39762013-07-09 10:46:52 -07001063 post_log_path(child);
Myles Watsonc25cc112010-05-21 14:33:48 +00001064 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001065 if (res->flags & IORESOURCE_FIXED)
1066 continue;
Myles Watson29cc9ed2009-07-02 18:56:24 +00001067 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001068 allocate_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001069 res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001070 continue;
1071 }
1072 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001073 allocate_resources(child->link_list,
Kyösti Mälkkifdc0a902015-03-26 20:04:38 +02001074 res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001075 continue;
1076 }
1077 }
1078 }
Myles Watson894a3472010-06-09 22:41:35 +00001079 assign_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001080 printk(BIOS_INFO, "Done setting resources.\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001081 print_resource_tree(root, BIOS_SPEW, "After assigning values.");
Eric Biederman03acab62004-10-14 21:25:53 +00001082
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001083 printk(BIOS_INFO, "Done allocating resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001084}
1085
Li-Ta Loe5266692004-03-23 21:28:05 +00001086/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001087 * Enable devices on the device tree.
Li-Ta Loe5266692004-03-23 21:28:05 +00001088 *
1089 * Starting at the root, walk the tree and enable all devices/bridges by
1090 * calling the device's enable_resources() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001091 */
1092void dev_enable(void)
1093{
Myles Watson7eac4452010-06-17 16:16:56 +00001094 struct bus *link;
1095
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001096 printk(BIOS_INFO, "Enabling resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001097
Uwe Hermanne4870472010-11-04 23:23:47 +00001098 /* Now enable everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001099 for (link = dev_root.link_list; link; link = link->next)
1100 enable_resources(link);
Li-Ta Loe5266692004-03-23 21:28:05 +00001101
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001102 printk(BIOS_INFO, "done.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001103}
1104
Li-Ta Loe5266692004-03-23 21:28:05 +00001105/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001106 * Initialize a specific device.
Myles Watson7eac4452010-06-17 16:16:56 +00001107 *
Uwe Hermanne4870472010-11-04 23:23:47 +00001108 * The parent should be initialized first to avoid having an ordering problem.
Martin Roth63373ed2013-07-08 16:24:19 -06001109 * This is done by calling the parent's init() method before its children's
Uwe Hermanne4870472010-11-04 23:23:47 +00001110 * init() methods.
Myles Watson7eac4452010-06-17 16:16:56 +00001111 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001112 * @param dev The device to be initialized.
Myles Watson7eac4452010-06-17 16:16:56 +00001113 */
1114static void init_dev(struct device *dev)
1115{
Uwe Hermanne4870472010-11-04 23:23:47 +00001116 if (!dev->enabled)
Myles Watson7eac4452010-06-17 16:16:56 +00001117 return;
Myles Watson7eac4452010-06-17 16:16:56 +00001118
1119 if (!dev->initialized && dev->ops && dev->ops->init) {
Aaron Durbin05294292013-04-30 15:41:13 -05001120#if CONFIG_HAVE_MONOTONIC_TIMER
Aaron Durbin46ba4802014-09-23 16:34:40 -05001121 struct stopwatch sw;
1122 stopwatch_init(&sw);
Aaron Durbin05294292013-04-30 15:41:13 -05001123#endif
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
Paul Menzeldb232152015-06-07 20:28:17 +02001129 printk(BIOS_DEBUG, "%s init ...\n", dev_path(dev));
Myles Watson7eac4452010-06-17 16:16:56 +00001130 dev->initialized = 1;
1131 dev->ops->init(dev);
Aaron Durbin05294292013-04-30 15:41:13 -05001132#if CONFIG_HAVE_MONOTONIC_TIMER
Paul Menzeldb232152015-06-07 20:28:17 +02001133 printk(BIOS_DEBUG, "%s init finished in %ld usecs\n", dev_path(dev),
Aaron Durbin46ba4802014-09-23 16:34:40 -05001134 stopwatch_duration_usecs(&sw));
Aaron Durbin05294292013-04-30 15:41:13 -05001135#endif
Myles Watson7eac4452010-06-17 16:16:56 +00001136 }
1137}
1138
1139static void init_link(struct bus *link)
1140{
1141 struct device *dev;
1142 struct bus *c_link;
1143
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001144 for (dev = link->children; dev; dev = dev->sibling) {
Duncan Lauriecb73a842013-06-10 10:41:04 -07001145 post_code(POST_BS_DEV_INIT);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001146 post_log_path(dev);
Myles Watson7eac4452010-06-17 16:16:56 +00001147 init_dev(dev);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001148 }
Myles Watson7eac4452010-06-17 16:16:56 +00001149
1150 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +00001151 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +00001152 init_link(c_link);
Myles Watson7eac4452010-06-17 16:16:56 +00001153 }
1154}
1155
1156/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001157 * Initialize all devices in the global device tree.
Myles Watson7eac4452010-06-17 16:16:56 +00001158 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001159 * Starting at the root device, call the device's init() method to do
1160 * device-specific setup, then call each child's init() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001161 */
1162void dev_initialize(void)
1163{
Myles Watson7eac4452010-06-17 16:16:56 +00001164 struct bus *link;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001165
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001166 printk(BIOS_INFO, "Initializing devices...\n");
Myles Watson7eac4452010-06-17 16:16:56 +00001167
Duncan Laurieb4aaaa72012-01-17 09:03:11 -08001168#if CONFIG_ARCH_X86
1169 /* Ensure EBDA is prepared before Option ROMs. */
1170 setup_default_ebda();
1171#endif
1172
Myles Watson1bd3fb72010-08-16 16:25:23 +00001173 /* First call the mainboard init. */
1174 init_dev(&dev_root);
1175
Uwe Hermanne4870472010-11-04 23:23:47 +00001176 /* Now initialize everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001177 for (link = dev_root.link_list; link; link = link->next)
1178 init_link(link);
Duncan Laurie8adf7a22013-06-10 10:34:20 -07001179 post_log_clear();
Myles Watson7eac4452010-06-17 16:16:56 +00001180
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001181 printk(BIOS_INFO, "Devices initialized\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001182 show_all_devs(BIOS_SPEW, "After init.");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001183}
Marc Jones2a58ecd2013-10-29 17:32:00 -06001184
1185/**
1186 * Finalize a specific device.
1187 *
1188 * The parent should be finalized first to avoid having an ordering problem.
1189 * This is done by calling the parent's final() method before its childrens'
1190 * final() methods.
1191 *
1192 * @param dev The device to be initialized.
1193 */
1194static void final_dev(struct device *dev)
1195{
1196 if (!dev->enabled)
1197 return;
1198
1199 if (dev->ops && dev->ops->final) {
1200 printk(BIOS_DEBUG, "%s final\n", dev_path(dev));
1201 dev->ops->final(dev);
1202 }
1203}
1204
1205static void final_link(struct bus *link)
1206{
1207 struct device *dev;
1208 struct bus *c_link;
1209
1210 for (dev = link->children; dev; dev = dev->sibling)
1211 final_dev(dev);
1212
1213 for (dev = link->children; dev; dev = dev->sibling) {
1214 for (c_link = dev->link_list; c_link; c_link = c_link->next)
1215 final_link(c_link);
1216 }
1217}
1218/**
1219 * Finalize all devices in the global device tree.
1220 *
1221 * Starting at the root device, call the device's final() method to do
1222 * device-specific cleanup, then call each child's final() method.
1223 */
1224void dev_finalize(void)
1225{
1226 struct bus *link;
1227
1228 printk(BIOS_INFO, "Finalize devices...\n");
1229
1230 /* First call the mainboard finalize. */
1231 final_dev(&dev_root);
1232
1233 /* Now finalize everything. */
1234 for (link = dev_root.link_list; link; link = link->next)
1235 final_link(link);
1236
1237 printk(BIOS_INFO, "Devices finalized\n");
1238}