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.c112
1 files changed, 53 insertions, 59 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index cb1a027eb552..c48cd377b3f5 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -71,53 +71,50 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
71void pci_setup_cardbus(struct pci_bus *bus) 71void pci_setup_cardbus(struct pci_bus *bus)
72{ 72{
73 struct pci_dev *bridge = bus->self; 73 struct pci_dev *bridge = bus->self;
74 struct resource *res;
74 struct pci_bus_region region; 75 struct pci_bus_region region;
75 76
76 dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", 77 dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
77 pci_domain_nr(bus), bus->number); 78 bus->secondary, bus->subordinate);
78 79
79 pcibios_resource_to_bus(bridge, &region, bus->resource[0]); 80 res = bus->resource[0];
80 if (bus->resource[0]->flags & IORESOURCE_IO) { 81 pcibios_resource_to_bus(bridge, &region, res);
82 if (res->flags & IORESOURCE_IO) {
81 /* 83 /*
82 * The IO resource is allocated a range twice as large as it 84 * The IO resource is allocated a range twice as large as it
83 * would normally need. This allows us to set both IO regs. 85 * would normally need. This allows us to set both IO regs.
84 */ 86 */
85 dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", 87 dev_info(&bridge->dev, " bridge window %pR\n", res);
86 (unsigned long)region.start,
87 (unsigned long)region.end);
88 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, 88 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
89 region.start); 89 region.start);
90 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, 90 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
91 region.end); 91 region.end);
92 } 92 }
93 93
94 pcibios_resource_to_bus(bridge, &region, bus->resource[1]); 94 res = bus->resource[1];
95 if (bus->resource[1]->flags & IORESOURCE_IO) { 95 pcibios_resource_to_bus(bridge, &region, res);
96 dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", 96 if (res->flags & IORESOURCE_IO) {
97 (unsigned long)region.start, 97 dev_info(&bridge->dev, " bridge window %pR\n", res);
98 (unsigned long)region.end);
99 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, 98 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
100 region.start); 99 region.start);
101 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, 100 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
102 region.end); 101 region.end);
103 } 102 }
104 103
105 pcibios_resource_to_bus(bridge, &region, bus->resource[2]); 104 res = bus->resource[2];
106 if (bus->resource[2]->flags & IORESOURCE_MEM) { 105 pcibios_resource_to_bus(bridge, &region, res);
107 dev_info(&bridge->dev, " PREFETCH window: %#08lx-%#08lx\n", 106 if (res->flags & IORESOURCE_MEM) {
108 (unsigned long)region.start, 107 dev_info(&bridge->dev, " bridge window %pR\n", res);
109 (unsigned long)region.end);
110 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, 108 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
111 region.start); 109 region.start);
112 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, 110 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
113 region.end); 111 region.end);
114 } 112 }
115 113
116 pcibios_resource_to_bus(bridge, &region, bus->resource[3]); 114 res = bus->resource[3];
117 if (bus->resource[3]->flags & IORESOURCE_MEM) { 115 pcibios_resource_to_bus(bridge, &region, res);
118 dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", 116 if (res->flags & IORESOURCE_MEM) {
119 (unsigned long)region.start, 117 dev_info(&bridge->dev, " bridge window %pR\n", res);
120 (unsigned long)region.end);
121 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, 118 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
122 region.start); 119 region.start);
123 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, 120 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -140,34 +137,33 @@ EXPORT_SYMBOL(pci_setup_cardbus);
140static void pci_setup_bridge(struct pci_bus *bus) 137static void pci_setup_bridge(struct pci_bus *bus)
141{ 138{
142 struct pci_dev *bridge = bus->self; 139 struct pci_dev *bridge = bus->self;
140 struct resource *res;
143 struct pci_bus_region region; 141 struct pci_bus_region region;
144 u32 l, bu, lu, io_upper16; 142 u32 l, bu, lu, io_upper16;
145 int pref_mem64;
146 143
147 if (pci_is_enabled(bridge)) 144 if (pci_is_enabled(bridge))
148 return; 145 return;
149 146
150 dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", 147 dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
151 pci_domain_nr(bus), bus->number); 148 bus->secondary, bus->subordinate);
152 149
153 /* Set up the top and bottom of the PCI I/O segment for this bus. */ 150 /* Set up the top and bottom of the PCI I/O segment for this bus. */
154 pcibios_resource_to_bus(bridge, &region, bus->resource[0]); 151 res = bus->resource[0];
155 if (bus->resource[0]->flags & IORESOURCE_IO) { 152 pcibios_resource_to_bus(bridge, &region, res);
153 if (res->flags & IORESOURCE_IO) {
156 pci_read_config_dword(bridge, PCI_IO_BASE, &l); 154 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
157 l &= 0xffff0000; 155 l &= 0xffff0000;
158 l |= (region.start >> 8) & 0x00f0; 156 l |= (region.start >> 8) & 0x00f0;
159 l |= region.end & 0xf000; 157 l |= region.end & 0xf000;
160 /* Set up upper 16 bits of I/O base/limit. */ 158 /* Set up upper 16 bits of I/O base/limit. */
161 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); 159 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
162 dev_info(&bridge->dev, " IO window: %#04lx-%#04lx\n", 160 dev_info(&bridge->dev, " bridge window %pR\n", res);
163 (unsigned long)region.start,
164 (unsigned long)region.end);
165 } 161 }
166 else { 162 else {
167 /* Clear upper 16 bits of I/O base/limit. */ 163 /* Clear upper 16 bits of I/O base/limit. */
168 io_upper16 = 0; 164 io_upper16 = 0;
169 l = 0x00f0; 165 l = 0x00f0;
170 dev_info(&bridge->dev, " IO window: disabled\n"); 166 dev_info(&bridge->dev, " bridge window [io disabled]\n");
171 } 167 }
172 /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ 168 /* Temporarily disable the I/O range before updating PCI_IO_BASE. */
173 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); 169 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
@@ -178,17 +174,16 @@ static void pci_setup_bridge(struct pci_bus *bus)
178 174
179 /* Set up the top and bottom of the PCI Memory segment 175 /* Set up the top and bottom of the PCI Memory segment
180 for this bus. */ 176 for this bus. */
181 pcibios_resource_to_bus(bridge, &region, bus->resource[1]); 177 res = bus->resource[1];
182 if (bus->resource[1]->flags & IORESOURCE_MEM) { 178 pcibios_resource_to_bus(bridge, &region, res);
179 if (res->flags & IORESOURCE_MEM) {
183 l = (region.start >> 16) & 0xfff0; 180 l = (region.start >> 16) & 0xfff0;
184 l |= region.end & 0xfff00000; 181 l |= region.end & 0xfff00000;
185 dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", 182 dev_info(&bridge->dev, " bridge window %pR\n", res);
186 (unsigned long)region.start,
187 (unsigned long)region.end);
188 } 183 }
189 else { 184 else {
190 l = 0x0000fff0; 185 l = 0x0000fff0;
191 dev_info(&bridge->dev, " MEM window: disabled\n"); 186 dev_info(&bridge->dev, " bridge window [mem disabled]\n");
192 } 187 }
193 pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); 188 pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
194 189
@@ -198,34 +193,27 @@ static void pci_setup_bridge(struct pci_bus *bus)
198 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); 193 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
199 194
200 /* Set up PREF base/limit. */ 195 /* Set up PREF base/limit. */
201 pref_mem64 = 0;
202 bu = lu = 0; 196 bu = lu = 0;
203 pcibios_resource_to_bus(bridge, &region, bus->resource[2]); 197 res = bus->resource[2];
204 if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { 198 pcibios_resource_to_bus(bridge, &region, res);
205 int width = 8; 199 if (res->flags & IORESOURCE_PREFETCH) {
206 l = (region.start >> 16) & 0xfff0; 200 l = (region.start >> 16) & 0xfff0;
207 l |= region.end & 0xfff00000; 201 l |= region.end & 0xfff00000;
208 if (bus->resource[2]->flags & IORESOURCE_MEM_64) { 202 if (res->flags & IORESOURCE_MEM_64) {
209 pref_mem64 = 1;
210 bu = upper_32_bits(region.start); 203 bu = upper_32_bits(region.start);
211 lu = upper_32_bits(region.end); 204 lu = upper_32_bits(region.end);
212 width = 16;
213 } 205 }
214 dev_info(&bridge->dev, " PREFETCH window: %#0*llx-%#0*llx\n", 206 dev_info(&bridge->dev, " bridge window %pR\n", res);
215 width, (unsigned long long)region.start,
216 width, (unsigned long long)region.end);
217 } 207 }
218 else { 208 else {
219 l = 0x0000fff0; 209 l = 0x0000fff0;
220 dev_info(&bridge->dev, " PREFETCH window: disabled\n"); 210 dev_info(&bridge->dev, " bridge window [mem pref disabled]\n");
221 } 211 }
222 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); 212 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
223 213
224 if (pref_mem64) { 214 /* Set the upper 32 bits of PREF base & limit. */
225 /* Set the upper 32 bits of PREF base & limit. */ 215 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
226 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); 216 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
227 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
228 }
229 217
230 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); 218 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
231} 219}
@@ -345,6 +333,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
345#endif 333#endif
346 size = ALIGN(size + size1, 4096); 334 size = ALIGN(size + size1, 4096);
347 if (!size) { 335 if (!size) {
336 if (b_res->start || b_res->end)
337 dev_info(&bus->self->dev, "disabling bridge window "
338 "%pR to [bus %02x-%02x] (unused)\n", b_res,
339 bus->secondary, bus->subordinate);
348 b_res->flags = 0; 340 b_res->flags = 0;
349 return; 341 return;
350 } 342 }
@@ -390,8 +382,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
390 align = pci_resource_alignment(dev, r); 382 align = pci_resource_alignment(dev, r);
391 order = __ffs(align) - 20; 383 order = __ffs(align) - 20;
392 if (order > 11) { 384 if (order > 11) {
393 dev_warn(&dev->dev, "BAR %d bad alignment %llx: " 385 dev_warn(&dev->dev, "disabling BAR %d: %pR "
394 "%pR\n", i, (unsigned long long)align, r); 386 "(bad alignment %#llx)\n", i, r,
387 (unsigned long long) align);
395 r->flags = 0; 388 r->flags = 0;
396 continue; 389 continue;
397 } 390 }
@@ -425,6 +418,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
425 } 418 }
426 size = ALIGN(size, min_align); 419 size = ALIGN(size, min_align);
427 if (!size) { 420 if (!size) {
421 if (b_res->start || b_res->end)
422 dev_info(&bus->self->dev, "disabling bridge window "
423 "%pR to [bus %02x-%02x] (unused)\n", b_res,
424 bus->secondary, bus->subordinate);
428 b_res->flags = 0; 425 b_res->flags = 0;
429 return 1; 426 return 1;
430 } 427 }
@@ -582,10 +579,7 @@ static void pci_bus_dump_res(struct pci_bus *bus)
582 if (!res || !res->end) 579 if (!res || !res->end)
583 continue; 580 continue;
584 581
585 dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i, 582 dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
586 (res->flags & IORESOURCE_IO) ? "io: " :
587 ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"),
588 res);
589 } 583 }
590} 584}
591 585