blob: 0ad4e5591509697c0d6aca9dbc05d37aabedcaae [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
Li-Ta Lobec039c2005-01-19 23:19:26 +0000221 if ((dev->on_mainboard) && (dev->rom_address == 0)) {
222 //skip it if rom_address is not set in MB Config.lb
Yinghai Lubcde1612005-01-14 05:34:09 +0000223 return;
224 }
225
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000226 /* Initialize the resources to nothing */
227 resource = new_resource(dev, index);
228
229 /* Get the initial value */
230 value = pci_read_config32(dev, index);
231
232 /* See which bits move */
233 moving = pci_moving_config32(dev, index);
234 /* clear the Enable bit */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000235 moving = moving & ~PCI_ROM_ADDRESS_ENABLE;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000236
237 /* Find the resource constraints.
238 *
239 * Start by finding the bits that move. From there:
240 * - Size is the least significant bit of the bits that move.
241 * - Limit is all of the bits that move plus all of the lower bits.
242 * See PCI Spec 6.2.5.1 ...
243 */
244 limit = 0;
245
246 if (moving) {
247 resource->size = 1;
248 resource->align = resource->gran = 0;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000249 while (!(moving & resource->size)) {
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000250 resource->size <<= 1;
251 resource->align += 1;
252 resource->gran += 1;
253 }
254 resource->limit = limit = moving | (resource->size - 1);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000255 }
256
257 if (moving == 0) {
258 if (value != 0) {
259 printk_debug("%s register %02x(%08x), read-only ignoring it\n",
260 dev_path(dev), index, value);
261 }
262 resource->flags = 0;
263 } else {
264 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY;
265 }
Yinghai Luc7870ac2005-01-13 19:14:52 +0000266
267 /* for on board device with embedded ROM image, the ROM image is at
268 * fixed address specified in the Config.lb, the dev->rom_address is
269 * inited by driver_pci_onboard_ops::enable_dev() */
Yinghai Lubcde1612005-01-14 05:34:09 +0000270 if ((dev->on_mainboard) && (dev->rom_address != 0)) {
Yinghai Luc7870ac2005-01-13 19:14:52 +0000271 resource->base = dev->rom_address;
272 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY |
273 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
274 }
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000275}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000276
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000277/** Read the base address registers for a given device.
278 * @param dev Pointer to the dev structure
279 * @param howmany How many registers to read (6 for device, 2 for bridge)
280 */
281static void pci_read_bases(struct device *dev, unsigned int howmany, unsigned long rom)
282{
283 unsigned long index;
284
285 for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
286 struct resource *resource;
287 resource = pci_get_resource(dev, index);
288 index += (resource->flags & IORESOURCE_PCI64)?8:4;
289 }
Li-Ta Lobc5399a2005-01-13 05:44:16 +0000290 if (rom)
291 pci_get_rom_resource(dev, rom);
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000292
293 compact_resources(dev);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000294}
295
Eric Biederman03acab62004-10-14 21:25:53 +0000296static void pci_set_resource(struct device *dev, struct resource *resource);
297
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000298static void pci_record_bridge_resource( struct device *dev, resource_t moving,
299 unsigned index, unsigned long mask,
300 unsigned long type)
Eric Biederman03acab62004-10-14 21:25:53 +0000301{
302 /* Initiliaze the constraints on the current bus */
303 struct resource *resource;
304 resource = 0;
305 if (moving) {
306 unsigned long gran;
307 resource_t step;
308 resource = new_resource(dev, index);
309 resource->size = 0;
310 gran = 0;
311 step = 1;
312 while((moving & step) == 0) {
313 gran += 1;
314 step <<= 1;
315 }
316 resource->gran = gran;
317 resource->align = gran;
318 resource->limit = moving | (step - 1);
319 resource->flags = type | IORESOURCE_PCI_BRIDGE;
320 compute_allocate_resource(&dev->link[0], resource, mask, type);
321 /* If there is nothing behind the resource,
322 * clear it and forget it.
323 */
324 if (resource->size == 0) {
325 resource->base = moving;
326 resource->flags |= IORESOURCE_ASSIGNED;
327 resource->flags &= ~IORESOURCE_STORED;
328 pci_set_resource(dev, resource);
329 resource->flags = 0;
330 }
331 }
332 return;
333}
334
Eric Biederman8ca8d762003-04-22 19:02:15 +0000335static void pci_bridge_read_bases(struct device *dev)
336{
Eric Biederman03acab62004-10-14 21:25:53 +0000337 resource_t moving_base, moving_limit, moving;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000338
Eric Biederman03acab62004-10-14 21:25:53 +0000339 /* See if the bridge I/O resources are implemented */
340 moving_base = ((uint32_t)pci_moving_config8(dev, PCI_IO_BASE)) << 8;
341 moving_base |= ((uint32_t)pci_moving_config16(dev, PCI_IO_BASE_UPPER16)) << 16;
342
343 moving_limit = ((uint32_t)pci_moving_config8(dev, PCI_IO_LIMIT)) << 8;
344 moving_limit |= ((uint32_t)pci_moving_config16(dev, PCI_IO_LIMIT_UPPER16)) << 16;
345
346 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000347
348 /* Initialize the io space constraints on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000349 pci_record_bridge_resource(dev, moving, PCI_IO_BASE,
350 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000351
352 /* See if the bridge prefmem resources are implemented */
353 moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
354 moving_base |= ((resource_t)pci_moving_config32(dev, PCI_PREF_BASE_UPPER32)) << 32;
355
356 moving_limit = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_LIMIT)) << 16;
357 moving_limit |= ((resource_t)pci_moving_config32(dev, PCI_PREF_LIMIT_UPPER32)) << 32;
358
359 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000360 /* Initiliaze the prefetchable memory constraints on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000361 pci_record_bridge_resource(dev, moving, PCI_PREF_MEMORY_BASE,
362 IORESOURCE_MEM | IORESOURCE_PREFETCH,
363 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000364
365 /* See if the bridge mem resources are implemented */
366 moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
367 moving_limit = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_LIMIT)) << 16;
368
369 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000370
371 /* Initialize the memory resources on the current bus */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000372 pci_record_bridge_resource(dev, moving, PCI_MEMORY_BASE,
373 IORESOURCE_MEM | IORESOURCE_PREFETCH,
374 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000375
Eric Biederman5cd81732004-03-11 15:01:31 +0000376 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000377}
378
Eric Biederman5899fd82003-04-24 06:25:08 +0000379void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000380{
381 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000382
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000383 pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000384}
385
Eric Biederman5899fd82003-04-24 06:25:08 +0000386void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000387{
388 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000389
Eric Biederman8ca8d762003-04-22 19:02:15 +0000390 pci_bridge_read_bases(dev);
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000391 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000392}
393
Eric Biederman8ca8d762003-04-22 19:02:15 +0000394static void pci_set_resource(struct device *dev, struct resource *resource)
395{
Eric Biederman03acab62004-10-14 21:25:53 +0000396 resource_t base, end;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000397
Eric Biederman8ca8d762003-04-22 19:02:15 +0000398 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000399 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000400 printk_err("ERROR: %s %02x not allocated\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000401 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000402 return;
403 }
404
Eric Biederman5cd81732004-03-11 15:01:31 +0000405 /* If I have already stored this resource don't worry about it */
406 if (resource->flags & IORESOURCE_STORED) {
407 return;
408 }
409
Eric Biederman03acab62004-10-14 21:25:53 +0000410 /* If the resources is substractive don't worry about it */
411 if (resource->flags & IORESOURCE_SUBTRACTIVE) {
412 return;
413 }
414
Eric Biederman8ca8d762003-04-22 19:02:15 +0000415 /* Only handle PCI memory and IO resources for now */
416 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
417 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000418
Eric Biederman03acab62004-10-14 21:25:53 +0000419 /* Enable the resources in the command register */
420 if (resource->size) {
421 if (resource->flags & IORESOURCE_MEM) {
422 dev->command |= PCI_COMMAND_MEMORY;
423 }
424 if (resource->flags & IORESOURCE_IO) {
425 dev->command |= PCI_COMMAND_IO;
426 }
427 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
428 dev->command |= PCI_COMMAND_MASTER;
429 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000430 }
431 /* Get the base address */
432 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000433
Eric Biederman03acab62004-10-14 21:25:53 +0000434 /* Get the end */
435 end = resource_end(resource);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000436
Eric Biederman5cd81732004-03-11 15:01:31 +0000437 /* Now store the resource */
438 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000439 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000440 unsigned long base_lo, base_hi;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000441 /*
442 * some chipsets allow us to set/clear the IO bit.
443 * (e.g. VIA 82c686a.) So set it to be safe)
444 */
Eric Biederman03acab62004-10-14 21:25:53 +0000445 base_lo = base & 0xffffffff;
446 base_hi = (base >> 32) & 0xffffffff;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000447 if (resource->flags & IORESOURCE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000448 base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000449 }
Eric Biederman03acab62004-10-14 21:25:53 +0000450 pci_write_config32(dev, resource->index, base_lo);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000451 if (resource->flags & IORESOURCE_PCI64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000452 pci_write_config32(dev, resource->index + 4, base_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000453 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000454 }
455 else if (resource->index == PCI_IO_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000456 /* set the IO ranges */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000457 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000458 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000459 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
460 pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16);
461 pci_write_config8(dev, PCI_IO_LIMIT, end >> 8);
462 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000463 }
464 else if (resource->index == PCI_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000465 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000466 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000467 IORESOURCE_MEM | IORESOURCE_PREFETCH,
468 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000469 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
Eric Biederman03acab62004-10-14 21:25:53 +0000470 pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000471 }
472 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000473 /* set the prefetchable memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000474 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000475 IORESOURCE_MEM | IORESOURCE_PREFETCH,
476 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000477 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
478 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32);
479 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16);
480 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, end >> 32);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000481 }
482 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000483 /* Don't let me think I stored the resource */
484 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000485 printk_err("ERROR: invalid resource->index %x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000486 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000487 }
Eric Biederman03acab62004-10-14 21:25:53 +0000488 report_resource_stored(dev, resource, "");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000489 return;
490}
491
Eric Biederman5899fd82003-04-24 06:25:08 +0000492void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000493{
494 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000495 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000496 uint8_t line;
497
498 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000499
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000500 for (resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000501 pci_set_resource(dev, resource);
502 }
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000503 for (link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000504 struct bus *bus;
505 bus = &dev->link[link];
506 if (bus->children) {
507 assign_resources(bus);
508 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000509 }
510
511 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000512 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000513
514 /* set a default secondary latency timer */
515 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000516 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000517 }
518
519 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000520 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000521 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000522 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000523 }
524 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000525 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000526}
527
Eric Biedermane9a271e32003-09-02 03:36:25 +0000528void pci_dev_enable_resources(struct device *dev)
529{
Eric Biedermana9e632c2004-11-18 22:38:08 +0000530 const struct pci_operations *ops;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000531 uint16_t command;
Eric Biederman03acab62004-10-14 21:25:53 +0000532
533 /* Set the subsystem vendor and device id for mainboard devices */
534 ops = ops_pci(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000535 if (dev->on_mainboard && ops && ops->set_subsystem) {
Eric Biederman03acab62004-10-14 21:25:53 +0000536 printk_debug("%s subsystem <- %02x/%02x\n",
537 dev_path(dev),
538 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
539 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
540 ops->set_subsystem(dev,
541 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
542 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
543 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000544 command = pci_read_config16(dev, PCI_COMMAND);
545 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000546 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000547 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
548 pci_write_config16(dev, PCI_COMMAND, command);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000549}
550
551void pci_bus_enable_resources(struct device *dev)
552{
553 uint16_t ctrl;
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000554
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000555#if CONFIG_CONSOLE_VGA == 1
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000556 /* enable IO in command register if there is VGA card
557 * connected with (even it does not claim IO resource) */
558 if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
559 dev->command |= PCI_COMMAND_IO;
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000560#endif
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000561
Eric Biedermane9a271e32003-09-02 03:36:25 +0000562 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
563 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000564 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000565 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
566 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
567
568 pci_dev_enable_resources(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000569
570 enable_childrens_resources(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000571}
572
Eric Biedermandbec2d42004-10-21 10:44:08 +0000573void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
Eric Biederman03acab62004-10-14 21:25:53 +0000574{
575 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
576 ((device & 0xffff) << 16) | (vendor & 0xffff));
577}
578
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000579#if CONFIG_PCI_ROM_RUN == 1
Li-Ta Lo883b8792005-01-10 23:16:22 +0000580void pci_dev_init(struct device *dev)
581{
582 struct rom_header *rom, *ram;
583
584 rom = pci_rom_probe(dev);
585 if (rom == NULL)
586 return;
587 ram = pci_rom_load(dev, rom);
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000588 if (ram == NULL)
589 return;
Li-Ta Lo883b8792005-01-10 23:16:22 +0000590
591 run_bios(dev, ram);
592}
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000593#endif
Li-Ta Lo883b8792005-01-10 23:16:22 +0000594
Li-Ta Loe5266692004-03-23 21:28:05 +0000595/** Default device operation for PCI devices */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000596static struct pci_operations pci_dev_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000597 .set_subsystem = pci_dev_set_subsystem,
598};
599
Eric Biederman8ca8d762003-04-22 19:02:15 +0000600struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000601 .read_resources = pci_dev_read_resources,
602 .set_resources = pci_dev_set_resources,
603 .enable_resources = pci_dev_enable_resources,
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000604#if CONFIG_PCI_ROM_RUN == 1
Li-Ta Lo883b8792005-01-10 23:16:22 +0000605 .init = pci_dev_init,
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000606#else
607 .init = 0,
608#endif
Li-Ta Loe5266692004-03-23 21:28:05 +0000609 .scan_bus = 0,
Eric Biederman03acab62004-10-14 21:25:53 +0000610 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000611 .ops_pci = &pci_dev_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000612};
Li-Ta Loe5266692004-03-23 21:28:05 +0000613
614/** Default device operations for PCI bridges */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000615static struct pci_operations pci_bus_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000616 .set_subsystem = 0,
617};
Li-Ta Lo883b8792005-01-10 23:16:22 +0000618
Eric Biederman8ca8d762003-04-22 19:02:15 +0000619struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000620 .read_resources = pci_bus_read_resources,
621 .set_resources = pci_dev_set_resources,
622 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000623 .init = 0,
624 .scan_bus = pci_scan_bridge,
Eric Biederman03acab62004-10-14 21:25:53 +0000625 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000626 .ops_pci = &pci_bus_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000627};
Li-Ta Loe5266692004-03-23 21:28:05 +0000628
629/**
630 * @brief Set up PCI device operation
631 *
632 *
633 * @param dev
634 *
635 * @see pci_drivers
636 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000637static void set_pci_ops(struct device *dev)
638{
639 struct pci_driver *driver;
640 if (dev->ops) {
641 return;
642 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000643
Eric Biederman8ca8d762003-04-22 19:02:15 +0000644 /* Look through the list of setup drivers and find one for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000645 * this pci device
646 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000647 for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000648 if ((driver->vendor == dev->vendor) &&
Li-Ta Lo04930692004-11-25 17:37:19 +0000649 (driver->device == dev->device))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000650 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000651 dev->ops = driver->ops;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000652 printk_debug("%s [%04x/%04x] %sops\n",
653 dev_path(dev),
654 driver->vendor, driver->device,
655 (driver->ops->scan_bus?"bus ":""));
Eric Biederman5899fd82003-04-24 06:25:08 +0000656 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000657 }
658 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000659
Eric Biederman8ca8d762003-04-22 19:02:15 +0000660 /* If I don't have a specific driver use the default operations */
661 switch(dev->hdr_type & 0x7f) { /* header type */
662 case PCI_HEADER_TYPE_NORMAL: /* standard header */
663 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
664 goto bad;
665 dev->ops = &default_pci_ops_dev;
666 break;
667 case PCI_HEADER_TYPE_BRIDGE:
668 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
669 goto bad;
670 dev->ops = &default_pci_ops_bus;
671 break;
672 default:
673 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000674 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000675 printk_err("%s [%04x/%04x/%06x] has unknown header "
Eric Biedermanb78c1972004-10-14 20:54:17 +0000676 "type %02x, ignoring.\n",
677 dev_path(dev),
678 dev->vendor, dev->device,
679 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000680 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000681 }
682 return;
683}
684
685/**
Eric Biederman03acab62004-10-14 21:25:53 +0000686 * @brief See if we have already allocated a device structure for a given devfn.
Li-Ta Loe5266692004-03-23 21:28:05 +0000687 *
688 * Given a linked list of PCI device structures and a devfn number, find the
Li-Ta Lo3a812852004-12-03 22:39:34 +0000689 * device structure correspond to the devfn, if present. This function also
690 * removes the device structure from the linked list.
Li-Ta Loe5266692004-03-23 21:28:05 +0000691 *
692 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000693 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000694 *
Li-Ta Lo3a812852004-12-03 22:39:34 +0000695 * @return pointer to the device structure found or null of we have not
696 * allocated a device for this devfn yet.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000697 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000698static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000699{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000700 struct device *dev;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000701 dev = 0;
702 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000703 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000704 printk_err("child %s not a pci device\n",
Li-Ta Lo3a812852004-12-03 22:39:34 +0000705 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000706 continue;
707 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000708 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000709 /* Unlink from the list */
710 dev = *list;
711 *list = (*list)->sibling;
712 dev->sibling = 0;
713 break;
714 }
715 }
Li-Ta Lo3a812852004-12-03 22:39:34 +0000716 /* Just like alloc_dev add the device to the list of device on the bus.
717 * When the list of devices was formed we removed all of the parents
718 * children, and now we are interleaving static and dynamic devices in
719 * order on the bus.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000720 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000721 if (dev) {
722 device_t child;
723 /* Find the last child of our parent */
Li-Ta Lo3a812852004-12-03 22:39:34 +0000724 for (child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000725 child = child->sibling;
726 }
727 /* Place the device on the list of children of it's parent. */
728 if (child) {
729 child->sibling = dev;
730 } else {
731 dev->bus->children = dev;
732 }
733 }
734
Eric Biederman8ca8d762003-04-22 19:02:15 +0000735 return dev;
736}
737
Eric Biedermanb78c1972004-10-14 20:54:17 +0000738/**
739 * @brief Scan a PCI bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000740 *
741 * Determine the existence of devices and bridges on a PCI bus. If there are
742 * bridges on the bus, recursively scan the buses behind the bridges.
743 *
Eric Biedermane9a271e32003-09-02 03:36:25 +0000744 * @param bus pointer to the bus structure
745 * @param min_devfn minimum devfn to look at in the scan usually 0x00
746 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000747 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +0000748 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000749 * @return The maximum bus number found, after scanning all subordinate busses
750 */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000751unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn,
752 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000753{
754 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000755 device_t dev;
756 device_t old_devices;
757 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000758
759 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
760
761 old_devices = bus->children;
762 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000763
764 post_code(0x24);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000765
Li-Ta Lo9782f752004-05-05 21:15:42 +0000766 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000767 * non-existence and single funcion devices
768 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000769 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000770 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000771 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000772
Eric Biederman03acab62004-10-14 21:25:53 +0000773 /* First thing setup the device structure */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000774 dev = pci_scan_get_dev(&old_devices, devfn);
Eric Biederman03acab62004-10-14 21:25:53 +0000775
776 /* Detect if a device is present */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000777 if (!dev) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000778 struct device dummy;
779 dummy.bus = bus;
780 dummy.path.type = DEVICE_PATH_PCI;
781 dummy.path.u.pci.devfn = devfn;
782 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
783 /* some broken boards return 0 if a slot is empty: */
Li-Ta Lo04930692004-11-25 17:37:19 +0000784 if ((id == 0xffffffff) || (id == 0x00000000) ||
785 (id == 0x0000ffff) || (id == 0xffff0000))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000786 {
787 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000788 if (PCI_FUNC(devfn) == 0x00) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000789 /* if this is a function 0 device and
790 * it is not present,
791 * skip to next device
792 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000793 devfn += 0x07;
794 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000795 /* This function in a multi function device is
796 * not present, skip to the next function.
797 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000798 continue;
799 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000800 dev = alloc_dev(bus, &dummy.path);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000801 }
802 else {
Eric Biederman03acab62004-10-14 21:25:53 +0000803 /* Enable/disable the device. Once we have
804 * found the device specific operations this
805 * operations we will disable the device with
806 * those as well.
807 *
Eric Biedermanb78c1972004-10-14 20:54:17 +0000808 * This is geared toward devices that have subfunctions
809 * that do not show up by default.
810 *
811 * If a device is a stuff option on the motherboard
812 * it may be absent and enable_dev must cope.
813 *
814 */
Eric Biederman7003ba42004-10-16 06:20:29 +0000815 if (dev->chip_ops && dev->chip_ops->enable_dev)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000816 {
Eric Biederman7003ba42004-10-16 06:20:29 +0000817 dev->chip_ops->enable_dev(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000818 }
819 /* Now read the vendor and device id */
820 id = pci_read_config32(dev, PCI_VENDOR_ID);
Eric Biederman03acab62004-10-14 21:25:53 +0000821
822 /* If the device does not have a pci id disable it.
823 * Possibly this is because we have already disabled
824 * the device. But this also handles optional devices
825 * that may not always show up.
826 */
827 if (id == 0xffffffff || id == 0x00000000 ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000828 id == 0x0000ffff || id == 0xffff0000)
Eric Biederman03acab62004-10-14 21:25:53 +0000829 {
830 if (dev->enabled) {
831 printk_info("Disabling static device: %s\n",
832 dev_path(dev));
833 dev->enabled = 0;
834 }
835 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000836 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000837 /* Read the rest of the pci configuration information */
838 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
839 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000840
Eric Biedermane9a271e32003-09-02 03:36:25 +0000841 /* Store the interesting information in the device structure */
842 dev->vendor = id & 0xffff;
843 dev->device = (id >> 16) & 0xffff;
844 dev->hdr_type = hdr_type;
845 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
846 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000847
Eric Biederman03acab62004-10-14 21:25:53 +0000848 /* Architectural/System devices always need to
849 * be bus masters.
850 */
851 if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
852 dev->command |= PCI_COMMAND_MASTER;
853 }
854
Eric Biederman8ca8d762003-04-22 19:02:15 +0000855 /* Look at the vendor and device id, or at least the
Li-Ta Loe5266692004-03-23 21:28:05 +0000856 * header type and class and figure out which set of
857 * configuration methods to use. Unless we already
858 * have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000859 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000860 set_pci_ops(dev);
861 /* Error if we don't have some pci operations for it */
Eric Biederman5cd81732004-03-11 15:01:31 +0000862 if (!dev->ops) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000863 printk_err("%s No device operations\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000864 dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000865 continue;
866 }
867
868 /* Now run the magic enable/disable sequence for the device */
869 if (dev->ops && dev->ops->enable) {
870 dev->ops->enable(dev);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000871 }
Eric Biederman4086d162003-07-17 03:26:03 +0000872
Eric Biedermane9a271e32003-09-02 03:36:25 +0000873 printk_debug("%s [%04x/%04x] %s\n",
Eric Biederman03acab62004-10-14 21:25:53 +0000874 dev_path(dev),
875 dev->vendor, dev->device,
876 dev->enabled?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000877
Eric Biederman8ca8d762003-04-22 19:02:15 +0000878 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000879 /* if this is not a multi function device,
880 * don't waste time probing another function.
881 * Skip to next device.
882 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000883 devfn += 0x07;
884 }
885 }
886 post_code(0x25);
887
Eric Biedermanb78c1972004-10-14 20:54:17 +0000888 /* For all children that implement scan_bus (i.e. bridges)
889 * scan the bus behind that child.
890 */
Li-Ta Lo04930692004-11-25 17:37:19 +0000891 for (child = bus->children; child; child = child->sibling) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000892 if (!child->enabled ||
Li-Ta Lo04930692004-11-25 17:37:19 +0000893 !child->ops ||
894 !child->ops->scan_bus)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000895 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000896 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000897 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000898 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000899 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000900
Eric Biederman8ca8d762003-04-22 19:02:15 +0000901 /*
902 * We've scanned the bus and so we know all about what's on
903 * the other side of any bridges that may be on this bus plus
904 * any devices.
905 *
906 * Return how far we've got finding sub-buses.
907 */
908 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
909 post_code(0x55);
910 return max;
911}
912
Li-Ta Loe5266692004-03-23 21:28:05 +0000913/**
914 * @brief Scan a PCI bridge and the buses behind the bridge.
915 *
916 * Determine the existence of buses behind the bridge. Set up the bridge
917 * according to the result of the scan.
918 *
919 * This function is the default scan_bus() method for PCI bridge devices.
920 *
921 * @param dev pointer to the bridge device
922 * @param max the highest bus number assgined up to now
923 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000924 * @return The maximum bus number found, after scanning all subordinate busses
925 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000926unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000927{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000928 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000929 uint32_t buses;
930 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000931
Li-Ta Lo3a812852004-12-03 22:39:34 +0000932 printk_spew("%s for %s\n", __func__, dev_path(dev));
933
Eric Biedermane9a271e32003-09-02 03:36:25 +0000934 bus = &dev->link[0];
Eric Biedermana9e632c2004-11-18 22:38:08 +0000935 bus->dev = dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000936 dev->links = 1;
937
Eric Biederman8ca8d762003-04-22 19:02:15 +0000938 /* Set up the primary, secondary and subordinate bus numbers. We have
939 * no idea how many buses are behind this bridge yet, so we set the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000940 * subordinate bus number to 0xff for the moment.
941 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000942 bus->secondary = ++max;
943 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +0000944
Eric Biederman8ca8d762003-04-22 19:02:15 +0000945 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000946 cr = pci_read_config16(dev, PCI_COMMAND);
947 pci_write_config16(dev, PCI_COMMAND, 0x0000);
948 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000949
Eric Biedermanb78c1972004-10-14 20:54:17 +0000950 /*
951 * Read the existing primary/secondary/subordinate bus
952 * number configuration.
953 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000954 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000955
956 /* Configure the bus numbers for this bridge: the configuration
957 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +0000958 * correctly configured.
959 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000960 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000961 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Li-Ta Lo3a812852004-12-03 22:39:34 +0000962 ((unsigned int) (bus->secondary) << 8) |
963 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000964 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000965
Eric Biedermanb78c1972004-10-14 20:54:17 +0000966 /* Now we can scan all subordinate buses
967 * i.e. the bus behind the bridge.
968 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000969 max = pci_scan_bus(bus, 0x00, 0xff, max);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000970
Eric Biederman8ca8d762003-04-22 19:02:15 +0000971 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +0000972 * bus number to its real value.
973 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000974 bus->subordinate = max;
975 buses = (buses & 0xff00ffff) |
976 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000977 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
978 pci_write_config16(dev, PCI_COMMAND, cr);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000979
Eric Biedermanb78c1972004-10-14 20:54:17 +0000980 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000981 return max;
982}
Li-Ta Loe5266692004-03-23 21:28:05 +0000983
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000984/*
985 Tell the EISA int controller this int must be level triggered
986 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
987*/
988static void pci_level_irq(unsigned char intNum)
989{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000990 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000991
Eric Biedermanb78c1972004-10-14 20:54:17 +0000992 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000993 intBits |= (1 << intNum);
994
Eric Biedermanb78c1972004-10-14 20:54:17 +0000995 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000996
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000997 // Write new values
998 outb((unsigned char) intBits, 0x4d0);
999 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001000
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001001 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +00001002#if 1
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001003 if (inb(0x4d0) != (intBits & 0xf)) {
1004 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +00001005 __func__, intBits &0xf, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001006 }
1007 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
1008 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +00001009 __func__, (intBits>>8) &0xf, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001010 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001011#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001012}
1013
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001014/*
1015 This function assigns IRQs for all functions contained within
1016 the indicated device address. If the device does not exist or does
1017 not require interrupts then this function has no effect.
1018
1019 This function should be called for each PCI slot in your system.
1020
1021 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
1022 this slot.
1023 The particular irq #s that are passed in depend on the routing inside
1024 your southbridge and on your motherboard.
1025
1026 -kevinh@ispiri.com
1027*/
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +00001028void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4])
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001029{
1030 unsigned functNum;
1031 device_t pdev;
1032 unsigned char line;
1033 unsigned char irq;
1034 unsigned char readback;
1035
1036 /* Each slot may contain up to eight functions */
1037 for (functNum = 0; functNum < 8; functNum++) {
1038 pdev = dev_find_slot(bus, (slot << 3) + functNum);
1039
1040 if (pdev) {
1041 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
1042
1043 // PCI spec says all other values are reserved
1044 if ((line >= 1) && (line <= 4)) {
1045 irq = pIntAtoD[line - 1];
1046
1047 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
1048 irq, bus, slot, functNum);
1049
1050 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
1051 pIntAtoD[line - 1]);
1052
1053 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
1054 printk_debug(" Readback = %d\n", readback);
1055
1056 // Change to level triggered
1057 pci_level_irq(pIntAtoD[line - 1]);
1058 }
1059 }
1060 }
1061}