aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index a00f85471b6e..b636e245445d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -58,7 +58,6 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
58 res = list->res; 58 res = list->res;
59 idx = res - &list->dev->resource[0]; 59 idx = res - &list->dev->resource[0];
60 if (pci_assign_resource(list->dev, idx)) { 60 if (pci_assign_resource(list->dev, idx)) {
61 /* FIXME: get rid of this */
62 res->start = 0; 61 res->start = 0;
63 res->end = 0; 62 res->end = 0;
64 res->flags = 0; 63 res->flags = 0;
@@ -143,6 +142,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
143 struct pci_dev *bridge = bus->self; 142 struct pci_dev *bridge = bus->self;
144 struct pci_bus_region region; 143 struct pci_bus_region region;
145 u32 l, bu, lu, io_upper16; 144 u32 l, bu, lu, io_upper16;
145 int pref_mem64;
146 146
147 if (pci_is_enabled(bridge)) 147 if (pci_is_enabled(bridge))
148 return; 148 return;
@@ -198,16 +198,22 @@ static void pci_setup_bridge(struct pci_bus *bus)
198 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); 198 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
199 199
200 /* Set up PREF base/limit. */ 200 /* Set up PREF base/limit. */
201 pref_mem64 = 0;
201 bu = lu = 0; 202 bu = lu = 0;
202 pcibios_resource_to_bus(bridge, &region, bus->resource[2]); 203 pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
203 if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { 204 if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
205 int width = 8;
204 l = (region.start >> 16) & 0xfff0; 206 l = (region.start >> 16) & 0xfff0;
205 l |= region.end & 0xfff00000; 207 l |= region.end & 0xfff00000;
206 bu = upper_32_bits(region.start); 208 if (bus->resource[2]->flags & IORESOURCE_MEM_64) {
207 lu = upper_32_bits(region.end); 209 pref_mem64 = 1;
208 dev_info(&bridge->dev, " PREFETCH window: %#016llx-%#016llx\n", 210 bu = upper_32_bits(region.start);
209 (unsigned long long)region.start, 211 lu = upper_32_bits(region.end);
210 (unsigned long long)region.end); 212 width = 16;
213 }
214 dev_info(&bridge->dev, " PREFETCH window: %#0*llx-%#0*llx\n",
215 width, (unsigned long long)region.start,
216 width, (unsigned long long)region.end);
211 } 217 }
212 else { 218 else {
213 l = 0x0000fff0; 219 l = 0x0000fff0;
@@ -215,9 +221,11 @@ static void pci_setup_bridge(struct pci_bus *bus)
215 } 221 }
216 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); 222 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
217 223
218 /* Set the upper 32 bits of PREF base & limit. */ 224 if (pref_mem64) {
219 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); 225 /* Set the upper 32 bits of PREF base & limit. */
220 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); 226 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
227 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
228 }
221 229
222 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); 230 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
223} 231}
@@ -255,8 +263,25 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
255 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); 263 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
256 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); 264 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
257 } 265 }
258 if (pmem) 266 if (pmem) {
259 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; 267 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
268 if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
269 b_res[2].flags |= IORESOURCE_MEM_64;
270 }
271
272 /* double check if bridge does support 64 bit pref */
273 if (b_res[2].flags & IORESOURCE_MEM_64) {
274 u32 mem_base_hi, tmp;
275 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
276 &mem_base_hi);
277 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
278 0xffffffff);
279 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
280 if (!tmp)
281 b_res[2].flags &= ~IORESOURCE_MEM_64;
282 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
283 mem_base_hi);
284 }
260} 285}
261 286
262/* Helper function for sizing routines: find first available 287/* Helper function for sizing routines: find first available
@@ -336,6 +361,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
336 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ 361 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
337 int order, max_order; 362 int order, max_order;
338 struct resource *b_res = find_free_bus_resource(bus, type); 363 struct resource *b_res = find_free_bus_resource(bus, type);
364 unsigned int mem64_mask = 0;
339 365
340 if (!b_res) 366 if (!b_res)
341 return 0; 367 return 0;
@@ -344,9 +370,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
344 max_order = 0; 370 max_order = 0;
345 size = 0; 371 size = 0;
346 372
373 mem64_mask = b_res->flags & IORESOURCE_MEM_64;
374 b_res->flags &= ~IORESOURCE_MEM_64;
375
347 list_for_each_entry(dev, &bus->devices, bus_list) { 376 list_for_each_entry(dev, &bus->devices, bus_list) {
348 int i; 377 int i;
349 378
350 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 379 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
351 struct resource *r = &dev->resource[i]; 380 struct resource *r = &dev->resource[i];
352 resource_size_t r_size; 381 resource_size_t r_size;
@@ -372,6 +401,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
372 aligns[order] += align; 401 aligns[order] += align;
373 if (order > max_order) 402 if (order > max_order)
374 max_order = order; 403 max_order = order;
404 mem64_mask &= r->flags & IORESOURCE_MEM_64;
375 } 405 }
376 } 406 }
377 407
@@ -396,6 +426,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
396 b_res->start = min_align; 426 b_res->start = min_align;
397 b_res->end = size + min_align - 1; 427 b_res->end = size + min_align - 1;
398 b_res->flags |= IORESOURCE_STARTALIGN; 428 b_res->flags |= IORESOURCE_STARTALIGN;
429 b_res->flags |= mem64_mask;
399 return 1; 430 return 1;
400} 431}
401 432