blob: f021c9b3a386c935cab0e45f9b43b6c3aeb0ca64 [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>
36#include <bitops.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000037#include <arch/io.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000038#include <device/device.h>
39#include <device/pci.h>
Li-Ta Lo54f05f62004-05-14 17:20:29 +000040#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000041#include <stdlib.h>
42#include <string.h>
Eric Biederman03acab62004-10-14 21:25:53 +000043#include <smp/spinlock.h>
Duncan Laurieb4aaaa72012-01-17 09:03:11 -080044#if CONFIG_ARCH_X86
45#include <arch/ebda.h>
46#endif
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
Uwe Hermannc1ee4292010-10-17 19:01:48 +000055DECLARE_SPIN_LOCK(dev_lock)
Eric Biederman8ca8d762003-04-22 19:02:15 +000056
Kyösti Mälkkib25374c2012-08-01 08:05:22 +030057#if CONFIG_GFXUMA
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +030058/* IGD UMA memory */
59uint64_t uma_memory_base = 0;
60uint64_t uma_memory_size = 0;
Kyösti Mälkkib25374c2012-08-01 08:05:22 +030061#endif
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +030062
Li-Ta Loe5266692004-03-23 21:28:05 +000063/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +000064 * Allocate a new device structure.
Myles Watson032a9652009-05-11 22:24:53 +000065 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +000066 * Allocte a new device structure and attach it to the device tree as a
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +000067 * child of the parent bus.
Li-Ta Loe5266692004-03-23 21:28:05 +000068 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +000069 * @param parent Parent bus the newly created device should be attached to.
70 * @param path Path to the device to be created.
71 * @return Pointer to the newly created device structure.
Li-Ta Loe5266692004-03-23 21:28:05 +000072 *
73 * @see device_path
Eric Biederman8ca8d762003-04-22 19:02:15 +000074 */
Kyösti Mälkkia5650a42012-07-07 17:15:51 +030075static device_t __alloc_dev(struct bus *parent, struct device_path *path)
Eric Biederman8ca8d762003-04-22 19:02:15 +000076{
Eric Biedermane9a271e32003-09-02 03:36:25 +000077 device_t dev, child;
Li-Ta Loe5266692004-03-23 21:28:05 +000078
Myles Watson29cc9ed2009-07-02 18:56:24 +000079 /* Find the last child of our parent. */
Uwe Hermanne4870472010-11-04 23:23:47 +000080 for (child = parent->children; child && child->sibling; /* */ )
Eric Biedermane9a271e32003-09-02 03:36:25 +000081 child = child->sibling;
Li-Ta Lo3a812852004-12-03 22:39:34 +000082
Eric Biedermane9a271e32003-09-02 03:36:25 +000083 dev = malloc(sizeof(*dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +000084 if (dev == 0)
Uwe Hermanne4870472010-11-04 23:23:47 +000085 die("alloc_dev(): out of memory.\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +000086
Eric Biedermane9a271e32003-09-02 03:36:25 +000087 memset(dev, 0, sizeof(*dev));
88 memcpy(&dev->path, path, sizeof(*path));
89
Myles Watson29cc9ed2009-07-02 18:56:24 +000090 /* By default devices are enabled. */
Eric Biederman03acab62004-10-14 21:25:53 +000091 dev->enabled = 1;
Eric Biedermane9a271e32003-09-02 03:36:25 +000092
Eric Biedermanb78c1972004-10-14 20:54:17 +000093 /* Add the new device to the list of children of the bus. */
Eric Biedermane9a271e32003-09-02 03:36:25 +000094 dev->bus = parent;
Uwe Hermanne4870472010-11-04 23:23:47 +000095 if (child)
Eric Biedermane9a271e32003-09-02 03:36:25 +000096 child->sibling = dev;
Uwe Hermanne4870472010-11-04 23:23:47 +000097 else
Eric Biedermane9a271e32003-09-02 03:36:25 +000098 parent->children = dev;
Li-Ta Loe5266692004-03-23 21:28:05 +000099
Eric Biederman03acab62004-10-14 21:25:53 +0000100 /* Append a new device to the global device list.
101 * The list is used to find devices once everything is set up.
102 */
Myles Watson70679a02010-09-01 21:03:03 +0000103 last_dev->next = dev;
104 last_dev = dev;
Eric Biederman03acab62004-10-14 21:25:53 +0000105
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300106 return dev;
107}
108
109device_t alloc_dev(struct bus *parent, struct device_path *path)
110{
111 device_t dev;
112 spin_lock(&dev_lock);
113 dev = __alloc_dev(parent, path);
Eric Biederman03acab62004-10-14 21:25:53 +0000114 spin_unlock(&dev_lock);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000115 return dev;
116}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000117
Li-Ta Loe5266692004-03-23 21:28:05 +0000118/**
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300119 * See if a device structure already exists and if not allocate it.
120 *
121 * @param parent The bus to find the device on.
122 * @param path The relative path from the bus to the appropriate device.
123 * @return Pointer to a device structure for the device on bus at path.
124 */
125device_t alloc_find_dev(struct bus *parent, struct device_path *path)
126{
127 device_t child;
128 spin_lock(&dev_lock);
129 child = find_dev_path(parent, path);
130 if (!child)
131 child = __alloc_dev(parent, path);
132 spin_unlock(&dev_lock);
133 return child;
134}
135
136/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000137 * Round a number up to an alignment.
138 *
139 * @param val The starting value.
140 * @param roundup Alignment as a power of two.
141 * @return Rounded up number.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000142 */
Eric Biederman448bd632004-10-14 22:52:15 +0000143static resource_t round(resource_t val, unsigned long pow)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000144{
Eric Biederman448bd632004-10-14 22:52:15 +0000145 resource_t mask;
146 mask = (1ULL << pow) - 1ULL;
147 val += mask;
148 val &= ~mask;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000149 return val;
150}
151
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000152/**
153 * Read the resources on all devices of a given bus.
154 *
155 * @param bus Bus to read the resources on.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000156 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000157static void read_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000158{
159 struct device *curdev;
160
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000161 printk(BIOS_SPEW, "%s %s bus %x link: %d\n", dev_path(bus->dev),
162 __func__, bus->secondary, bus->link_num);
Eric Biederman448bd632004-10-14 22:52:15 +0000163
Myles Watson29cc9ed2009-07-02 18:56:24 +0000164 /* Walk through all devices and find which resources they need. */
165 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Myles Watson894a3472010-06-09 22:41:35 +0000166 struct bus *link;
Uwe Hermanne4870472010-11-04 23:23:47 +0000167
168 if (!curdev->enabled)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000169 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000170
Eric Biedermane9a271e32003-09-02 03:36:25 +0000171 if (!curdev->ops || !curdev->ops->read_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000172 printk(BIOS_ERR, "%s missing read_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000173 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000174 continue;
175 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000176 curdev->ops->read_resources(curdev);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000177
178 /* Read in the resources behind the current device's links. */
Myles Watson894a3472010-06-09 22:41:35 +0000179 for (link = curdev->link_list; link; link = link->next)
180 read_resources(link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000181 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000182 printk(BIOS_SPEW, "%s read_resources bus %d link: %d done\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000183 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000184}
185
Eric Biedermane9a271e32003-09-02 03:36:25 +0000186struct pick_largest_state {
187 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000188 struct device *result_dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000189 struct resource *result;
190 int seen_last;
191};
192
Myles Watson29cc9ed2009-07-02 18:56:24 +0000193static void pick_largest_resource(void *gp, struct device *dev,
194 struct resource *resource)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000195{
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000196 struct pick_largest_state *state = gp;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000197 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000198
Eric Biedermane9a271e32003-09-02 03:36:25 +0000199 last = state->last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000200
201 /* Be certain to pick the successor to last. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000202 if (resource == last) {
203 state->seen_last = 1;
204 return;
205 }
Myles Watson032a9652009-05-11 22:24:53 +0000206 if (resource->flags & IORESOURCE_FIXED)
Uwe Hermanne4870472010-11-04 23:23:47 +0000207 return; /* Skip it. */
Myles Watson032a9652009-05-11 22:24:53 +0000208 if (last && ((last->align < resource->align) ||
209 ((last->align == resource->align) &&
210 (last->size < resource->size)) ||
211 ((last->align == resource->align) &&
212 (last->size == resource->size) && (!state->seen_last)))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000213 return;
214 }
Myles Watson032a9652009-05-11 22:24:53 +0000215 if (!state->result ||
216 (state->result->align < resource->align) ||
217 ((state->result->align == resource->align) &&
Myles Watson29cc9ed2009-07-02 18:56:24 +0000218 (state->result->size < resource->size))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000219 state->result_dev = dev;
220 state->result = resource;
Myles Watson032a9652009-05-11 22:24:53 +0000221 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000222}
223
Myles Watson29cc9ed2009-07-02 18:56:24 +0000224static struct device *largest_resource(struct bus *bus,
225 struct resource **result_res,
226 unsigned long type_mask,
227 unsigned long type)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000228{
229 struct pick_largest_state state;
230
231 state.last = *result_res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000232 state.result_dev = NULL;
233 state.result = NULL;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000234 state.seen_last = 0;
235
Myles Watson032a9652009-05-11 22:24:53 +0000236 search_bus_resources(bus, type_mask, type, pick_largest_resource,
237 &state);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000238
239 *result_res = state.result;
240 return state.result_dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000241}
242
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000243/**
Uwe Hermanne4870472010-11-04 23:23:47 +0000244 * This function is the guts of the resource allocator.
Myles Watson032a9652009-05-11 22:24:53 +0000245 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000246 * The problem.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000247 * - Allocate resource locations for every device.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000248 * - Don't overlap, and follow the rules of bridges.
249 * - Don't overlap with resources in fixed locations.
250 * - Be efficient so we don't have ugly strategies.
251 *
252 * The strategy.
253 * - Devices that have fixed addresses are the minority so don't
Myles Watson29cc9ed2009-07-02 18:56:24 +0000254 * worry about them too much. Instead only use part of the address
255 * space for devices with programmable addresses. This easily handles
Eric Biederman8ca8d762003-04-22 19:02:15 +0000256 * everything except bridges.
257 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000258 * - PCI devices are required to have their sizes and their alignments
259 * equal. In this case an optimal solution to the packing problem
260 * exists. Allocate all devices from highest alignment to least
261 * alignment or vice versa. Use this.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000262 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000263 * - So we can handle more than PCI run two allocation passes on bridges. The
264 * first to see how large the resources are behind the bridge, and what
265 * their alignment requirements are. The second to assign a safe address to
266 * the devices behind the bridge. This allows us to treat a bridge as just
267 * a device with a couple of resources, and not need to special case it in
268 * the allocator. Also this allows handling of other types of bridges.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000269 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000270 * @param bus The bus we are traversing.
271 * @param bridge The bridge resource which must contain the bus' resources.
272 * @param type_mask This value gets ANDed with the resource type.
273 * @param type This value must match the result of the AND.
274 * @return TODO
Eric Biederman8ca8d762003-04-22 19:02:15 +0000275 */
Myles Watson54913b92009-10-13 20:00:09 +0000276static void compute_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000277 unsigned long type_mask, unsigned long type)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000278{
279 struct device *dev;
280 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000281 resource_t base;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000282 base = round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000283
Uwe Hermanne4870472010-11-04 23:23:47 +0000284 printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d"
285 " limit: %llx\n", dev_path(bus->dev), __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000286 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
Uwe Hermanne4870472010-11-04 23:23:47 +0000287 "prefmem" : "mem", base, bridge->size, bridge->align,
288 bridge->gran, bridge->limit);
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000289
Uwe Hermanne4870472010-11-04 23:23:47 +0000290 /* For each child which is a bridge, compute the resource needs. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000291 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000292 struct resource *child_bridge;
293
Myles Watson894a3472010-06-09 22:41:35 +0000294 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000295 continue;
296
297 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000298 for (child_bridge = dev->resource_list; child_bridge;
299 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000300 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000301
Uwe Hermanne4870472010-11-04 23:23:47 +0000302 if (!(child_bridge->flags & IORESOURCE_BRIDGE)
303 || (child_bridge->flags & type_mask) != type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000304 continue;
305
Uwe Hermanne4870472010-11-04 23:23:47 +0000306 /*
307 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000308 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000309 * and non-prefetchable memory. Bridges below them need
310 * it separated. Add the PREFETCH flag to the type_mask
311 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000312 */
Myles Watson894a3472010-06-09 22:41:35 +0000313 link = dev->link_list;
314 while (link && link->link_num !=
315 IOINDEX_LINK(child_bridge->index))
316 link = link->next;
Uwe Hermanne4870472010-11-04 23:23:47 +0000317
318 if (link == NULL) {
Myles Watson894a3472010-06-09 22:41:35 +0000319 printk(BIOS_ERR, "link %ld not found on %s\n",
320 IOINDEX_LINK(child_bridge->index),
321 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000322 }
323
Myles Watson894a3472010-06-09 22:41:35 +0000324 compute_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000325 type_mask | IORESOURCE_PREFETCH,
326 type | (child_bridge->flags &
327 IORESOURCE_PREFETCH));
328 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000329 }
330
Myles Watson29cc9ed2009-07-02 18:56:24 +0000331 /* Remember we haven't found anything yet. */
332 resource = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000333
Uwe Hermanne4870472010-11-04 23:23:47 +0000334 /*
335 * Walk through all the resources on the current bus and compute the
336 * amount of address space taken by them. Take granularity and
Myles Watson29cc9ed2009-07-02 18:56:24 +0000337 * alignment into account.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000338 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000339 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000340
Myles Watson29cc9ed2009-07-02 18:56:24 +0000341 /* Size 0 resources can be skipped. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000342 if (!resource->size)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000343 continue;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000344
Myles Watson29cc9ed2009-07-02 18:56:24 +0000345 /* Propagate the resource alignment to the bridge resource. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000346 if (resource->align > bridge->align)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000347 bridge->align = resource->align;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000348
349 /* Propagate the resource limit to the bridge register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000350 if (bridge->limit > resource->limit)
Eric Biedermandbec2d42004-10-21 10:44:08 +0000351 bridge->limit = resource->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000352
353 /* Warn if it looks like APICs aren't declared. */
354 if ((resource->limit == 0xffffffff) &&
355 (resource->flags & IORESOURCE_ASSIGNED)) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000356 printk(BIOS_ERR,
357 "Resource limit looks wrong! (no APIC?)\n");
Patrick Georgi51615092012-03-11 19:31:03 +0100358 printk(BIOS_ERR, "%s %02lx limit %08llx\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000359 dev_path(dev), resource->index, resource->limit);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000360 }
Stefan Reinauer51754a32008-08-01 12:28:38 +0000361
Eric Biederman8ca8d762003-04-22 19:02:15 +0000362 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000363 /*
364 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000365 * expansion card addresses. The legacy PCI decodes
366 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
367 * 0x00 - 0xff can be used out of each 0x400 block of
368 * I/O space.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000369 */
Eric Biedermanbbb6d102003-08-04 19:54:48 +0000370 if ((base & 0x300) != 0) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000371 base = (base & ~0x3ff) + 0x400;
372 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000373 /*
374 * Don't allow allocations in the VGA I/O range.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000375 * PCI has special cases for that.
376 */
377 else if ((base >= 0x3b0) && (base <= 0x3df)) {
378 base = 0x3e0;
379 }
380 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000381 /* Base must be aligned. */
382 base = round(base, resource->align);
383 resource->base = base;
384 base += resource->size;
Myles Watson032a9652009-05-11 22:24:53 +0000385
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000386 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000387 dev_path(dev), resource->index, resource->base,
388 resource->base + resource->size - 1,
389 (resource->flags & IORESOURCE_IO) ? "io" :
390 (resource->flags & IORESOURCE_PREFETCH) ?
391 "prefmem" : "mem");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000392 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000393
394 /*
395 * A PCI bridge resource does not need to be a power of two size, but
396 * it does have a minimum granularity. Round the size up to that
397 * minimum granularity so we know not to place something else at an
398 * address postitively decoded by the bridge.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000399 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000400 bridge->size = round(base, bridge->gran) -
401 round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000402
Uwe Hermanne4870472010-11-04 23:23:47 +0000403 printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d"
404 " limit: %llx done\n", dev_path(bus->dev), __func__,
405 (bridge->flags & IORESOURCE_IO) ? "io" :
406 (bridge->flags & IORESOURCE_PREFETCH) ? "prefmem" : "mem",
407 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000408}
409
410/**
411 * This function is the second part of the resource allocator.
412 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000413 * See the compute_resources function for a more detailed explanation.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000414 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000415 * This function assigns the resources a value.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000416 *
417 * @param bus The bus we are traversing.
418 * @param bridge The bridge resource which must contain the bus' resources.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000419 * @param type_mask This value gets ANDed with the resource type.
420 * @param type This value must match the result of the AND.
Uwe Hermanne4870472010-11-04 23:23:47 +0000421 *
422 * @see compute_resources
Myles Watson29cc9ed2009-07-02 18:56:24 +0000423 */
Myles Watson54913b92009-10-13 20:00:09 +0000424static void allocate_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000425 unsigned long type_mask, unsigned long type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000426{
427 struct device *dev;
428 struct resource *resource;
429 resource_t base;
430 base = bridge->base;
431
Uwe Hermanne4870472010-11-04 23:23:47 +0000432 printk(BIOS_SPEW, "%s %s_%s: base:%llx size:%llx align:%d gran:%d "
433 "limit:%llx\n", dev_path(bus->dev), __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000434 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
435 "prefmem" : "mem",
436 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
437
438 /* Remember we haven't found anything yet. */
439 resource = NULL;
440
Uwe Hermanne4870472010-11-04 23:23:47 +0000441 /*
442 * Walk through all the resources on the current bus and allocate them
Myles Watson29cc9ed2009-07-02 18:56:24 +0000443 * address space.
444 */
445 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
446
447 /* Propagate the bridge limit to the resource register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000448 if (resource->limit > bridge->limit)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000449 resource->limit = bridge->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000450
451 /* Size 0 resources can be skipped. */
452 if (!resource->size) {
453 /* Set the base to limit so it doesn't confuse tolm. */
454 resource->base = resource->limit;
455 resource->flags |= IORESOURCE_ASSIGNED;
456 continue;
457 }
458
459 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000460 /*
461 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000462 * expansion card addresses. The legacy PCI decodes
463 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
464 * 0x00 - 0xff can be used out of each 0x400 block of
465 * I/O space.
466 */
467 if ((base & 0x300) != 0) {
468 base = (base & ~0x3ff) + 0x400;
469 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000470 /*
471 * Don't allow allocations in the VGA I/O range.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000472 * PCI has special cases for that.
473 */
474 else if ((base >= 0x3b0) && (base <= 0x3df)) {
475 base = 0x3e0;
476 }
477 }
478
479 if ((round(base, resource->align) + resource->size - 1) <=
480 resource->limit) {
481 /* Base must be aligned. */
482 base = round(base, resource->align);
483 resource->base = base;
484 resource->flags |= IORESOURCE_ASSIGNED;
485 resource->flags &= ~IORESOURCE_STORED;
486 base += resource->size;
487 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000488 printk(BIOS_ERR, "!! Resource didn't fit !!\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000489 printk(BIOS_ERR, " aligned base %llx size %llx "
490 "limit %llx\n", round(base, resource->align),
491 resource->size, resource->limit);
492 printk(BIOS_ERR, " %llx needs to be <= %llx "
493 "(limit)\n", (round(base, resource->align) +
Myles Watson29cc9ed2009-07-02 18:56:24 +0000494 resource->size) - 1, resource->limit);
Uwe Hermanne4870472010-11-04 23:23:47 +0000495 printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx]"
496 " %s\n", (resource->flags & IORESOURCE_ASSIGNED)
497 ? "Assigned: " : "", dev_path(dev),
498 resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000499 resource->base + resource->size - 1,
Uwe Hermanne4870472010-11-04 23:23:47 +0000500 (resource->flags & IORESOURCE_IO) ? "io"
501 : (resource->flags & IORESOURCE_PREFETCH)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000502 ? "prefmem" : "mem");
503 }
504
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000505 printk(BIOS_SPEW, "%s%s %02lx * [0x%llx - 0x%llx] %s\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000506 (resource->flags & IORESOURCE_ASSIGNED) ? "Assigned: "
Uwe Hermanne4870472010-11-04 23:23:47 +0000507 : "", dev_path(dev), resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000508 resource->size ? resource->base + resource->size - 1 :
Uwe Hermanne4870472010-11-04 23:23:47 +0000509 resource->base, (resource->flags & IORESOURCE_IO)
510 ? "io" : (resource->flags & IORESOURCE_PREFETCH)
511 ? "prefmem" : "mem");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000512 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000513
514 /*
515 * A PCI bridge resource does not need to be a power of two size, but
Myles Watson29cc9ed2009-07-02 18:56:24 +0000516 * it does have a minimum granularity. Round the size up to that
517 * minimum granularity so we know not to place something else at an
518 * address positively decoded by the bridge.
519 */
520
521 bridge->flags |= IORESOURCE_ASSIGNED;
522
Uwe Hermanne4870472010-11-04 23:23:47 +0000523 printk(BIOS_SPEW, "%s %s_%s: next_base: %llx size: %llx align: %d "
524 "gran: %d done\n", dev_path(bus->dev), __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000525 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
Uwe Hermanne4870472010-11-04 23:23:47 +0000526 "prefmem" : "mem", base, bridge->size, bridge->align,
527 bridge->gran);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000528
529 /* For each child which is a bridge, allocate_resources. */
530 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000531 struct resource *child_bridge;
532
Myles Watson894a3472010-06-09 22:41:35 +0000533 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000534 continue;
535
536 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000537 for (child_bridge = dev->resource_list; child_bridge;
538 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000539 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000540
541 if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
542 (child_bridge->flags & type_mask) != type)
543 continue;
544
Uwe Hermanne4870472010-11-04 23:23:47 +0000545 /*
546 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000547 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000548 * and non-prefetchable memory. Bridges below them need
549 * it separated. Add the PREFETCH flag to the type_mask
550 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000551 */
Myles Watson894a3472010-06-09 22:41:35 +0000552 link = dev->link_list;
553 while (link && link->link_num !=
554 IOINDEX_LINK(child_bridge->index))
555 link = link->next;
556 if (link == NULL)
557 printk(BIOS_ERR, "link %ld not found on %s\n",
558 IOINDEX_LINK(child_bridge->index),
559 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000560
Myles Watson894a3472010-06-09 22:41:35 +0000561 allocate_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000562 type_mask | IORESOURCE_PREFETCH,
563 type | (child_bridge->flags &
564 IORESOURCE_PREFETCH));
565 }
566 }
567}
568
Patrick Georgie1667822012-05-05 15:29:32 +0200569#if CONFIG_PCI_64BIT_PREF_MEM
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000570#define MEM_MASK (IORESOURCE_PREFETCH | IORESOURCE_MEM)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000571#else
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000572#define MEM_MASK (IORESOURCE_MEM)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000573#endif
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000574
Uwe Hermanne4870472010-11-04 23:23:47 +0000575#define IO_MASK (IORESOURCE_IO)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000576#define PREF_TYPE (IORESOURCE_PREFETCH | IORESOURCE_MEM)
Uwe Hermanne4870472010-11-04 23:23:47 +0000577#define MEM_TYPE (IORESOURCE_MEM)
578#define IO_TYPE (IORESOURCE_IO)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000579
580struct constraints {
581 struct resource pref, io, mem;
582};
583
584static void constrain_resources(struct device *dev, struct constraints* limits)
585{
586 struct device *child;
587 struct resource *res;
588 struct resource *lim;
Myles Watson894a3472010-06-09 22:41:35 +0000589 struct bus *link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000590
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000591 printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000592
593 /* Constrain limits based on the fixed resources of this device. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000594 for (res = dev->resource_list; res; res = res->next) {
Patrick Georgi18c585b2009-08-28 12:48:02 +0000595 if (!(res->flags & IORESOURCE_FIXED))
596 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000597 if (!res->size) {
598 /* It makes no sense to have 0-sized, fixed resources.*/
Uwe Hermanne4870472010-11-04 23:23:47 +0000599 printk(BIOS_ERR, "skipping %s@%lx fixed resource, "
600 "size=0!\n", dev_path(dev), res->index);
Patrick Georgi6bd93f42009-08-19 17:29:41 +0000601 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000602 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000603
604 /* PREFETCH, MEM, or I/O - skip any others. */
605 if ((res->flags & MEM_MASK) == PREF_TYPE)
606 lim = &limits->pref;
607 else if ((res->flags & MEM_MASK) == MEM_TYPE)
608 lim = &limits->mem;
609 else if ((res->flags & IO_MASK) == IO_TYPE)
610 lim = &limits->io;
611 else
612 continue;
613
Uwe Hermanne4870472010-11-04 23:23:47 +0000614 /*
615 * Is it a fixed resource outside the current known region?
616 * If so, we don't have to consider it - it will be handled
617 * correctly and doesn't affect current region's limits.
618 */
619 if (((res->base + res->size -1) < lim->base)
620 || (res->base > lim->limit))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000621 continue;
622
Uwe Hermanne4870472010-11-04 23:23:47 +0000623 /*
624 * Choose to be above or below fixed resources. This check is
625 * signed so that "negative" amounts of space are handled
626 * correctly.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000627 */
Uwe Hermanne4870472010-11-04 23:23:47 +0000628 if ((signed long long)(lim->limit - (res->base + res->size -1))
629 > (signed long long)(res->base - lim->base))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000630 lim->base = res->base + res->size;
631 else
632 lim->limit = res->base -1;
633 }
634
635 /* Descend into every enabled child and look for fixed resources. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000636 for (link = dev->link_list; link; link = link->next) {
637 for (child = link->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000638 if (child->enabled)
639 constrain_resources(child, limits);
Uwe Hermanne4870472010-11-04 23:23:47 +0000640 }
641 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000642}
643
644static void avoid_fixed_resources(struct device *dev)
645{
646 struct constraints limits;
647 struct resource *res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000648
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000649 printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000650
Uwe Hermanne4870472010-11-04 23:23:47 +0000651 /* Initialize constraints to maximum size. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000652 limits.pref.base = 0;
653 limits.pref.limit = 0xffffffffffffffffULL;
654 limits.io.base = 0;
655 limits.io.limit = 0xffffffffffffffffULL;
656 limits.mem.base = 0;
657 limits.mem.limit = 0xffffffffffffffffULL;
658
659 /* Constrain the limits to dev's initial resources. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000660 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000661 if ((res->flags & IORESOURCE_FIXED))
662 continue;
Patrick Georgi51615092012-03-11 19:31:03 +0100663 printk(BIOS_SPEW, "%s:@%s %02lx limit %08llx\n", __func__,
Uwe Hermanne4870472010-11-04 23:23:47 +0000664 dev_path(dev), res->index, res->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000665 if ((res->flags & MEM_MASK) == PREF_TYPE &&
666 (res->limit < limits.pref.limit))
667 limits.pref.limit = res->limit;
668 if ((res->flags & MEM_MASK) == MEM_TYPE &&
669 (res->limit < limits.mem.limit))
670 limits.mem.limit = res->limit;
671 if ((res->flags & IO_MASK) == IO_TYPE &&
672 (res->limit < limits.io.limit))
673 limits.io.limit = res->limit;
674 }
675
676 /* Look through the tree for fixed resources and update the limits. */
677 constrain_resources(dev, &limits);
678
679 /* Update dev's resources with new limits. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000680 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000681 struct resource *lim;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000682
683 if ((res->flags & IORESOURCE_FIXED))
684 continue;
685
686 /* PREFETCH, MEM, or I/O - skip any others. */
687 if ((res->flags & MEM_MASK) == PREF_TYPE)
688 lim = &limits.pref;
689 else if ((res->flags & MEM_MASK) == MEM_TYPE)
690 lim = &limits.mem;
691 else if ((res->flags & IO_MASK) == IO_TYPE)
692 lim = &limits.io;
693 else
694 continue;
695
Patrick Georgi51615092012-03-11 19:31:03 +0100696 printk(BIOS_SPEW, "%s2: %s@%02lx limit %08llx\n", __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000697 dev_path(dev), res->index, res->limit);
Patrick Georgi51615092012-03-11 19:31:03 +0100698 printk(BIOS_SPEW, "\tlim->base %08llx lim->limit %08llx\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000699 lim->base, lim->limit);
700
701 /* Is the resource outside the limits? */
702 if (lim->base > res->base)
703 res->base = lim->base;
704 if (res->limit > lim->limit)
705 res->limit = lim->limit;
706 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000707}
arch import user (historical)dc811182005-07-06 17:16:09 +0000708
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000709device_t vga_pri = 0;
Myles Watsonc7233e02009-07-02 19:02:33 +0000710static void set_vga_bridge_bits(void)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000711{
Uwe Hermann312673c2009-10-27 21:49:33 +0000712 /*
Uwe Hermanne4870472010-11-04 23:23:47 +0000713 * FIXME: Modify set_vga_bridge() so it is less PCI centric!
Uwe Hermann312673c2009-10-27 21:49:33 +0000714 * This function knows too much about PCI stuff, it should be just
715 * an iterator/visitor.
716 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000717
Myles Watson29cc9ed2009-07-02 18:56:24 +0000718 /* FIXME: Handle the VGA palette snooping. */
Patrick Georgi557ecf22012-07-20 12:16:17 +0200719 struct device *dev, *vga, *vga_onboard;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000720 struct bus *bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000721
Eric Biedermanb78c1972004-10-14 20:54:17 +0000722 bus = 0;
723 vga = 0;
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000724 vga_onboard = 0;
Uwe Hermanne4870472010-11-04 23:23:47 +0000725
Patrick Georgi557ecf22012-07-20 12:16:17 +0200726 dev = NULL;
727 while ((dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev))) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000728 if (!dev->enabled)
729 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000730
Patrick Georgi557ecf22012-07-20 12:16:17 +0200731 printk(BIOS_DEBUG, "found VGA at %s\n", dev_path(dev));
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000732
Patrick Georgi557ecf22012-07-20 12:16:17 +0200733 if (dev->on_mainboard) {
734 vga_onboard = dev;
Kostr1f0d3792012-10-06 13:27:58 +0400735 } else {
Patrick Georgi557ecf22012-07-20 12:16:17 +0200736 vga = dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000737 }
Myles Watson032a9652009-05-11 22:24:53 +0000738
Patrick Georgi557ecf22012-07-20 12:16:17 +0200739 /* It isn't safe to enable all VGA cards. */
740 dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Patrick Georgi594473d2012-07-25 08:55:53 +0200741 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000742
Uwe Hermanne4870472010-11-04 23:23:47 +0000743 if (!vga)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000744 vga = vga_onboard;
Patrick Georgi557ecf22012-07-20 12:16:17 +0200745
746 if (CONFIG_ONBOARD_VGA_IS_PRIMARY && vga_onboard)
747 vga = vga_onboard;
Myles Watson032a9652009-05-11 22:24:53 +0000748
Patrick Georgi5869fa22012-07-20 12:29:33 +0200749 /* If we prefer plugin VGA over chipset VGA, the chipset might
750 want to know. */
751 if (!CONFIG_ONBOARD_VGA_IS_PRIMARY && (vga != vga_onboard) &&
752 vga_onboard && vga_onboard->ops && vga_onboard->ops->disable) {
753 printk(BIOS_DEBUG, "Use plugin graphics over integrated.\n");
754 vga_onboard->ops->disable(vga_onboard);
755 }
756
arch import user (historical)dc811182005-07-06 17:16:09 +0000757 if (vga) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000758 /* VGA is first add-on card or the only onboard VGA. */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000759 printk(BIOS_DEBUG, "Setting up VGA for %s\n", dev_path(vga));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000760 /* All legacy VGA cards have MEM & I/O space registers. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000761 vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
762 vga_pri = vga;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000763 bus = vga->bus;
764 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000765
Myles Watson29cc9ed2009-07-02 18:56:24 +0000766 /* Now walk up the bridges setting the VGA enable. */
767 while (bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000768 printk(BIOS_DEBUG, "Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000769 dev_path(bus->dev));
Li-Ta Lodb7f47c2004-01-08 21:15:49 +0000770 bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000771 bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus;
Myles Watson032a9652009-05-11 22:24:53 +0000772 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000773}
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000774
Li-Ta Lo04930692004-11-25 17:37:19 +0000775/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000776 * Assign the computed resources to the devices on the bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000777 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000778 * Use the device specific set_resources() method to store the computed
Li-Ta Lo04930692004-11-25 17:37:19 +0000779 * resources to hardware. For bridge devices, the set_resources() method
780 * has to recurse into every down stream buses.
781 *
782 * Mutual recursion:
783 * assign_resources() -> device_operation::set_resources()
784 * device_operation::set_resources() -> assign_resources()
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000785 *
786 * @param bus Pointer to the structure for this bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000787 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000788void assign_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000789{
790 struct device *curdev;
791
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000792 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000793 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000794
Myles Watson29cc9ed2009-07-02 18:56:24 +0000795 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000796 if (!curdev->enabled || !curdev->resource_list)
Eric Biederman03acab62004-10-14 21:25:53 +0000797 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000798
Eric Biedermane9a271e32003-09-02 03:36:25 +0000799 if (!curdev->ops || !curdev->ops->set_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000800 printk(BIOS_ERR, "%s missing set_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000801 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000802 continue;
803 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000804 curdev->ops->set_resources(curdev);
805 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000806 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000807 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000808}
809
Li-Ta Lo5782d272004-04-26 17:51:20 +0000810/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000811 * Enable the resources for devices on a link.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000812 *
813 * Enable resources of the device by calling the device specific
814 * enable_resources() method.
815 *
816 * The parent's resources should be enabled first to avoid having enabling
817 * order problem. This is done by calling the parent's enable_resources()
Myles Watson7eac4452010-06-17 16:16:56 +0000818 * method before its childrens' enable_resources() methods.
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000819 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000820 * @param link The link whose devices' resources are to be enabled.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000821 */
Myles Watson7eac4452010-06-17 16:16:56 +0000822static void enable_resources(struct bus *link)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000823{
Myles Watson7eac4452010-06-17 16:16:56 +0000824 struct device *dev;
825 struct bus *c_link;
826
827 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000828 if (dev->enabled && dev->ops && dev->ops->enable_resources)
Myles Watson7eac4452010-06-17 16:16:56 +0000829 dev->ops->enable_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000830 }
Myles Watson7eac4452010-06-17 16:16:56 +0000831
832 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000833 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +0000834 enable_resources(c_link);
Eric Biederman83b991a2003-10-11 06:20:25 +0000835 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000836}
837
Myles Watson032a9652009-05-11 22:24:53 +0000838/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000839 * Reset all of the devices on a bus and clear the bus's reset_needed flag.
840 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000841 * @param bus Pointer to the bus structure.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000842 * @return 1 if the bus was successfully reset, 0 otherwise.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000843 */
844int reset_bus(struct bus *bus)
845{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000846 if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000847 bus->dev->ops->reset_bus(bus);
848 bus->reset_needed = 0;
849 return 1;
850 }
851 return 0;
852}
853
Myles Watson032a9652009-05-11 22:24:53 +0000854/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000855 * Scan for devices on a bus.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000856 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000857 * If there are bridges on the bus, recursively scan the buses behind the
858 * bridges. If the setting up and tuning of the bus causes a reset to be
859 * required, reset the bus and scan it again.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000860 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000861 * @param busdev Pointer to the bus device.
862 * @param max Current bus number.
863 * @return The maximum bus number found, after scanning all subordinate buses.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000864 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000865unsigned int scan_bus(struct device *busdev, unsigned int max)
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000866{
867 unsigned int new_max;
868 int do_scan_bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000869
Myles Watson29cc9ed2009-07-02 18:56:24 +0000870 if (!busdev || !busdev->enabled || !busdev->ops ||
871 !busdev->ops->scan_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000872 return max;
873 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000874
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000875 do_scan_bus = 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000876 while (do_scan_bus) {
Myles Watson894a3472010-06-09 22:41:35 +0000877 struct bus *link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000878 new_max = busdev->ops->scan_bus(busdev, max);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000879 do_scan_bus = 0;
Myles Watson894a3472010-06-09 22:41:35 +0000880 for (link = busdev->link_list; link; link = link->next) {
881 if (link->reset_needed) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000882 if (reset_bus(link))
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000883 do_scan_bus = 1;
Uwe Hermanne4870472010-11-04 23:23:47 +0000884 else
Myles Watson29cc9ed2009-07-02 18:56:24 +0000885 busdev->bus->reset_needed = 1;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000886 }
887 }
888 }
889 return new_max;
890}
891
Li-Ta Loe5266692004-03-23 21:28:05 +0000892/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000893 * Determine the existence of devices and extend the device tree.
Li-Ta Lo04930692004-11-25 17:37:19 +0000894 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000895 * Most of the devices in the system are listed in the mainboard devicetree.cb
Li-Ta Lo04930692004-11-25 17:37:19 +0000896 * file. The device structures for these devices are generated at compile
897 * time by the config tool and are organized into the device tree. This
898 * function determines if the devices created at compile time actually exist
899 * in the physical system.
900 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000901 * For devices in the physical system but not listed in devicetree.cb,
Li-Ta Lo04930692004-11-25 17:37:19 +0000902 * the device structures have to be created at run time and attached to the
Li-Ta Loe5266692004-03-23 21:28:05 +0000903 * device tree.
904 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000905 * This function starts from the root device 'dev_root', scans the buses in
906 * the system recursively, and modifies the device tree according to the
907 * result of the probe.
Li-Ta Loe5266692004-03-23 21:28:05 +0000908 *
Li-Ta Lo5782d272004-04-26 17:51:20 +0000909 * This function has no idea how to scan and probe buses and devices at all.
910 * It depends on the bus/device specific scan_bus() method to do it. The
Li-Ta Lo04930692004-11-25 17:37:19 +0000911 * scan_bus() method also has to create the device structure and attach
Myles Watson032a9652009-05-11 22:24:53 +0000912 * it to the device tree.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000913 */
914void dev_enumerate(void)
915{
916 struct device *root;
Uwe Hermanne4870472010-11-04 23:23:47 +0000917
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000918 printk(BIOS_INFO, "Enumerating buses...\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000919
Eric Biederman8ca8d762003-04-22 19:02:15 +0000920 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000921
Uwe Hermanne4870472010-11-04 23:23:47 +0000922 show_all_devs(BIOS_SPEW, "Before device enumeration.");
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000923 printk(BIOS_SPEW, "Compare with tree...\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +0000924 show_devs_tree(root, BIOS_SPEW, 0, 0);
Myles Watsoncd5d7562009-05-12 13:43:34 +0000925
Stefan Reinauera675d492012-08-07 14:50:47 -0700926 if (root->chip_ops && root->chip_ops->enable_dev)
927 root->chip_ops->enable_dev(root);
Uwe Hermanne4870472010-11-04 23:23:47 +0000928
Eric Biedermanb78c1972004-10-14 20:54:17 +0000929 if (!root->ops || !root->ops->scan_bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000930 printk(BIOS_ERR, "dev_root missing scan_bus operation");
Eric Biedermanb78c1972004-10-14 20:54:17 +0000931 return;
932 }
Stefan Reinauer6afcea82009-07-18 17:58:44 +0000933 scan_bus(root, 0);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000934 printk(BIOS_INFO, "done\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000935}
936
Li-Ta Loe5266692004-03-23 21:28:05 +0000937/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000938 * Configure devices on the devices tree.
Myles Watson032a9652009-05-11 22:24:53 +0000939 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000940 * Starting at the root of the device tree, travel it recursively in two
941 * passes. In the first pass, we compute and allocate resources (ranges)
942 * requried by each device. In the second pass, the resources ranges are
943 * relocated to their final position and stored to the hardware.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000944 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000945 * I/O resources grow upward. MEM resources grow downward.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000946 *
947 * Since the assignment is hierarchical we set the values into the dev_root
Myles Watson032a9652009-05-11 22:24:53 +0000948 * struct.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000949 */
950void dev_configure(void)
951{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000952 struct resource *res;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000953 struct device *root;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000954 struct device *child;
Li-Ta Loe5266692004-03-23 21:28:05 +0000955
Marc Jones80bd74c2012-02-21 17:44:35 +0100956 set_vga_bridge_bits();
Marc Jones80bd74c2012-02-21 17:44:35 +0100957
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000958 printk(BIOS_INFO, "Allocating resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000959
Eric Biedermanb78c1972004-10-14 20:54:17 +0000960 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000961
Uwe Hermanne4870472010-11-04 23:23:47 +0000962 /*
963 * Each domain should create resources which contain the entire address
Myles Watson29cc9ed2009-07-02 18:56:24 +0000964 * space for IO, MEM, and PREFMEM resources in the domain. The
965 * allocation of device resources will be done from this address space.
966 */
Myles Watsoncd5d7562009-05-12 13:43:34 +0000967
Myles Watson29cc9ed2009-07-02 18:56:24 +0000968 /* Read the resources for the entire tree. */
Li-Ta Lo04930692004-11-25 17:37:19 +0000969
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000970 printk(BIOS_INFO, "Reading resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +0000971 read_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000972 printk(BIOS_INFO, "Done reading resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000973
Stefan Reinauer39e72292009-10-26 16:47:05 +0000974 print_resource_tree(root, BIOS_SPEW, "After reading.");
Myles Watsoncd5d7562009-05-12 13:43:34 +0000975
Myles Watson29cc9ed2009-07-02 18:56:24 +0000976 /* Compute resources for all domains. */
Myles Watson894a3472010-06-09 22:41:35 +0000977 for (child = root->link_list->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000978 if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN))
979 continue;
Myles Watsonc25cc112010-05-21 14:33:48 +0000980 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000981 if (res->flags & IORESOURCE_FIXED)
982 continue;
983 if (res->flags & IORESOURCE_PREFETCH) {
Myles Watson894a3472010-06-09 22:41:35 +0000984 compute_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +0000985 res, MEM_MASK, PREF_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000986 continue;
987 }
988 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +0000989 compute_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +0000990 res, MEM_MASK, MEM_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000991 continue;
992 }
993 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +0000994 compute_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +0000995 res, IO_MASK, IO_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000996 continue;
997 }
998 }
999 }
1000
1001 /* For all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001002 for (child = root->link_list->children; child; child=child->sibling)
Myles Watson29cc9ed2009-07-02 18:56:24 +00001003 if (child->path.type == DEVICE_PATH_PCI_DOMAIN)
1004 avoid_fixed_resources(child);
1005
Uwe Hermanne4870472010-11-04 23:23:47 +00001006 /*
1007 * Now we need to adjust the resources. MEM resources need to start at
Myles Watson29cc9ed2009-07-02 18:56:24 +00001008 * the highest address managable.
Eric Biedermanb78c1972004-10-14 20:54:17 +00001009 */
Myles Watson894a3472010-06-09 22:41:35 +00001010 for (child = root->link_list->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001011 if (child->path.type != DEVICE_PATH_PCI_DOMAIN)
1012 continue;
Myles Watsonc25cc112010-05-21 14:33:48 +00001013 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001014 if (!(res->flags & IORESOURCE_MEM) ||
1015 res->flags & IORESOURCE_FIXED)
1016 continue;
1017 res->base = resource_max(res);
1018 }
1019 }
Eric Biederman5cd81732004-03-11 15:01:31 +00001020
Eric Biedermanb78c1972004-10-14 20:54:17 +00001021 /* Store the computed resource allocations into device registers ... */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001022 printk(BIOS_INFO, "Setting resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001023 for (child = root->link_list->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001024 if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN))
1025 continue;
Myles Watsonc25cc112010-05-21 14:33:48 +00001026 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001027 if (res->flags & IORESOURCE_FIXED)
1028 continue;
1029 if (res->flags & IORESOURCE_PREFETCH) {
Myles Watson894a3472010-06-09 22:41:35 +00001030 allocate_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001031 res, MEM_MASK, PREF_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001032 continue;
1033 }
1034 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001035 allocate_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001036 res, MEM_MASK, MEM_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001037 continue;
1038 }
1039 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001040 allocate_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001041 res, IO_MASK, IO_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001042 continue;
1043 }
1044 }
1045 }
Myles Watson894a3472010-06-09 22:41:35 +00001046 assign_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001047 printk(BIOS_INFO, "Done setting resources.\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001048 print_resource_tree(root, BIOS_SPEW, "After assigning values.");
Eric Biederman03acab62004-10-14 21:25:53 +00001049
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001050 printk(BIOS_INFO, "Done allocating resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001051}
1052
Li-Ta Loe5266692004-03-23 21:28:05 +00001053/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001054 * Enable devices on the device tree.
Li-Ta Loe5266692004-03-23 21:28:05 +00001055 *
1056 * Starting at the root, walk the tree and enable all devices/bridges by
1057 * calling the device's enable_resources() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001058 */
1059void dev_enable(void)
1060{
Myles Watson7eac4452010-06-17 16:16:56 +00001061 struct bus *link;
1062
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001063 printk(BIOS_INFO, "Enabling resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001064
Uwe Hermanne4870472010-11-04 23:23:47 +00001065 /* Now enable everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001066 for (link = dev_root.link_list; link; link = link->next)
1067 enable_resources(link);
Li-Ta Loe5266692004-03-23 21:28:05 +00001068
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001069 printk(BIOS_INFO, "done.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001070}
1071
Li-Ta Loe5266692004-03-23 21:28:05 +00001072/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001073 * Initialize a specific device.
Myles Watson7eac4452010-06-17 16:16:56 +00001074 *
Uwe Hermanne4870472010-11-04 23:23:47 +00001075 * The parent should be initialized first to avoid having an ordering problem.
1076 * This is done by calling the parent's init() method before its childrens'
1077 * init() methods.
Myles Watson7eac4452010-06-17 16:16:56 +00001078 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001079 * @param dev The device to be initialized.
Myles Watson7eac4452010-06-17 16:16:56 +00001080 */
1081static void init_dev(struct device *dev)
1082{
Uwe Hermanne4870472010-11-04 23:23:47 +00001083 if (!dev->enabled)
Myles Watson7eac4452010-06-17 16:16:56 +00001084 return;
Myles Watson7eac4452010-06-17 16:16:56 +00001085
1086 if (!dev->initialized && dev->ops && dev->ops->init) {
1087 if (dev->path.type == DEVICE_PATH_I2C) {
1088 printk(BIOS_DEBUG, "smbus: %s[%d]->",
1089 dev_path(dev->bus->dev), dev->bus->link_num);
1090 }
1091
1092 printk(BIOS_DEBUG, "%s init\n", dev_path(dev));
1093 dev->initialized = 1;
1094 dev->ops->init(dev);
1095 }
1096}
1097
1098static void init_link(struct bus *link)
1099{
1100 struct device *dev;
1101 struct bus *c_link;
1102
Uwe Hermanne4870472010-11-04 23:23:47 +00001103 for (dev = link->children; dev; dev = dev->sibling)
Myles Watson7eac4452010-06-17 16:16:56 +00001104 init_dev(dev);
Myles Watson7eac4452010-06-17 16:16:56 +00001105
1106 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +00001107 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +00001108 init_link(c_link);
Myles Watson7eac4452010-06-17 16:16:56 +00001109 }
1110}
1111
1112/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001113 * Initialize all devices in the global device tree.
Myles Watson7eac4452010-06-17 16:16:56 +00001114 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001115 * Starting at the root device, call the device's init() method to do
1116 * device-specific setup, then call each child's init() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001117 */
1118void dev_initialize(void)
1119{
Myles Watson7eac4452010-06-17 16:16:56 +00001120 struct bus *link;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001121
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001122 printk(BIOS_INFO, "Initializing devices...\n");
Myles Watson7eac4452010-06-17 16:16:56 +00001123
Duncan Laurieb4aaaa72012-01-17 09:03:11 -08001124#if CONFIG_ARCH_X86
1125 /* Ensure EBDA is prepared before Option ROMs. */
1126 setup_default_ebda();
1127#endif
1128
Myles Watson1bd3fb72010-08-16 16:25:23 +00001129 /* First call the mainboard init. */
1130 init_dev(&dev_root);
1131
Uwe Hermanne4870472010-11-04 23:23:47 +00001132 /* Now initialize everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001133 for (link = dev_root.link_list; link; link = link->next)
1134 init_link(link);
1135
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001136 printk(BIOS_INFO, "Devices initialized\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001137 show_all_devs(BIOS_SPEW, "After init.");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001138}