blob: 7757c00269075447ae0957e90136713e46bc04a1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * drivers/pci/setup-bus.c
3 *
4 * Extruded from code written by
5 * Dave Rusling (david.rusling@reo.mts.dec.com)
6 * David Mosberger (davidm@cs.arizona.edu)
7 * David Miller (davem@redhat.com)
8 *
9 * Support routines for initializing a PCI subsystem.
10 */
11
12/*
13 * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
14 * PCI-PCI bridges cleanup, sorted resource allocation.
15 * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
16 * Converted to allocation in 3 passes, which gives
17 * tighter packing. Prefetchable range support.
18 */
19
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/pci.h>
24#include <linux/errno.h>
25#include <linux/ioport.h>
26#include <linux/cache.h>
27#include <linux/slab.h>
Chris Wright6faf17f2009-08-28 13:00:06 -070028#include "pci.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
Yinghai Lu568ddef2010-01-22 01:02:21 -080030struct resource_list_x {
31 struct resource_list_x *next;
32 struct resource *res;
33 struct pci_dev *dev;
34 resource_size_t start;
35 resource_size_t end;
Ram Paic8adf9a2011-02-14 17:43:20 -080036 resource_size_t add_size;
Ram Pai2bbc6942011-07-25 13:08:39 -070037 resource_size_t min_align;
Yinghai Lu568ddef2010-01-22 01:02:21 -080038 unsigned long flags;
39};
40
Ram Pai094732a2011-02-14 17:43:18 -080041#define free_list(type, head) do { \
42 struct type *list, *tmp; \
43 for (list = (head)->next; list;) { \
44 tmp = list; \
45 list = list->next; \
46 kfree(tmp); \
47 } \
48 (head)->next = NULL; \
49} while (0)
50
Ram Paif483d392011-07-07 11:19:10 -070051int pci_realloc_enable = 0;
52#define pci_realloc_enabled() pci_realloc_enable
53void pci_realloc(void)
54{
55 pci_realloc_enable = 1;
56}
57
Ram Paic8adf9a2011-02-14 17:43:20 -080058/**
59 * add_to_list() - add a new resource tracker to the list
60 * @head: Head of the list
61 * @dev: device corresponding to which the resource
62 * belongs
63 * @res: The resource to be tracked
64 * @add_size: additional size to be optionally added
65 * to the resource
66 */
Yinghai Luef62dfe2012-01-21 02:08:18 -080067static int add_to_list(struct resource_list_x *head,
Ram Paic8adf9a2011-02-14 17:43:20 -080068 struct pci_dev *dev, struct resource *res,
Ram Pai2bbc6942011-07-25 13:08:39 -070069 resource_size_t add_size, resource_size_t min_align)
Yinghai Lu568ddef2010-01-22 01:02:21 -080070{
71 struct resource_list_x *list = head;
72 struct resource_list_x *ln = list->next;
73 struct resource_list_x *tmp;
74
75 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
76 if (!tmp) {
Ram Paic8adf9a2011-02-14 17:43:20 -080077 pr_warning("add_to_list: kmalloc() failed!\n");
Yinghai Luef62dfe2012-01-21 02:08:18 -080078 return -ENOMEM;
Yinghai Lu568ddef2010-01-22 01:02:21 -080079 }
80
81 tmp->next = ln;
82 tmp->res = res;
83 tmp->dev = dev;
84 tmp->start = res->start;
85 tmp->end = res->end;
86 tmp->flags = res->flags;
Ram Paic8adf9a2011-02-14 17:43:20 -080087 tmp->add_size = add_size;
Ram Pai2bbc6942011-07-25 13:08:39 -070088 tmp->min_align = min_align;
Yinghai Lu568ddef2010-01-22 01:02:21 -080089 list->next = tmp;
Yinghai Luef62dfe2012-01-21 02:08:18 -080090
91 return 0;
Yinghai Lu568ddef2010-01-22 01:02:21 -080092}
93
Ram Paic8adf9a2011-02-14 17:43:20 -080094static void add_to_failed_list(struct resource_list_x *head,
95 struct pci_dev *dev, struct resource *res)
96{
Ram Pai2bbc6942011-07-25 13:08:39 -070097 add_to_list(head, dev, res,
98 0 /* dont care */,
99 0 /* dont care */);
Ram Paic8adf9a2011-02-14 17:43:20 -0800100}
101
Yinghai Lu3e6e0d82012-01-21 02:08:20 -0800102static void remove_from_list(struct resource_list_x *realloc_head,
103 struct resource *res)
104{
105 struct resource_list_x *prev, *tmp, *list;
106
107 prev = realloc_head;
108 for (list = realloc_head->next; list;) {
109 if (list->res != res) {
110 prev = list;
111 list = list->next;
112 continue;
113 }
114 tmp = list;
115 prev->next = list = list->next;
116 kfree(tmp);
117 }
118}
119
Yinghai Lu1c372352012-01-21 02:08:19 -0800120static resource_size_t get_res_add_size(struct resource_list_x *realloc_head,
121 struct resource *res)
122{
123 struct resource_list_x *list;
124
125 /* check if it is in realloc_head list */
126 for (list = realloc_head->next; list && list->res != res;
127 list = list->next)
128 ;
Yinghai Lu3e6e0d82012-01-21 02:08:20 -0800129
130 if (list) {
131 dev_printk(KERN_DEBUG, &list->dev->dev,
132 "%pR get_res_add_size add_size %llx\n",
133 list->res, (unsigned long long)list->add_size);
Yinghai Lu1c372352012-01-21 02:08:19 -0800134 return list->add_size;
Yinghai Lu3e6e0d82012-01-21 02:08:20 -0800135 }
Yinghai Lu1c372352012-01-21 02:08:19 -0800136
137 return 0;
138}
139
Yinghai Lu6841ec62010-01-22 01:02:25 -0800140static void __dev_sort_resources(struct pci_dev *dev,
141 struct resource_list *head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142{
Yinghai Lu6841ec62010-01-22 01:02:25 -0800143 u16 class = dev->class >> 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144
Yinghai Lu6841ec62010-01-22 01:02:25 -0800145 /* Don't touch classless devices or host bridges or ioapics. */
146 if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
147 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
Yinghai Lu6841ec62010-01-22 01:02:25 -0800149 /* Don't touch ioapic devices already enabled by firmware */
150 if (class == PCI_CLASS_SYSTEM_PIC) {
151 u16 command;
152 pci_read_config_word(dev, PCI_COMMAND, &command);
153 if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
154 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 }
156
Yinghai Lu6841ec62010-01-22 01:02:25 -0800157 pdev_sort_resources(dev, head);
158}
159
Ram Paifc075e12011-02-14 17:43:19 -0800160static inline void reset_resource(struct resource *res)
161{
162 res->start = 0;
163 res->end = 0;
164 res->flags = 0;
165}
166
Ram Paic8adf9a2011-02-14 17:43:20 -0800167/**
Ram Pai9e8bf932011-07-25 13:08:42 -0700168 * reassign_resources_sorted() - satisfy any additional resource requests
Ram Paic8adf9a2011-02-14 17:43:20 -0800169 *
Ram Pai9e8bf932011-07-25 13:08:42 -0700170 * @realloc_head : head of the list tracking requests requiring additional
Ram Paic8adf9a2011-02-14 17:43:20 -0800171 * resources
172 * @head : head of the list tracking requests with allocated
173 * resources
174 *
Ram Pai9e8bf932011-07-25 13:08:42 -0700175 * Walk through each element of the realloc_head and try to procure
Ram Paic8adf9a2011-02-14 17:43:20 -0800176 * additional resources for the element, provided the element
177 * is in the head list.
178 */
Ram Pai9e8bf932011-07-25 13:08:42 -0700179static void reassign_resources_sorted(struct resource_list_x *realloc_head,
Ram Paic8adf9a2011-02-14 17:43:20 -0800180 struct resource_list *head)
181{
182 struct resource *res;
183 struct resource_list_x *list, *tmp, *prev;
184 struct resource_list *hlist;
185 resource_size_t add_size;
186 int idx;
187
Ram Pai9e8bf932011-07-25 13:08:42 -0700188 prev = realloc_head;
189 for (list = realloc_head->next; list;) {
Ram Paic8adf9a2011-02-14 17:43:20 -0800190 res = list->res;
191 /* skip resource that has been reset */
192 if (!res->flags)
193 goto out;
194
195 /* skip this resource if not found in head list */
196 for (hlist = head->next; hlist && hlist->res != res;
197 hlist = hlist->next);
198 if (!hlist) { /* just skip */
199 prev = list;
200 list = list->next;
201 continue;
202 }
203
204 idx = res - &list->dev->resource[0];
205 add_size=list->add_size;
Ram Pai2bbc6942011-07-25 13:08:39 -0700206 if (!resource_size(res)) {
Ram Pai0a2daa12011-07-25 13:08:41 -0700207 res->start = list->start;
Ram Pai2bbc6942011-07-25 13:08:39 -0700208 res->end = res->start + add_size - 1;
209 if(pci_assign_resource(list->dev, idx))
Ram Paic8adf9a2011-02-14 17:43:20 -0800210 reset_resource(res);
Ram Pai2bbc6942011-07-25 13:08:39 -0700211 } else {
212 resource_size_t align = list->min_align;
213 res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN);
214 if (pci_reassign_resource(list->dev, idx, add_size, align))
215 dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n",
216 res);
Ram Paic8adf9a2011-02-14 17:43:20 -0800217 }
218out:
219 tmp = list;
220 prev->next = list = list->next;
221 kfree(tmp);
222 }
223}
224
225/**
226 * assign_requested_resources_sorted() - satisfy resource requests
227 *
228 * @head : head of the list tracking requests for resources
229 * @failed_list : head of the list tracking requests that could
230 * not be allocated
231 *
232 * Satisfy resource requests of each element in the list. Add
233 * requests that could not satisfied to the failed_list.
234 */
235static void assign_requested_resources_sorted(struct resource_list *head,
Yinghai Lu6841ec62010-01-22 01:02:25 -0800236 struct resource_list_x *fail_head)
237{
238 struct resource *res;
Ram Paic8adf9a2011-02-14 17:43:20 -0800239 struct resource_list *list;
Yinghai Lu6841ec62010-01-22 01:02:25 -0800240 int idx;
241
Ram Paic8adf9a2011-02-14 17:43:20 -0800242 for (list = head->next; list; list = list->next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 res = list->res;
244 idx = res - &list->dev->resource[0];
Ram Paic8adf9a2011-02-14 17:43:20 -0800245 if (resource_size(res) && pci_assign_resource(list->dev, idx)) {
Yinghai Lu9a928662010-02-28 15:49:39 -0800246 if (fail_head && !pci_is_root_bus(list->dev->bus)) {
247 /*
248 * if the failed res is for ROM BAR, and it will
249 * be enabled later, don't add it to the list
250 */
251 if (!((idx == PCI_ROM_RESOURCE) &&
252 (!(res->flags & IORESOURCE_ROM_ENABLE))))
253 add_to_failed_list(fail_head, list->dev, res);
254 }
Ram Paifc075e12011-02-14 17:43:19 -0800255 reset_resource(res);
Rajesh Shah542df5d2005-04-28 00:25:50 -0700256 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 }
258}
259
Ram Paic8adf9a2011-02-14 17:43:20 -0800260static void __assign_resources_sorted(struct resource_list *head,
Ram Pai9e8bf932011-07-25 13:08:42 -0700261 struct resource_list_x *realloc_head,
Ram Paic8adf9a2011-02-14 17:43:20 -0800262 struct resource_list_x *fail_head)
263{
Yinghai Lu3e6e0d82012-01-21 02:08:20 -0800264 /*
265 * Should not assign requested resources at first.
266 * they could be adjacent, so later reassign can not reallocate
267 * them one by one in parent resource window.
268 * Try to assign requested + add_size at begining
269 * if could do that, could get out early.
270 * if could not do that, we still try to assign requested at first,
271 * then try to reassign add_size for some resources.
272 */
273 struct resource_list_x save_head, local_fail_head, *list;
274 struct resource_list *l;
275
276 /* Check if optional add_size is there */
277 if (!realloc_head || !realloc_head->next)
278 goto requested_and_reassign;
279
280 /* Save original start, end, flags etc at first */
281 save_head.next = NULL;
282 for (l = head->next; l; l = l->next)
283 if (add_to_list(&save_head, l->dev, l->res, 0, 0)) {
284 free_list(resource_list_x, &save_head);
285 goto requested_and_reassign;
286 }
287
288 /* Update res in head list with add_size in realloc_head list */
289 for (l = head->next; l; l = l->next)
290 l->res->end += get_res_add_size(realloc_head, l->res);
291
292 /* Try updated head list with add_size added */
293 local_fail_head.next = NULL;
294 assign_requested_resources_sorted(head, &local_fail_head);
295
296 /* all assigned with add_size ? */
297 if (!local_fail_head.next) {
298 /* Remove head list from realloc_head list */
299 for (l = head->next; l; l = l->next)
300 remove_from_list(realloc_head, l->res);
301 free_list(resource_list_x, &save_head);
302 free_list(resource_list, head);
303 return;
304 }
305
306 free_list(resource_list_x, &local_fail_head);
307 /* Release assigned resource */
308 for (l = head->next; l; l = l->next)
309 if (l->res->parent)
310 release_resource(l->res);
311 /* Restore start/end/flags from saved list */
312 for (list = save_head.next; list; list = list->next) {
313 struct resource *res = list->res;
314
315 res->start = list->start;
316 res->end = list->end;
317 res->flags = list->flags;
318 }
319 free_list(resource_list_x, &save_head);
320
321requested_and_reassign:
Ram Paic8adf9a2011-02-14 17:43:20 -0800322 /* Satisfy the must-have resource requests */
323 assign_requested_resources_sorted(head, fail_head);
324
Ram Pai0a2daa12011-07-25 13:08:41 -0700325 /* Try to satisfy any additional optional resource
Ram Paic8adf9a2011-02-14 17:43:20 -0800326 requests */
Ram Pai9e8bf932011-07-25 13:08:42 -0700327 if (realloc_head)
328 reassign_resources_sorted(realloc_head, head);
Ram Paic8adf9a2011-02-14 17:43:20 -0800329 free_list(resource_list, head);
330}
331
Yinghai Lu6841ec62010-01-22 01:02:25 -0800332static void pdev_assign_resources_sorted(struct pci_dev *dev,
333 struct resource_list_x *fail_head)
334{
335 struct resource_list head;
336
337 head.next = NULL;
338 __dev_sort_resources(dev, &head);
Ram Paic8adf9a2011-02-14 17:43:20 -0800339 __assign_resources_sorted(&head, NULL, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800340
341}
342
343static void pbus_assign_resources_sorted(const struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700344 struct resource_list_x *realloc_head,
Yinghai Lu6841ec62010-01-22 01:02:25 -0800345 struct resource_list_x *fail_head)
346{
347 struct pci_dev *dev;
348 struct resource_list head;
349
350 head.next = NULL;
351 list_for_each_entry(dev, &bus->devices, bus_list)
352 __dev_sort_resources(dev, &head);
353
Ram Pai9e8bf932011-07-25 13:08:42 -0700354 __assign_resources_sorted(&head, realloc_head, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800355}
356
Dominik Brodowskib3743fa2005-09-09 13:03:23 -0700357void pci_setup_cardbus(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358{
359 struct pci_dev *bridge = bus->self;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600360 struct resource *res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 struct pci_bus_region region;
362
Bjorn Helgaas865df572009-11-04 10:32:57 -0700363 dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
364 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600366 res = bus->resource[0];
367 pcibios_resource_to_bus(bridge, &region, res);
368 if (res->flags & IORESOURCE_IO) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 /*
370 * The IO resource is allocated a range twice as large as it
371 * would normally need. This allows us to set both IO regs.
372 */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600373 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
375 region.start);
376 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
377 region.end);
378 }
379
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600380 res = bus->resource[1];
381 pcibios_resource_to_bus(bridge, &region, res);
382 if (res->flags & IORESOURCE_IO) {
383 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
385 region.start);
386 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
387 region.end);
388 }
389
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600390 res = bus->resource[2];
391 pcibios_resource_to_bus(bridge, &region, res);
392 if (res->flags & IORESOURCE_MEM) {
393 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
395 region.start);
396 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
397 region.end);
398 }
399
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600400 res = bus->resource[3];
401 pcibios_resource_to_bus(bridge, &region, res);
402 if (res->flags & IORESOURCE_MEM) {
403 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
405 region.start);
406 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
407 region.end);
408 }
409}
Dominik Brodowskib3743fa2005-09-09 13:03:23 -0700410EXPORT_SYMBOL(pci_setup_cardbus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
412/* Initialize bridges with base/limit values we have collected.
413 PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
414 requires that if there is no I/O ports or memory behind the
415 bridge, corresponding range must be turned off by writing base
416 value greater than limit to the bridge's base/limit registers.
417
418 Note: care must be taken when updating I/O base/limit registers
419 of bridges which support 32-bit I/O. This update requires two
420 config space writes, so it's quite possible that an I/O window of
421 the bridge will have some undesirable address (e.g. 0) after the
422 first write. Ditto 64-bit prefetchable MMIO. */
Yinghai Lu7cc59972009-12-22 15:02:21 -0800423static void pci_setup_bridge_io(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424{
425 struct pci_dev *bridge = bus->self;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600426 struct resource *res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 struct pci_bus_region region;
Yinghai Lu7cc59972009-12-22 15:02:21 -0800428 u32 l, io_upper16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430 /* Set up the top and bottom of the PCI I/O segment for this bus. */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600431 res = bus->resource[0];
432 pcibios_resource_to_bus(bridge, &region, res);
433 if (res->flags & IORESOURCE_IO) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
435 l &= 0xffff0000;
436 l |= (region.start >> 8) & 0x00f0;
437 l |= region.end & 0xf000;
438 /* Set up upper 16 bits of I/O base/limit. */
439 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600440 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800441 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 /* Clear upper 16 bits of I/O base/limit. */
443 io_upper16 = 0;
444 l = 0x00f0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
446 /* Temporarily disable the I/O range before updating PCI_IO_BASE. */
447 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
448 /* Update lower 16 bits of I/O base/limit. */
449 pci_write_config_dword(bridge, PCI_IO_BASE, l);
450 /* Update upper 16 bits of I/O base/limit. */
451 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800452}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453
Yinghai Lu7cc59972009-12-22 15:02:21 -0800454static void pci_setup_bridge_mmio(struct pci_bus *bus)
455{
456 struct pci_dev *bridge = bus->self;
457 struct resource *res;
458 struct pci_bus_region region;
459 u32 l;
460
461 /* Set up the top and bottom of the PCI Memory segment for this bus. */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600462 res = bus->resource[1];
463 pcibios_resource_to_bus(bridge, &region, res);
464 if (res->flags & IORESOURCE_MEM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 l = (region.start >> 16) & 0xfff0;
466 l |= region.end & 0xfff00000;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600467 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800468 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 l = 0x0000fff0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 }
471 pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800472}
473
474static void pci_setup_bridge_mmio_pref(struct pci_bus *bus)
475{
476 struct pci_dev *bridge = bus->self;
477 struct resource *res;
478 struct pci_bus_region region;
479 u32 l, bu, lu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
481 /* Clear out the upper 32 bits of PREF limit.
482 If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily
483 disables PREF range, which is ok. */
484 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
485
486 /* Set up PREF base/limit. */
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100487 bu = lu = 0;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600488 res = bus->resource[2];
489 pcibios_resource_to_bus(bridge, &region, res);
490 if (res->flags & IORESOURCE_PREFETCH) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 l = (region.start >> 16) & 0xfff0;
492 l |= region.end & 0xfff00000;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600493 if (res->flags & IORESOURCE_MEM_64) {
Yinghai Lu1f82de12009-04-23 20:48:32 -0700494 bu = upper_32_bits(region.start);
495 lu = upper_32_bits(region.end);
Yinghai Lu1f82de12009-04-23 20:48:32 -0700496 }
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600497 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800498 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 l = 0x0000fff0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 }
501 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
502
Alex Williamson59353ea2009-11-30 14:51:44 -0700503 /* Set the upper 32 bits of PREF base & limit. */
504 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
505 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800506}
507
508static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
509{
510 struct pci_dev *bridge = bus->self;
511
Yinghai Lu7cc59972009-12-22 15:02:21 -0800512 dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
513 bus->secondary, bus->subordinate);
514
515 if (type & IORESOURCE_IO)
516 pci_setup_bridge_io(bus);
517
518 if (type & IORESOURCE_MEM)
519 pci_setup_bridge_mmio(bus);
520
521 if (type & IORESOURCE_PREFETCH)
522 pci_setup_bridge_mmio_pref(bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
524 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
525}
526
Benjamin Herrenschmidte2444272011-09-11 14:08:38 -0300527void pci_setup_bridge(struct pci_bus *bus)
Yinghai Lu7cc59972009-12-22 15:02:21 -0800528{
529 unsigned long type = IORESOURCE_IO | IORESOURCE_MEM |
530 IORESOURCE_PREFETCH;
531
532 __pci_setup_bridge(bus, type);
533}
534
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535/* Check whether the bridge supports optional I/O and
536 prefetchable memory ranges. If not, the respective
537 base/limit registers must be read-only and read as 0. */
Sam Ravnborg96bde062007-03-26 21:53:30 -0800538static void pci_bridge_check_ranges(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539{
540 u16 io;
541 u32 pmem;
542 struct pci_dev *bridge = bus->self;
543 struct resource *b_res;
544
545 b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
546 b_res[1].flags |= IORESOURCE_MEM;
547
548 pci_read_config_word(bridge, PCI_IO_BASE, &io);
549 if (!io) {
550 pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
551 pci_read_config_word(bridge, PCI_IO_BASE, &io);
552 pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
553 }
554 if (io)
555 b_res[0].flags |= IORESOURCE_IO;
556 /* DECchip 21050 pass 2 errata: the bridge may miss an address
557 disconnect boundary by one PCI data phase.
558 Workaround: do not use prefetching on this device. */
559 if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
560 return;
561 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
562 if (!pmem) {
563 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
564 0xfff0fff0);
565 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
566 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
567 }
Yinghai Lu1f82de12009-04-23 20:48:32 -0700568 if (pmem) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
Yinghai Lu99586102010-01-22 01:02:28 -0800570 if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
571 PCI_PREF_RANGE_TYPE_64) {
Yinghai Lu1f82de12009-04-23 20:48:32 -0700572 b_res[2].flags |= IORESOURCE_MEM_64;
Yinghai Lu99586102010-01-22 01:02:28 -0800573 b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
574 }
Yinghai Lu1f82de12009-04-23 20:48:32 -0700575 }
576
577 /* double check if bridge does support 64 bit pref */
578 if (b_res[2].flags & IORESOURCE_MEM_64) {
579 u32 mem_base_hi, tmp;
580 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
581 &mem_base_hi);
582 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
583 0xffffffff);
584 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
585 if (!tmp)
586 b_res[2].flags &= ~IORESOURCE_MEM_64;
587 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
588 mem_base_hi);
589 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590}
591
592/* Helper function for sizing routines: find first available
593 bus resource of a given type. Note: we intentionally skip
594 the bus resources which have already been assigned (that is,
595 have non-NULL parent resource). */
Sam Ravnborg96bde062007-03-26 21:53:30 -0800596static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597{
598 int i;
599 struct resource *r;
600 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
601 IORESOURCE_PREFETCH;
602
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -0700603 pci_bus_for_each_resource(bus, r, i) {
Ivan Kokshaysky299de032005-06-15 18:59:27 +0400604 if (r == &ioport_resource || r == &iomem_resource)
605 continue;
Jesse Barnes55a10982009-10-27 09:39:18 -0700606 if (r && (r->flags & type_mask) == type && !r->parent)
607 return r;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 }
609 return NULL;
610}
611
Ram Pai13583b12011-02-14 17:43:17 -0800612static resource_size_t calculate_iosize(resource_size_t size,
613 resource_size_t min_size,
614 resource_size_t size1,
615 resource_size_t old_size,
616 resource_size_t align)
617{
618 if (size < min_size)
619 size = min_size;
620 if (old_size == 1 )
621 old_size = 0;
622 /* To be fixed in 2.5: we should have sort of HAVE_ISA
623 flag in the struct pci_bus. */
624#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
625 size = (size & 0xff) + ((size & ~0xffUL) << 2);
626#endif
627 size = ALIGN(size + size1, align);
628 if (size < old_size)
629 size = old_size;
630 return size;
631}
632
633static resource_size_t calculate_memsize(resource_size_t size,
634 resource_size_t min_size,
635 resource_size_t size1,
636 resource_size_t old_size,
637 resource_size_t align)
638{
639 if (size < min_size)
640 size = min_size;
641 if (old_size == 1 )
642 old_size = 0;
643 if (size < old_size)
644 size = old_size;
645 size = ALIGN(size + size1, align);
646 return size;
647}
648
Ram Paic8adf9a2011-02-14 17:43:20 -0800649/**
650 * pbus_size_io() - size the io window of a given bus
651 *
652 * @bus : the bus
653 * @min_size : the minimum io window that must to be allocated
654 * @add_size : additional optional io window
Ram Pai9e8bf932011-07-25 13:08:42 -0700655 * @realloc_head : track the additional io window on this list
Ram Paic8adf9a2011-02-14 17:43:20 -0800656 *
657 * Sizing the IO windows of the PCI-PCI bridge is trivial,
658 * since these windows have 4K granularity and the IO ranges
659 * of non-bridge PCI devices are limited to 256 bytes.
660 * We must be careful with the ISA aliasing though.
661 */
662static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
Ram Pai9e8bf932011-07-25 13:08:42 -0700663 resource_size_t add_size, struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664{
665 struct pci_dev *dev;
666 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
Ram Paic8adf9a2011-02-14 17:43:20 -0800667 unsigned long size = 0, size0 = 0, size1 = 0;
Yinghai Lube768912011-07-25 13:08:38 -0700668 resource_size_t children_add_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
670 if (!b_res)
671 return;
672
673 list_for_each_entry(dev, &bus->devices, bus_list) {
674 int i;
675
676 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
677 struct resource *r = &dev->resource[i];
678 unsigned long r_size;
679
680 if (r->parent || !(r->flags & IORESOURCE_IO))
681 continue;
Zhao, Yu022edd82008-10-13 19:24:28 +0800682 r_size = resource_size(r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683
684 if (r_size < 0x400)
685 /* Might be re-aligned for ISA */
686 size += r_size;
687 else
688 size1 += r_size;
Yinghai Lube768912011-07-25 13:08:38 -0700689
Ram Pai9e8bf932011-07-25 13:08:42 -0700690 if (realloc_head)
691 children_add_size += get_res_add_size(realloc_head, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 }
693 }
Ram Paic8adf9a2011-02-14 17:43:20 -0800694 size0 = calculate_iosize(size, min_size, size1,
Ram Pai13583b12011-02-14 17:43:17 -0800695 resource_size(b_res), 4096);
Yinghai Lube768912011-07-25 13:08:38 -0700696 if (children_add_size > add_size)
697 add_size = children_add_size;
Ram Pai9e8bf932011-07-25 13:08:42 -0700698 size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
Yinghai Lua4ac9fe2012-01-21 02:08:17 -0800699 calculate_iosize(size, min_size, add_size + size1,
Ram Paic8adf9a2011-02-14 17:43:20 -0800700 resource_size(b_res), 4096);
701 if (!size0 && !size1) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700702 if (b_res->start || b_res->end)
703 dev_info(&bus->self->dev, "disabling bridge window "
704 "%pR to [bus %02x-%02x] (unused)\n", b_res,
705 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 b_res->flags = 0;
707 return;
708 }
709 /* Alignment of the IO window is always 4K */
710 b_res->start = 4096;
Ram Paic8adf9a2011-02-14 17:43:20 -0800711 b_res->end = b_res->start + size0 - 1;
Ivan Kokshaysky88452562008-03-30 19:50:14 +0400712 b_res->flags |= IORESOURCE_STARTALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700713 if (size1 > size0 && realloc_head)
714 add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715}
716
Ram Paic8adf9a2011-02-14 17:43:20 -0800717/**
718 * pbus_size_mem() - size the memory window of a given bus
719 *
720 * @bus : the bus
721 * @min_size : the minimum memory window that must to be allocated
722 * @add_size : additional optional memory window
Ram Pai9e8bf932011-07-25 13:08:42 -0700723 * @realloc_head : track the additional memory window on this list
Ram Paic8adf9a2011-02-14 17:43:20 -0800724 *
725 * Calculate the size of the bus and minimal alignment which
726 * guarantees that all child resources fit in this size.
727 */
Eric W. Biederman28760482009-09-09 14:09:24 -0700728static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
Ram Paic8adf9a2011-02-14 17:43:20 -0800729 unsigned long type, resource_size_t min_size,
730 resource_size_t add_size,
Ram Pai9e8bf932011-07-25 13:08:42 -0700731 struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732{
733 struct pci_dev *dev;
Ram Paic8adf9a2011-02-14 17:43:20 -0800734 resource_size_t min_align, align, size, size0, size1;
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100735 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 int order, max_order;
737 struct resource *b_res = find_free_bus_resource(bus, type);
Yinghai Lu1f82de12009-04-23 20:48:32 -0700738 unsigned int mem64_mask = 0;
Yinghai Lube768912011-07-25 13:08:38 -0700739 resource_size_t children_add_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 if (!b_res)
742 return 0;
743
744 memset(aligns, 0, sizeof(aligns));
745 max_order = 0;
746 size = 0;
747
Yinghai Lu1f82de12009-04-23 20:48:32 -0700748 mem64_mask = b_res->flags & IORESOURCE_MEM_64;
749 b_res->flags &= ~IORESOURCE_MEM_64;
750
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 list_for_each_entry(dev, &bus->devices, bus_list) {
752 int i;
Yinghai Lu1f82de12009-04-23 20:48:32 -0700753
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
755 struct resource *r = &dev->resource[i];
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100756 resource_size_t r_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757
758 if (r->parent || (r->flags & mask) != type)
759 continue;
Zhao, Yu022edd82008-10-13 19:24:28 +0800760 r_size = resource_size(r);
Yinghai Lu2aceefc2011-07-25 13:08:40 -0700761#ifdef CONFIG_PCI_IOV
762 /* put SRIOV requested res to the optional list */
Ram Pai9e8bf932011-07-25 13:08:42 -0700763 if (realloc_head && i >= PCI_IOV_RESOURCES &&
Yinghai Lu2aceefc2011-07-25 13:08:40 -0700764 i <= PCI_IOV_RESOURCE_END) {
765 r->end = r->start - 1;
Ram Pai9e8bf932011-07-25 13:08:42 -0700766 add_to_list(realloc_head, dev, r, r_size, 0/* dont' care */);
Yinghai Lu2aceefc2011-07-25 13:08:40 -0700767 children_add_size += r_size;
768 continue;
769 }
770#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 /* For bridges size != alignment */
Chris Wright6faf17f2009-08-28 13:00:06 -0700772 align = pci_resource_alignment(dev, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 order = __ffs(align) - 20;
774 if (order > 11) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700775 dev_warn(&dev->dev, "disabling BAR %d: %pR "
776 "(bad alignment %#llx)\n", i, r,
777 (unsigned long long) align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 r->flags = 0;
779 continue;
780 }
781 size += r_size;
782 if (order < 0)
783 order = 0;
784 /* Exclude ranges with size > align from
785 calculation of the alignment. */
786 if (r_size == align)
787 aligns[order] += align;
788 if (order > max_order)
789 max_order = order;
Yinghai Lu1f82de12009-04-23 20:48:32 -0700790 mem64_mask &= r->flags & IORESOURCE_MEM_64;
Yinghai Lube768912011-07-25 13:08:38 -0700791
Ram Pai9e8bf932011-07-25 13:08:42 -0700792 if (realloc_head)
793 children_add_size += get_res_add_size(realloc_head, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 }
795 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 align = 0;
797 min_align = 0;
798 for (order = 0; order <= max_order; order++) {
Jeremy Fitzhardinge8308c542008-09-11 01:31:50 -0700799 resource_size_t align1 = 1;
800
801 align1 <<= (order + 20);
802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 if (!align)
804 min_align = align1;
Milind Arun Choudhary6f6f8c22007-07-09 11:55:51 -0700805 else if (ALIGN(align + min_align, min_align) < align1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 min_align = align1 >> 1;
807 align += aligns[order];
808 }
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700809 size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
Yinghai Lube768912011-07-25 13:08:38 -0700810 if (children_add_size > add_size)
811 add_size = children_add_size;
Ram Pai9e8bf932011-07-25 13:08:42 -0700812 size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
Yinghai Lua4ac9fe2012-01-21 02:08:17 -0800813 calculate_memsize(size, min_size, add_size,
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700814 resource_size(b_res), min_align);
Ram Paic8adf9a2011-02-14 17:43:20 -0800815 if (!size0 && !size1) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700816 if (b_res->start || b_res->end)
817 dev_info(&bus->self->dev, "disabling bridge window "
818 "%pR to [bus %02x-%02x] (unused)\n", b_res,
819 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 b_res->flags = 0;
821 return 1;
822 }
823 b_res->start = min_align;
Ram Paic8adf9a2011-02-14 17:43:20 -0800824 b_res->end = size0 + min_align - 1;
825 b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask;
Ram Pai9e8bf932011-07-25 13:08:42 -0700826 if (size1 > size0 && realloc_head)
827 add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 return 1;
829}
830
Ram Pai0a2daa12011-07-25 13:08:41 -0700831unsigned long pci_cardbus_resource_alignment(struct resource *res)
832{
833 if (res->flags & IORESOURCE_IO)
834 return pci_cardbus_io_size;
835 if (res->flags & IORESOURCE_MEM)
836 return pci_cardbus_mem_size;
837 return 0;
838}
839
840static void pci_bus_size_cardbus(struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700841 struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842{
843 struct pci_dev *bridge = bus->self;
844 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
845 u16 ctrl;
846
847 /*
848 * Reserve some resources for CardBus. We reserve
849 * a fixed amount of bus space for CardBus bridges.
850 */
Linus Torvalds934b7022008-04-22 18:16:30 -0700851 b_res[0].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700852 b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700853 if (realloc_head)
854 add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
Linus Torvalds934b7022008-04-22 18:16:30 -0700856 b_res[1].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700857 b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700858 if (realloc_head)
859 add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
861 /*
862 * Check whether prefetchable memory is supported
863 * by this bridge.
864 */
865 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
866 if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) {
867 ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
868 pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl);
869 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
870 }
871
872 /*
873 * If we have prefetchable memory support, allocate
874 * two regions. Otherwise, allocate one region of
875 * twice the size.
876 */
877 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
Linus Torvalds934b7022008-04-22 18:16:30 -0700878 b_res[2].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700879 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700880 if (realloc_head)
881 add_to_list(realloc_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Linus Torvalds934b7022008-04-22 18:16:30 -0700883 b_res[3].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700884 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700885 if (realloc_head)
886 add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 } else {
Linus Torvalds934b7022008-04-22 18:16:30 -0700888 b_res[3].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700889 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700890 if (realloc_head)
891 add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 }
Ram Pai0a2daa12011-07-25 13:08:41 -0700893
894 /* set the size of the resource to zero, so that the resource does not
895 * get assigned during required-resource allocation cycle but gets assigned
896 * during the optional-resource allocation cycle.
897 */
898 b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1;
899 b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900}
901
Ram Paic8adf9a2011-02-14 17:43:20 -0800902void __ref __pci_bus_size_bridges(struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700903 struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904{
905 struct pci_dev *dev;
906 unsigned long mask, prefmask;
Ram Paic8adf9a2011-02-14 17:43:20 -0800907 resource_size_t additional_mem_size = 0, additional_io_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908
909 list_for_each_entry(dev, &bus->devices, bus_list) {
910 struct pci_bus *b = dev->subordinate;
911 if (!b)
912 continue;
913
914 switch (dev->class >> 8) {
915 case PCI_CLASS_BRIDGE_CARDBUS:
Ram Pai9e8bf932011-07-25 13:08:42 -0700916 pci_bus_size_cardbus(b, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 break;
918
919 case PCI_CLASS_BRIDGE_PCI:
920 default:
Ram Pai9e8bf932011-07-25 13:08:42 -0700921 __pci_bus_size_bridges(b, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 break;
923 }
924 }
925
926 /* The root bus? */
927 if (!bus->self)
928 return;
929
930 switch (bus->self->class >> 8) {
931 case PCI_CLASS_BRIDGE_CARDBUS:
932 /* don't size cardbuses yet. */
933 break;
934
935 case PCI_CLASS_BRIDGE_PCI:
936 pci_bridge_check_ranges(bus);
Eric W. Biederman28760482009-09-09 14:09:24 -0700937 if (bus->self->is_hotplug_bridge) {
Ram Paic8adf9a2011-02-14 17:43:20 -0800938 additional_io_size = pci_hotplug_io_size;
939 additional_mem_size = pci_hotplug_mem_size;
Eric W. Biederman28760482009-09-09 14:09:24 -0700940 }
Ram Paic8adf9a2011-02-14 17:43:20 -0800941 /*
942 * Follow thru
943 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 default:
Ram Pai9e8bf932011-07-25 13:08:42 -0700945 pbus_size_io(bus, 0, additional_io_size, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 /* If the bridge supports prefetchable range, size it
947 separately. If it doesn't, or its prefetchable window
948 has already been allocated by arch code, try
949 non-prefetchable range for both types of PCI memory
950 resources. */
951 mask = IORESOURCE_MEM;
952 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
Ram Pai9e8bf932011-07-25 13:08:42 -0700953 if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, realloc_head))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 mask = prefmask; /* Success, size non-prefetch only. */
Eric W. Biederman28760482009-09-09 14:09:24 -0700955 else
Ram Paic8adf9a2011-02-14 17:43:20 -0800956 additional_mem_size += additional_mem_size;
Ram Pai9e8bf932011-07-25 13:08:42 -0700957 pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 break;
959 }
960}
Ram Paic8adf9a2011-02-14 17:43:20 -0800961
962void __ref pci_bus_size_bridges(struct pci_bus *bus)
963{
964 __pci_bus_size_bridges(bus, NULL);
965}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966EXPORT_SYMBOL(pci_bus_size_bridges);
967
Yinghai Lu568ddef2010-01-22 01:02:21 -0800968static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700969 struct resource_list_x *realloc_head,
Yinghai Lu568ddef2010-01-22 01:02:21 -0800970 struct resource_list_x *fail_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971{
972 struct pci_bus *b;
973 struct pci_dev *dev;
974
Ram Pai9e8bf932011-07-25 13:08:42 -0700975 pbus_assign_resources_sorted(bus, realloc_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 list_for_each_entry(dev, &bus->devices, bus_list) {
978 b = dev->subordinate;
979 if (!b)
980 continue;
981
Ram Pai9e8bf932011-07-25 13:08:42 -0700982 __pci_bus_assign_resources(b, realloc_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
984 switch (dev->class >> 8) {
985 case PCI_CLASS_BRIDGE_PCI:
Yinghai Lu6841ec62010-01-22 01:02:25 -0800986 if (!pci_is_enabled(dev))
987 pci_setup_bridge(b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 break;
989
990 case PCI_CLASS_BRIDGE_CARDBUS:
991 pci_setup_cardbus(b);
992 break;
993
994 default:
Bjorn Helgaas80ccba12008-06-13 10:52:11 -0600995 dev_info(&dev->dev, "not setting up bridge for bus "
996 "%04x:%02x\n", pci_domain_nr(b), b->number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 break;
998 }
999 }
1000}
Yinghai Lu568ddef2010-01-22 01:02:21 -08001001
1002void __ref pci_bus_assign_resources(const struct pci_bus *bus)
1003{
Ram Paic8adf9a2011-02-14 17:43:20 -08001004 __pci_bus_assign_resources(bus, NULL, NULL);
Yinghai Lu568ddef2010-01-22 01:02:21 -08001005}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006EXPORT_SYMBOL(pci_bus_assign_resources);
1007
Yinghai Lu6841ec62010-01-22 01:02:25 -08001008static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
1009 struct resource_list_x *fail_head)
1010{
1011 struct pci_bus *b;
1012
1013 pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
1014
1015 b = bridge->subordinate;
1016 if (!b)
1017 return;
1018
Ram Paic8adf9a2011-02-14 17:43:20 -08001019 __pci_bus_assign_resources(b, NULL, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -08001020
1021 switch (bridge->class >> 8) {
1022 case PCI_CLASS_BRIDGE_PCI:
1023 pci_setup_bridge(b);
1024 break;
1025
1026 case PCI_CLASS_BRIDGE_CARDBUS:
1027 pci_setup_cardbus(b);
1028 break;
1029
1030 default:
1031 dev_info(&bridge->dev, "not setting up bridge for bus "
1032 "%04x:%02x\n", pci_domain_nr(b), b->number);
1033 break;
1034 }
1035}
Yinghai Lu5009b462010-01-22 01:02:20 -08001036static void pci_bridge_release_resources(struct pci_bus *bus,
1037 unsigned long type)
1038{
1039 int idx;
1040 bool changed = false;
1041 struct pci_dev *dev;
1042 struct resource *r;
1043 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1044 IORESOURCE_PREFETCH;
1045
1046 dev = bus->self;
1047 for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END;
1048 idx++) {
1049 r = &dev->resource[idx];
1050 if ((r->flags & type_mask) != type)
1051 continue;
1052 if (!r->parent)
1053 continue;
1054 /*
1055 * if there are children under that, we should release them
1056 * all
1057 */
1058 release_child_resources(r);
1059 if (!release_resource(r)) {
1060 dev_printk(KERN_DEBUG, &dev->dev,
1061 "resource %d %pR released\n", idx, r);
1062 /* keep the old size */
1063 r->end = resource_size(r) - 1;
1064 r->start = 0;
1065 r->flags = 0;
1066 changed = true;
1067 }
1068 }
1069
1070 if (changed) {
1071 /* avoiding touch the one without PREF */
1072 if (type & IORESOURCE_PREFETCH)
1073 type = IORESOURCE_PREFETCH;
1074 __pci_setup_bridge(bus, type);
1075 }
1076}
1077
1078enum release_type {
1079 leaf_only,
1080 whole_subtree,
1081};
1082/*
1083 * try to release pci bridge resources that is from leaf bridge,
1084 * so we can allocate big new one later
1085 */
1086static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
1087 unsigned long type,
1088 enum release_type rel_type)
1089{
1090 struct pci_dev *dev;
1091 bool is_leaf_bridge = true;
1092
1093 list_for_each_entry(dev, &bus->devices, bus_list) {
1094 struct pci_bus *b = dev->subordinate;
1095 if (!b)
1096 continue;
1097
1098 is_leaf_bridge = false;
1099
1100 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
1101 continue;
1102
1103 if (rel_type == whole_subtree)
1104 pci_bus_release_bridge_resources(b, type,
1105 whole_subtree);
1106 }
1107
1108 if (pci_is_root_bus(bus))
1109 return;
1110
1111 if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
1112 return;
1113
1114 if ((rel_type == whole_subtree) || is_leaf_bridge)
1115 pci_bridge_release_resources(bus, type);
1116}
1117
Yinghai Lu76fbc262008-06-23 20:33:06 +02001118static void pci_bus_dump_res(struct pci_bus *bus)
1119{
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001120 struct resource *res;
1121 int i;
Yinghai Lu76fbc262008-06-23 20:33:06 +02001122
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001123 pci_bus_for_each_resource(bus, res, i) {
Yinghai Lu7c9342b2009-12-22 15:02:24 -08001124 if (!res || !res->end || !res->flags)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001125 continue;
1126
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -06001127 dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001128 }
1129}
1130
1131static void pci_bus_dump_resources(struct pci_bus *bus)
1132{
1133 struct pci_bus *b;
1134 struct pci_dev *dev;
1135
1136
1137 pci_bus_dump_res(bus);
1138
1139 list_for_each_entry(dev, &bus->devices, bus_list) {
1140 b = dev->subordinate;
1141 if (!b)
1142 continue;
1143
1144 pci_bus_dump_resources(b);
1145 }
1146}
1147
Yinghai Luda7822e2011-05-12 17:11:37 -07001148static int __init pci_bus_get_depth(struct pci_bus *bus)
1149{
1150 int depth = 0;
1151 struct pci_dev *dev;
1152
1153 list_for_each_entry(dev, &bus->devices, bus_list) {
1154 int ret;
1155 struct pci_bus *b = dev->subordinate;
1156 if (!b)
1157 continue;
1158
1159 ret = pci_bus_get_depth(b);
1160 if (ret + 1 > depth)
1161 depth = ret + 1;
1162 }
1163
1164 return depth;
1165}
1166static int __init pci_get_max_depth(void)
1167{
1168 int depth = 0;
1169 struct pci_bus *bus;
1170
1171 list_for_each_entry(bus, &pci_root_buses, node) {
1172 int ret;
1173
1174 ret = pci_bus_get_depth(bus);
1175 if (ret > depth)
1176 depth = ret;
1177 }
1178
1179 return depth;
1180}
1181
Ram Paif483d392011-07-07 11:19:10 -07001182
Yinghai Luda7822e2011-05-12 17:11:37 -07001183/*
1184 * first try will not touch pci bridge res
1185 * second and later try will clear small leaf bridge res
1186 * will stop till to the max deepth if can not find good one
1187 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188void __init
1189pci_assign_unassigned_resources(void)
1190{
1191 struct pci_bus *bus;
Ram Pai9e8bf932011-07-25 13:08:42 -07001192 struct resource_list_x realloc_list; /* list of resources that
Ram Paic8adf9a2011-02-14 17:43:20 -08001193 want additional resources */
Yinghai Luda7822e2011-05-12 17:11:37 -07001194 int tried_times = 0;
1195 enum release_type rel_type = leaf_only;
1196 struct resource_list_x head, *list;
1197 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1198 IORESOURCE_PREFETCH;
1199 unsigned long failed_type;
1200 int max_depth = pci_get_max_depth();
1201 int pci_try_num;
1202
1203
1204 head.next = NULL;
Ram Pai9e8bf932011-07-25 13:08:42 -07001205 realloc_list.next = NULL;
Yinghai Luda7822e2011-05-12 17:11:37 -07001206
1207 pci_try_num = max_depth + 1;
1208 printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
1209 max_depth, pci_try_num);
1210
1211again:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 /* Depth first, calculate sizes and alignments of all
1213 subordinate buses. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001214 list_for_each_entry(bus, &pci_root_buses, node)
Ram Pai9e8bf932011-07-25 13:08:42 -07001215 __pci_bus_size_bridges(bus, &realloc_list);
Ram Paic8adf9a2011-02-14 17:43:20 -08001216
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 /* Depth last, allocate resources and update the hardware. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001218 list_for_each_entry(bus, &pci_root_buses, node)
Ram Pai9e8bf932011-07-25 13:08:42 -07001219 __pci_bus_assign_resources(bus, &realloc_list, &head);
1220 BUG_ON(realloc_list.next);
Yinghai Luda7822e2011-05-12 17:11:37 -07001221 tried_times++;
1222
1223 /* any device complain? */
1224 if (!head.next)
1225 goto enable_and_dump;
Ram Paif483d392011-07-07 11:19:10 -07001226
1227 /* don't realloc if asked to do so */
1228 if (!pci_realloc_enabled()) {
1229 free_list(resource_list_x, &head);
1230 goto enable_and_dump;
1231 }
1232
Yinghai Luda7822e2011-05-12 17:11:37 -07001233 failed_type = 0;
1234 for (list = head.next; list;) {
1235 failed_type |= list->flags;
1236 list = list->next;
1237 }
1238 /*
1239 * io port are tight, don't try extra
1240 * or if reach the limit, don't want to try more
1241 */
1242 failed_type &= type_mask;
1243 if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
1244 free_list(resource_list_x, &head);
1245 goto enable_and_dump;
1246 }
1247
1248 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1249 tried_times + 1);
1250
1251 /* third times and later will not check if it is leaf */
1252 if ((tried_times + 1) > 2)
1253 rel_type = whole_subtree;
1254
1255 /*
1256 * Try to release leaf bridge's resources that doesn't fit resource of
1257 * child device under that bridge
1258 */
1259 for (list = head.next; list;) {
1260 bus = list->dev->bus;
1261 pci_bus_release_bridge_resources(bus, list->flags & type_mask,
1262 rel_type);
1263 list = list->next;
1264 }
1265 /* restore size and flags */
1266 for (list = head.next; list;) {
1267 struct resource *res = list->res;
1268
1269 res->start = list->start;
1270 res->end = list->end;
1271 res->flags = list->flags;
1272 if (list->dev->subordinate)
1273 res->flags = 0;
1274
1275 list = list->next;
1276 }
1277 free_list(resource_list_x, &head);
1278
1279 goto again;
1280
1281enable_and_dump:
1282 /* Depth last, update the hardware. */
1283 list_for_each_entry(bus, &pci_root_buses, node)
1284 pci_enable_bridges(bus);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001285
1286 /* dump the resource on buses */
Yinghai Luda7822e2011-05-12 17:11:37 -07001287 list_for_each_entry(bus, &pci_root_buses, node)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001288 pci_bus_dump_resources(bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289}
Yinghai Lu6841ec62010-01-22 01:02:25 -08001290
1291void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
1292{
1293 struct pci_bus *parent = bridge->subordinate;
Yinghai Lu32180e42010-01-22 01:02:27 -08001294 int tried_times = 0;
1295 struct resource_list_x head, *list;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001296 int retval;
Yinghai Lu32180e42010-01-22 01:02:27 -08001297 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1298 IORESOURCE_PREFETCH;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001299
Yinghai Lu32180e42010-01-22 01:02:27 -08001300 head.next = NULL;
1301
1302again:
Yinghai Lu6841ec62010-01-22 01:02:25 -08001303 pci_bus_size_bridges(parent);
Yinghai Lu32180e42010-01-22 01:02:27 -08001304 __pci_bridge_assign_resources(bridge, &head);
Yinghai Lu32180e42010-01-22 01:02:27 -08001305
1306 tried_times++;
1307
1308 if (!head.next)
Yinghai Lu3f579c32010-05-21 14:35:06 -07001309 goto enable_all;
Yinghai Lu32180e42010-01-22 01:02:27 -08001310
1311 if (tried_times >= 2) {
1312 /* still fail, don't need to try more */
Ram Pai094732a2011-02-14 17:43:18 -08001313 free_list(resource_list_x, &head);
Yinghai Lu3f579c32010-05-21 14:35:06 -07001314 goto enable_all;
Yinghai Lu32180e42010-01-22 01:02:27 -08001315 }
1316
1317 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1318 tried_times + 1);
1319
1320 /*
1321 * Try to release leaf bridge's resources that doesn't fit resource of
1322 * child device under that bridge
1323 */
1324 for (list = head.next; list;) {
1325 struct pci_bus *bus = list->dev->bus;
1326 unsigned long flags = list->flags;
1327
1328 pci_bus_release_bridge_resources(bus, flags & type_mask,
1329 whole_subtree);
1330 list = list->next;
1331 }
1332 /* restore size and flags */
1333 for (list = head.next; list;) {
1334 struct resource *res = list->res;
1335
1336 res->start = list->start;
1337 res->end = list->end;
1338 res->flags = list->flags;
1339 if (list->dev->subordinate)
1340 res->flags = 0;
1341
1342 list = list->next;
1343 }
Ram Pai094732a2011-02-14 17:43:18 -08001344 free_list(resource_list_x, &head);
Yinghai Lu32180e42010-01-22 01:02:27 -08001345
1346 goto again;
Yinghai Lu3f579c32010-05-21 14:35:06 -07001347
1348enable_all:
1349 retval = pci_reenable_device(bridge);
1350 pci_set_master(bridge);
1351 pci_enable_bridges(parent);
Yinghai Lu6841ec62010-01-22 01:02:25 -08001352}
1353EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);