blob: a2a64b2caeffeaac1c52e4202cb70d5239a6ce9f [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>
38#include <device/pci.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) {
69 dev->chip_ops->init(dev->chip_info);
70 dev->chip_ops->initialized = 1;
71 }
72 }
73}
74
Marc Jones2a58ecd2013-10-29 17:32:00 -060075/**
76 * Finalize all chips of statically known devices.
77 *
78 * This is the last call before calling the payload. This is a good place
79 * to lock registers or other final cleanup.
80 */
81void dev_finalize_chips(void)
82{
83 struct device *dev;
84
85 for (dev = all_devices; dev; dev = dev->next) {
86 /* Initialize chip if we haven't yet. */
87 if (dev->chip_ops && dev->chip_ops->final &&
88 !dev->chip_ops->finalized) {
89 dev->chip_ops->final(dev->chip_info);
90 dev->chip_ops->finalized = 1;
91 }
92 }
93}
94
Uwe Hermannc1ee4292010-10-17 19:01:48 +000095DECLARE_SPIN_LOCK(dev_lock)
Eric Biederman8ca8d762003-04-22 19:02:15 +000096
Kyösti Mälkkib25374c2012-08-01 08:05:22 +030097#if CONFIG_GFXUMA
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +030098/* IGD UMA memory */
99uint64_t uma_memory_base = 0;
100uint64_t uma_memory_size = 0;
Kyösti Mälkkib25374c2012-08-01 08:05:22 +0300101#endif
Kyösti Mälkkicc55b9b2012-07-11 07:55:21 +0300102
Li-Ta Loe5266692004-03-23 21:28:05 +0000103/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000104 * Allocate a new device structure.
Myles Watson032a9652009-05-11 22:24:53 +0000105 *
Martin Roth63373ed2013-07-08 16:24:19 -0600106 * Allocate a new device structure and attach it to the device tree as a
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000107 * child of the parent bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000108 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000109 * @param parent Parent bus the newly created device should be attached to.
110 * @param path Path to the device to be created.
111 * @return Pointer to the newly created device structure.
Li-Ta Loe5266692004-03-23 21:28:05 +0000112 *
113 * @see device_path
Eric Biederman8ca8d762003-04-22 19:02:15 +0000114 */
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300115static device_t __alloc_dev(struct bus *parent, struct device_path *path)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000116{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000117 device_t dev, child;
Li-Ta Loe5266692004-03-23 21:28:05 +0000118
Myles Watson29cc9ed2009-07-02 18:56:24 +0000119 /* Find the last child of our parent. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000120 for (child = parent->children; child && child->sibling; /* */ )
Eric Biedermane9a271e32003-09-02 03:36:25 +0000121 child = child->sibling;
Li-Ta Lo3a812852004-12-03 22:39:34 +0000122
Eric Biedermane9a271e32003-09-02 03:36:25 +0000123 dev = malloc(sizeof(*dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000124 if (dev == 0)
Uwe Hermanne4870472010-11-04 23:23:47 +0000125 die("alloc_dev(): out of memory.\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000126
Eric Biedermane9a271e32003-09-02 03:36:25 +0000127 memset(dev, 0, sizeof(*dev));
128 memcpy(&dev->path, path, sizeof(*path));
129
Myles Watson29cc9ed2009-07-02 18:56:24 +0000130 /* By default devices are enabled. */
Eric Biederman03acab62004-10-14 21:25:53 +0000131 dev->enabled = 1;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000132
Eric Biedermanb78c1972004-10-14 20:54:17 +0000133 /* Add the new device to the list of children of the bus. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000134 dev->bus = parent;
Uwe Hermanne4870472010-11-04 23:23:47 +0000135 if (child)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000136 child->sibling = dev;
Uwe Hermanne4870472010-11-04 23:23:47 +0000137 else
Eric Biedermane9a271e32003-09-02 03:36:25 +0000138 parent->children = dev;
Li-Ta Loe5266692004-03-23 21:28:05 +0000139
Eric Biederman03acab62004-10-14 21:25:53 +0000140 /* Append a new device to the global device list.
141 * The list is used to find devices once everything is set up.
142 */
Myles Watson70679a02010-09-01 21:03:03 +0000143 last_dev->next = dev;
144 last_dev = dev;
Eric Biederman03acab62004-10-14 21:25:53 +0000145
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300146 return dev;
147}
148
149device_t alloc_dev(struct bus *parent, struct device_path *path)
150{
151 device_t dev;
152 spin_lock(&dev_lock);
153 dev = __alloc_dev(parent, path);
Eric Biederman03acab62004-10-14 21:25:53 +0000154 spin_unlock(&dev_lock);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000155 return dev;
156}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000157
Li-Ta Loe5266692004-03-23 21:28:05 +0000158/**
Kyösti Mälkkia5650a42012-07-07 17:15:51 +0300159 * See if a device structure already exists and if not allocate it.
160 *
161 * @param parent The bus to find the device on.
162 * @param path The relative path from the bus to the appropriate device.
163 * @return Pointer to a device structure for the device on bus at path.
164 */
165device_t alloc_find_dev(struct bus *parent, struct device_path *path)
166{
167 device_t child;
168 spin_lock(&dev_lock);
169 child = find_dev_path(parent, path);
170 if (!child)
171 child = __alloc_dev(parent, path);
172 spin_unlock(&dev_lock);
173 return child;
174}
175
176/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000177 * Round a number up to an alignment.
178 *
179 * @param val The starting value.
180 * @param roundup Alignment as a power of two.
181 * @return Rounded up number.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000182 */
Eric Biederman448bd632004-10-14 22:52:15 +0000183static resource_t round(resource_t val, unsigned long pow)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000184{
Eric Biederman448bd632004-10-14 22:52:15 +0000185 resource_t mask;
186 mask = (1ULL << pow) - 1ULL;
187 val += mask;
188 val &= ~mask;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000189 return val;
190}
191
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000192/**
193 * Read the resources on all devices of a given bus.
194 *
195 * @param bus Bus to read the resources on.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000196 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000197static void read_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000198{
199 struct device *curdev;
200
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000201 printk(BIOS_SPEW, "%s %s bus %x link: %d\n", dev_path(bus->dev),
202 __func__, bus->secondary, bus->link_num);
Eric Biederman448bd632004-10-14 22:52:15 +0000203
Myles Watson29cc9ed2009-07-02 18:56:24 +0000204 /* Walk through all devices and find which resources they need. */
205 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Myles Watson894a3472010-06-09 22:41:35 +0000206 struct bus *link;
Uwe Hermanne4870472010-11-04 23:23:47 +0000207
208 if (!curdev->enabled)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000209 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000210
Eric Biedermane9a271e32003-09-02 03:36:25 +0000211 if (!curdev->ops || !curdev->ops->read_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000212 printk(BIOS_ERR, "%s missing read_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000213 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000214 continue;
215 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000216 curdev->ops->read_resources(curdev);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000217
218 /* Read in the resources behind the current device's links. */
Myles Watson894a3472010-06-09 22:41:35 +0000219 for (link = curdev->link_list; link; link = link->next)
220 read_resources(link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000221 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000222 printk(BIOS_SPEW, "%s read_resources bus %d link: %d done\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000223 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000224}
225
Eric Biedermane9a271e32003-09-02 03:36:25 +0000226struct pick_largest_state {
227 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000228 struct device *result_dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000229 struct resource *result;
230 int seen_last;
231};
232
Myles Watson29cc9ed2009-07-02 18:56:24 +0000233static void pick_largest_resource(void *gp, struct device *dev,
234 struct resource *resource)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000235{
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000236 struct pick_largest_state *state = gp;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000237 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000238
Eric Biedermane9a271e32003-09-02 03:36:25 +0000239 last = state->last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000240
241 /* Be certain to pick the successor to last. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000242 if (resource == last) {
243 state->seen_last = 1;
244 return;
245 }
Myles Watson032a9652009-05-11 22:24:53 +0000246 if (resource->flags & IORESOURCE_FIXED)
Uwe Hermanne4870472010-11-04 23:23:47 +0000247 return; /* Skip it. */
Myles Watson032a9652009-05-11 22:24:53 +0000248 if (last && ((last->align < resource->align) ||
249 ((last->align == resource->align) &&
250 (last->size < resource->size)) ||
251 ((last->align == resource->align) &&
252 (last->size == resource->size) && (!state->seen_last)))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000253 return;
254 }
Myles Watson032a9652009-05-11 22:24:53 +0000255 if (!state->result ||
256 (state->result->align < resource->align) ||
257 ((state->result->align == resource->align) &&
Myles Watson29cc9ed2009-07-02 18:56:24 +0000258 (state->result->size < resource->size))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000259 state->result_dev = dev;
260 state->result = resource;
Myles Watson032a9652009-05-11 22:24:53 +0000261 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000262}
263
Myles Watson29cc9ed2009-07-02 18:56:24 +0000264static struct device *largest_resource(struct bus *bus,
265 struct resource **result_res,
266 unsigned long type_mask,
267 unsigned long type)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000268{
269 struct pick_largest_state state;
270
271 state.last = *result_res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000272 state.result_dev = NULL;
273 state.result = NULL;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000274 state.seen_last = 0;
275
Myles Watson032a9652009-05-11 22:24:53 +0000276 search_bus_resources(bus, type_mask, type, pick_largest_resource,
277 &state);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000278
279 *result_res = state.result;
280 return state.result_dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000281}
282
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000283/**
Uwe Hermanne4870472010-11-04 23:23:47 +0000284 * This function is the guts of the resource allocator.
Myles Watson032a9652009-05-11 22:24:53 +0000285 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000286 * The problem.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000287 * - Allocate resource locations for every device.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000288 * - Don't overlap, and follow the rules of bridges.
289 * - Don't overlap with resources in fixed locations.
290 * - Be efficient so we don't have ugly strategies.
291 *
292 * The strategy.
293 * - Devices that have fixed addresses are the minority so don't
Myles Watson29cc9ed2009-07-02 18:56:24 +0000294 * worry about them too much. Instead only use part of the address
295 * space for devices with programmable addresses. This easily handles
Eric Biederman8ca8d762003-04-22 19:02:15 +0000296 * everything except bridges.
297 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000298 * - PCI devices are required to have their sizes and their alignments
299 * equal. In this case an optimal solution to the packing problem
300 * exists. Allocate all devices from highest alignment to least
301 * alignment or vice versa. Use this.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000302 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000303 * - So we can handle more than PCI run two allocation passes on bridges. The
304 * first to see how large the resources are behind the bridge, and what
305 * their alignment requirements are. The second to assign a safe address to
306 * the devices behind the bridge. This allows us to treat a bridge as just
307 * a device with a couple of resources, and not need to special case it in
308 * the allocator. Also this allows handling of other types of bridges.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000309 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000310 * @param bus The bus we are traversing.
311 * @param bridge The bridge resource which must contain the bus' resources.
312 * @param type_mask This value gets ANDed with the resource type.
313 * @param type This value must match the result of the AND.
314 * @return TODO
Eric Biederman8ca8d762003-04-22 19:02:15 +0000315 */
Myles Watson54913b92009-10-13 20:00:09 +0000316static void compute_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000317 unsigned long type_mask, unsigned long type)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000318{
319 struct device *dev;
320 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000321 resource_t base;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000322 base = round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000323
Uwe Hermanne4870472010-11-04 23:23:47 +0000324 printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d"
325 " limit: %llx\n", dev_path(bus->dev), __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000326 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
Uwe Hermanne4870472010-11-04 23:23:47 +0000327 "prefmem" : "mem", base, bridge->size, bridge->align,
328 bridge->gran, bridge->limit);
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000329
Uwe Hermanne4870472010-11-04 23:23:47 +0000330 /* For each child which is a bridge, compute the resource needs. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000331 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000332 struct resource *child_bridge;
333
Myles Watson894a3472010-06-09 22:41:35 +0000334 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000335 continue;
336
337 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000338 for (child_bridge = dev->resource_list; child_bridge;
339 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000340 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000341
Uwe Hermanne4870472010-11-04 23:23:47 +0000342 if (!(child_bridge->flags & IORESOURCE_BRIDGE)
343 || (child_bridge->flags & type_mask) != type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000344 continue;
345
Uwe Hermanne4870472010-11-04 23:23:47 +0000346 /*
347 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000348 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000349 * and non-prefetchable memory. Bridges below them need
350 * it separated. Add the PREFETCH flag to the type_mask
351 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000352 */
Myles Watson894a3472010-06-09 22:41:35 +0000353 link = dev->link_list;
354 while (link && link->link_num !=
355 IOINDEX_LINK(child_bridge->index))
356 link = link->next;
Uwe Hermanne4870472010-11-04 23:23:47 +0000357
358 if (link == NULL) {
Myles Watson894a3472010-06-09 22:41:35 +0000359 printk(BIOS_ERR, "link %ld not found on %s\n",
360 IOINDEX_LINK(child_bridge->index),
361 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000362 }
363
Myles Watson894a3472010-06-09 22:41:35 +0000364 compute_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000365 type_mask | IORESOURCE_PREFETCH,
366 type | (child_bridge->flags &
367 IORESOURCE_PREFETCH));
368 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000369 }
370
Myles Watson29cc9ed2009-07-02 18:56:24 +0000371 /* Remember we haven't found anything yet. */
372 resource = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000373
Uwe Hermanne4870472010-11-04 23:23:47 +0000374 /*
375 * Walk through all the resources on the current bus and compute the
376 * amount of address space taken by them. Take granularity and
Myles Watson29cc9ed2009-07-02 18:56:24 +0000377 * alignment into account.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000378 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000379 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000380
Myles Watson29cc9ed2009-07-02 18:56:24 +0000381 /* Size 0 resources can be skipped. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000382 if (!resource->size)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000383 continue;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000384
Myles Watson29cc9ed2009-07-02 18:56:24 +0000385 /* Propagate the resource alignment to the bridge resource. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000386 if (resource->align > bridge->align)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000387 bridge->align = resource->align;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000388
389 /* Propagate the resource limit to the bridge register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000390 if (bridge->limit > resource->limit)
Eric Biedermandbec2d42004-10-21 10:44:08 +0000391 bridge->limit = resource->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000392
393 /* Warn if it looks like APICs aren't declared. */
394 if ((resource->limit == 0xffffffff) &&
395 (resource->flags & IORESOURCE_ASSIGNED)) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000396 printk(BIOS_ERR,
397 "Resource limit looks wrong! (no APIC?)\n");
Patrick Georgi51615092012-03-11 19:31:03 +0100398 printk(BIOS_ERR, "%s %02lx limit %08llx\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000399 dev_path(dev), resource->index, resource->limit);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000400 }
Stefan Reinauer51754a32008-08-01 12:28:38 +0000401
Eric Biederman8ca8d762003-04-22 19:02:15 +0000402 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000403 /*
404 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000405 * expansion card addresses. The legacy PCI decodes
406 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
407 * 0x00 - 0xff can be used out of each 0x400 block of
408 * I/O space.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000409 */
Eric Biedermanbbb6d102003-08-04 19:54:48 +0000410 if ((base & 0x300) != 0) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000411 base = (base & ~0x3ff) + 0x400;
412 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000413 /*
414 * Don't allow allocations in the VGA I/O range.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000415 * PCI has special cases for that.
416 */
417 else if ((base >= 0x3b0) && (base <= 0x3df)) {
418 base = 0x3e0;
419 }
420 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000421 /* Base must be aligned. */
422 base = round(base, resource->align);
423 resource->base = base;
424 base += resource->size;
Myles Watson032a9652009-05-11 22:24:53 +0000425
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000426 printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000427 dev_path(dev), resource->index, resource->base,
428 resource->base + resource->size - 1,
429 (resource->flags & IORESOURCE_IO) ? "io" :
430 (resource->flags & IORESOURCE_PREFETCH) ?
431 "prefmem" : "mem");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000432 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000433
434 /*
435 * A PCI bridge resource does not need to be a power of two size, but
436 * it does have a minimum granularity. Round the size up to that
437 * minimum granularity so we know not to place something else at an
Martin Roth63373ed2013-07-08 16:24:19 -0600438 * address positively decoded by the bridge.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000439 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000440 bridge->size = round(base, bridge->gran) -
441 round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000442
Uwe Hermanne4870472010-11-04 23:23:47 +0000443 printk(BIOS_SPEW, "%s %s_%s: base: %llx size: %llx align: %d gran: %d"
444 " limit: %llx done\n", dev_path(bus->dev), __func__,
445 (bridge->flags & IORESOURCE_IO) ? "io" :
446 (bridge->flags & IORESOURCE_PREFETCH) ? "prefmem" : "mem",
447 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000448}
449
450/**
451 * This function is the second part of the resource allocator.
452 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000453 * See the compute_resources function for a more detailed explanation.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000454 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000455 * This function assigns the resources a value.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000456 *
457 * @param bus The bus we are traversing.
458 * @param bridge The bridge resource which must contain the bus' resources.
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000459 * @param type_mask This value gets ANDed with the resource type.
460 * @param type This value must match the result of the AND.
Uwe Hermanne4870472010-11-04 23:23:47 +0000461 *
462 * @see compute_resources
Myles Watson29cc9ed2009-07-02 18:56:24 +0000463 */
Myles Watson54913b92009-10-13 20:00:09 +0000464static void allocate_resources(struct bus *bus, struct resource *bridge,
Uwe Hermanne4870472010-11-04 23:23:47 +0000465 unsigned long type_mask, unsigned long type)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000466{
467 struct device *dev;
468 struct resource *resource;
469 resource_t base;
470 base = bridge->base;
471
Uwe Hermanne4870472010-11-04 23:23:47 +0000472 printk(BIOS_SPEW, "%s %s_%s: base:%llx size:%llx align:%d gran:%d "
473 "limit:%llx\n", dev_path(bus->dev), __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000474 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
475 "prefmem" : "mem",
476 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
477
478 /* Remember we haven't found anything yet. */
479 resource = NULL;
480
Uwe Hermanne4870472010-11-04 23:23:47 +0000481 /*
482 * Walk through all the resources on the current bus and allocate them
Myles Watson29cc9ed2009-07-02 18:56:24 +0000483 * address space.
484 */
485 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
486
487 /* Propagate the bridge limit to the resource register. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000488 if (resource->limit > bridge->limit)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000489 resource->limit = bridge->limit;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000490
491 /* Size 0 resources can be skipped. */
492 if (!resource->size) {
493 /* Set the base to limit so it doesn't confuse tolm. */
494 resource->base = resource->limit;
495 resource->flags |= IORESOURCE_ASSIGNED;
496 continue;
497 }
498
499 if (resource->flags & IORESOURCE_IO) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000500 /*
501 * Don't allow potential aliases over the legacy PCI
Myles Watson29cc9ed2009-07-02 18:56:24 +0000502 * expansion card addresses. The legacy PCI decodes
503 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
504 * 0x00 - 0xff can be used out of each 0x400 block of
505 * I/O space.
506 */
507 if ((base & 0x300) != 0) {
508 base = (base & ~0x3ff) + 0x400;
509 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000510 /*
511 * Don't allow allocations in the VGA I/O range.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000512 * PCI has special cases for that.
513 */
514 else if ((base >= 0x3b0) && (base <= 0x3df)) {
515 base = 0x3e0;
516 }
517 }
518
519 if ((round(base, resource->align) + resource->size - 1) <=
520 resource->limit) {
521 /* Base must be aligned. */
522 base = round(base, resource->align);
523 resource->base = base;
524 resource->flags |= IORESOURCE_ASSIGNED;
525 resource->flags &= ~IORESOURCE_STORED;
526 base += resource->size;
527 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000528 printk(BIOS_ERR, "!! Resource didn't fit !!\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000529 printk(BIOS_ERR, " aligned base %llx size %llx "
530 "limit %llx\n", round(base, resource->align),
531 resource->size, resource->limit);
532 printk(BIOS_ERR, " %llx needs to be <= %llx "
533 "(limit)\n", (round(base, resource->align) +
Myles Watson29cc9ed2009-07-02 18:56:24 +0000534 resource->size) - 1, resource->limit);
Uwe Hermanne4870472010-11-04 23:23:47 +0000535 printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx]"
536 " %s\n", (resource->flags & IORESOURCE_ASSIGNED)
537 ? "Assigned: " : "", dev_path(dev),
538 resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000539 resource->base + resource->size - 1,
Uwe Hermanne4870472010-11-04 23:23:47 +0000540 (resource->flags & IORESOURCE_IO) ? "io"
541 : (resource->flags & IORESOURCE_PREFETCH)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000542 ? "prefmem" : "mem");
543 }
544
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000545 printk(BIOS_SPEW, "%s%s %02lx * [0x%llx - 0x%llx] %s\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000546 (resource->flags & IORESOURCE_ASSIGNED) ? "Assigned: "
Uwe Hermanne4870472010-11-04 23:23:47 +0000547 : "", dev_path(dev), resource->index, resource->base,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000548 resource->size ? resource->base + resource->size - 1 :
Uwe Hermanne4870472010-11-04 23:23:47 +0000549 resource->base, (resource->flags & IORESOURCE_IO)
550 ? "io" : (resource->flags & IORESOURCE_PREFETCH)
551 ? "prefmem" : "mem");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000552 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000553
554 /*
555 * A PCI bridge resource does not need to be a power of two size, but
Myles Watson29cc9ed2009-07-02 18:56:24 +0000556 * it does have a minimum granularity. Round the size up to that
557 * minimum granularity so we know not to place something else at an
558 * address positively decoded by the bridge.
559 */
560
561 bridge->flags |= IORESOURCE_ASSIGNED;
562
Uwe Hermanne4870472010-11-04 23:23:47 +0000563 printk(BIOS_SPEW, "%s %s_%s: next_base: %llx size: %llx align: %d "
564 "gran: %d done\n", dev_path(bus->dev), __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000565 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
Uwe Hermanne4870472010-11-04 23:23:47 +0000566 "prefmem" : "mem", base, bridge->size, bridge->align,
567 bridge->gran);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000568
569 /* For each child which is a bridge, allocate_resources. */
570 for (dev = bus->children; dev; dev = dev->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000571 struct resource *child_bridge;
572
Myles Watson894a3472010-06-09 22:41:35 +0000573 if (!dev->link_list)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000574 continue;
575
576 /* Find the resources with matching type flags. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000577 for (child_bridge = dev->resource_list; child_bridge;
578 child_bridge = child_bridge->next) {
Myles Watson894a3472010-06-09 22:41:35 +0000579 struct bus* link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000580
581 if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
582 (child_bridge->flags & type_mask) != type)
583 continue;
584
Uwe Hermanne4870472010-11-04 23:23:47 +0000585 /*
586 * Split prefetchable memory if combined. Many domains
Myles Watson29cc9ed2009-07-02 18:56:24 +0000587 * use the same address space for prefetchable memory
Uwe Hermanne4870472010-11-04 23:23:47 +0000588 * and non-prefetchable memory. Bridges below them need
589 * it separated. Add the PREFETCH flag to the type_mask
590 * and type.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000591 */
Myles Watson894a3472010-06-09 22:41:35 +0000592 link = dev->link_list;
593 while (link && link->link_num !=
594 IOINDEX_LINK(child_bridge->index))
595 link = link->next;
596 if (link == NULL)
597 printk(BIOS_ERR, "link %ld not found on %s\n",
598 IOINDEX_LINK(child_bridge->index),
599 dev_path(dev));
Uwe Hermanne4870472010-11-04 23:23:47 +0000600
Myles Watson894a3472010-06-09 22:41:35 +0000601 allocate_resources(link, child_bridge,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000602 type_mask | IORESOURCE_PREFETCH,
603 type | (child_bridge->flags &
604 IORESOURCE_PREFETCH));
605 }
606 }
607}
608
Patrick Georgie1667822012-05-05 15:29:32 +0200609#if CONFIG_PCI_64BIT_PREF_MEM
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000610#define MEM_MASK (IORESOURCE_PREFETCH | IORESOURCE_MEM)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000611#else
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000612#define MEM_MASK (IORESOURCE_MEM)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000613#endif
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000614
Uwe Hermanne4870472010-11-04 23:23:47 +0000615#define IO_MASK (IORESOURCE_IO)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000616#define PREF_TYPE (IORESOURCE_PREFETCH | IORESOURCE_MEM)
Uwe Hermanne4870472010-11-04 23:23:47 +0000617#define MEM_TYPE (IORESOURCE_MEM)
618#define IO_TYPE (IORESOURCE_IO)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000619
620struct constraints {
621 struct resource pref, io, mem;
622};
623
624static void constrain_resources(struct device *dev, struct constraints* limits)
625{
626 struct device *child;
627 struct resource *res;
628 struct resource *lim;
Myles Watson894a3472010-06-09 22:41:35 +0000629 struct bus *link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000630
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000631 printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000632
633 /* Constrain limits based on the fixed resources of this device. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000634 for (res = dev->resource_list; res; res = res->next) {
Patrick Georgi18c585b2009-08-28 12:48:02 +0000635 if (!(res->flags & IORESOURCE_FIXED))
636 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000637 if (!res->size) {
638 /* It makes no sense to have 0-sized, fixed resources.*/
Uwe Hermanne4870472010-11-04 23:23:47 +0000639 printk(BIOS_ERR, "skipping %s@%lx fixed resource, "
640 "size=0!\n", dev_path(dev), res->index);
Patrick Georgi6bd93f42009-08-19 17:29:41 +0000641 continue;
Myles Watsonce9d8642009-08-19 19:12:39 +0000642 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000643
644 /* PREFETCH, MEM, or I/O - skip any others. */
645 if ((res->flags & MEM_MASK) == PREF_TYPE)
646 lim = &limits->pref;
647 else if ((res->flags & MEM_MASK) == MEM_TYPE)
648 lim = &limits->mem;
649 else if ((res->flags & IO_MASK) == IO_TYPE)
650 lim = &limits->io;
651 else
652 continue;
653
Uwe Hermanne4870472010-11-04 23:23:47 +0000654 /*
655 * Is it a fixed resource outside the current known region?
656 * If so, we don't have to consider it - it will be handled
657 * correctly and doesn't affect current region's limits.
658 */
659 if (((res->base + res->size -1) < lim->base)
660 || (res->base > lim->limit))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000661 continue;
662
Uwe Hermanne4870472010-11-04 23:23:47 +0000663 /*
664 * Choose to be above or below fixed resources. This check is
665 * signed so that "negative" amounts of space are handled
666 * correctly.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000667 */
Uwe Hermanne4870472010-11-04 23:23:47 +0000668 if ((signed long long)(lim->limit - (res->base + res->size -1))
669 > (signed long long)(res->base - lim->base))
Myles Watson29cc9ed2009-07-02 18:56:24 +0000670 lim->base = res->base + res->size;
671 else
672 lim->limit = res->base -1;
673 }
674
675 /* Descend into every enabled child and look for fixed resources. */
Uwe Hermanne4870472010-11-04 23:23:47 +0000676 for (link = dev->link_list; link; link = link->next) {
677 for (child = link->children; child; child = child->sibling) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000678 if (child->enabled)
679 constrain_resources(child, limits);
Uwe Hermanne4870472010-11-04 23:23:47 +0000680 }
681 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000682}
683
684static void avoid_fixed_resources(struct device *dev)
685{
686 struct constraints limits;
687 struct resource *res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000688
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000689 printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000690
Uwe Hermanne4870472010-11-04 23:23:47 +0000691 /* Initialize constraints to maximum size. */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000692 limits.pref.base = 0;
693 limits.pref.limit = 0xffffffffffffffffULL;
694 limits.io.base = 0;
695 limits.io.limit = 0xffffffffffffffffULL;
696 limits.mem.base = 0;
697 limits.mem.limit = 0xffffffffffffffffULL;
698
699 /* Constrain the limits to dev's initial resources. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000700 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000701 if ((res->flags & IORESOURCE_FIXED))
702 continue;
Patrick Georgi51615092012-03-11 19:31:03 +0100703 printk(BIOS_SPEW, "%s:@%s %02lx limit %08llx\n", __func__,
Uwe Hermanne4870472010-11-04 23:23:47 +0000704 dev_path(dev), res->index, res->limit);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000705 if ((res->flags & MEM_MASK) == PREF_TYPE &&
706 (res->limit < limits.pref.limit))
707 limits.pref.limit = res->limit;
708 if ((res->flags & MEM_MASK) == MEM_TYPE &&
709 (res->limit < limits.mem.limit))
710 limits.mem.limit = res->limit;
711 if ((res->flags & IO_MASK) == IO_TYPE &&
712 (res->limit < limits.io.limit))
713 limits.io.limit = res->limit;
714 }
715
716 /* Look through the tree for fixed resources and update the limits. */
717 constrain_resources(dev, &limits);
718
719 /* Update dev's resources with new limits. */
Myles Watsonc25cc112010-05-21 14:33:48 +0000720 for (res = dev->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000721 struct resource *lim;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000722
723 if ((res->flags & IORESOURCE_FIXED))
724 continue;
725
726 /* PREFETCH, MEM, or I/O - skip any others. */
727 if ((res->flags & MEM_MASK) == PREF_TYPE)
728 lim = &limits.pref;
729 else if ((res->flags & MEM_MASK) == MEM_TYPE)
730 lim = &limits.mem;
731 else if ((res->flags & IO_MASK) == IO_TYPE)
732 lim = &limits.io;
733 else
734 continue;
735
Patrick Georgi51615092012-03-11 19:31:03 +0100736 printk(BIOS_SPEW, "%s2: %s@%02lx limit %08llx\n", __func__,
Myles Watson29cc9ed2009-07-02 18:56:24 +0000737 dev_path(dev), res->index, res->limit);
Patrick Georgi51615092012-03-11 19:31:03 +0100738 printk(BIOS_SPEW, "\tlim->base %08llx lim->limit %08llx\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000739 lim->base, lim->limit);
740
741 /* Is the resource outside the limits? */
742 if (lim->base > res->base)
743 res->base = lim->base;
744 if (res->limit > lim->limit)
745 res->limit = lim->limit;
746 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000747}
arch import user (historical)dc811182005-07-06 17:16:09 +0000748
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000749device_t vga_pri = 0;
Myles Watsonc7233e02009-07-02 19:02:33 +0000750static void set_vga_bridge_bits(void)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000751{
Uwe Hermann312673c2009-10-27 21:49:33 +0000752 /*
Martin Roth63373ed2013-07-08 16:24:19 -0600753 * FIXME: Modify set_vga_bridge() so it is less PCI-centric!
Uwe Hermann312673c2009-10-27 21:49:33 +0000754 * This function knows too much about PCI stuff, it should be just
755 * an iterator/visitor.
756 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000757
Myles Watson29cc9ed2009-07-02 18:56:24 +0000758 /* FIXME: Handle the VGA palette snooping. */
Patrick Georgi557ecf22012-07-20 12:16:17 +0200759 struct device *dev, *vga, *vga_onboard;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000760 struct bus *bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000761
Eric Biedermanb78c1972004-10-14 20:54:17 +0000762 bus = 0;
763 vga = 0;
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000764 vga_onboard = 0;
Uwe Hermanne4870472010-11-04 23:23:47 +0000765
Patrick Georgi557ecf22012-07-20 12:16:17 +0200766 dev = NULL;
767 while ((dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev))) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000768 if (!dev->enabled)
769 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000770
Patrick Georgi557ecf22012-07-20 12:16:17 +0200771 printk(BIOS_DEBUG, "found VGA at %s\n", dev_path(dev));
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000772
Patrick Georgi557ecf22012-07-20 12:16:17 +0200773 if (dev->on_mainboard) {
774 vga_onboard = dev;
Kostr1f0d3792012-10-06 13:27:58 +0400775 } else {
Patrick Georgi557ecf22012-07-20 12:16:17 +0200776 vga = dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000777 }
Myles Watson032a9652009-05-11 22:24:53 +0000778
Patrick Georgi557ecf22012-07-20 12:16:17 +0200779 /* It isn't safe to enable all VGA cards. */
780 dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Patrick Georgi594473d2012-07-25 08:55:53 +0200781 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000782
Uwe Hermanne4870472010-11-04 23:23:47 +0000783 if (!vga)
Myles Watson29cc9ed2009-07-02 18:56:24 +0000784 vga = vga_onboard;
Patrick Georgi557ecf22012-07-20 12:16:17 +0200785
786 if (CONFIG_ONBOARD_VGA_IS_PRIMARY && vga_onboard)
787 vga = vga_onboard;
Myles Watson032a9652009-05-11 22:24:53 +0000788
Patrick Georgi5869fa22012-07-20 12:29:33 +0200789 /* If we prefer plugin VGA over chipset VGA, the chipset might
790 want to know. */
791 if (!CONFIG_ONBOARD_VGA_IS_PRIMARY && (vga != vga_onboard) &&
792 vga_onboard && vga_onboard->ops && vga_onboard->ops->disable) {
793 printk(BIOS_DEBUG, "Use plugin graphics over integrated.\n");
794 vga_onboard->ops->disable(vga_onboard);
795 }
796
arch import user (historical)dc811182005-07-06 17:16:09 +0000797 if (vga) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000798 /* VGA is first add-on card or the only onboard VGA. */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000799 printk(BIOS_DEBUG, "Setting up VGA for %s\n", dev_path(vga));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000800 /* All legacy VGA cards have MEM & I/O space registers. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000801 vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
802 vga_pri = vga;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000803 bus = vga->bus;
804 }
Uwe Hermanne4870472010-11-04 23:23:47 +0000805
Myles Watson29cc9ed2009-07-02 18:56:24 +0000806 /* Now walk up the bridges setting the VGA enable. */
807 while (bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000808 printk(BIOS_DEBUG, "Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000809 dev_path(bus->dev));
Li-Ta Lodb7f47c2004-01-08 21:15:49 +0000810 bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000811 bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus;
Myles Watson032a9652009-05-11 22:24:53 +0000812 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000813}
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000814
Li-Ta Lo04930692004-11-25 17:37:19 +0000815/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000816 * Assign the computed resources to the devices on the bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000817 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000818 * Use the device specific set_resources() method to store the computed
Li-Ta Lo04930692004-11-25 17:37:19 +0000819 * resources to hardware. For bridge devices, the set_resources() method
820 * has to recurse into every down stream buses.
821 *
822 * Mutual recursion:
823 * assign_resources() -> device_operation::set_resources()
824 * device_operation::set_resources() -> assign_resources()
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000825 *
826 * @param bus Pointer to the structure for this bus.
Li-Ta Lo04930692004-11-25 17:37:19 +0000827 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000828void assign_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000829{
830 struct device *curdev;
831
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000832 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000833 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000834
Myles Watson29cc9ed2009-07-02 18:56:24 +0000835 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000836 if (!curdev->enabled || !curdev->resource_list)
Eric Biederman03acab62004-10-14 21:25:53 +0000837 continue;
Uwe Hermanne4870472010-11-04 23:23:47 +0000838
Eric Biedermane9a271e32003-09-02 03:36:25 +0000839 if (!curdev->ops || !curdev->ops->set_resources) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000840 printk(BIOS_ERR, "%s missing set_resources\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000841 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000842 continue;
843 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000844 curdev->ops->set_resources(curdev);
845 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000846 printk(BIOS_SPEW, "%s assign_resources, bus %d link: %d\n",
Uwe Hermanne4870472010-11-04 23:23:47 +0000847 dev_path(bus->dev), bus->secondary, bus->link_num);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000848}
849
Li-Ta Lo5782d272004-04-26 17:51:20 +0000850/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000851 * Enable the resources for devices on a link.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000852 *
853 * Enable resources of the device by calling the device specific
854 * enable_resources() method.
855 *
856 * The parent's resources should be enabled first to avoid having enabling
857 * order problem. This is done by calling the parent's enable_resources()
Martin Roth63373ed2013-07-08 16:24:19 -0600858 * method before its children's enable_resources() methods.
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000859 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000860 * @param link The link whose devices' resources are to be enabled.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000861 */
Myles Watson7eac4452010-06-17 16:16:56 +0000862static void enable_resources(struct bus *link)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000863{
Myles Watson7eac4452010-06-17 16:16:56 +0000864 struct device *dev;
865 struct bus *c_link;
866
867 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000868 if (dev->enabled && dev->ops && dev->ops->enable_resources)
Myles Watson7eac4452010-06-17 16:16:56 +0000869 dev->ops->enable_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000870 }
Myles Watson7eac4452010-06-17 16:16:56 +0000871
872 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000873 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +0000874 enable_resources(c_link);
Eric Biederman83b991a2003-10-11 06:20:25 +0000875 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000876}
877
Myles Watson032a9652009-05-11 22:24:53 +0000878/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000879 * Reset all of the devices on a bus and clear the bus's reset_needed flag.
880 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000881 * @param bus Pointer to the bus structure.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000882 * @return 1 if the bus was successfully reset, 0 otherwise.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000883 */
884int reset_bus(struct bus *bus)
885{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000886 if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000887 bus->dev->ops->reset_bus(bus);
888 bus->reset_needed = 0;
889 return 1;
890 }
891 return 0;
892}
893
Myles Watson032a9652009-05-11 22:24:53 +0000894/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000895 * Scan for devices on a bus.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000896 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000897 * If there are bridges on the bus, recursively scan the buses behind the
898 * bridges. If the setting up and tuning of the bus causes a reset to be
899 * required, reset the bus and scan it again.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000900 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000901 * @param busdev Pointer to the bus device.
902 * @param max Current bus number.
903 * @return The maximum bus number found, after scanning all subordinate buses.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000904 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000905unsigned int scan_bus(struct device *busdev, unsigned int max)
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000906{
907 unsigned int new_max;
908 int do_scan_bus;
Uwe Hermanne4870472010-11-04 23:23:47 +0000909
Myles Watson29cc9ed2009-07-02 18:56:24 +0000910 if (!busdev || !busdev->enabled || !busdev->ops ||
911 !busdev->ops->scan_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000912 return max;
913 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000914
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000915 do_scan_bus = 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000916 while (do_scan_bus) {
Myles Watson894a3472010-06-09 22:41:35 +0000917 struct bus *link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000918 new_max = busdev->ops->scan_bus(busdev, max);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000919 do_scan_bus = 0;
Myles Watson894a3472010-06-09 22:41:35 +0000920 for (link = busdev->link_list; link; link = link->next) {
921 if (link->reset_needed) {
Uwe Hermanne4870472010-11-04 23:23:47 +0000922 if (reset_bus(link))
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000923 do_scan_bus = 1;
Uwe Hermanne4870472010-11-04 23:23:47 +0000924 else
Myles Watson29cc9ed2009-07-02 18:56:24 +0000925 busdev->bus->reset_needed = 1;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000926 }
927 }
928 }
929 return new_max;
930}
931
Li-Ta Loe5266692004-03-23 21:28:05 +0000932/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000933 * Determine the existence of devices and extend the device tree.
Li-Ta Lo04930692004-11-25 17:37:19 +0000934 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000935 * Most of the devices in the system are listed in the mainboard devicetree.cb
Li-Ta Lo04930692004-11-25 17:37:19 +0000936 * file. The device structures for these devices are generated at compile
937 * time by the config tool and are organized into the device tree. This
938 * function determines if the devices created at compile time actually exist
939 * in the physical system.
940 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000941 * For devices in the physical system but not listed in devicetree.cb,
Li-Ta Lo04930692004-11-25 17:37:19 +0000942 * the device structures have to be created at run time and attached to the
Li-Ta Loe5266692004-03-23 21:28:05 +0000943 * device tree.
944 *
Uwe Hermanne4870472010-11-04 23:23:47 +0000945 * This function starts from the root device 'dev_root', scans the buses in
946 * the system recursively, and modifies the device tree according to the
947 * result of the probe.
Li-Ta Loe5266692004-03-23 21:28:05 +0000948 *
Li-Ta Lo5782d272004-04-26 17:51:20 +0000949 * This function has no idea how to scan and probe buses and devices at all.
950 * It depends on the bus/device specific scan_bus() method to do it. The
Li-Ta Lo04930692004-11-25 17:37:19 +0000951 * scan_bus() method also has to create the device structure and attach
Myles Watson032a9652009-05-11 22:24:53 +0000952 * it to the device tree.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000953 */
954void dev_enumerate(void)
955{
956 struct device *root;
Uwe Hermanne4870472010-11-04 23:23:47 +0000957
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000958 printk(BIOS_INFO, "Enumerating buses...\n");
Uwe Hermanne4870472010-11-04 23:23:47 +0000959
Eric Biederman8ca8d762003-04-22 19:02:15 +0000960 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000961
Uwe Hermanne4870472010-11-04 23:23:47 +0000962 show_all_devs(BIOS_SPEW, "Before device enumeration.");
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000963 printk(BIOS_SPEW, "Compare with tree...\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +0000964 show_devs_tree(root, BIOS_SPEW, 0, 0);
Myles Watsoncd5d7562009-05-12 13:43:34 +0000965
Stefan Reinauera675d492012-08-07 14:50:47 -0700966 if (root->chip_ops && root->chip_ops->enable_dev)
967 root->chip_ops->enable_dev(root);
Uwe Hermanne4870472010-11-04 23:23:47 +0000968
Eric Biedermanb78c1972004-10-14 20:54:17 +0000969 if (!root->ops || !root->ops->scan_bus) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000970 printk(BIOS_ERR, "dev_root missing scan_bus operation");
Eric Biedermanb78c1972004-10-14 20:54:17 +0000971 return;
972 }
Stefan Reinauer6afcea82009-07-18 17:58:44 +0000973 scan_bus(root, 0);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000974 printk(BIOS_INFO, "done\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000975}
976
Li-Ta Loe5266692004-03-23 21:28:05 +0000977/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +0000978 * Configure devices on the devices tree.
Myles Watson032a9652009-05-11 22:24:53 +0000979 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000980 * Starting at the root of the device tree, travel it recursively in two
981 * passes. In the first pass, we compute and allocate resources (ranges)
Martin Roth63373ed2013-07-08 16:24:19 -0600982 * required by each device. In the second pass, the resources ranges are
Li-Ta Lo04930692004-11-25 17:37:19 +0000983 * relocated to their final position and stored to the hardware.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000984 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000985 * I/O resources grow upward. MEM resources grow downward.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000986 *
987 * Since the assignment is hierarchical we set the values into the dev_root
Myles Watson032a9652009-05-11 22:24:53 +0000988 * struct.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000989 */
990void dev_configure(void)
991{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000992 struct resource *res;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000993 struct device *root;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000994 struct device *child;
Li-Ta Loe5266692004-03-23 21:28:05 +0000995
Marc Jones80bd74c2012-02-21 17:44:35 +0100996 set_vga_bridge_bits();
Marc Jones80bd74c2012-02-21 17:44:35 +0100997
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000998 printk(BIOS_INFO, "Allocating resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000999
Eric Biedermanb78c1972004-10-14 20:54:17 +00001000 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +00001001
Uwe Hermanne4870472010-11-04 23:23:47 +00001002 /*
1003 * Each domain should create resources which contain the entire address
Myles Watson29cc9ed2009-07-02 18:56:24 +00001004 * space for IO, MEM, and PREFMEM resources in the domain. The
1005 * allocation of device resources will be done from this address space.
1006 */
Myles Watsoncd5d7562009-05-12 13:43:34 +00001007
Myles Watson29cc9ed2009-07-02 18:56:24 +00001008 /* Read the resources for the entire tree. */
Li-Ta Lo04930692004-11-25 17:37:19 +00001009
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001010 printk(BIOS_INFO, "Reading resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001011 read_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001012 printk(BIOS_INFO, "Done reading resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001013
Stefan Reinauer39e72292009-10-26 16:47:05 +00001014 print_resource_tree(root, BIOS_SPEW, "After reading.");
Myles Watsoncd5d7562009-05-12 13:43:34 +00001015
Myles Watson29cc9ed2009-07-02 18:56:24 +00001016 /* Compute resources for all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001017 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001018 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001019 continue;
Myles Watsonc25cc112010-05-21 14:33:48 +00001020 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001021 if (res->flags & IORESOURCE_FIXED)
1022 continue;
1023 if (res->flags & IORESOURCE_PREFETCH) {
Myles Watson894a3472010-06-09 22:41:35 +00001024 compute_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001025 res, MEM_MASK, PREF_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001026 continue;
1027 }
1028 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001029 compute_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001030 res, MEM_MASK, MEM_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001031 continue;
1032 }
1033 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001034 compute_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001035 res, IO_MASK, IO_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001036 continue;
1037 }
1038 }
1039 }
1040
1041 /* For all domains. */
Myles Watson894a3472010-06-09 22:41:35 +00001042 for (child = root->link_list->children; child; child=child->sibling)
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001043 if (child->path.type == DEVICE_PATH_DOMAIN)
Myles Watson29cc9ed2009-07-02 18:56:24 +00001044 avoid_fixed_resources(child);
1045
Uwe Hermanne4870472010-11-04 23:23:47 +00001046 /*
1047 * Now we need to adjust the resources. MEM resources need to start at
Martin Roth63373ed2013-07-08 16:24:19 -06001048 * the highest address manageable.
Eric Biedermanb78c1972004-10-14 20:54:17 +00001049 */
Myles Watson894a3472010-06-09 22:41:35 +00001050 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001051 if (child->path.type != DEVICE_PATH_DOMAIN)
Myles Watson29cc9ed2009-07-02 18:56:24 +00001052 continue;
Myles Watsonc25cc112010-05-21 14:33:48 +00001053 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001054 if (!(res->flags & IORESOURCE_MEM) ||
1055 res->flags & IORESOURCE_FIXED)
1056 continue;
1057 res->base = resource_max(res);
1058 }
1059 }
Eric Biederman5cd81732004-03-11 15:01:31 +00001060
Eric Biedermanb78c1972004-10-14 20:54:17 +00001061 /* Store the computed resource allocations into device registers ... */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001062 printk(BIOS_INFO, "Setting resources...\n");
Myles Watson894a3472010-06-09 22:41:35 +00001063 for (child = root->link_list->children; child; child = child->sibling) {
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001064 if (!(child->path.type == DEVICE_PATH_DOMAIN))
Myles Watson29cc9ed2009-07-02 18:56:24 +00001065 continue;
Myles Watsonc25cc112010-05-21 14:33:48 +00001066 for (res = child->resource_list; res; res = res->next) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001067 if (res->flags & IORESOURCE_FIXED)
1068 continue;
1069 if (res->flags & IORESOURCE_PREFETCH) {
Myles Watson894a3472010-06-09 22:41:35 +00001070 allocate_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001071 res, MEM_MASK, PREF_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001072 continue;
1073 }
1074 if (res->flags & IORESOURCE_MEM) {
Myles Watson894a3472010-06-09 22:41:35 +00001075 allocate_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001076 res, MEM_MASK, MEM_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001077 continue;
1078 }
1079 if (res->flags & IORESOURCE_IO) {
Myles Watson894a3472010-06-09 22:41:35 +00001080 allocate_resources(child->link_list,
Uwe Hermanne4870472010-11-04 23:23:47 +00001081 res, IO_MASK, IO_TYPE);
Myles Watson29cc9ed2009-07-02 18:56:24 +00001082 continue;
1083 }
1084 }
1085 }
Myles Watson894a3472010-06-09 22:41:35 +00001086 assign_resources(root->link_list);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001087 printk(BIOS_INFO, "Done setting resources.\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001088 print_resource_tree(root, BIOS_SPEW, "After assigning values.");
Eric Biederman03acab62004-10-14 21:25:53 +00001089
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001090 printk(BIOS_INFO, "Done allocating resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001091}
1092
Li-Ta Loe5266692004-03-23 21:28:05 +00001093/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001094 * Enable devices on the device tree.
Li-Ta Loe5266692004-03-23 21:28:05 +00001095 *
1096 * Starting at the root, walk the tree and enable all devices/bridges by
1097 * calling the device's enable_resources() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001098 */
1099void dev_enable(void)
1100{
Myles Watson7eac4452010-06-17 16:16:56 +00001101 struct bus *link;
1102
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001103 printk(BIOS_INFO, "Enabling resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001104
Uwe Hermanne4870472010-11-04 23:23:47 +00001105 /* Now enable everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001106 for (link = dev_root.link_list; link; link = link->next)
1107 enable_resources(link);
Li-Ta Loe5266692004-03-23 21:28:05 +00001108
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001109 printk(BIOS_INFO, "done.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001110}
1111
Li-Ta Loe5266692004-03-23 21:28:05 +00001112/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001113 * Initialize a specific device.
Myles Watson7eac4452010-06-17 16:16:56 +00001114 *
Uwe Hermanne4870472010-11-04 23:23:47 +00001115 * The parent should be initialized first to avoid having an ordering problem.
Martin Roth63373ed2013-07-08 16:24:19 -06001116 * This is done by calling the parent's init() method before its children's
Uwe Hermanne4870472010-11-04 23:23:47 +00001117 * init() methods.
Myles Watson7eac4452010-06-17 16:16:56 +00001118 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001119 * @param dev The device to be initialized.
Myles Watson7eac4452010-06-17 16:16:56 +00001120 */
1121static void init_dev(struct device *dev)
1122{
Uwe Hermanne4870472010-11-04 23:23:47 +00001123 if (!dev->enabled)
Myles Watson7eac4452010-06-17 16:16:56 +00001124 return;
Myles Watson7eac4452010-06-17 16:16:56 +00001125
1126 if (!dev->initialized && dev->ops && dev->ops->init) {
Aaron Durbin05294292013-04-30 15:41:13 -05001127#if CONFIG_HAVE_MONOTONIC_TIMER
1128 struct mono_time start_time;
1129 struct rela_time dev_init_time;
1130
1131 timer_monotonic_get(&start_time);
1132#endif
Myles Watson7eac4452010-06-17 16:16:56 +00001133 if (dev->path.type == DEVICE_PATH_I2C) {
1134 printk(BIOS_DEBUG, "smbus: %s[%d]->",
1135 dev_path(dev->bus->dev), dev->bus->link_num);
1136 }
1137
1138 printk(BIOS_DEBUG, "%s init\n", dev_path(dev));
1139 dev->initialized = 1;
1140 dev->ops->init(dev);
Aaron Durbin05294292013-04-30 15:41:13 -05001141#if CONFIG_HAVE_MONOTONIC_TIMER
1142 dev_init_time = current_time_from(&start_time);
1143 printk(BIOS_DEBUG, "%s init %ld usecs\n", dev_path(dev),
1144 rela_time_in_microseconds(&dev_init_time));
1145#endif
Myles Watson7eac4452010-06-17 16:16:56 +00001146 }
1147}
1148
1149static void init_link(struct bus *link)
1150{
1151 struct device *dev;
1152 struct bus *c_link;
1153
Uwe Hermanne4870472010-11-04 23:23:47 +00001154 for (dev = link->children; dev; dev = dev->sibling)
Myles Watson7eac4452010-06-17 16:16:56 +00001155 init_dev(dev);
Myles Watson7eac4452010-06-17 16:16:56 +00001156
1157 for (dev = link->children; dev; dev = dev->sibling) {
Uwe Hermanne4870472010-11-04 23:23:47 +00001158 for (c_link = dev->link_list; c_link; c_link = c_link->next)
Myles Watson7eac4452010-06-17 16:16:56 +00001159 init_link(c_link);
Myles Watson7eac4452010-06-17 16:16:56 +00001160 }
1161}
1162
1163/**
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001164 * Initialize all devices in the global device tree.
Myles Watson7eac4452010-06-17 16:16:56 +00001165 *
Uwe Hermannc1ee4292010-10-17 19:01:48 +00001166 * Starting at the root device, call the device's init() method to do
1167 * device-specific setup, then call each child's init() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001168 */
1169void dev_initialize(void)
1170{
Myles Watson7eac4452010-06-17 16:16:56 +00001171 struct bus *link;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001172
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001173 printk(BIOS_INFO, "Initializing devices...\n");
Myles Watson7eac4452010-06-17 16:16:56 +00001174
Duncan Laurieb4aaaa72012-01-17 09:03:11 -08001175#if CONFIG_ARCH_X86
1176 /* Ensure EBDA is prepared before Option ROMs. */
1177 setup_default_ebda();
1178#endif
1179
Myles Watson1bd3fb72010-08-16 16:25:23 +00001180 /* First call the mainboard init. */
1181 init_dev(&dev_root);
1182
Uwe Hermanne4870472010-11-04 23:23:47 +00001183 /* Now initialize everything. */
Myles Watson7eac4452010-06-17 16:16:56 +00001184 for (link = dev_root.link_list; link; link = link->next)
1185 init_link(link);
1186
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001187 printk(BIOS_INFO, "Devices initialized\n");
Stefan Reinauer39e72292009-10-26 16:47:05 +00001188 show_all_devs(BIOS_SPEW, "After init.");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001189}
Marc Jones2a58ecd2013-10-29 17:32:00 -06001190
1191/**
1192 * Finalize a specific device.
1193 *
1194 * The parent should be finalized first to avoid having an ordering problem.
1195 * This is done by calling the parent's final() method before its childrens'
1196 * final() methods.
1197 *
1198 * @param dev The device to be initialized.
1199 */
1200static void final_dev(struct device *dev)
1201{
1202 if (!dev->enabled)
1203 return;
1204
1205 if (dev->ops && dev->ops->final) {
1206 printk(BIOS_DEBUG, "%s final\n", dev_path(dev));
1207 dev->ops->final(dev);
1208 }
1209}
1210
1211static void final_link(struct bus *link)
1212{
1213 struct device *dev;
1214 struct bus *c_link;
1215
1216 for (dev = link->children; dev; dev = dev->sibling)
1217 final_dev(dev);
1218
1219 for (dev = link->children; dev; dev = dev->sibling) {
1220 for (c_link = dev->link_list; c_link; c_link = c_link->next)
1221 final_link(c_link);
1222 }
1223}
1224/**
1225 * Finalize all devices in the global device tree.
1226 *
1227 * Starting at the root device, call the device's final() method to do
1228 * device-specific cleanup, then call each child's final() method.
1229 */
1230void dev_finalize(void)
1231{
1232 struct bus *link;
1233
1234 printk(BIOS_INFO, "Finalize devices...\n");
1235
1236 /* First call the mainboard finalize. */
1237 final_dev(&dev_root);
1238
1239 /* Now finalize everything. */
1240 for (link = dev_root.link_list; link; link = link->next)
1241 final_link(link);
1242
1243 printk(BIOS_INFO, "Devices finalized\n");
1244}