blob: 4aef2229b301930cf152bc3aa46f97987fb63f07 [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
Yinghai Lubcde1612005-01-14 05:34:09 +0000221 if ((dev->on_mainboard) && (dev->rom_address == 0)) { //skip it if rom_address is not set in MB Config.lb
222 return;
223 }
224
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000225 /* Initialize the resources to nothing */
226 resource = new_resource(dev, index);
227
228 /* Get the initial value */
229 value = pci_read_config32(dev, index);
230
231 /* See which bits move */
232 moving = pci_moving_config32(dev, index);
233 /* clear the Enable bit */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000234 moving = moving & ~PCI_ROM_ADDRESS_ENABLE;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000235
236 /* Find the resource constraints.
237 *
238 * Start by finding the bits that move. From there:
239 * - Size is the least significant bit of the bits that move.
240 * - Limit is all of the bits that move plus all of the lower bits.
241 * See PCI Spec 6.2.5.1 ...
242 */
243 limit = 0;
244
245 if (moving) {
246 resource->size = 1;
247 resource->align = resource->gran = 0;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000248 while (!(moving & resource->size)) {
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000249 resource->size <<= 1;
250 resource->align += 1;
251 resource->gran += 1;
252 }
253 resource->limit = limit = moving | (resource->size - 1);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000254 }
255
256 if (moving == 0) {
257 if (value != 0) {
258 printk_debug("%s register %02x(%08x), read-only ignoring it\n",
259 dev_path(dev), index, value);
260 }
261 resource->flags = 0;
262 } else {
263 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY;
264 }
Yinghai Luc7870ac2005-01-13 19:14:52 +0000265
266 /* for on board device with embedded ROM image, the ROM image is at
267 * fixed address specified in the Config.lb, the dev->rom_address is
268 * inited by driver_pci_onboard_ops::enable_dev() */
Yinghai Lubcde1612005-01-14 05:34:09 +0000269 if ((dev->on_mainboard) && (dev->rom_address != 0)) {
Yinghai Luc7870ac2005-01-13 19:14:52 +0000270 resource->base = dev->rom_address;
271 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY |
272 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
273 }
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000274}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000275
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000276/** Read the base address registers for a given device.
277 * @param dev Pointer to the dev structure
278 * @param howmany How many registers to read (6 for device, 2 for bridge)
279 */
280static void pci_read_bases(struct device *dev, unsigned int howmany, unsigned long rom)
281{
282 unsigned long index;
283
284 for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
285 struct resource *resource;
286 resource = pci_get_resource(dev, index);
287 index += (resource->flags & IORESOURCE_PCI64)?8:4;
288 }
Li-Ta Lobc5399a2005-01-13 05:44:16 +0000289 if (rom)
290 pci_get_rom_resource(dev, rom);
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000291
292 compact_resources(dev);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000293}
294
Eric Biederman03acab62004-10-14 21:25:53 +0000295static void pci_set_resource(struct device *dev, struct resource *resource);
296
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000297static void pci_record_bridge_resource( struct device *dev, resource_t moving,
298 unsigned index, unsigned long mask,
299 unsigned long type)
Eric Biederman03acab62004-10-14 21:25:53 +0000300{
301 /* Initiliaze the constraints on the current bus */
302 struct resource *resource;
303 resource = 0;
304 if (moving) {
305 unsigned long gran;
306 resource_t step;
307 resource = new_resource(dev, index);
308 resource->size = 0;
309 gran = 0;
310 step = 1;
311 while((moving & step) == 0) {
312 gran += 1;
313 step <<= 1;
314 }
315 resource->gran = gran;
316 resource->align = gran;
317 resource->limit = moving | (step - 1);
318 resource->flags = type | IORESOURCE_PCI_BRIDGE;
319 compute_allocate_resource(&dev->link[0], resource, mask, type);
320 /* If there is nothing behind the resource,
321 * clear it and forget it.
322 */
323 if (resource->size == 0) {
324 resource->base = moving;
325 resource->flags |= IORESOURCE_ASSIGNED;
326 resource->flags &= ~IORESOURCE_STORED;
327 pci_set_resource(dev, resource);
328 resource->flags = 0;
329 }
330 }
331 return;
332}
333
Eric Biederman8ca8d762003-04-22 19:02:15 +0000334static void pci_bridge_read_bases(struct device *dev)
335{
Eric Biederman03acab62004-10-14 21:25:53 +0000336 resource_t moving_base, moving_limit, moving;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000337
Eric Biederman03acab62004-10-14 21:25:53 +0000338 /* See if the bridge I/O resources are implemented */
339 moving_base = ((uint32_t)pci_moving_config8(dev, PCI_IO_BASE)) << 8;
340 moving_base |= ((uint32_t)pci_moving_config16(dev, PCI_IO_BASE_UPPER16)) << 16;
341
342 moving_limit = ((uint32_t)pci_moving_config8(dev, PCI_IO_LIMIT)) << 8;
343 moving_limit |= ((uint32_t)pci_moving_config16(dev, PCI_IO_LIMIT_UPPER16)) << 16;
344
345 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000346
347 /* Initialize the io space constraints on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000348 pci_record_bridge_resource(dev, moving, PCI_IO_BASE,
349 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000350
351 /* See if the bridge prefmem resources are implemented */
352 moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
353 moving_base |= ((resource_t)pci_moving_config32(dev, PCI_PREF_BASE_UPPER32)) << 32;
354
355 moving_limit = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_LIMIT)) << 16;
356 moving_limit |= ((resource_t)pci_moving_config32(dev, PCI_PREF_LIMIT_UPPER32)) << 32;
357
358 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000359 /* Initiliaze the prefetchable memory constraints on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000360 pci_record_bridge_resource(dev, moving, PCI_PREF_MEMORY_BASE,
361 IORESOURCE_MEM | IORESOURCE_PREFETCH,
362 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000363
364 /* See if the bridge mem resources are implemented */
365 moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
366 moving_limit = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_LIMIT)) << 16;
367
368 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000369
370 /* Initialize the memory resources on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000371 pci_record_bridge_resource(dev, moving, PCI_MEMORY_BASE,
372 IORESOURCE_MEM | IORESOURCE_PREFETCH,
373 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000374
Eric Biederman5cd81732004-03-11 15:01:31 +0000375 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000376}
377
Eric Biederman5899fd82003-04-24 06:25:08 +0000378void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000379{
380 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000381
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000382 pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000383}
384
Eric Biederman5899fd82003-04-24 06:25:08 +0000385void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000386{
387 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000388
Eric Biederman8ca8d762003-04-22 19:02:15 +0000389 pci_bridge_read_bases(dev);
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000390 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000391}
392
Eric Biederman8ca8d762003-04-22 19:02:15 +0000393static void pci_set_resource(struct device *dev, struct resource *resource)
394{
Eric Biederman03acab62004-10-14 21:25:53 +0000395 resource_t base, end;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000396
Eric Biederman8ca8d762003-04-22 19:02:15 +0000397 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000398 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000399 printk_err("ERROR: %s %02x not allocated\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000400 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000401 return;
402 }
403
Eric Biederman5cd81732004-03-11 15:01:31 +0000404 /* If I have already stored this resource don't worry about it */
405 if (resource->flags & IORESOURCE_STORED) {
406 return;
407 }
408
Eric Biederman03acab62004-10-14 21:25:53 +0000409 /* If the resources is substractive don't worry about it */
410 if (resource->flags & IORESOURCE_SUBTRACTIVE) {
411 return;
412 }
413
Eric Biederman8ca8d762003-04-22 19:02:15 +0000414 /* Only handle PCI memory and IO resources for now */
415 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
416 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000417
Eric Biederman03acab62004-10-14 21:25:53 +0000418 /* Enable the resources in the command register */
419 if (resource->size) {
420 if (resource->flags & IORESOURCE_MEM) {
421 dev->command |= PCI_COMMAND_MEMORY;
422 }
423 if (resource->flags & IORESOURCE_IO) {
424 dev->command |= PCI_COMMAND_IO;
425 }
426 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
427 dev->command |= PCI_COMMAND_MASTER;
428 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000429 }
430 /* Get the base address */
431 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000432
Eric Biederman03acab62004-10-14 21:25:53 +0000433 /* Get the end */
434 end = resource_end(resource);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000435
Eric Biederman5cd81732004-03-11 15:01:31 +0000436 /* Now store the resource */
437 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000438 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000439 unsigned long base_lo, base_hi;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000440 /*
441 * some chipsets allow us to set/clear the IO bit.
442 * (e.g. VIA 82c686a.) So set it to be safe)
443 */
Eric Biederman03acab62004-10-14 21:25:53 +0000444 base_lo = base & 0xffffffff;
445 base_hi = (base >> 32) & 0xffffffff;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000446 if (resource->flags & IORESOURCE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000447 base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000448 }
Eric Biederman03acab62004-10-14 21:25:53 +0000449 pci_write_config32(dev, resource->index, base_lo);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000450 if (resource->flags & IORESOURCE_PCI64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000451 pci_write_config32(dev, resource->index + 4, base_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000452 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000453 }
454 else if (resource->index == PCI_IO_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000455 /* set the IO ranges */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000456 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000457 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000458 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
459 pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16);
460 pci_write_config8(dev, PCI_IO_LIMIT, end >> 8);
461 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000462 }
463 else if (resource->index == PCI_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000464 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000465 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000466 IORESOURCE_MEM | IORESOURCE_PREFETCH,
467 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000468 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
Eric Biederman03acab62004-10-14 21:25:53 +0000469 pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000470 }
471 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000472 /* set the prefetchable memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000473 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000474 IORESOURCE_MEM | IORESOURCE_PREFETCH,
475 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000476 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
477 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32);
478 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16);
479 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, end >> 32);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000480 }
481 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000482 /* Don't let me think I stored the resource */
483 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000484 printk_err("ERROR: invalid resource->index %x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000485 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000486 }
Eric Biederman03acab62004-10-14 21:25:53 +0000487 report_resource_stored(dev, resource, "");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000488 return;
489}
490
Eric Biederman5899fd82003-04-24 06:25:08 +0000491void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000492{
493 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000494 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000495 uint8_t line;
496
497 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000498
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000499 for (resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000500 pci_set_resource(dev, resource);
501 }
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000502 for (link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000503 struct bus *bus;
504 bus = &dev->link[link];
505 if (bus->children) {
506 assign_resources(bus);
507 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000508 }
509
510 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000511 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000512
513 /* set a default secondary latency timer */
514 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000515 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000516 }
517
518 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000519 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000520 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000521 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000522 }
523 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000524 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000525}
526
Eric Biedermane9a271e32003-09-02 03:36:25 +0000527void pci_dev_enable_resources(struct device *dev)
528{
Eric Biedermana9e632c2004-11-18 22:38:08 +0000529 const struct pci_operations *ops;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000530 uint16_t command;
Eric Biederman03acab62004-10-14 21:25:53 +0000531
532 /* Set the subsystem vendor and device id for mainboard devices */
533 ops = ops_pci(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000534 if (dev->on_mainboard && ops && ops->set_subsystem) {
Eric Biederman03acab62004-10-14 21:25:53 +0000535 printk_debug("%s subsystem <- %02x/%02x\n",
536 dev_path(dev),
537 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
538 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
539 ops->set_subsystem(dev,
540 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
541 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
542 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000543 command = pci_read_config16(dev, PCI_COMMAND);
544 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000545 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000546 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
547 pci_write_config16(dev, PCI_COMMAND, command);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000548}
549
550void pci_bus_enable_resources(struct device *dev)
551{
552 uint16_t ctrl;
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000553
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000554#if CONFIG_CONSOLE_VGA == 1
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000555 /* enable IO in command register if there is VGA card
556 * connected with (even it does not claim IO resource) */
557 if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
558 dev->command |= PCI_COMMAND_IO;
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000559#endif
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000560
Eric Biedermane9a271e32003-09-02 03:36:25 +0000561 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
562 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000563 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000564 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
565 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
566
567 pci_dev_enable_resources(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000568
569 enable_childrens_resources(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000570}
571
Eric Biedermandbec2d42004-10-21 10:44:08 +0000572void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
Eric Biederman03acab62004-10-14 21:25:53 +0000573{
574 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
575 ((device & 0xffff) << 16) | (vendor & 0xffff));
576}
577
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000578#if CONFIG_PCI_ROM_RUN == 1
Li-Ta Lo883b8792005-01-10 23:16:22 +0000579void pci_dev_init(struct device *dev)
580{
581 struct rom_header *rom, *ram;
582
583 rom = pci_rom_probe(dev);
584 if (rom == NULL)
585 return;
586 ram = pci_rom_load(dev, rom);
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000587 if (ram == NULL)
588 return;
Li-Ta Lo883b8792005-01-10 23:16:22 +0000589
590 run_bios(dev, ram);
591}
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000592#endif
Li-Ta Lo883b8792005-01-10 23:16:22 +0000593
Li-Ta Loe5266692004-03-23 21:28:05 +0000594/** Default device operation for PCI devices */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000595static struct pci_operations pci_dev_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000596 .set_subsystem = pci_dev_set_subsystem,
597};
598
Eric Biederman8ca8d762003-04-22 19:02:15 +0000599struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000600 .read_resources = pci_dev_read_resources,
601 .set_resources = pci_dev_set_resources,
602 .enable_resources = pci_dev_enable_resources,
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000603#if CONFIG_PCI_ROM_RUN == 1
Li-Ta Lo883b8792005-01-10 23:16:22 +0000604 .init = pci_dev_init,
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000605#else
606 .init = 0,
607#endif
Li-Ta Loe5266692004-03-23 21:28:05 +0000608 .scan_bus = 0,
Eric Biederman03acab62004-10-14 21:25:53 +0000609 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000610 .ops_pci = &pci_dev_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000611};
Li-Ta Loe5266692004-03-23 21:28:05 +0000612
613/** Default device operations for PCI bridges */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000614static struct pci_operations pci_bus_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000615 .set_subsystem = 0,
616};
Li-Ta Lo883b8792005-01-10 23:16:22 +0000617
Eric Biederman8ca8d762003-04-22 19:02:15 +0000618struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000619 .read_resources = pci_bus_read_resources,
620 .set_resources = pci_dev_set_resources,
621 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000622 .init = 0,
623 .scan_bus = pci_scan_bridge,
Eric Biederman03acab62004-10-14 21:25:53 +0000624 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000625 .ops_pci = &pci_bus_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000626};
Li-Ta Loe5266692004-03-23 21:28:05 +0000627
628/**
629 * @brief Set up PCI device operation
630 *
631 *
632 * @param dev
633 *
634 * @see pci_drivers
635 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000636static void set_pci_ops(struct device *dev)
637{
638 struct pci_driver *driver;
639 if (dev->ops) {
640 return;
641 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000642
Eric Biederman8ca8d762003-04-22 19:02:15 +0000643 /* Look through the list of setup drivers and find one for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000644 * this pci device
645 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000646 for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000647 if ((driver->vendor == dev->vendor) &&
Li-Ta Lo04930692004-11-25 17:37:19 +0000648 (driver->device == dev->device))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000649 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000650 dev->ops = driver->ops;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000651 printk_debug("%s [%04x/%04x] %sops\n",
652 dev_path(dev),
653 driver->vendor, driver->device,
654 (driver->ops->scan_bus?"bus ":""));
Eric Biederman5899fd82003-04-24 06:25:08 +0000655 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000656 }
657 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000658
Eric Biederman8ca8d762003-04-22 19:02:15 +0000659 /* If I don't have a specific driver use the default operations */
660 switch(dev->hdr_type & 0x7f) { /* header type */
661 case PCI_HEADER_TYPE_NORMAL: /* standard header */
662 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
663 goto bad;
664 dev->ops = &default_pci_ops_dev;
665 break;
666 case PCI_HEADER_TYPE_BRIDGE:
667 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
668 goto bad;
669 dev->ops = &default_pci_ops_bus;
670 break;
671 default:
672 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000673 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000674 printk_err("%s [%04x/%04x/%06x] has unknown header "
Eric Biedermanb78c1972004-10-14 20:54:17 +0000675 "type %02x, ignoring.\n",
676 dev_path(dev),
677 dev->vendor, dev->device,
678 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000679 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000680 }
681 return;
682}
683
684/**
Eric Biederman03acab62004-10-14 21:25:53 +0000685 * @brief See if we have already allocated a device structure for a given devfn.
Li-Ta Loe5266692004-03-23 21:28:05 +0000686 *
687 * Given a linked list of PCI device structures and a devfn number, find the
Li-Ta Lo3a812852004-12-03 22:39:34 +0000688 * device structure correspond to the devfn, if present. This function also
689 * removes the device structure from the linked list.
Li-Ta Loe5266692004-03-23 21:28:05 +0000690 *
691 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000692 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000693 *
Li-Ta Lo3a812852004-12-03 22:39:34 +0000694 * @return pointer to the device structure found or null of we have not
695 * allocated a device for this devfn yet.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000696 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000697static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000698{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000699 struct device *dev;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000700 dev = 0;
701 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000702 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000703 printk_err("child %s not a pci device\n",
Li-Ta Lo3a812852004-12-03 22:39:34 +0000704 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000705 continue;
706 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000707 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000708 /* Unlink from the list */
709 dev = *list;
710 *list = (*list)->sibling;
711 dev->sibling = 0;
712 break;
713 }
714 }
Li-Ta Lo3a812852004-12-03 22:39:34 +0000715 /* Just like alloc_dev add the device to the list of device on the bus.
716 * When the list of devices was formed we removed all of the parents
717 * children, and now we are interleaving static and dynamic devices in
718 * order on the bus.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000719 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000720 if (dev) {
721 device_t child;
722 /* Find the last child of our parent */
Li-Ta Lo3a812852004-12-03 22:39:34 +0000723 for (child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000724 child = child->sibling;
725 }
726 /* Place the device on the list of children of it's parent. */
727 if (child) {
728 child->sibling = dev;
729 } else {
730 dev->bus->children = dev;
731 }
732 }
733
Eric Biederman8ca8d762003-04-22 19:02:15 +0000734 return dev;
735}
736
Eric Biedermanb78c1972004-10-14 20:54:17 +0000737/**
738 * @brief Scan a PCI bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000739 *
740 * Determine the existence of devices and bridges on a PCI bus. If there are
741 * bridges on the bus, recursively scan the buses behind the bridges.
742 *
Eric Biedermane9a271e32003-09-02 03:36:25 +0000743 * @param bus pointer to the bus structure
744 * @param min_devfn minimum devfn to look at in the scan usually 0x00
745 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000746 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +0000747 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000748 * @return The maximum bus number found, after scanning all subordinate busses
749 */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000750unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn,
751 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000752{
753 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000754 device_t dev;
755 device_t old_devices;
756 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000757
758 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
759
760 old_devices = bus->children;
761 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000762
763 post_code(0x24);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000764
Li-Ta Lo9782f752004-05-05 21:15:42 +0000765 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000766 * non-existence and single funcion devices
767 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000768 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000769 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000770 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000771
Eric Biederman03acab62004-10-14 21:25:53 +0000772 /* First thing setup the device structure */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000773 dev = pci_scan_get_dev(&old_devices, devfn);
Eric Biederman03acab62004-10-14 21:25:53 +0000774
775 /* Detect if a device is present */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000776 if (!dev) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000777 struct device dummy;
778 dummy.bus = bus;
779 dummy.path.type = DEVICE_PATH_PCI;
780 dummy.path.u.pci.devfn = devfn;
781 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
782 /* some broken boards return 0 if a slot is empty: */
Li-Ta Lo04930692004-11-25 17:37:19 +0000783 if ((id == 0xffffffff) || (id == 0x00000000) ||
784 (id == 0x0000ffff) || (id == 0xffff0000))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000785 {
786 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000787 if (PCI_FUNC(devfn) == 0x00) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000788 /* if this is a function 0 device and
789 * it is not present,
790 * skip to next device
791 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000792 devfn += 0x07;
793 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000794 /* This function in a multi function device is
795 * not present, skip to the next function.
796 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000797 continue;
798 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000799 dev = alloc_dev(bus, &dummy.path);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000800 }
801 else {
Eric Biederman03acab62004-10-14 21:25:53 +0000802 /* Enable/disable the device. Once we have
803 * found the device specific operations this
804 * operations we will disable the device with
805 * those as well.
806 *
Eric Biedermanb78c1972004-10-14 20:54:17 +0000807 * This is geared toward devices that have subfunctions
808 * that do not show up by default.
809 *
810 * If a device is a stuff option on the motherboard
811 * it may be absent and enable_dev must cope.
812 *
813 */
Eric Biederman7003ba42004-10-16 06:20:29 +0000814 if (dev->chip_ops && dev->chip_ops->enable_dev)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000815 {
Eric Biederman7003ba42004-10-16 06:20:29 +0000816 dev->chip_ops->enable_dev(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000817 }
818 /* Now read the vendor and device id */
819 id = pci_read_config32(dev, PCI_VENDOR_ID);
Eric Biederman03acab62004-10-14 21:25:53 +0000820
821 /* If the device does not have a pci id disable it.
822 * Possibly this is because we have already disabled
823 * the device. But this also handles optional devices
824 * that may not always show up.
825 */
826 if (id == 0xffffffff || id == 0x00000000 ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000827 id == 0x0000ffff || id == 0xffff0000)
Eric Biederman03acab62004-10-14 21:25:53 +0000828 {
829 if (dev->enabled) {
830 printk_info("Disabling static device: %s\n",
831 dev_path(dev));
832 dev->enabled = 0;
833 }
834 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000835 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000836 /* Read the rest of the pci configuration information */
837 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
838 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000839
Eric Biedermane9a271e32003-09-02 03:36:25 +0000840 /* Store the interesting information in the device structure */
841 dev->vendor = id & 0xffff;
842 dev->device = (id >> 16) & 0xffff;
843 dev->hdr_type = hdr_type;
844 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
845 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000846
Eric Biederman03acab62004-10-14 21:25:53 +0000847 /* Architectural/System devices always need to
848 * be bus masters.
849 */
850 if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
851 dev->command |= PCI_COMMAND_MASTER;
852 }
853
Eric Biederman8ca8d762003-04-22 19:02:15 +0000854 /* Look at the vendor and device id, or at least the
Li-Ta Loe5266692004-03-23 21:28:05 +0000855 * header type and class and figure out which set of
856 * configuration methods to use. Unless we already
857 * have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000858 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000859 set_pci_ops(dev);
860 /* Error if we don't have some pci operations for it */
Eric Biederman5cd81732004-03-11 15:01:31 +0000861 if (!dev->ops) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000862 printk_err("%s No device operations\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000863 dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000864 continue;
865 }
866
867 /* Now run the magic enable/disable sequence for the device */
868 if (dev->ops && dev->ops->enable) {
869 dev->ops->enable(dev);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000870 }
Eric Biederman4086d162003-07-17 03:26:03 +0000871
Eric Biedermane9a271e32003-09-02 03:36:25 +0000872 printk_debug("%s [%04x/%04x] %s\n",
Eric Biederman03acab62004-10-14 21:25:53 +0000873 dev_path(dev),
874 dev->vendor, dev->device,
875 dev->enabled?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000876
Eric Biederman8ca8d762003-04-22 19:02:15 +0000877 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000878 /* if this is not a multi function device,
879 * don't waste time probing another function.
880 * Skip to next device.
881 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000882 devfn += 0x07;
883 }
884 }
885 post_code(0x25);
886
Eric Biedermanb78c1972004-10-14 20:54:17 +0000887 /* For all children that implement scan_bus (i.e. bridges)
888 * scan the bus behind that child.
889 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000890 for (child = bus->children; child; child = child->sibling) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000891 if (!child->enabled ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000892 !child->ops ||
893 !child->ops->scan_bus)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000894 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000895 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000896 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000897 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000898 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000899
Eric Biederman8ca8d762003-04-22 19:02:15 +0000900 /*
901 * We've scanned the bus and so we know all about what's on
902 * the other side of any bridges that may be on this bus plus
903 * any devices.
904 *
905 * Return how far we've got finding sub-buses.
906 */
907 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
908 post_code(0x55);
909 return max;
910}
911
Li-Ta Loe5266692004-03-23 21:28:05 +0000912/**
913 * @brief Scan a PCI bridge and the buses behind the bridge.
914 *
915 * Determine the existence of buses behind the bridge. Set up the bridge
916 * according to the result of the scan.
917 *
918 * This function is the default scan_bus() method for PCI bridge devices.
919 *
920 * @param dev pointer to the bridge device
921 * @param max the highest bus number assgined up to now
922 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000923 * @return The maximum bus number found, after scanning all subordinate busses
924 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000925unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000926{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000927 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000928 uint32_t buses;
929 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000930
Li-Ta Lo3a812852004-12-03 22:39:34 +0000931 printk_spew("%s for %s\n", __func__, dev_path(dev));
932
Eric Biedermane9a271e32003-09-02 03:36:25 +0000933 bus = &dev->link[0];
Eric Biedermana9e632c2004-11-18 22:38:08 +0000934 bus->dev = dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000935 dev->links = 1;
936
Eric Biederman8ca8d762003-04-22 19:02:15 +0000937 /* Set up the primary, secondary and subordinate bus numbers. We have
938 * no idea how many buses are behind this bridge yet, so we set the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000939 * subordinate bus number to 0xff for the moment.
940 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000941 bus->secondary = ++max;
942 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +0000943
Eric Biederman8ca8d762003-04-22 19:02:15 +0000944 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000945 cr = pci_read_config16(dev, PCI_COMMAND);
946 pci_write_config16(dev, PCI_COMMAND, 0x0000);
947 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000948
Eric Biedermanb78c1972004-10-14 20:54:17 +0000949 /*
950 * Read the existing primary/secondary/subordinate bus
951 * number configuration.
952 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000953 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000954
955 /* Configure the bus numbers for this bridge: the configuration
956 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +0000957 * correctly configured.
958 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000959 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000960 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Li-Ta Lo3a812852004-12-03 22:39:34 +0000961 ((unsigned int) (bus->secondary) << 8) |
962 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000963 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000964
Eric Biedermanb78c1972004-10-14 20:54:17 +0000965 /* Now we can scan all subordinate buses
966 * i.e. the bus behind the bridge.
967 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000968 max = pci_scan_bus(bus, 0x00, 0xff, max);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000969
Eric Biederman8ca8d762003-04-22 19:02:15 +0000970 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +0000971 * bus number to its real value.
972 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000973 bus->subordinate = max;
974 buses = (buses & 0xff00ffff) |
975 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000976 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
977 pci_write_config16(dev, PCI_COMMAND, cr);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000978
Eric Biedermanb78c1972004-10-14 20:54:17 +0000979 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000980 return max;
981}
Li-Ta Loe5266692004-03-23 21:28:05 +0000982
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000983/*
984 Tell the EISA int controller this int must be level triggered
985 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
986*/
987static void pci_level_irq(unsigned char intNum)
988{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000989 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000990
Eric Biedermanb78c1972004-10-14 20:54:17 +0000991 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000992 intBits |= (1 << intNum);
993
Eric Biedermanb78c1972004-10-14 20:54:17 +0000994 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000995
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000996 // Write new values
997 outb((unsigned char) intBits, 0x4d0);
998 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000999
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001000 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +00001001#if 1
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001002 if (inb(0x4d0) != (intBits & 0xf)) {
1003 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +00001004 __func__, intBits &0xf, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001005 }
1006 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
1007 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +00001008 __func__, (intBits>>8) &0xf, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001009 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001010#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001011}
1012
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001013/*
1014 This function assigns IRQs for all functions contained within
1015 the indicated device address. If the device does not exist or does
1016 not require interrupts then this function has no effect.
1017
1018 This function should be called for each PCI slot in your system.
1019
1020 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
1021 this slot.
1022 The particular irq #s that are passed in depend on the routing inside
1023 your southbridge and on your motherboard.
1024
1025 -kevinh@ispiri.com
1026*/
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +00001027void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4])
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001028{
1029 unsigned functNum;
1030 device_t pdev;
1031 unsigned char line;
1032 unsigned char irq;
1033 unsigned char readback;
1034
1035 /* Each slot may contain up to eight functions */
1036 for (functNum = 0; functNum < 8; functNum++) {
1037 pdev = dev_find_slot(bus, (slot << 3) + functNum);
1038
1039 if (pdev) {
1040 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
1041
1042 // PCI spec says all other values are reserved
1043 if ((line >= 1) && (line <= 4)) {
1044 irq = pIntAtoD[line - 1];
1045
1046 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
1047 irq, bus, slot, functNum);
1048
1049 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
1050 pIntAtoD[line - 1]);
1051
1052 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
1053 printk_debug(" Readback = %d\n", readback);
1054
1055 // Change to level triggered
1056 pci_level_irq(pIntAtoD[line - 1]);
1057 }
1058 }
1059 }
1060}