blob: 5d72f03ccd719579a9a348e35a401fdcfcc6c8e1 [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 Biederman83b991a2003-10-11 06:20:25 +000021#include <device/chip.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000022#include <part/hard_reset.h>
Eric Biederman30e143a2003-09-01 23:45:32 +000023#include <part/fallback_boot.h>
Eric Biederman03acab62004-10-14 21:25:53 +000024#include <delay.h>
25
26static uint8_t pci_moving_config8(struct device *dev, unsigned reg)
27{
28 uint8_t value, ones, zeroes;
29 value = pci_read_config8(dev, reg);
30
31 pci_write_config8(dev, reg, 0xff);
32 ones = pci_read_config8(dev, reg);
33
34 pci_write_config8(dev, reg, 0x00);
35 zeroes = pci_read_config8(dev, reg);
36
37 pci_write_config8(dev, reg, value);
38
39 return ones ^ zeroes;
40}
41static 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}
56static uint32_t pci_moving_config32(struct device *dev, unsigned reg)
57{
58 uint32_t value, ones, zeroes;
59 value = pci_read_config32(dev, reg);
60
61 pci_write_config32(dev, reg, 0xffffffff);
62 ones = pci_read_config32(dev, reg);
63
64 pci_write_config32(dev, reg, 0x00000000);
65 zeroes = pci_read_config32(dev, reg);
66
67 pci_write_config32(dev, reg, value);
68
69 return ones ^ zeroes;
70}
71
72unsigned pci_find_capability(device_t dev, unsigned cap)
73{
74 unsigned pos;
75 pos = 0;
76 switch(dev->hdr_type & 0x7f) {
77 case PCI_HEADER_TYPE_NORMAL:
78 case PCI_HEADER_TYPE_BRIDGE:
79 pos = PCI_CAPABILITY_LIST;
80 break;
81 }
82 if (pos > PCI_CAP_LIST_NEXT) {
83 pos = pci_read_config8(dev, pos);
84 }
85 while(pos != 0) { /* loop through the linked list */
86 int this_cap;
87 this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
88 if (this_cap == cap) {
89 return pos;
90 }
91 }
92 return 0;
93}
94
Eric Biederman8ca8d762003-04-22 19:02:15 +000095
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);
115
116 /* 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) &&
121 ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
122 {
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;
137 while(!(moving & resource->size)) {
138 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) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000157 printk_debug(
Eric Biedermane9a271e32003-09-02 03:36:25 +0000158 "%s register %02x(%08x), read-only ignoring it\n",
Eric Biederman03acab62004-10-14 21:25:53 +0000159 dev_path(dev), index, value);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000160 }
161 resource->flags = 0;
162 }
Eric Biederman03acab62004-10-14 21:25:53 +0000163 else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
164 /* An I/O mapped base address */
165 attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000166 resource->flags |= IORESOURCE_IO;
Eric Biederman03acab62004-10-14 21:25:53 +0000167 /* I don't want to deal with 32bit I/O resources */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000168 resource->limit = 0xffff;
169 }
170 else {
171 /* A Memory mapped base address */
Eric Biederman03acab62004-10-14 21:25:53 +0000172 attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000173 resource->flags |= IORESOURCE_MEM;
Eric Biederman03acab62004-10-14 21:25:53 +0000174 if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000175 resource->flags |= IORESOURCE_PREFETCH;
176 }
Eric Biederman03acab62004-10-14 21:25:53 +0000177 attr &= PCI_BASE_ADDRESS_MEM_LIMIT_MASK;
178 if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000179 /* 32bit limit */
180 resource->limit = 0xffffffffUL;
181 }
Eric Biederman03acab62004-10-14 21:25:53 +0000182 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000183 /* 1MB limit */
184 resource->limit = 0x000fffffUL;
185 }
Eric Biederman03acab62004-10-14 21:25:53 +0000186 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
187 /* 64bit limit */
188 resource->limit = 0xffffffffffffffffULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000189 resource->flags |= IORESOURCE_PCI64;
Eric Biederman03acab62004-10-14 21:25:53 +0000190 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000191 else {
192 /* Invalid value */
193 resource->flags = 0;
194 }
195 }
Eric Biederman03acab62004-10-14 21:25:53 +0000196 /* Don't let the limit exceed which bits can move */
197 if (resource->limit > limit) {
198 resource->limit = limit;
199 }
200#if 0
201 if (resource->flags) {
202 printk_debug("%s %02x ->",
203 dev_path(dev), resource->index);
204 printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
205 value, zeroes, ones, attr);
206 printk_debug(
207 "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ",
208 dev_path(dev),
209 resource->index,
210 resource->size, resource->limit,
211 (resource->flags == 0) ? "unused":
212 (resource->flags & IORESOURCE_IO)? "io":
213 (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem",
214 (resource->flags & IORESOURCE_PCI64)?"64":"");
215 }
216#endif
217
Eric Biederman5cd81732004-03-11 15:01:31 +0000218 return resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000219}
220
221/** Read the base address registers for a given device.
222 * @param dev Pointer to the dev structure
223 * @param howmany How many registers to read (6 for device, 2 for bridge)
224 */
225static void pci_read_bases(struct device *dev, unsigned int howmany)
226{
Eric Biederman8ca8d762003-04-22 19:02:15 +0000227 unsigned long index;
228
Eric Biedermanb78c1972004-10-14 20:54:17 +0000229 for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000230 struct resource *resource;
Eric Biederman5cd81732004-03-11 15:01:31 +0000231 resource = pci_get_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000232 index += (resource->flags & IORESOURCE_PCI64)?8:4;
233 }
Eric Biederman5cd81732004-03-11 15:01:31 +0000234 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000235}
236
Eric Biederman03acab62004-10-14 21:25:53 +0000237static void pci_set_resource(struct device *dev, struct resource *resource);
238
239static void pci_record_bridge_resource(
240 struct device *dev, resource_t moving,
241 unsigned index, unsigned long mask, unsigned long type)
242{
243 /* Initiliaze the constraints on the current bus */
244 struct resource *resource;
245 resource = 0;
246 if (moving) {
247 unsigned long gran;
248 resource_t step;
249 resource = new_resource(dev, index);
250 resource->size = 0;
251 gran = 0;
252 step = 1;
253 while((moving & step) == 0) {
254 gran += 1;
255 step <<= 1;
256 }
257 resource->gran = gran;
258 resource->align = gran;
259 resource->limit = moving | (step - 1);
260 resource->flags = type | IORESOURCE_PCI_BRIDGE;
261 compute_allocate_resource(&dev->link[0], resource, mask, type);
262 /* If there is nothing behind the resource,
263 * clear it and forget it.
264 */
265 if (resource->size == 0) {
266 resource->base = moving;
267 resource->flags |= IORESOURCE_ASSIGNED;
268 resource->flags &= ~IORESOURCE_STORED;
269 pci_set_resource(dev, resource);
270 resource->flags = 0;
271 }
272 }
273 return;
274}
275
276
Eric Biederman8ca8d762003-04-22 19:02:15 +0000277static void pci_bridge_read_bases(struct device *dev)
278{
Eric Biederman03acab62004-10-14 21:25:53 +0000279 resource_t moving_base, moving_limit, moving;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000280
Eric Biederman03acab62004-10-14 21:25:53 +0000281
282 /* See if the bridge I/O resources are implemented */
283 moving_base = ((uint32_t)pci_moving_config8(dev, PCI_IO_BASE)) << 8;
284 moving_base |= ((uint32_t)pci_moving_config16(dev, PCI_IO_BASE_UPPER16)) << 16;
285
286 moving_limit = ((uint32_t)pci_moving_config8(dev, PCI_IO_LIMIT)) << 8;
287 moving_limit |= ((uint32_t)pci_moving_config16(dev, PCI_IO_LIMIT_UPPER16)) << 16;
288
289 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000290
291 /* Initialize the io space constraints on the current bus */
Eric Biederman03acab62004-10-14 21:25:53 +0000292 pci_record_bridge_resource(
293 dev, moving, PCI_IO_BASE,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000294 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000295
Eric Biederman03acab62004-10-14 21:25:53 +0000296
297 /* See if the bridge prefmem resources are implemented */
298 moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
299 moving_base |= ((resource_t)pci_moving_config32(dev, PCI_PREF_BASE_UPPER32)) << 32;
300
301 moving_limit = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_LIMIT)) << 16;
302 moving_limit |= ((resource_t)pci_moving_config32(dev, PCI_PREF_LIMIT_UPPER32)) << 32;
303
304 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000305 /* Initiliaze the prefetchable memory constraints on the current bus */
Eric Biederman03acab62004-10-14 21:25:53 +0000306 pci_record_bridge_resource(
307 dev, moving, PCI_PREF_MEMORY_BASE,
308 IORESOURCE_MEM | IORESOURCE_PREFETCH,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000309 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000310
311
312 /* See if the bridge mem resources are implemented */
313 moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
314 moving_limit = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_LIMIT)) << 16;
315
316 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000317
318 /* Initialize the memory resources on the current bus */
Eric Biederman03acab62004-10-14 21:25:53 +0000319 pci_record_bridge_resource(
320 dev, moving, PCI_MEMORY_BASE,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000321 IORESOURCE_MEM | IORESOURCE_PREFETCH,
322 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000323
Eric Biederman5cd81732004-03-11 15:01:31 +0000324 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000325}
326
Eric Biederman5899fd82003-04-24 06:25:08 +0000327void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000328{
329 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000330
Eric Biederman8ca8d762003-04-22 19:02:15 +0000331 pci_read_bases(dev, 6);
Li-Ta Loe5266692004-03-23 21:28:05 +0000332
Eric Biederman7a5416a2003-06-12 19:23:51 +0000333 addr = pci_read_config32(dev, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000334 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
335}
336
Eric Biederman5899fd82003-04-24 06:25:08 +0000337void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000338{
339 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000340
Eric Biederman8ca8d762003-04-22 19:02:15 +0000341 pci_bridge_read_bases(dev);
342 pci_read_bases(dev, 2);
343
Eric Biederman7a5416a2003-06-12 19:23:51 +0000344 addr = pci_read_config32(dev, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000345 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000346}
347
Eric Biederman8ca8d762003-04-22 19:02:15 +0000348static void pci_set_resource(struct device *dev, struct resource *resource)
349{
Eric Biederman03acab62004-10-14 21:25:53 +0000350 resource_t base, end;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000351
Eric Biederman8ca8d762003-04-22 19:02:15 +0000352 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000353 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000354 printk_err("ERROR: %s %02x not allocated\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000355 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000356 return;
357 }
358
Eric Biederman5cd81732004-03-11 15:01:31 +0000359 /* If I have already stored this resource don't worry about it */
360 if (resource->flags & IORESOURCE_STORED) {
361 return;
362 }
363
Eric Biederman03acab62004-10-14 21:25:53 +0000364 /* If the resources is substractive don't worry about it */
365 if (resource->flags & IORESOURCE_SUBTRACTIVE) {
366 return;
367 }
368
Eric Biederman8ca8d762003-04-22 19:02:15 +0000369 /* Only handle PCI memory and IO resources for now */
370 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
371 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000372
Eric Biederman03acab62004-10-14 21:25:53 +0000373 /* Enable the resources in the command register */
374 if (resource->size) {
375 if (resource->flags & IORESOURCE_MEM) {
376 dev->command |= PCI_COMMAND_MEMORY;
377 }
378 if (resource->flags & IORESOURCE_IO) {
379 dev->command |= PCI_COMMAND_IO;
380 }
381 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
382 dev->command |= PCI_COMMAND_MASTER;
383 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000384 }
385 /* Get the base address */
386 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000387
Eric Biederman03acab62004-10-14 21:25:53 +0000388 /* Get the end */
389 end = resource_end(resource);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000390
Eric Biederman5cd81732004-03-11 15:01:31 +0000391 /* Now store the resource */
392 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000393 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000394 unsigned long base_lo, base_hi;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000395 /*
396 * some chipsets allow us to set/clear the IO bit.
397 * (e.g. VIA 82c686a.) So set it to be safe)
398 */
Eric Biederman03acab62004-10-14 21:25:53 +0000399 base_lo = base & 0xffffffff;
400 base_hi = (base >> 32) & 0xffffffff;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000401 if (resource->flags & IORESOURCE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000402 base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000403 }
Eric Biederman03acab62004-10-14 21:25:53 +0000404 pci_write_config32(dev, resource->index, base_lo);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000405 if (resource->flags & IORESOURCE_PCI64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000406 pci_write_config32(dev, resource->index + 4, base_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000407 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000408 }
409 else if (resource->index == PCI_IO_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000410 /* set the IO ranges */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000411 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000412 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000413 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
414 pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16);
415 pci_write_config8(dev, PCI_IO_LIMIT, end >> 8);
416 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000417 }
418 else if (resource->index == PCI_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000419 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000420 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000421 IORESOURCE_MEM | IORESOURCE_PREFETCH,
422 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000423 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
Eric Biederman03acab62004-10-14 21:25:53 +0000424 pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000425 }
426 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000427 /* set the prefetchable memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000428 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000429 IORESOURCE_MEM | IORESOURCE_PREFETCH,
430 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000431 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
432 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32);
433 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16);
434 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, end >> 32);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000435 }
436 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000437 /* Don't let me think I stored the resource */
438 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000439 printk_err("ERROR: invalid resource->index %x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000440 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000441 }
Eric Biederman03acab62004-10-14 21:25:53 +0000442 report_resource_stored(dev, resource, "");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000443 return;
444}
445
Eric Biederman5899fd82003-04-24 06:25:08 +0000446void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000447{
448 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000449 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000450 uint8_t line;
451
452 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000453
454 for(resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000455 pci_set_resource(dev, resource);
456 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000457 for(link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000458 struct bus *bus;
459 bus = &dev->link[link];
460 if (bus->children) {
461 assign_resources(bus);
462 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000463 }
464
465 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000466 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000467
468 /* set a default secondary latency timer */
469 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000470 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000471 }
472
473 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000474 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000475 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000476 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000477 }
478 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000479 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000480}
481
Eric Biedermane9a271e32003-09-02 03:36:25 +0000482void pci_dev_enable_resources(struct device *dev)
483{
Eric Biederman03acab62004-10-14 21:25:53 +0000484 struct pci_operations *ops;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000485 uint16_t command;
Eric Biederman03acab62004-10-14 21:25:53 +0000486
487 /* Set the subsystem vendor and device id for mainboard devices */
488 ops = ops_pci(dev);
489 if (dev->chip && ops && ops->set_subsystem) {
490 printk_debug("%s subsystem <- %02x/%02x\n",
491 dev_path(dev),
492 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
493 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
494 ops->set_subsystem(dev,
495 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
496 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
497 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000498 command = pci_read_config16(dev, PCI_COMMAND);
499 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000500 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000501 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
502 pci_write_config16(dev, PCI_COMMAND, command);
503
504 enable_childrens_resources(dev);
505}
506
507void pci_bus_enable_resources(struct device *dev)
508{
509 uint16_t ctrl;
510 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
511 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000512 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000513 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
514 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
515
516 pci_dev_enable_resources(dev);
517}
518
Eric Biederman03acab62004-10-14 21:25:53 +0000519static void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
520{
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 Biederman03acab62004-10-14 21:25:53 +0000526static struct pci_operations pci_ops_pci_dev = {
527 .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,
537 .ops_pci = &pci_ops_pci_dev,
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 Biederman03acab62004-10-14 21:25:53 +0000541static struct pci_operations pci_ops_pci_bus = {
542 .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,
551 .ops_pci = &pci_ops_pci_bus,
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 */
572 for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000573 if ((driver->vendor == dev->vendor) &&
Eric Biedermanb78c1972004-10-14 20:54:17 +0000574 (driver->device == dev->device))
575 {
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 *
668 * This function is the default scan_bus() method for the root device
669 * 'dev_root'.
670 *
Eric Biedermane9a271e32003-09-02 03:36:25 +0000671 * @param bus pointer to the bus structure
672 * @param min_devfn minimum devfn to look at in the scan usually 0x00
673 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000674 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +0000675 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000676 * @return The maximum bus number found, after scanning all subordinate busses
677 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000678unsigned int pci_scan_bus(struct bus *bus,
679 unsigned min_devfn, unsigned max_devfn,
680 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000681{
682 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000683 device_t dev;
684 device_t old_devices;
685 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000686
687 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
688
689 old_devices = bus->children;
690 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000691
692 post_code(0x24);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000693
Li-Ta Lo9782f752004-05-05 21:15:42 +0000694 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000695 * non-existence and single funcion devices
696 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000697 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000698 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000699 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000700
Eric Biederman03acab62004-10-14 21:25:53 +0000701 /* First thing setup the device structure */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000702 dev = pci_scan_get_dev(&old_devices, devfn);
Eric Biederman03acab62004-10-14 21:25:53 +0000703
704 /* Detect if a device is present */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000705 if (!dev) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000706 struct device dummy;
707 dummy.bus = bus;
708 dummy.path.type = DEVICE_PATH_PCI;
709 dummy.path.u.pci.devfn = devfn;
710 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
711 /* some broken boards return 0 if a slot is empty: */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000712 if ( (id == 0xffffffff) || (id == 0x00000000) ||
713 (id == 0x0000ffff) || (id == 0xffff0000))
714 {
715 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000716 if (PCI_FUNC(devfn) == 0x00) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000717 /* if this is a function 0 device and
718 * it is not present,
719 * skip to next device
720 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000721 devfn += 0x07;
722 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000723 /* This function in a multi function device is
724 * not present, skip to the next function.
725 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000726 continue;
727 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000728 dev = alloc_dev(bus, &dummy.path);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000729 }
730 else {
Eric Biederman03acab62004-10-14 21:25:53 +0000731 /* Enable/disable the device. Once we have
732 * found the device specific operations this
733 * operations we will disable the device with
734 * those as well.
735 *
Eric Biedermanb78c1972004-10-14 20:54:17 +0000736 * This is geared toward devices that have subfunctions
737 * that do not show up by default.
738 *
739 * If a device is a stuff option on the motherboard
740 * it may be absent and enable_dev must cope.
741 *
742 */
743 if ( dev->chip && dev->chip->control &&
744 dev->chip->control->enable_dev)
745 {
Eric Biederman83b991a2003-10-11 06:20:25 +0000746 dev->chip->control->enable_dev(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000747 }
748 /* Now read the vendor and device id */
749 id = pci_read_config32(dev, PCI_VENDOR_ID);
Eric Biederman03acab62004-10-14 21:25:53 +0000750
751 /* If the device does not have a pci id disable it.
752 * Possibly this is because we have already disabled
753 * the device. But this also handles optional devices
754 * that may not always show up.
755 */
756 if (id == 0xffffffff || id == 0x00000000 ||
757 id == 0x0000ffff || id == 0xffff0000)
758 {
759 if (dev->enabled) {
760 printk_info("Disabling static device: %s\n",
761 dev_path(dev));
762 dev->enabled = 0;
763 }
764 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000765 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000766 /* Read the rest of the pci configuration information */
767 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
768 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000769
Eric Biedermane9a271e32003-09-02 03:36:25 +0000770 /* Store the interesting information in the device structure */
771 dev->vendor = id & 0xffff;
772 dev->device = (id >> 16) & 0xffff;
773 dev->hdr_type = hdr_type;
774 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
775 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000776
Eric Biederman03acab62004-10-14 21:25:53 +0000777 /* Architectural/System devices always need to
778 * be bus masters.
779 */
780 if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
781 dev->command |= PCI_COMMAND_MASTER;
782 }
783
Eric Biederman8ca8d762003-04-22 19:02:15 +0000784 /* Look at the vendor and device id, or at least the
Li-Ta Loe5266692004-03-23 21:28:05 +0000785 * header type and class and figure out which set of
786 * configuration methods to use. Unless we already
787 * have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000788 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000789 set_pci_ops(dev);
790 /* Error if we don't have some pci operations for it */
Eric Biederman5cd81732004-03-11 15:01:31 +0000791 if (!dev->ops) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000792 printk_err("%s No device operations\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000793 dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000794 continue;
795 }
796
797 /* Now run the magic enable/disable sequence for the device */
798 if (dev->ops && dev->ops->enable) {
799 dev->ops->enable(dev);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000800 }
Eric Biederman4086d162003-07-17 03:26:03 +0000801
Eric Biedermane9a271e32003-09-02 03:36:25 +0000802 printk_debug("%s [%04x/%04x] %s\n",
Eric Biederman03acab62004-10-14 21:25:53 +0000803 dev_path(dev),
804 dev->vendor, dev->device,
805 dev->enabled?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000806
Eric Biederman8ca8d762003-04-22 19:02:15 +0000807 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000808 /* if this is not a multi function device,
809 * don't waste time probing another function.
810 * Skip to next device.
811 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000812 devfn += 0x07;
813 }
814 }
815 post_code(0x25);
816
Eric Biedermanb78c1972004-10-14 20:54:17 +0000817 /* For all children that implement scan_bus (i.e. bridges)
818 * scan the bus behind that child.
819 */
820 for(child = bus->children; child; child = child->sibling) {
821 if (!child->enabled ||
822 !child->ops ||
823 !child->ops->scan_bus)
824 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000825 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000826 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000827 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000828 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000829
Eric Biederman8ca8d762003-04-22 19:02:15 +0000830 /*
831 * We've scanned the bus and so we know all about what's on
832 * the other side of any bridges that may be on this bus plus
833 * any devices.
834 *
835 * Return how far we've got finding sub-buses.
836 */
837 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
838 post_code(0x55);
839 return max;
840}
841
Li-Ta Loe5266692004-03-23 21:28:05 +0000842/**
843 * @brief Scan a PCI bridge and the buses behind the bridge.
844 *
845 * Determine the existence of buses behind the bridge. Set up the bridge
846 * according to the result of the scan.
847 *
848 * This function is the default scan_bus() method for PCI bridge devices.
849 *
850 * @param dev pointer to the bridge device
851 * @param max the highest bus number assgined up to now
852 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000853 * @return The maximum bus number found, after scanning all subordinate busses
854 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000855unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000856{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000857 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000858 uint32_t buses;
859 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000860
Eric Biedermane9a271e32003-09-02 03:36:25 +0000861 bus = &dev->link[0];
862 dev->links = 1;
863
Eric Biederman8ca8d762003-04-22 19:02:15 +0000864 /* Set up the primary, secondary and subordinate bus numbers. We have
865 * no idea how many buses are behind this bridge yet, so we set the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000866 * subordinate bus number to 0xff for the moment.
867 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000868 bus->secondary = ++max;
869 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +0000870
Eric Biederman8ca8d762003-04-22 19:02:15 +0000871 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000872 cr = pci_read_config16(dev, PCI_COMMAND);
873 pci_write_config16(dev, PCI_COMMAND, 0x0000);
874 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000875
Eric Biedermanb78c1972004-10-14 20:54:17 +0000876 /*
877 * Read the existing primary/secondary/subordinate bus
878 * number configuration.
879 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000880 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000881
882 /* Configure the bus numbers for this bridge: the configuration
883 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +0000884 * correctly configured.
885 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000886 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000887 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Eric Biedermanb78c1972004-10-14 20:54:17 +0000888 ((unsigned int) (bus->secondary) << 8) |
889 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000890 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000891
892 /* Now we can scan all subordinate buses
893 * i.e. the bus behind the bridge.
894 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000895 max = pci_scan_bus(bus, 0x00, 0xff, max);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000896
Eric Biederman8ca8d762003-04-22 19:02:15 +0000897 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +0000898 * bus number to its real value.
899 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000900 bus->subordinate = max;
901 buses = (buses & 0xff00ffff) |
902 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000903 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
904 pci_write_config16(dev, PCI_COMMAND, cr);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000905
906 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000907 return max;
908}
Li-Ta Loe5266692004-03-23 21:28:05 +0000909
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000910/*
911 Tell the EISA int controller this int must be level triggered
912 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
913*/
914static void pci_level_irq(unsigned char intNum)
915{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000916 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000917
Eric Biedermanb78c1972004-10-14 20:54:17 +0000918 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000919 intBits |= (1 << intNum);
920
Eric Biedermanb78c1972004-10-14 20:54:17 +0000921 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000922
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000923 // Write new values
924 outb((unsigned char) intBits, 0x4d0);
925 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000926
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000927 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000928#if 1
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000929 if (inb(0x4d0) != (intBits & 0xf)) {
930 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000931 __func__, intBits &0xf, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000932 }
933 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
934 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000935 __func__, (intBits>>8) &0xf, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000936 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000937#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000938}
939
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000940/*
941 This function assigns IRQs for all functions contained within
942 the indicated device address. If the device does not exist or does
943 not require interrupts then this function has no effect.
944
945 This function should be called for each PCI slot in your system.
946
947 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
948 this slot.
949 The particular irq #s that are passed in depend on the routing inside
950 your southbridge and on your motherboard.
951
952 -kevinh@ispiri.com
953*/
954void pci_assign_irqs(unsigned bus, unsigned slot,
955 const unsigned char pIntAtoD[4])
956{
957 unsigned functNum;
958 device_t pdev;
959 unsigned char line;
960 unsigned char irq;
961 unsigned char readback;
962
963 /* Each slot may contain up to eight functions */
964 for (functNum = 0; functNum < 8; functNum++) {
965 pdev = dev_find_slot(bus, (slot << 3) + functNum);
966
967 if (pdev) {
968 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
969
970 // PCI spec says all other values are reserved
971 if ((line >= 1) && (line <= 4)) {
972 irq = pIntAtoD[line - 1];
973
974 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
975 irq, bus, slot, functNum);
976
977 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
978 pIntAtoD[line - 1]);
979
980 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
981 printk_debug(" Readback = %d\n", readback);
982
983 // Change to level triggered
984 pci_level_irq(pIntAtoD[line - 1]);
985 }
986 }
987 }
988}