blob: a32c3a675f2992540e2b842074eb1e31a6f71cc8 [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001/*
2 * PCI Bus Services, see include/linux/pci.h for further explanation.
3 *
4 * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
5 * David Mosberger-Tang
6 *
7 * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 *
9 * Copyright 2003 -- Eric Biederman <ebiederman@lnxi.com>
10 */
11
12#include <console/console.h>
13#include <stdlib.h>
14#include <stdint.h>
15#include <bitops.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000016#include <string.h>
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +000017#include <arch/io.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000018#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000021#include <part/hard_reset.h>
Eric Biederman30e143a2003-09-01 23:45:32 +000022#include <part/fallback_boot.h>
Eric Biederman03acab62004-10-14 21:25:53 +000023#include <delay.h>
24
25static uint8_t pci_moving_config8(struct device *dev, unsigned reg)
26{
27 uint8_t value, ones, zeroes;
28 value = pci_read_config8(dev, reg);
29
30 pci_write_config8(dev, reg, 0xff);
31 ones = pci_read_config8(dev, reg);
32
33 pci_write_config8(dev, reg, 0x00);
34 zeroes = pci_read_config8(dev, reg);
35
36 pci_write_config8(dev, reg, value);
37
38 return ones ^ zeroes;
39}
40static uint16_t pci_moving_config16(struct device *dev, unsigned reg)
41{
42 uint16_t value, ones, zeroes;
43 value = pci_read_config16(dev, reg);
44
45 pci_write_config16(dev, reg, 0xffff);
46 ones = pci_read_config16(dev, reg);
47
48 pci_write_config16(dev, reg, 0x0000);
49 zeroes = pci_read_config16(dev, reg);
50
51 pci_write_config16(dev, reg, value);
52
53 return ones ^ zeroes;
54}
55static uint32_t pci_moving_config32(struct device *dev, unsigned reg)
56{
57 uint32_t value, ones, zeroes;
58 value = pci_read_config32(dev, reg);
59
60 pci_write_config32(dev, reg, 0xffffffff);
61 ones = pci_read_config32(dev, reg);
62
63 pci_write_config32(dev, reg, 0x00000000);
64 zeroes = pci_read_config32(dev, reg);
65
66 pci_write_config32(dev, reg, value);
67
68 return ones ^ zeroes;
69}
70
71unsigned pci_find_capability(device_t dev, unsigned cap)
72{
73 unsigned pos;
74 pos = 0;
75 switch(dev->hdr_type & 0x7f) {
76 case PCI_HEADER_TYPE_NORMAL:
77 case PCI_HEADER_TYPE_BRIDGE:
78 pos = PCI_CAPABILITY_LIST;
79 break;
80 }
81 if (pos > PCI_CAP_LIST_NEXT) {
82 pos = pci_read_config8(dev, pos);
83 }
84 while(pos != 0) { /* loop through the linked list */
85 int this_cap;
86 this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
87 if (this_cap == cap) {
88 return pos;
89 }
90 }
91 return 0;
92}
93
Eric Biederman8ca8d762003-04-22 19:02:15 +000094
Eric Biederman8ca8d762003-04-22 19:02:15 +000095/** Given a device and register, read the size of the BAR for that register.
96 * @param dev Pointer to the device structure
97 * @param resource Pointer to the resource structure
98 * @param index Address of the pci configuration register
99 */
Eric Biederman03acab62004-10-14 21:25:53 +0000100struct resource *pci_get_resource(struct device *dev, unsigned long index)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000101{
Eric Biederman5cd81732004-03-11 15:01:31 +0000102 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000103 unsigned long value, attr;
104 resource_t moving, limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000105
106 /* Initialize the resources to nothing */
Eric Biederman03acab62004-10-14 21:25:53 +0000107 resource = new_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000108
Eric Biederman03acab62004-10-14 21:25:53 +0000109 /* Get the initial value */
110 value = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000111
Eric Biederman03acab62004-10-14 21:25:53 +0000112 /* See which bits move */
113 moving = pci_moving_config32(dev, index);
114
115 /* Initialize attr to the bits that do not move */
116 attr = value & ~moving;
117
118 /* If it is a 64bit resource look at the high half as well */
119 if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) &&
120 ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
121 {
122 /* Find the high bits that move */
123 moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32;
124 }
125 /* Find the resource constraints.
126 *
127 * Start by finding the bits that move. From there:
128 * - Size is the least significant bit of the bits that move.
129 * - Limit is all of the bits that move plus all of the lower bits.
130 * See PCI Spec 6.2.5.1 ...
Eric Biederman8ca8d762003-04-22 19:02:15 +0000131 */
Eric Biederman03acab62004-10-14 21:25:53 +0000132 limit = 0;
133 if (moving) {
134 resource->size = 1;
135 resource->align = resource->gran = 0;
136 while(!(moving & resource->size)) {
137 resource->size <<= 1;
138 resource->align += 1;
139 resource->gran += 1;
140 }
141 resource->limit = limit = moving | (resource->size - 1);
142 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000143 /*
144 * some broken hardware has read-only registers that do not
Eric Biederman03acab62004-10-14 21:25:53 +0000145 * really size correctly.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000146 * Example: the acer m7229 has BARs 1-4 normally read-only.
147 * so BAR1 at offset 0x10 reads 0x1f1. If you size that register
148 * by writing 0xffffffff to it, it will read back as 0x1f1 -- a
149 * violation of the spec.
Eric Biederman03acab62004-10-14 21:25:53 +0000150 * We catch this case and ignore it by observing which bits move,
151 * This also catches the common case unimplemented registers
152 * that always read back as 0.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000153 */
Eric Biederman03acab62004-10-14 21:25:53 +0000154 if (moving == 0) {
155 if (value != 0) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000156 printk_debug(
Eric Biedermane9a271e32003-09-02 03:36:25 +0000157 "%s register %02x(%08x), read-only ignoring it\n",
Eric Biederman03acab62004-10-14 21:25:53 +0000158 dev_path(dev), index, value);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000159 }
160 resource->flags = 0;
161 }
Eric Biederman03acab62004-10-14 21:25:53 +0000162 else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
163 /* An I/O mapped base address */
164 attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000165 resource->flags |= IORESOURCE_IO;
Eric Biederman03acab62004-10-14 21:25:53 +0000166 /* I don't want to deal with 32bit I/O resources */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000167 resource->limit = 0xffff;
168 }
169 else {
170 /* A Memory mapped base address */
Eric Biederman03acab62004-10-14 21:25:53 +0000171 attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000172 resource->flags |= IORESOURCE_MEM;
Eric Biederman03acab62004-10-14 21:25:53 +0000173 if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000174 resource->flags |= IORESOURCE_PREFETCH;
175 }
Eric Biederman03acab62004-10-14 21:25:53 +0000176 attr &= PCI_BASE_ADDRESS_MEM_LIMIT_MASK;
177 if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000178 /* 32bit limit */
179 resource->limit = 0xffffffffUL;
180 }
Eric Biederman03acab62004-10-14 21:25:53 +0000181 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000182 /* 1MB limit */
183 resource->limit = 0x000fffffUL;
184 }
Eric Biederman03acab62004-10-14 21:25:53 +0000185 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
186 /* 64bit limit */
187 resource->limit = 0xffffffffffffffffULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000188 resource->flags |= IORESOURCE_PCI64;
Eric Biederman03acab62004-10-14 21:25:53 +0000189 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000190 else {
191 /* Invalid value */
192 resource->flags = 0;
193 }
194 }
Eric Biederman03acab62004-10-14 21:25:53 +0000195 /* Don't let the limit exceed which bits can move */
196 if (resource->limit > limit) {
197 resource->limit = limit;
198 }
199#if 0
200 if (resource->flags) {
201 printk_debug("%s %02x ->",
202 dev_path(dev), resource->index);
203 printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
204 value, zeroes, ones, attr);
205 printk_debug(
206 "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ",
207 dev_path(dev),
208 resource->index,
209 resource->size, resource->limit,
210 (resource->flags == 0) ? "unused":
211 (resource->flags & IORESOURCE_IO)? "io":
212 (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem",
213 (resource->flags & IORESOURCE_PCI64)?"64":"");
214 }
215#endif
216
Eric Biederman5cd81732004-03-11 15:01:31 +0000217 return resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000218}
219
220/** Read the base address registers for a given device.
221 * @param dev Pointer to the dev structure
222 * @param howmany How many registers to read (6 for device, 2 for bridge)
223 */
224static void pci_read_bases(struct device *dev, unsigned int howmany)
225{
Eric Biederman8ca8d762003-04-22 19:02:15 +0000226 unsigned long index;
227
Eric Biedermanb78c1972004-10-14 20:54:17 +0000228 for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000229 struct resource *resource;
Eric Biederman5cd81732004-03-11 15:01:31 +0000230 resource = pci_get_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000231 index += (resource->flags & IORESOURCE_PCI64)?8:4;
232 }
Eric Biederman5cd81732004-03-11 15:01:31 +0000233 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000234}
235
Eric Biederman03acab62004-10-14 21:25:53 +0000236static void pci_set_resource(struct device *dev, struct resource *resource);
237
238static void pci_record_bridge_resource(
239 struct device *dev, resource_t moving,
240 unsigned index, unsigned long mask, unsigned long type)
241{
242 /* Initiliaze the constraints on the current bus */
243 struct resource *resource;
244 resource = 0;
245 if (moving) {
246 unsigned long gran;
247 resource_t step;
248 resource = new_resource(dev, index);
249 resource->size = 0;
250 gran = 0;
251 step = 1;
252 while((moving & step) == 0) {
253 gran += 1;
254 step <<= 1;
255 }
256 resource->gran = gran;
257 resource->align = gran;
258 resource->limit = moving | (step - 1);
259 resource->flags = type | IORESOURCE_PCI_BRIDGE;
260 compute_allocate_resource(&dev->link[0], resource, mask, type);
261 /* If there is nothing behind the resource,
262 * clear it and forget it.
263 */
264 if (resource->size == 0) {
265 resource->base = moving;
266 resource->flags |= IORESOURCE_ASSIGNED;
267 resource->flags &= ~IORESOURCE_STORED;
268 pci_set_resource(dev, resource);
269 resource->flags = 0;
270 }
271 }
272 return;
273}
274
275
Eric Biederman8ca8d762003-04-22 19:02:15 +0000276static void pci_bridge_read_bases(struct device *dev)
277{
Eric Biederman03acab62004-10-14 21:25:53 +0000278 resource_t moving_base, moving_limit, moving;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000279
Eric Biederman03acab62004-10-14 21:25:53 +0000280
281 /* See if the bridge I/O resources are implemented */
282 moving_base = ((uint32_t)pci_moving_config8(dev, PCI_IO_BASE)) << 8;
283 moving_base |= ((uint32_t)pci_moving_config16(dev, PCI_IO_BASE_UPPER16)) << 16;
284
285 moving_limit = ((uint32_t)pci_moving_config8(dev, PCI_IO_LIMIT)) << 8;
286 moving_limit |= ((uint32_t)pci_moving_config16(dev, PCI_IO_LIMIT_UPPER16)) << 16;
287
288 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000289
290 /* Initialize the io space constraints on the current bus */
Eric Biederman03acab62004-10-14 21:25:53 +0000291 pci_record_bridge_resource(
292 dev, moving, PCI_IO_BASE,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000293 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000294
Eric Biederman03acab62004-10-14 21:25:53 +0000295
296 /* See if the bridge prefmem resources are implemented */
297 moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
298 moving_base |= ((resource_t)pci_moving_config32(dev, PCI_PREF_BASE_UPPER32)) << 32;
299
300 moving_limit = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_LIMIT)) << 16;
301 moving_limit |= ((resource_t)pci_moving_config32(dev, PCI_PREF_LIMIT_UPPER32)) << 32;
302
303 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000304 /* Initiliaze the prefetchable memory constraints on the current bus */
Eric Biederman03acab62004-10-14 21:25:53 +0000305 pci_record_bridge_resource(
306 dev, moving, PCI_PREF_MEMORY_BASE,
307 IORESOURCE_MEM | IORESOURCE_PREFETCH,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000308 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000309
310
311 /* See if the bridge mem resources are implemented */
312 moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
313 moving_limit = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_LIMIT)) << 16;
314
315 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000316
317 /* Initialize the memory resources on the current bus */
Eric Biederman03acab62004-10-14 21:25:53 +0000318 pci_record_bridge_resource(
319 dev, moving, PCI_MEMORY_BASE,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000320 IORESOURCE_MEM | IORESOURCE_PREFETCH,
321 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000322
Eric Biederman5cd81732004-03-11 15:01:31 +0000323 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000324}
325
Eric Biederman5899fd82003-04-24 06:25:08 +0000326void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000327{
328 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000329
Eric Biederman8ca8d762003-04-22 19:02:15 +0000330 pci_read_bases(dev, 6);
Li-Ta Loe5266692004-03-23 21:28:05 +0000331
Eric Biederman7a5416a2003-06-12 19:23:51 +0000332 addr = pci_read_config32(dev, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000333 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
334}
335
Eric Biederman5899fd82003-04-24 06:25:08 +0000336void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000337{
338 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000339
Eric Biederman8ca8d762003-04-22 19:02:15 +0000340 pci_bridge_read_bases(dev);
341 pci_read_bases(dev, 2);
342
Eric Biederman7a5416a2003-06-12 19:23:51 +0000343 addr = pci_read_config32(dev, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000344 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000345}
346
Eric Biederman8ca8d762003-04-22 19:02:15 +0000347static void pci_set_resource(struct device *dev, struct resource *resource)
348{
Eric Biederman03acab62004-10-14 21:25:53 +0000349 resource_t base, end;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000350
Eric Biederman8ca8d762003-04-22 19:02:15 +0000351 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000352 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000353 printk_err("ERROR: %s %02x not allocated\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000354 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000355 return;
356 }
357
Eric Biederman5cd81732004-03-11 15:01:31 +0000358 /* If I have already stored this resource don't worry about it */
359 if (resource->flags & IORESOURCE_STORED) {
360 return;
361 }
362
Eric Biederman03acab62004-10-14 21:25:53 +0000363 /* If the resources is substractive don't worry about it */
364 if (resource->flags & IORESOURCE_SUBTRACTIVE) {
365 return;
366 }
367
Eric Biederman8ca8d762003-04-22 19:02:15 +0000368 /* Only handle PCI memory and IO resources for now */
369 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
370 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000371
Eric Biederman03acab62004-10-14 21:25:53 +0000372 /* Enable the resources in the command register */
373 if (resource->size) {
374 if (resource->flags & IORESOURCE_MEM) {
375 dev->command |= PCI_COMMAND_MEMORY;
376 }
377 if (resource->flags & IORESOURCE_IO) {
378 dev->command |= PCI_COMMAND_IO;
379 }
380 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
381 dev->command |= PCI_COMMAND_MASTER;
382 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000383 }
384 /* Get the base address */
385 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000386
Eric Biederman03acab62004-10-14 21:25:53 +0000387 /* Get the end */
388 end = resource_end(resource);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000389
Eric Biederman5cd81732004-03-11 15:01:31 +0000390 /* Now store the resource */
391 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000392 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000393 unsigned long base_lo, base_hi;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000394 /*
395 * some chipsets allow us to set/clear the IO bit.
396 * (e.g. VIA 82c686a.) So set it to be safe)
397 */
Eric Biederman03acab62004-10-14 21:25:53 +0000398 base_lo = base & 0xffffffff;
399 base_hi = (base >> 32) & 0xffffffff;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000400 if (resource->flags & IORESOURCE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000401 base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000402 }
Eric Biederman03acab62004-10-14 21:25:53 +0000403 pci_write_config32(dev, resource->index, base_lo);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000404 if (resource->flags & IORESOURCE_PCI64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000405 pci_write_config32(dev, resource->index + 4, base_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000406 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000407 }
408 else if (resource->index == PCI_IO_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000409 /* set the IO ranges */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000410 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000411 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000412 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
413 pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16);
414 pci_write_config8(dev, PCI_IO_LIMIT, end >> 8);
415 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000416 }
417 else if (resource->index == PCI_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000418 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000419 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000420 IORESOURCE_MEM | IORESOURCE_PREFETCH,
421 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000422 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
Eric Biederman03acab62004-10-14 21:25:53 +0000423 pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000424 }
425 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000426 /* set the prefetchable memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000427 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000428 IORESOURCE_MEM | IORESOURCE_PREFETCH,
429 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000430 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
431 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32);
432 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16);
433 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, end >> 32);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000434 }
435 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000436 /* Don't let me think I stored the resource */
437 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000438 printk_err("ERROR: invalid resource->index %x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000439 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000440 }
Eric Biederman03acab62004-10-14 21:25:53 +0000441 report_resource_stored(dev, resource, "");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000442 return;
443}
444
Eric Biederman5899fd82003-04-24 06:25:08 +0000445void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000446{
447 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000448 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000449 uint8_t line;
450
451 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000452
453 for(resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000454 pci_set_resource(dev, resource);
455 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000456 for(link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000457 struct bus *bus;
458 bus = &dev->link[link];
459 if (bus->children) {
460 assign_resources(bus);
461 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000462 }
463
464 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000465 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000466
467 /* set a default secondary latency timer */
468 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000469 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000470 }
471
472 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000473 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000474 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000475 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000476 }
477 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000478 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000479}
480
Eric Biedermane9a271e32003-09-02 03:36:25 +0000481void pci_dev_enable_resources(struct device *dev)
482{
Eric Biedermana9e632c2004-11-18 22:38:08 +0000483 const struct pci_operations *ops;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000484 uint16_t command;
Eric Biederman03acab62004-10-14 21:25:53 +0000485
486 /* Set the subsystem vendor and device id for mainboard devices */
487 ops = ops_pci(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000488 if (dev->on_mainboard && ops && ops->set_subsystem) {
Eric Biederman03acab62004-10-14 21:25:53 +0000489 printk_debug("%s subsystem <- %02x/%02x\n",
490 dev_path(dev),
491 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
492 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
493 ops->set_subsystem(dev,
494 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
495 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
496 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000497 command = pci_read_config16(dev, PCI_COMMAND);
498 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000499 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000500 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
501 pci_write_config16(dev, PCI_COMMAND, command);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000502}
503
504void pci_bus_enable_resources(struct device *dev)
505{
506 uint16_t ctrl;
507 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
508 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000509 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000510 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
511 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
512
513 pci_dev_enable_resources(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000514
515 enable_childrens_resources(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000516}
517
Eric Biedermana9e632c2004-11-18 22:38:08 +0000518
Eric Biedermandbec2d42004-10-21 10:44:08 +0000519void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
Eric Biederman03acab62004-10-14 21:25:53 +0000520{
521 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
522 ((device & 0xffff) << 16) | (vendor & 0xffff));
523}
524
Li-Ta Loe5266692004-03-23 21:28:05 +0000525/** Default device operation for PCI devices */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000526static struct pci_operations pci_dev_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000527 .set_subsystem = pci_dev_set_subsystem,
528};
529
Eric Biederman8ca8d762003-04-22 19:02:15 +0000530struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000531 .read_resources = pci_dev_read_resources,
532 .set_resources = pci_dev_set_resources,
533 .enable_resources = pci_dev_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000534 .init = 0,
535 .scan_bus = 0,
Eric Biederman03acab62004-10-14 21:25:53 +0000536 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000537 .ops_pci = &pci_dev_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000538};
Li-Ta Loe5266692004-03-23 21:28:05 +0000539
540/** Default device operations for PCI bridges */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000541static struct pci_operations pci_bus_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000542 .set_subsystem = 0,
543};
Eric Biederman8ca8d762003-04-22 19:02:15 +0000544struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000545 .read_resources = pci_bus_read_resources,
546 .set_resources = pci_dev_set_resources,
547 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000548 .init = 0,
549 .scan_bus = pci_scan_bridge,
Eric Biederman03acab62004-10-14 21:25:53 +0000550 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000551 .ops_pci = &pci_bus_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000552};
Li-Ta Loe5266692004-03-23 21:28:05 +0000553
554/**
555 * @brief Set up PCI device operation
556 *
557 *
558 * @param dev
559 *
560 * @see pci_drivers
561 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000562static void set_pci_ops(struct device *dev)
563{
564 struct pci_driver *driver;
565 if (dev->ops) {
566 return;
567 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000568
Eric Biederman8ca8d762003-04-22 19:02:15 +0000569 /* Look through the list of setup drivers and find one for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000570 * this pci device
571 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000572 for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000573 if ((driver->vendor == dev->vendor) &&
Li-Ta Lo04930692004-11-25 17:37:19 +0000574 (driver->device == dev->device))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000575 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000576 dev->ops = driver->ops;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000577 printk_debug("%s [%04x/%04x] %sops\n",
578 dev_path(dev),
579 driver->vendor, driver->device,
580 (driver->ops->scan_bus?"bus ":""));
Eric Biederman5899fd82003-04-24 06:25:08 +0000581 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000582 }
583 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000584
Eric Biederman8ca8d762003-04-22 19:02:15 +0000585 /* If I don't have a specific driver use the default operations */
586 switch(dev->hdr_type & 0x7f) { /* header type */
587 case PCI_HEADER_TYPE_NORMAL: /* standard header */
588 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
589 goto bad;
590 dev->ops = &default_pci_ops_dev;
591 break;
592 case PCI_HEADER_TYPE_BRIDGE:
593 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
594 goto bad;
595 dev->ops = &default_pci_ops_bus;
596 break;
597 default:
598 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000599 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000600 printk_err("%s [%04x/%04x/%06x] has unknown header "
Eric Biedermanb78c1972004-10-14 20:54:17 +0000601 "type %02x, ignoring.\n",
602 dev_path(dev),
603 dev->vendor, dev->device,
604 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000605 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000606 }
607 return;
608}
609
610/**
Eric Biederman03acab62004-10-14 21:25:53 +0000611 * @brief See if we have already allocated a device structure for a given devfn.
Li-Ta Loe5266692004-03-23 21:28:05 +0000612 *
613 * Given a linked list of PCI device structures and a devfn number, find the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000614 * device structure correspond to the devfn, if present.
Li-Ta Loe5266692004-03-23 21:28:05 +0000615 *
616 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000617 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000618 *
Eric Biedermanb78c1972004-10-14 20:54:17 +0000619 * @return pointer to the device structure found or null of we have not allocated
620 * a device for this devfn yet.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000621 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000622static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000623{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000624 struct device *dev;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000625 dev = 0;
626 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000627 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000628 printk_err("child %s not a pci device\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000629 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000630 continue;
631 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000632 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000633 /* Unlink from the list */
634 dev = *list;
635 *list = (*list)->sibling;
636 dev->sibling = 0;
637 break;
638 }
639 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000640 /* Just like alloc_dev add the device to the
641 * list of device on the bus. When the list of devices was formed
642 * we removed all of the parents children, and now we are interleaving
643 * static and dynamic devices in order on the bus.
644 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000645 if (dev) {
646 device_t child;
647 /* Find the last child of our parent */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000648 for(child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000649 child = child->sibling;
650 }
651 /* Place the device on the list of children of it's parent. */
652 if (child) {
653 child->sibling = dev;
654 } else {
655 dev->bus->children = dev;
656 }
657 }
658
Eric Biederman8ca8d762003-04-22 19:02:15 +0000659 return dev;
660}
661
Eric Biedermanb78c1972004-10-14 20:54:17 +0000662/**
663 * @brief Scan a PCI bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000664 *
665 * Determine the existence of devices and bridges on a PCI bus. If there are
666 * bridges on the bus, recursively scan the buses behind the bridges.
667 *
Eric Biedermane9a271e32003-09-02 03:36:25 +0000668 * @param bus pointer to the bus structure
669 * @param min_devfn minimum devfn to look at in the scan usually 0x00
670 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000671 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +0000672 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000673 * @return The maximum bus number found, after scanning all subordinate busses
674 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000675unsigned int pci_scan_bus(struct bus *bus,
676 unsigned min_devfn, unsigned max_devfn,
677 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000678{
679 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000680 device_t dev;
681 device_t old_devices;
682 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000683
684 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
685
686 old_devices = bus->children;
687 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000688
689 post_code(0x24);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000690
Li-Ta Lo9782f752004-05-05 21:15:42 +0000691 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000692 * non-existence and single funcion devices
693 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000694 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000695 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000696 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000697
Eric Biederman03acab62004-10-14 21:25:53 +0000698 /* First thing setup the device structure */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000699 dev = pci_scan_get_dev(&old_devices, devfn);
Eric Biederman03acab62004-10-14 21:25:53 +0000700
701 /* Detect if a device is present */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000702 if (!dev) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000703 struct device dummy;
704 dummy.bus = bus;
705 dummy.path.type = DEVICE_PATH_PCI;
706 dummy.path.u.pci.devfn = devfn;
707 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
708 /* some broken boards return 0 if a slot is empty: */
Li-Ta Lo04930692004-11-25 17:37:19 +0000709 if ((id == 0xffffffff) || (id == 0x00000000) ||
710 (id == 0x0000ffff) || (id == 0xffff0000))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000711 {
712 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000713 if (PCI_FUNC(devfn) == 0x00) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000714 /* if this is a function 0 device and
715 * it is not present,
716 * skip to next device
717 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000718 devfn += 0x07;
719 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000720 /* This function in a multi function device is
721 * not present, skip to the next function.
722 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000723 continue;
724 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000725 dev = alloc_dev(bus, &dummy.path);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000726 }
727 else {
Eric Biederman03acab62004-10-14 21:25:53 +0000728 /* Enable/disable the device. Once we have
729 * found the device specific operations this
730 * operations we will disable the device with
731 * those as well.
732 *
Eric Biedermanb78c1972004-10-14 20:54:17 +0000733 * This is geared toward devices that have subfunctions
734 * that do not show up by default.
735 *
736 * If a device is a stuff option on the motherboard
737 * it may be absent and enable_dev must cope.
738 *
739 */
Eric Biederman7003ba42004-10-16 06:20:29 +0000740 if (dev->chip_ops && dev->chip_ops->enable_dev)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000741 {
Eric Biederman7003ba42004-10-16 06:20:29 +0000742 dev->chip_ops->enable_dev(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000743 }
744 /* Now read the vendor and device id */
745 id = pci_read_config32(dev, PCI_VENDOR_ID);
Eric Biederman03acab62004-10-14 21:25:53 +0000746
747 /* If the device does not have a pci id disable it.
748 * Possibly this is because we have already disabled
749 * the device. But this also handles optional devices
750 * that may not always show up.
751 */
752 if (id == 0xffffffff || id == 0x00000000 ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000753 id == 0x0000ffff || id == 0xffff0000)
Eric Biederman03acab62004-10-14 21:25:53 +0000754 {
755 if (dev->enabled) {
756 printk_info("Disabling static device: %s\n",
757 dev_path(dev));
758 dev->enabled = 0;
759 }
760 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000761 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000762 /* Read the rest of the pci configuration information */
763 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
764 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000765
Eric Biedermane9a271e32003-09-02 03:36:25 +0000766 /* Store the interesting information in the device structure */
767 dev->vendor = id & 0xffff;
768 dev->device = (id >> 16) & 0xffff;
769 dev->hdr_type = hdr_type;
770 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
771 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000772
Eric Biederman03acab62004-10-14 21:25:53 +0000773 /* Architectural/System devices always need to
774 * be bus masters.
775 */
776 if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
777 dev->command |= PCI_COMMAND_MASTER;
778 }
779
Eric Biederman8ca8d762003-04-22 19:02:15 +0000780 /* Look at the vendor and device id, or at least the
Li-Ta Loe5266692004-03-23 21:28:05 +0000781 * header type and class and figure out which set of
782 * configuration methods to use. Unless we already
783 * have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000784 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000785 set_pci_ops(dev);
786 /* Error if we don't have some pci operations for it */
Eric Biederman5cd81732004-03-11 15:01:31 +0000787 if (!dev->ops) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000788 printk_err("%s No device operations\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000789 dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000790 continue;
791 }
792
793 /* Now run the magic enable/disable sequence for the device */
794 if (dev->ops && dev->ops->enable) {
795 dev->ops->enable(dev);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000796 }
Eric Biederman4086d162003-07-17 03:26:03 +0000797
Eric Biedermane9a271e32003-09-02 03:36:25 +0000798 printk_debug("%s [%04x/%04x] %s\n",
Eric Biederman03acab62004-10-14 21:25:53 +0000799 dev_path(dev),
800 dev->vendor, dev->device,
801 dev->enabled?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000802
Eric Biederman8ca8d762003-04-22 19:02:15 +0000803 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000804 /* if this is not a multi function device,
805 * don't waste time probing another function.
806 * Skip to next device.
807 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000808 devfn += 0x07;
809 }
810 }
811 post_code(0x25);
812
Eric Biedermanb78c1972004-10-14 20:54:17 +0000813 /* For all children that implement scan_bus (i.e. bridges)
814 * scan the bus behind that child.
815 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000816 for (child = bus->children; child; child = child->sibling) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000817 if (!child->enabled ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000818 !child->ops ||
819 !child->ops->scan_bus)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000820 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000821 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000822 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000823 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000824 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000825
Eric Biederman8ca8d762003-04-22 19:02:15 +0000826 /*
827 * We've scanned the bus and so we know all about what's on
828 * the other side of any bridges that may be on this bus plus
829 * any devices.
830 *
831 * Return how far we've got finding sub-buses.
832 */
833 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
834 post_code(0x55);
835 return max;
836}
837
Li-Ta Loe5266692004-03-23 21:28:05 +0000838/**
839 * @brief Scan a PCI bridge and the buses behind the bridge.
840 *
841 * Determine the existence of buses behind the bridge. Set up the bridge
842 * according to the result of the scan.
843 *
844 * This function is the default scan_bus() method for PCI bridge devices.
845 *
846 * @param dev pointer to the bridge device
847 * @param max the highest bus number assgined up to now
848 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000849 * @return The maximum bus number found, after scanning all subordinate busses
850 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000851unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000852{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000853 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000854 uint32_t buses;
855 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000856
Eric Biedermane9a271e32003-09-02 03:36:25 +0000857 bus = &dev->link[0];
Eric Biedermana9e632c2004-11-18 22:38:08 +0000858 bus->dev = dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000859 dev->links = 1;
860
Eric Biederman8ca8d762003-04-22 19:02:15 +0000861 /* Set up the primary, secondary and subordinate bus numbers. We have
862 * no idea how many buses are behind this bridge yet, so we set the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000863 * subordinate bus number to 0xff for the moment.
864 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000865 bus->secondary = ++max;
866 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +0000867
Eric Biederman8ca8d762003-04-22 19:02:15 +0000868 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000869 cr = pci_read_config16(dev, PCI_COMMAND);
870 pci_write_config16(dev, PCI_COMMAND, 0x0000);
871 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000872
Eric Biedermanb78c1972004-10-14 20:54:17 +0000873 /*
874 * Read the existing primary/secondary/subordinate bus
875 * number configuration.
876 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000877 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000878
879 /* Configure the bus numbers for this bridge: the configuration
880 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +0000881 * correctly configured.
882 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000883 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000884 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Eric Biedermanb78c1972004-10-14 20:54:17 +0000885 ((unsigned int) (bus->secondary) << 8) |
886 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000887 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000888
889 /* Now we can scan all subordinate buses
890 * i.e. the bus behind the bridge.
891 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000892 max = pci_scan_bus(bus, 0x00, 0xff, max);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000893
Eric Biederman8ca8d762003-04-22 19:02:15 +0000894 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +0000895 * bus number to its real value.
896 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000897 bus->subordinate = max;
898 buses = (buses & 0xff00ffff) |
899 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000900 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
901 pci_write_config16(dev, PCI_COMMAND, cr);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000902
903 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000904 return max;
905}
Li-Ta Loe5266692004-03-23 21:28:05 +0000906
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000907/*
908 Tell the EISA int controller this int must be level triggered
909 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
910*/
911static void pci_level_irq(unsigned char intNum)
912{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000913 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000914
Eric Biedermanb78c1972004-10-14 20:54:17 +0000915 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000916 intBits |= (1 << intNum);
917
Eric Biedermanb78c1972004-10-14 20:54:17 +0000918 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000919
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000920 // Write new values
921 outb((unsigned char) intBits, 0x4d0);
922 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000923
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000924 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000925#if 1
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000926 if (inb(0x4d0) != (intBits & 0xf)) {
927 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000928 __func__, intBits &0xf, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000929 }
930 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
931 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000932 __func__, (intBits>>8) &0xf, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000933 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000934#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000935}
936
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000937/*
938 This function assigns IRQs for all functions contained within
939 the indicated device address. If the device does not exist or does
940 not require interrupts then this function has no effect.
941
942 This function should be called for each PCI slot in your system.
943
944 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
945 this slot.
946 The particular irq #s that are passed in depend on the routing inside
947 your southbridge and on your motherboard.
948
949 -kevinh@ispiri.com
950*/
951void pci_assign_irqs(unsigned bus, unsigned slot,
952 const unsigned char pIntAtoD[4])
953{
954 unsigned functNum;
955 device_t pdev;
956 unsigned char line;
957 unsigned char irq;
958 unsigned char readback;
959
960 /* Each slot may contain up to eight functions */
961 for (functNum = 0; functNum < 8; functNum++) {
962 pdev = dev_find_slot(bus, (slot << 3) + functNum);
963
964 if (pdev) {
965 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
966
967 // PCI spec says all other values are reserved
968 if ((line >= 1) && (line <= 4)) {
969 irq = pIntAtoD[line - 1];
970
971 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
972 irq, bus, slot, functNum);
973
974 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
975 pIntAtoD[line - 1]);
976
977 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
978 printk_debug(" Readback = %d\n", readback);
979
980 // Change to level triggered
981 pci_level_irq(pIntAtoD[line - 1]);
982 }
983 }
984 }
985}