blob: 5b038e4a8d6a255791463f9f375b5ae4322bbdd5 [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}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +000040
Eric Biederman03acab62004-10-14 21:25:53 +000041static uint16_t pci_moving_config16(struct device *dev, unsigned reg)
42{
43 uint16_t value, ones, zeroes;
44 value = pci_read_config16(dev, reg);
45
46 pci_write_config16(dev, reg, 0xffff);
47 ones = pci_read_config16(dev, reg);
48
49 pci_write_config16(dev, reg, 0x0000);
50 zeroes = pci_read_config16(dev, reg);
51
52 pci_write_config16(dev, reg, value);
53
54 return ones ^ zeroes;
55}
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +000056
Eric Biederman03acab62004-10-14 21:25:53 +000057static uint32_t pci_moving_config32(struct device *dev, unsigned reg)
58{
59 uint32_t value, ones, zeroes;
60 value = pci_read_config32(dev, reg);
61
62 pci_write_config32(dev, reg, 0xffffffff);
63 ones = pci_read_config32(dev, reg);
64
65 pci_write_config32(dev, reg, 0x00000000);
66 zeroes = pci_read_config32(dev, reg);
67
68 pci_write_config32(dev, reg, value);
69
70 return ones ^ zeroes;
71}
72
73unsigned pci_find_capability(device_t dev, unsigned cap)
74{
75 unsigned pos;
76 pos = 0;
77 switch(dev->hdr_type & 0x7f) {
78 case PCI_HEADER_TYPE_NORMAL:
79 case PCI_HEADER_TYPE_BRIDGE:
80 pos = PCI_CAPABILITY_LIST;
81 break;
82 }
83 if (pos > PCI_CAP_LIST_NEXT) {
84 pos = pci_read_config8(dev, pos);
85 }
Li-Ta Lo9a5b4962004-12-23 21:48:01 +000086 while (pos != 0) { /* loop through the linked list */
Eric Biederman03acab62004-10-14 21:25:53 +000087 int this_cap;
88 this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
89 if (this_cap == cap) {
90 return pos;
91 }
92 }
93 return 0;
94}
95
Eric Biederman8ca8d762003-04-22 19:02:15 +000096/** Given a device and register, read the size of the BAR for that register.
97 * @param dev Pointer to the device structure
98 * @param resource Pointer to the resource structure
99 * @param index Address of the pci configuration register
100 */
Eric Biederman03acab62004-10-14 21:25:53 +0000101struct resource *pci_get_resource(struct device *dev, unsigned long index)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000102{
Eric Biederman5cd81732004-03-11 15:01:31 +0000103 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000104 unsigned long value, attr;
105 resource_t moving, limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000106
107 /* Initialize the resources to nothing */
Eric Biederman03acab62004-10-14 21:25:53 +0000108 resource = new_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000109
Eric Biederman03acab62004-10-14 21:25:53 +0000110 /* Get the initial value */
111 value = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000112
Eric Biederman03acab62004-10-14 21:25:53 +0000113 /* See which bits move */
114 moving = pci_moving_config32(dev, index);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000115
Eric Biederman03acab62004-10-14 21:25:53 +0000116 /* Initialize attr to the bits that do not move */
117 attr = value & ~moving;
118
119 /* If it is a 64bit resource look at the high half as well */
120 if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) &&
Li-Ta Lo3a812852004-12-03 22:39:34 +0000121 ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
Eric Biederman03acab62004-10-14 21:25:53 +0000122 {
123 /* Find the high bits that move */
124 moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32;
125 }
126 /* Find the resource constraints.
127 *
128 * Start by finding the bits that move. From there:
129 * - Size is the least significant bit of the bits that move.
130 * - Limit is all of the bits that move plus all of the lower bits.
131 * See PCI Spec 6.2.5.1 ...
Eric Biederman8ca8d762003-04-22 19:02:15 +0000132 */
Eric Biederman03acab62004-10-14 21:25:53 +0000133 limit = 0;
134 if (moving) {
135 resource->size = 1;
136 resource->align = resource->gran = 0;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000137 while (!(moving & resource->size)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000138 resource->size <<= 1;
139 resource->align += 1;
140 resource->gran += 1;
141 }
142 resource->limit = limit = moving | (resource->size - 1);
143 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000144 /*
145 * some broken hardware has read-only registers that do not
Eric Biederman03acab62004-10-14 21:25:53 +0000146 * really size correctly.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000147 * Example: the acer m7229 has BARs 1-4 normally read-only.
148 * so BAR1 at offset 0x10 reads 0x1f1. If you size that register
149 * by writing 0xffffffff to it, it will read back as 0x1f1 -- a
150 * violation of the spec.
Eric Biederman03acab62004-10-14 21:25:53 +0000151 * We catch this case and ignore it by observing which bits move,
152 * This also catches the common case unimplemented registers
153 * that always read back as 0.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000154 */
Eric Biederman03acab62004-10-14 21:25:53 +0000155 if (moving == 0) {
156 if (value != 0) {
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000157 printk_debug("%s register %02x(%08x), read-only ignoring it\n",
158 dev_path(dev), index, value);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000159 }
160 resource->flags = 0;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000161 } else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000162 /* An I/O mapped base address */
163 attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000164 resource->flags |= IORESOURCE_IO;
Eric Biederman03acab62004-10-14 21:25:53 +0000165 /* I don't want to deal with 32bit I/O resources */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000166 resource->limit = 0xffff;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000167 } else {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000168 /* A Memory mapped base address */
Eric Biederman03acab62004-10-14 21:25:53 +0000169 attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000170 resource->flags |= IORESOURCE_MEM;
Eric Biederman03acab62004-10-14 21:25:53 +0000171 if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000172 resource->flags |= IORESOURCE_PREFETCH;
173 }
Eric Biederman03acab62004-10-14 21:25:53 +0000174 attr &= PCI_BASE_ADDRESS_MEM_LIMIT_MASK;
175 if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000176 /* 32bit limit */
177 resource->limit = 0xffffffffUL;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000178 } else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000179 /* 1MB limit */
180 resource->limit = 0x000fffffUL;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000181 } else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000182 /* 64bit limit */
183 resource->limit = 0xffffffffffffffffULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000184 resource->flags |= IORESOURCE_PCI64;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000185 } else {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000186 /* Invalid value */
187 resource->flags = 0;
188 }
189 }
Eric Biederman03acab62004-10-14 21:25:53 +0000190 /* Don't let the limit exceed which bits can move */
191 if (resource->limit > limit) {
192 resource->limit = limit;
193 }
194#if 0
195 if (resource->flags) {
196 printk_debug("%s %02x ->",
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000197 dev_path(dev), resource->index);
Eric Biederman03acab62004-10-14 21:25:53 +0000198 printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000199 value, zeroes, ones, attr);
Eric Biederman03acab62004-10-14 21:25:53 +0000200 printk_debug(
201 "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ",
202 dev_path(dev),
203 resource->index,
204 resource->size, resource->limit,
205 (resource->flags == 0) ? "unused":
206 (resource->flags & IORESOURCE_IO)? "io":
207 (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem",
208 (resource->flags & IORESOURCE_PCI64)?"64":"");
209 }
210#endif
211
Eric Biederman5cd81732004-03-11 15:01:31 +0000212 return resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000213}
214
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000215static void pci_get_rom_resource(struct device *dev, unsigned long index)
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000216{
217 struct resource *resource;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000218 unsigned long value;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000219 resource_t moving, limit;
220
221 /* Initialize the resources to nothing */
222 resource = new_resource(dev, index);
223
224 /* Get the initial value */
225 value = pci_read_config32(dev, index);
226
227 /* See which bits move */
228 moving = pci_moving_config32(dev, index);
229 /* clear the Enable bit */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000230 moving = moving & ~PCI_ROM_ADDRESS_ENABLE;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000231
232 /* Find the resource constraints.
233 *
234 * Start by finding the bits that move. From there:
235 * - Size is the least significant bit of the bits that move.
236 * - Limit is all of the bits that move plus all of the lower bits.
237 * See PCI Spec 6.2.5.1 ...
238 */
239 limit = 0;
240
241 if (moving) {
242 resource->size = 1;
243 resource->align = resource->gran = 0;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000244 while (!(moving & resource->size)) {
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000245 resource->size <<= 1;
246 resource->align += 1;
247 resource->gran += 1;
248 }
249 resource->limit = limit = moving | (resource->size - 1);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000250 }
251
252 if (moving == 0) {
253 if (value != 0) {
254 printk_debug("%s register %02x(%08x), read-only ignoring it\n",
255 dev_path(dev), index, value);
256 }
257 resource->flags = 0;
258 } else {
259 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY;
260 }
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000261}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000262
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000263/** Read the base address registers for a given device.
264 * @param dev Pointer to the dev structure
265 * @param howmany How many registers to read (6 for device, 2 for bridge)
266 */
267static void pci_read_bases(struct device *dev, unsigned int howmany, unsigned long rom)
268{
269 unsigned long index;
270
271 for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
272 struct resource *resource;
273 resource = pci_get_resource(dev, index);
274 index += (resource->flags & IORESOURCE_PCI64)?8:4;
275 }
276 if (rom)
277 pci_get_rom_resource(dev, rom);
278
279 compact_resources(dev);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000280}
281
Eric Biederman03acab62004-10-14 21:25:53 +0000282static void pci_set_resource(struct device *dev, struct resource *resource);
283
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000284static void pci_record_bridge_resource( struct device *dev, resource_t moving,
285 unsigned index, unsigned long mask,
286 unsigned long type)
Eric Biederman03acab62004-10-14 21:25:53 +0000287{
288 /* Initiliaze the constraints on the current bus */
289 struct resource *resource;
290 resource = 0;
291 if (moving) {
292 unsigned long gran;
293 resource_t step;
294 resource = new_resource(dev, index);
295 resource->size = 0;
296 gran = 0;
297 step = 1;
298 while((moving & step) == 0) {
299 gran += 1;
300 step <<= 1;
301 }
302 resource->gran = gran;
303 resource->align = gran;
304 resource->limit = moving | (step - 1);
305 resource->flags = type | IORESOURCE_PCI_BRIDGE;
306 compute_allocate_resource(&dev->link[0], resource, mask, type);
307 /* If there is nothing behind the resource,
308 * clear it and forget it.
309 */
310 if (resource->size == 0) {
311 resource->base = moving;
312 resource->flags |= IORESOURCE_ASSIGNED;
313 resource->flags &= ~IORESOURCE_STORED;
314 pci_set_resource(dev, resource);
315 resource->flags = 0;
316 }
317 }
318 return;
319}
320
Eric Biederman8ca8d762003-04-22 19:02:15 +0000321static void pci_bridge_read_bases(struct device *dev)
322{
Eric Biederman03acab62004-10-14 21:25:53 +0000323 resource_t moving_base, moving_limit, moving;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000324
Eric Biederman03acab62004-10-14 21:25:53 +0000325 /* See if the bridge I/O resources are implemented */
326 moving_base = ((uint32_t)pci_moving_config8(dev, PCI_IO_BASE)) << 8;
327 moving_base |= ((uint32_t)pci_moving_config16(dev, PCI_IO_BASE_UPPER16)) << 16;
328
329 moving_limit = ((uint32_t)pci_moving_config8(dev, PCI_IO_LIMIT)) << 8;
330 moving_limit |= ((uint32_t)pci_moving_config16(dev, PCI_IO_LIMIT_UPPER16)) << 16;
331
332 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000333
334 /* Initialize the io space constraints on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000335 pci_record_bridge_resource(dev, moving, PCI_IO_BASE,
336 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000337
338 /* See if the bridge prefmem resources are implemented */
339 moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
340 moving_base |= ((resource_t)pci_moving_config32(dev, PCI_PREF_BASE_UPPER32)) << 32;
341
342 moving_limit = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_LIMIT)) << 16;
343 moving_limit |= ((resource_t)pci_moving_config32(dev, PCI_PREF_LIMIT_UPPER32)) << 32;
344
345 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000346 /* Initiliaze the prefetchable memory constraints on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000347 pci_record_bridge_resource(dev, moving, PCI_PREF_MEMORY_BASE,
348 IORESOURCE_MEM | IORESOURCE_PREFETCH,
349 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000350
351 /* See if the bridge mem resources are implemented */
352 moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
353 moving_limit = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_LIMIT)) << 16;
354
355 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000356
357 /* Initialize the memory resources on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000358 pci_record_bridge_resource(dev, moving, PCI_MEMORY_BASE,
359 IORESOURCE_MEM | IORESOURCE_PREFETCH,
360 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000361
Eric Biederman5cd81732004-03-11 15:01:31 +0000362 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000363}
364
Eric Biederman5899fd82003-04-24 06:25:08 +0000365void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000366{
367 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000368
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000369 pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000370}
371
Eric Biederman5899fd82003-04-24 06:25:08 +0000372void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000373{
374 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000375
Eric Biederman8ca8d762003-04-22 19:02:15 +0000376 pci_bridge_read_bases(dev);
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000377 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000378}
379
Eric Biederman8ca8d762003-04-22 19:02:15 +0000380static void pci_set_resource(struct device *dev, struct resource *resource)
381{
Eric Biederman03acab62004-10-14 21:25:53 +0000382 resource_t base, end;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000383
Eric Biederman8ca8d762003-04-22 19:02:15 +0000384 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000385 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000386 printk_err("ERROR: %s %02x not allocated\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000387 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000388 return;
389 }
390
Eric Biederman5cd81732004-03-11 15:01:31 +0000391 /* If I have already stored this resource don't worry about it */
392 if (resource->flags & IORESOURCE_STORED) {
393 return;
394 }
395
Eric Biederman03acab62004-10-14 21:25:53 +0000396 /* If the resources is substractive don't worry about it */
397 if (resource->flags & IORESOURCE_SUBTRACTIVE) {
398 return;
399 }
400
Eric Biederman8ca8d762003-04-22 19:02:15 +0000401 /* Only handle PCI memory and IO resources for now */
402 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
403 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000404
Eric Biederman03acab62004-10-14 21:25:53 +0000405 /* Enable the resources in the command register */
406 if (resource->size) {
407 if (resource->flags & IORESOURCE_MEM) {
408 dev->command |= PCI_COMMAND_MEMORY;
409 }
410 if (resource->flags & IORESOURCE_IO) {
411 dev->command |= PCI_COMMAND_IO;
412 }
413 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
414 dev->command |= PCI_COMMAND_MASTER;
415 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000416 }
417 /* Get the base address */
418 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000419
Eric Biederman03acab62004-10-14 21:25:53 +0000420 /* Get the end */
421 end = resource_end(resource);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000422
Eric Biederman5cd81732004-03-11 15:01:31 +0000423 /* Now store the resource */
424 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000425 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000426 unsigned long base_lo, base_hi;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000427 /*
428 * some chipsets allow us to set/clear the IO bit.
429 * (e.g. VIA 82c686a.) So set it to be safe)
430 */
Eric Biederman03acab62004-10-14 21:25:53 +0000431 base_lo = base & 0xffffffff;
432 base_hi = (base >> 32) & 0xffffffff;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000433 if (resource->flags & IORESOURCE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000434 base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000435 }
Eric Biederman03acab62004-10-14 21:25:53 +0000436 pci_write_config32(dev, resource->index, base_lo);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000437 if (resource->flags & IORESOURCE_PCI64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000438 pci_write_config32(dev, resource->index + 4, base_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000439 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000440 }
441 else if (resource->index == PCI_IO_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000442 /* set the IO ranges */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000443 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000444 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000445 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
446 pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16);
447 pci_write_config8(dev, PCI_IO_LIMIT, end >> 8);
448 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000449 }
450 else if (resource->index == PCI_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000451 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000452 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000453 IORESOURCE_MEM | IORESOURCE_PREFETCH,
454 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000455 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
Eric Biederman03acab62004-10-14 21:25:53 +0000456 pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000457 }
458 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000459 /* set the prefetchable memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000460 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000461 IORESOURCE_MEM | IORESOURCE_PREFETCH,
462 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000463 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
464 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32);
465 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16);
466 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, end >> 32);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000467 }
468 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000469 /* Don't let me think I stored the resource */
470 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000471 printk_err("ERROR: invalid resource->index %x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000472 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000473 }
Eric Biederman03acab62004-10-14 21:25:53 +0000474 report_resource_stored(dev, resource, "");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000475 return;
476}
477
Eric Biederman5899fd82003-04-24 06:25:08 +0000478void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000479{
480 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000481 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000482 uint8_t line;
483
484 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000485
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000486 for (resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000487 pci_set_resource(dev, resource);
488 }
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000489 for (link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000490 struct bus *bus;
491 bus = &dev->link[link];
492 if (bus->children) {
493 assign_resources(bus);
494 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000495 }
496
497 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000498 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000499
500 /* set a default secondary latency timer */
501 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000502 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000503 }
504
505 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000506 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000507 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000508 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000509 }
510 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000511 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000512}
513
Eric Biedermane9a271e32003-09-02 03:36:25 +0000514void pci_dev_enable_resources(struct device *dev)
515{
Eric Biedermana9e632c2004-11-18 22:38:08 +0000516 const struct pci_operations *ops;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000517 uint16_t command;
Eric Biederman03acab62004-10-14 21:25:53 +0000518
519 /* Set the subsystem vendor and device id for mainboard devices */
520 ops = ops_pci(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000521 if (dev->on_mainboard && ops && ops->set_subsystem) {
Eric Biederman03acab62004-10-14 21:25:53 +0000522 printk_debug("%s subsystem <- %02x/%02x\n",
523 dev_path(dev),
524 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
525 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
526 ops->set_subsystem(dev,
527 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
528 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
529 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000530 command = pci_read_config16(dev, PCI_COMMAND);
531 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000532 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000533 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
534 pci_write_config16(dev, PCI_COMMAND, command);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000535}
536
537void pci_bus_enable_resources(struct device *dev)
538{
539 uint16_t ctrl;
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000540
541 /* enable IO in command register if there is VGA card
542 * connected with (even it does not claim IO resource) */
543 if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
544 dev->command |= PCI_COMMAND_IO;
545
Eric Biedermane9a271e32003-09-02 03:36:25 +0000546 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
547 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000548 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000549 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
550 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
551
552 pci_dev_enable_resources(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000553
554 enable_childrens_resources(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000555}
556
Eric Biedermandbec2d42004-10-21 10:44:08 +0000557void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
Eric Biederman03acab62004-10-14 21:25:53 +0000558{
559 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
560 ((device & 0xffff) << 16) | (vendor & 0xffff));
561}
562
Li-Ta Lo883b8792005-01-10 23:16:22 +0000563void pci_dev_init(struct device *dev)
564{
565 struct rom_header *rom, *ram;
566
567 rom = pci_rom_probe(dev);
568 if (rom == NULL)
569 return;
570 ram = pci_rom_load(dev, rom);
571
572 run_bios(dev, ram);
573}
574
Li-Ta Loe5266692004-03-23 21:28:05 +0000575/** Default device operation for PCI devices */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000576static struct pci_operations pci_dev_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000577 .set_subsystem = pci_dev_set_subsystem,
578};
579
Eric Biederman8ca8d762003-04-22 19:02:15 +0000580struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000581 .read_resources = pci_dev_read_resources,
582 .set_resources = pci_dev_set_resources,
583 .enable_resources = pci_dev_enable_resources,
Li-Ta Lo883b8792005-01-10 23:16:22 +0000584 .init = pci_dev_init,
Li-Ta Loe5266692004-03-23 21:28:05 +0000585 .scan_bus = 0,
Eric Biederman03acab62004-10-14 21:25:53 +0000586 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000587 .ops_pci = &pci_dev_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000588};
Li-Ta Loe5266692004-03-23 21:28:05 +0000589
590/** Default device operations for PCI bridges */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000591static struct pci_operations pci_bus_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000592 .set_subsystem = 0,
593};
Li-Ta Lo883b8792005-01-10 23:16:22 +0000594
Eric Biederman8ca8d762003-04-22 19:02:15 +0000595struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000596 .read_resources = pci_bus_read_resources,
597 .set_resources = pci_dev_set_resources,
598 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000599 .init = 0,
600 .scan_bus = pci_scan_bridge,
Eric Biederman03acab62004-10-14 21:25:53 +0000601 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000602 .ops_pci = &pci_bus_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000603};
Li-Ta Loe5266692004-03-23 21:28:05 +0000604
605/**
606 * @brief Set up PCI device operation
607 *
608 *
609 * @param dev
610 *
611 * @see pci_drivers
612 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000613static void set_pci_ops(struct device *dev)
614{
615 struct pci_driver *driver;
616 if (dev->ops) {
617 return;
618 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000619
Eric Biederman8ca8d762003-04-22 19:02:15 +0000620 /* Look through the list of setup drivers and find one for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000621 * this pci device
622 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000623 for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000624 if ((driver->vendor == dev->vendor) &&
Li-Ta Lo04930692004-11-25 17:37:19 +0000625 (driver->device == dev->device))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000626 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000627 dev->ops = driver->ops;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000628 printk_debug("%s [%04x/%04x] %sops\n",
629 dev_path(dev),
630 driver->vendor, driver->device,
631 (driver->ops->scan_bus?"bus ":""));
Eric Biederman5899fd82003-04-24 06:25:08 +0000632 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000633 }
634 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000635
Eric Biederman8ca8d762003-04-22 19:02:15 +0000636 /* If I don't have a specific driver use the default operations */
637 switch(dev->hdr_type & 0x7f) { /* header type */
638 case PCI_HEADER_TYPE_NORMAL: /* standard header */
639 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
640 goto bad;
641 dev->ops = &default_pci_ops_dev;
642 break;
643 case PCI_HEADER_TYPE_BRIDGE:
644 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
645 goto bad;
646 dev->ops = &default_pci_ops_bus;
647 break;
648 default:
649 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000650 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000651 printk_err("%s [%04x/%04x/%06x] has unknown header "
Eric Biedermanb78c1972004-10-14 20:54:17 +0000652 "type %02x, ignoring.\n",
653 dev_path(dev),
654 dev->vendor, dev->device,
655 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000656 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000657 }
658 return;
659}
660
661/**
Eric Biederman03acab62004-10-14 21:25:53 +0000662 * @brief See if we have already allocated a device structure for a given devfn.
Li-Ta Loe5266692004-03-23 21:28:05 +0000663 *
664 * Given a linked list of PCI device structures and a devfn number, find the
Li-Ta Lo3a812852004-12-03 22:39:34 +0000665 * device structure correspond to the devfn, if present. This function also
666 * removes the device structure from the linked list.
Li-Ta Loe5266692004-03-23 21:28:05 +0000667 *
668 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000669 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000670 *
Li-Ta Lo3a812852004-12-03 22:39:34 +0000671 * @return pointer to the device structure found or null of we have not
672 * allocated a device for this devfn yet.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000673 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000674static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000675{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000676 struct device *dev;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000677 dev = 0;
678 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000679 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000680 printk_err("child %s not a pci device\n",
Li-Ta Lo3a812852004-12-03 22:39:34 +0000681 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000682 continue;
683 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000684 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000685 /* Unlink from the list */
686 dev = *list;
687 *list = (*list)->sibling;
688 dev->sibling = 0;
689 break;
690 }
691 }
Li-Ta Lo3a812852004-12-03 22:39:34 +0000692 /* Just like alloc_dev add the device to the list of device on the bus.
693 * When the list of devices was formed we removed all of the parents
694 * children, and now we are interleaving static and dynamic devices in
695 * order on the bus.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000696 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000697 if (dev) {
698 device_t child;
699 /* Find the last child of our parent */
Li-Ta Lo3a812852004-12-03 22:39:34 +0000700 for (child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000701 child = child->sibling;
702 }
703 /* Place the device on the list of children of it's parent. */
704 if (child) {
705 child->sibling = dev;
706 } else {
707 dev->bus->children = dev;
708 }
709 }
710
Eric Biederman8ca8d762003-04-22 19:02:15 +0000711 return dev;
712}
713
Eric Biedermanb78c1972004-10-14 20:54:17 +0000714/**
715 * @brief Scan a PCI bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000716 *
717 * Determine the existence of devices and bridges on a PCI bus. If there are
718 * bridges on the bus, recursively scan the buses behind the bridges.
719 *
Eric Biedermane9a271e32003-09-02 03:36:25 +0000720 * @param bus pointer to the bus structure
721 * @param min_devfn minimum devfn to look at in the scan usually 0x00
722 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000723 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +0000724 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000725 * @return The maximum bus number found, after scanning all subordinate busses
726 */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000727unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn,
728 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000729{
730 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000731 device_t dev;
732 device_t old_devices;
733 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000734
735 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
736
737 old_devices = bus->children;
738 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000739
740 post_code(0x24);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000741
Li-Ta Lo9782f752004-05-05 21:15:42 +0000742 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000743 * non-existence and single funcion devices
744 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000745 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000746 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000747 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000748
Eric Biederman03acab62004-10-14 21:25:53 +0000749 /* First thing setup the device structure */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000750 dev = pci_scan_get_dev(&old_devices, devfn);
Eric Biederman03acab62004-10-14 21:25:53 +0000751
752 /* Detect if a device is present */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000753 if (!dev) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000754 struct device dummy;
755 dummy.bus = bus;
756 dummy.path.type = DEVICE_PATH_PCI;
757 dummy.path.u.pci.devfn = devfn;
758 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
759 /* some broken boards return 0 if a slot is empty: */
Li-Ta Lo04930692004-11-25 17:37:19 +0000760 if ((id == 0xffffffff) || (id == 0x00000000) ||
761 (id == 0x0000ffff) || (id == 0xffff0000))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000762 {
763 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000764 if (PCI_FUNC(devfn) == 0x00) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000765 /* if this is a function 0 device and
766 * it is not present,
767 * skip to next device
768 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000769 devfn += 0x07;
770 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000771 /* This function in a multi function device is
772 * not present, skip to the next function.
773 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000774 continue;
775 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000776 dev = alloc_dev(bus, &dummy.path);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000777 }
778 else {
Eric Biederman03acab62004-10-14 21:25:53 +0000779 /* Enable/disable the device. Once we have
780 * found the device specific operations this
781 * operations we will disable the device with
782 * those as well.
783 *
Eric Biedermanb78c1972004-10-14 20:54:17 +0000784 * This is geared toward devices that have subfunctions
785 * that do not show up by default.
786 *
787 * If a device is a stuff option on the motherboard
788 * it may be absent and enable_dev must cope.
789 *
790 */
Eric Biederman7003ba42004-10-16 06:20:29 +0000791 if (dev->chip_ops && dev->chip_ops->enable_dev)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000792 {
Eric Biederman7003ba42004-10-16 06:20:29 +0000793 dev->chip_ops->enable_dev(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000794 }
795 /* Now read the vendor and device id */
796 id = pci_read_config32(dev, PCI_VENDOR_ID);
Eric Biederman03acab62004-10-14 21:25:53 +0000797
798 /* If the device does not have a pci id disable it.
799 * Possibly this is because we have already disabled
800 * the device. But this also handles optional devices
801 * that may not always show up.
802 */
803 if (id == 0xffffffff || id == 0x00000000 ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000804 id == 0x0000ffff || id == 0xffff0000)
Eric Biederman03acab62004-10-14 21:25:53 +0000805 {
806 if (dev->enabled) {
807 printk_info("Disabling static device: %s\n",
808 dev_path(dev));
809 dev->enabled = 0;
810 }
811 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000812 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000813 /* Read the rest of the pci configuration information */
814 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
815 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000816
Eric Biedermane9a271e32003-09-02 03:36:25 +0000817 /* Store the interesting information in the device structure */
818 dev->vendor = id & 0xffff;
819 dev->device = (id >> 16) & 0xffff;
820 dev->hdr_type = hdr_type;
821 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
822 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000823
Eric Biederman03acab62004-10-14 21:25:53 +0000824 /* Architectural/System devices always need to
825 * be bus masters.
826 */
827 if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
828 dev->command |= PCI_COMMAND_MASTER;
829 }
830
Eric Biederman8ca8d762003-04-22 19:02:15 +0000831 /* Look at the vendor and device id, or at least the
Li-Ta Loe5266692004-03-23 21:28:05 +0000832 * header type and class and figure out which set of
833 * configuration methods to use. Unless we already
834 * have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000835 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000836 set_pci_ops(dev);
837 /* Error if we don't have some pci operations for it */
Eric Biederman5cd81732004-03-11 15:01:31 +0000838 if (!dev->ops) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000839 printk_err("%s No device operations\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000840 dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000841 continue;
842 }
843
844 /* Now run the magic enable/disable sequence for the device */
845 if (dev->ops && dev->ops->enable) {
846 dev->ops->enable(dev);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000847 }
Eric Biederman4086d162003-07-17 03:26:03 +0000848
Eric Biedermane9a271e32003-09-02 03:36:25 +0000849 printk_debug("%s [%04x/%04x] %s\n",
Eric Biederman03acab62004-10-14 21:25:53 +0000850 dev_path(dev),
851 dev->vendor, dev->device,
852 dev->enabled?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000853
Eric Biederman8ca8d762003-04-22 19:02:15 +0000854 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000855 /* if this is not a multi function device,
856 * don't waste time probing another function.
857 * Skip to next device.
858 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000859 devfn += 0x07;
860 }
861 }
862 post_code(0x25);
863
Eric Biedermanb78c1972004-10-14 20:54:17 +0000864 /* For all children that implement scan_bus (i.e. bridges)
865 * scan the bus behind that child.
866 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000867 for (child = bus->children; child; child = child->sibling) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000868 if (!child->enabled ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000869 !child->ops ||
870 !child->ops->scan_bus)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000871 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000872 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000873 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000874 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000875 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000876
Eric Biederman8ca8d762003-04-22 19:02:15 +0000877 /*
878 * We've scanned the bus and so we know all about what's on
879 * the other side of any bridges that may be on this bus plus
880 * any devices.
881 *
882 * Return how far we've got finding sub-buses.
883 */
884 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
885 post_code(0x55);
886 return max;
887}
888
Li-Ta Loe5266692004-03-23 21:28:05 +0000889/**
890 * @brief Scan a PCI bridge and the buses behind the bridge.
891 *
892 * Determine the existence of buses behind the bridge. Set up the bridge
893 * according to the result of the scan.
894 *
895 * This function is the default scan_bus() method for PCI bridge devices.
896 *
897 * @param dev pointer to the bridge device
898 * @param max the highest bus number assgined up to now
899 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000900 * @return The maximum bus number found, after scanning all subordinate busses
901 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000902unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000903{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000904 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000905 uint32_t buses;
906 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000907
Li-Ta Lo3a812852004-12-03 22:39:34 +0000908 printk_spew("%s for %s\n", __func__, dev_path(dev));
909
Eric Biedermane9a271e32003-09-02 03:36:25 +0000910 bus = &dev->link[0];
Eric Biedermana9e632c2004-11-18 22:38:08 +0000911 bus->dev = dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000912 dev->links = 1;
913
Eric Biederman8ca8d762003-04-22 19:02:15 +0000914 /* Set up the primary, secondary and subordinate bus numbers. We have
915 * no idea how many buses are behind this bridge yet, so we set the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000916 * subordinate bus number to 0xff for the moment.
917 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000918 bus->secondary = ++max;
919 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +0000920
Eric Biederman8ca8d762003-04-22 19:02:15 +0000921 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000922 cr = pci_read_config16(dev, PCI_COMMAND);
923 pci_write_config16(dev, PCI_COMMAND, 0x0000);
924 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000925
Eric Biedermanb78c1972004-10-14 20:54:17 +0000926 /*
927 * Read the existing primary/secondary/subordinate bus
928 * number configuration.
929 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000930 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000931
932 /* Configure the bus numbers for this bridge: the configuration
933 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +0000934 * correctly configured.
935 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000936 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000937 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Li-Ta Lo3a812852004-12-03 22:39:34 +0000938 ((unsigned int) (bus->secondary) << 8) |
939 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000940 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000941
Eric Biedermanb78c1972004-10-14 20:54:17 +0000942 /* Now we can scan all subordinate buses
943 * i.e. the bus behind the bridge.
944 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000945 max = pci_scan_bus(bus, 0x00, 0xff, max);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000946
Eric Biederman8ca8d762003-04-22 19:02:15 +0000947 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +0000948 * bus number to its real value.
949 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000950 bus->subordinate = max;
951 buses = (buses & 0xff00ffff) |
952 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000953 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
954 pci_write_config16(dev, PCI_COMMAND, cr);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000955
Eric Biedermanb78c1972004-10-14 20:54:17 +0000956 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000957 return max;
958}
Li-Ta Loe5266692004-03-23 21:28:05 +0000959
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000960/*
961 Tell the EISA int controller this int must be level triggered
962 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
963*/
964static void pci_level_irq(unsigned char intNum)
965{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000966 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000967
Eric Biedermanb78c1972004-10-14 20:54:17 +0000968 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000969 intBits |= (1 << intNum);
970
Eric Biedermanb78c1972004-10-14 20:54:17 +0000971 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000972
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000973 // Write new values
974 outb((unsigned char) intBits, 0x4d0);
975 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000976
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000977 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000978#if 1
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000979 if (inb(0x4d0) != (intBits & 0xf)) {
980 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000981 __func__, intBits &0xf, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000982 }
983 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
984 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000985 __func__, (intBits>>8) &0xf, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000986 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000987#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000988}
989
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000990/*
991 This function assigns IRQs for all functions contained within
992 the indicated device address. If the device does not exist or does
993 not require interrupts then this function has no effect.
994
995 This function should be called for each PCI slot in your system.
996
997 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
998 this slot.
999 The particular irq #s that are passed in depend on the routing inside
1000 your southbridge and on your motherboard.
1001
1002 -kevinh@ispiri.com
1003*/
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +00001004void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4])
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001005{
1006 unsigned functNum;
1007 device_t pdev;
1008 unsigned char line;
1009 unsigned char irq;
1010 unsigned char readback;
1011
1012 /* Each slot may contain up to eight functions */
1013 for (functNum = 0; functNum < 8; functNum++) {
1014 pdev = dev_find_slot(bus, (slot << 3) + functNum);
1015
1016 if (pdev) {
1017 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
1018
1019 // PCI spec says all other values are reserved
1020 if ((line >= 1) && (line <= 4)) {
1021 irq = pIntAtoD[line - 1];
1022
1023 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
1024 irq, bus, slot, functNum);
1025
1026 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
1027 pIntAtoD[line - 1]);
1028
1029 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
1030 printk_debug(" Readback = %d\n", readback);
1031
1032 // Change to level triggered
1033 pci_level_irq(pIntAtoD[line - 1]);
1034 }
1035 }
1036 }
1037}