blob: 6f7fabf67b550dadf97efe741cff7801f6f6f4d2 [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001/*
2 * PCI Bus Services, see include/linux/pci.h for further explanation.
3 *
4 * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
5 * David Mosberger-Tang
6 *
7 * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 *
9 * Copyright 2003 -- Eric Biederman <ebiederman@lnxi.com>
10 */
11
12#include <console/console.h>
13#include <stdlib.h>
14#include <stdint.h>
15#include <bitops.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000016#include <string.h>
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +000017#include <arch/io.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000018#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ids.h>
Eric Biederman83b991a2003-10-11 06:20:25 +000021#include <device/chip.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000022#include <part/hard_reset.h>
Eric Biederman30e143a2003-09-01 23:45:32 +000023#include <part/fallback_boot.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000024
Eric Biederman8ca8d762003-04-22 19:02:15 +000025/** Given a device and register, read the size of the BAR for that register.
26 * @param dev Pointer to the device structure
27 * @param resource Pointer to the resource structure
28 * @param index Address of the pci configuration register
29 */
Eric Biederman5cd81732004-03-11 15:01:31 +000030static struct resource *pci_get_resource(struct device *dev, unsigned long index)
Eric Biederman8ca8d762003-04-22 19:02:15 +000031{
Eric Biederman5cd81732004-03-11 15:01:31 +000032 struct resource *resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +000033 uint32_t addr, size, base;
34 unsigned long type;
35
36 /* Initialize the resources to nothing */
Eric Biederman5cd81732004-03-11 15:01:31 +000037 resource = get_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +000038
Eric Biederman7a5416a2003-06-12 19:23:51 +000039 addr = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +000040
41 /* FIXME: more consideration for 64-bit PCI devices,
42 * we currently detect their size but otherwise
43 * treat them as 32-bit resources
44 */
45 /* get the size */
Eric Biederman7a5416a2003-06-12 19:23:51 +000046 pci_write_config32(dev, index, ~0);
47 size = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +000048
49 /* get the minimum value the bar can be set to */
Eric Biederman7a5416a2003-06-12 19:23:51 +000050 pci_write_config32(dev, index, 0);
51 base = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +000052
53 /* restore addr */
Eric Biederman7a5416a2003-06-12 19:23:51 +000054 pci_write_config32(dev, index, addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +000055
56 /*
57 * some broken hardware has read-only registers that do not
58 * really size correctly. You can tell this if addr == size
59 * Example: the acer m7229 has BARs 1-4 normally read-only.
60 * so BAR1 at offset 0x10 reads 0x1f1. If you size that register
61 * by writing 0xffffffff to it, it will read back as 0x1f1 -- a
62 * violation of the spec.
63 * We catch this case and ignore it by settting size and type to 0.
64 * This incidentally catches the common case where registers
65 * read back as 0 for both address and size.
66 */
67 if ((addr == size) && (addr == base)) {
68 if (size != 0) {
69 printk_debug(
Eric Biedermane9a271e32003-09-02 03:36:25 +000070 "%s register %02x(%08x), read-only ignoring it\n",
71 dev_path(dev),
Eric Biederman8ca8d762003-04-22 19:02:15 +000072 index, addr);
73 }
74 resource->flags = 0;
75 }
76 /* Now compute the actual size, See PCI Spec 6.2.5.1 ... */
77 else if (size & PCI_BASE_ADDRESS_SPACE_IO) {
78 type = size & (~PCI_BASE_ADDRESS_IO_MASK);
79 /* BUG! Top 16 bits can be zero (or not)
80 * So set them to 0xffff so they go away ...
81 */
82 resource->size = (~((size | 0xffff0000) & PCI_BASE_ADDRESS_IO_MASK)) +1;
83 resource->align = log2(resource->size);
84 resource->gran = resource->align;
Eric Biederman5cd81732004-03-11 15:01:31 +000085 resource->flags |= IORESOURCE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +000086 resource->limit = 0xffff;
87 }
88 else {
89 /* A Memory mapped base address */
90 type = size & (~PCI_BASE_ADDRESS_MEM_MASK);
91 resource->size = (~(size &PCI_BASE_ADDRESS_MEM_MASK)) +1;
92 resource->align = log2(resource->size);
93 resource->gran = resource->align;
Eric Biederman5cd81732004-03-11 15:01:31 +000094 resource->flags |= IORESOURCE_MEM;
Eric Biederman8ca8d762003-04-22 19:02:15 +000095 if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
96 resource->flags |= IORESOURCE_PREFETCH;
97 }
98 type &= PCI_BASE_ADDRESS_MEM_TYPE_MASK;
99 if (type == PCI_BASE_ADDRESS_MEM_TYPE_32) {
100 /* 32bit limit */
101 resource->limit = 0xffffffffUL;
102 }
103 else if (type == PCI_BASE_ADDRESS_MEM_TYPE_1M) {
104 /* 1MB limit */
105 resource->limit = 0x000fffffUL;
106 }
107 else if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
108 unsigned long index_hi;
109 /* 64bit limit
110 * For now just treat this as a 32bit limit
111 */
112 index_hi = index + 4;
113 resource->limit = 0xffffffffUL;
114 resource->flags |= IORESOURCE_PCI64;
Eric Biederman7a5416a2003-06-12 19:23:51 +0000115 addr = pci_read_config32( dev, index_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000116 /* get the extended size */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000117 pci_write_config32(dev, index_hi, 0xffffffffUL);
118 size = pci_read_config32( dev, index_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000119
120 /* get the minimum value the bar can be set to */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000121 pci_write_config32(dev, index_hi, 0);
122 base = pci_read_config32(dev, index_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000123
124 /* restore addr */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000125 pci_write_config32(dev, index_hi, addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000126
127 if ((size == 0xffffffff) && (base == 0)) {
128 /* Clear the top half of the bar */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000129 pci_write_config32(dev, index_hi, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000130 }
131 else {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000132 printk_err("%s Unable to handle 64-bit address\n",
133 dev_path(dev));
Eric Biederman8ca8d762003-04-22 19:02:15 +0000134 resource->flags = IORESOURCE_PCI64;
135 }
136 }
137 else {
138 /* Invalid value */
139 resource->flags = 0;
140 }
141 }
142 /* dev->size holds the flags... */
Eric Biederman5cd81732004-03-11 15:01:31 +0000143 return resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000144}
145
146/** Read the base address registers for a given device.
147 * @param dev Pointer to the dev structure
148 * @param howmany How many registers to read (6 for device, 2 for bridge)
149 */
150static void pci_read_bases(struct device *dev, unsigned int howmany)
151{
Eric Biederman8ca8d762003-04-22 19:02:15 +0000152 unsigned long index;
153
Eric Biedermanb78c1972004-10-14 20:54:17 +0000154 for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000155 struct resource *resource;
Eric Biederman5cd81732004-03-11 15:01:31 +0000156 resource = pci_get_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000157 index += (resource->flags & IORESOURCE_PCI64)?8:4;
158 }
Eric Biederman5cd81732004-03-11 15:01:31 +0000159 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000160}
161
Eric Biederman8ca8d762003-04-22 19:02:15 +0000162static void pci_bridge_read_bases(struct device *dev)
163{
Eric Biederman5cd81732004-03-11 15:01:31 +0000164 struct resource *resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000165
166 /* FIXME handle bridges without some of the optional resources */
167
168 /* Initialize the io space constraints on the current bus */
Eric Biederman5cd81732004-03-11 15:01:31 +0000169 resource = get_resource(dev, PCI_IO_BASE);
170 resource->size = 0;
171 resource->align = log2(PCI_IO_BRIDGE_ALIGN);
172 resource->gran = log2(PCI_IO_BRIDGE_ALIGN);
173 resource->limit = 0xffffUL;
174 resource->flags |= IORESOURCE_IO | IORESOURCE_PCI_BRIDGE;
175 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000176 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000177
178 /* Initiliaze the prefetchable memory constraints on the current bus */
Eric Biederman5cd81732004-03-11 15:01:31 +0000179 resource = get_resource(dev, PCI_PREF_MEMORY_BASE);
180 resource->size = 0;
181 resource->align = log2(PCI_MEM_BRIDGE_ALIGN);
182 resource->gran = log2(PCI_MEM_BRIDGE_ALIGN);
183 resource->limit = 0xffffffffUL;
184 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_PCI_BRIDGE;
185 resource->index = PCI_PREF_MEMORY_BASE;
186 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000187 IORESOURCE_MEM | IORESOURCE_PREFETCH,
188 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000189
190 /* Initialize the memory resources on the current bus */
Eric Biederman5cd81732004-03-11 15:01:31 +0000191 resource = get_resource(dev, PCI_MEMORY_BASE);
192 resource->size = 0;
193 resource->align = log2(PCI_MEM_BRIDGE_ALIGN);
194 resource->gran = log2(PCI_MEM_BRIDGE_ALIGN);
195 resource->limit = 0xffffffffUL;
196 resource->flags = IORESOURCE_MEM | IORESOURCE_PCI_BRIDGE;
197 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000198 IORESOURCE_MEM | IORESOURCE_PREFETCH,
199 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000200
Eric Biederman5cd81732004-03-11 15:01:31 +0000201 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000202}
203
Eric Biederman5899fd82003-04-24 06:25:08 +0000204void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000205{
206 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000207
Eric Biederman8ca8d762003-04-22 19:02:15 +0000208 pci_read_bases(dev, 6);
Li-Ta Loe5266692004-03-23 21:28:05 +0000209
Eric Biederman7a5416a2003-06-12 19:23:51 +0000210 addr = pci_read_config32(dev, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000211 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
212}
213
Eric Biederman5899fd82003-04-24 06:25:08 +0000214void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000215{
216 uint32_t addr;
Li-Ta Loe5266692004-03-23 21:28:05 +0000217
Eric Biederman8ca8d762003-04-22 19:02:15 +0000218 pci_bridge_read_bases(dev);
219 pci_read_bases(dev, 2);
220
Eric Biederman7a5416a2003-06-12 19:23:51 +0000221 addr = pci_read_config32(dev, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000222 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000223}
224
Li-Ta Loe5266692004-03-23 21:28:05 +0000225/**
Eric Biedermanb78c1972004-10-14 20:54:17 +0000226 * @brief round a number up to the next multiple of gran
Li-Ta Loe5266692004-03-23 21:28:05 +0000227 * @param val the starting value
Eric Biedermanb78c1972004-10-14 20:54:17 +0000228 * @param gran granularity we are aligning the number to.
229 * @returns aligned value
Li-Ta Loe5266692004-03-23 21:28:05 +0000230 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000231static unsigned long align(unsigned long val, unsigned long gran)
Li-Ta Loe5266692004-03-23 21:28:05 +0000232{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000233 /* GRAN MUST BE A POWER OF TWO. */
234 unsigned long mask;
235 mask = ~(gran - 1);
236 val += (gran - 1);
237 val &= mask;
Li-Ta Loe5266692004-03-23 21:28:05 +0000238 return val;
239}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000240
241static void pci_set_resource(struct device *dev, struct resource *resource)
242{
243 unsigned long base, limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000244 unsigned char buf[10];
Eric Biederman5cd81732004-03-11 15:01:31 +0000245 unsigned long gran;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000246
Eric Biederman8ca8d762003-04-22 19:02:15 +0000247 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000248 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000249 printk_err("ERROR: %s %02x not allocated\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000250 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000251 return;
252 }
253
Eric Biederman5cd81732004-03-11 15:01:31 +0000254 /* If I have already stored this resource don't worry about it */
255 if (resource->flags & IORESOURCE_STORED) {
256 return;
257 }
258
Eric Biederman8ca8d762003-04-22 19:02:15 +0000259 /* Only handle PCI memory and IO resources for now */
260 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
261 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000262
Eric Biederman8ca8d762003-04-22 19:02:15 +0000263 if (resource->flags & IORESOURCE_MEM) {
264 dev->command |= PCI_COMMAND_MEMORY;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000265 }
266 if (resource->flags & IORESOURCE_IO) {
267 dev->command |= PCI_COMMAND_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000268 }
269 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
270 dev->command |= PCI_COMMAND_MASTER;
271 }
272 /* Get the base address */
273 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000274 /* Get the resource granularity */
275 gran = 1UL << resource->gran;
276
277 /* For a non bridge resource granularity and alignment are the same.
278 * For a bridge resource align is the largest needed alignment below
279 * the bridge. While the granularity is simply how many low bits of the
280 * address cannot be set.
281 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000282
283 /* Get the limit (rounded up) */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000284 limit = base + align(resource->size, gran) - 1UL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000285
Eric Biederman5cd81732004-03-11 15:01:31 +0000286 /* Now store the resource */
287 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000288 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000289 /*
290 * some chipsets allow us to set/clear the IO bit.
291 * (e.g. VIA 82c686a.) So set it to be safe)
292 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000293 limit = base + resource->size -1;
294 if (resource->flags & IORESOURCE_IO) {
295 base |= PCI_BASE_ADDRESS_SPACE_IO;
296 }
Eric Biederman7a5416a2003-06-12 19:23:51 +0000297 pci_write_config32(dev, resource->index, base & 0xffffffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000298 if (resource->flags & IORESOURCE_PCI64) {
299 /* FIXME handle real 64bit base addresses */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000300 pci_write_config32(dev, resource->index + 4, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000301 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000302 }
303 else if (resource->index == PCI_IO_BASE) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000304 /* set the IO ranges
305 * WARNING: we don't really do 32-bit addressing for IO yet!
306 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000307 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000308 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000309 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
310 pci_write_config8(dev, PCI_IO_LIMIT, limit >> 8);
Eric Biederman5fb929e2003-07-17 02:15:46 +0000311 pci_write_config16(dev, PCI_IO_BASE_UPPER16, 0);
312 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, 0);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000313 }
314 else if (resource->index == PCI_MEMORY_BASE) {
315 /* set the memory range
316 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000317 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000318 IORESOURCE_MEM | IORESOURCE_PREFETCH,
319 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000320 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
321 pci_write_config16(dev, PCI_MEMORY_LIMIT, limit >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000322 }
323 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000324 /* set the prefetchable memory range
Eric Biedermanb78c1972004-10-14 20:54:17 +0000325 * WARNING: we don't really do 64-bit addressing
326 * for prefetchable memory yet!
327 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000328 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000329 IORESOURCE_MEM | IORESOURCE_PREFETCH,
330 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000331 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
332 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, limit >> 16);
Eric Biederman5fb929e2003-07-17 02:15:46 +0000333 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, 0);
334 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, 0);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000335 }
336 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000337 /* Don't let me think I stored the resource */
338 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000339 printk_err("ERROR: invalid resource->index %x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000340 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000341 }
342 buf[0] = '\0';
343 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000344 sprintf(buf, "bus %d ", dev->link[0].secondary);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000345 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000346 printk_debug(
347 "%s %02x <- [0x%08lx - 0x%08lx] %s%s\n",
348 dev_path(dev),
349 resource->index,
350 (unsigned long)(resource->base), limit,
351 buf,
352 (resource->flags & IORESOURCE_IO)? "io":
353 (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000354 return;
355}
356
Eric Biederman5899fd82003-04-24 06:25:08 +0000357void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000358{
359 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000360 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000361 uint8_t line;
362
363 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000364
365 for(resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000366 pci_set_resource(dev, resource);
367 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000368 for(link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000369 struct bus *bus;
370 bus = &dev->link[link];
371 if (bus->children) {
372 assign_resources(bus);
373 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000374 }
375
376 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000377 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000378
379 /* set a default secondary latency timer */
380 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000381 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000382 }
383
384 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000385 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000386 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000387 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000388 }
389 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000390 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000391}
392
Eric Biedermane9a271e32003-09-02 03:36:25 +0000393void pci_dev_enable_resources(struct device *dev)
394{
395 uint16_t command;
396 command = pci_read_config16(dev, PCI_COMMAND);
397 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000398 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000399 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
400 pci_write_config16(dev, PCI_COMMAND, command);
401
402 enable_childrens_resources(dev);
403}
404
405void pci_bus_enable_resources(struct device *dev)
406{
407 uint16_t ctrl;
408 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
409 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000410 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000411 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
412 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
413
414 pci_dev_enable_resources(dev);
415}
416
Li-Ta Loe5266692004-03-23 21:28:05 +0000417/** Default device operation for PCI devices */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000418struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000419 .read_resources = pci_dev_read_resources,
420 .set_resources = pci_dev_set_resources,
421 .enable_resources = pci_dev_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000422 .init = 0,
423 .scan_bus = 0,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000424};
Li-Ta Loe5266692004-03-23 21:28:05 +0000425
426/** Default device operations for PCI bridges */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000427struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000428 .read_resources = pci_bus_read_resources,
429 .set_resources = pci_dev_set_resources,
430 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000431 .init = 0,
432 .scan_bus = pci_scan_bridge,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000433};
Li-Ta Loe5266692004-03-23 21:28:05 +0000434
435/**
436 * @brief Set up PCI device operation
437 *
438 *
439 * @param dev
440 *
441 * @see pci_drivers
442 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000443static void set_pci_ops(struct device *dev)
444{
445 struct pci_driver *driver;
Li-Ta Loe5266692004-03-23 21:28:05 +0000446
Eric Biederman8ca8d762003-04-22 19:02:15 +0000447 if (dev->ops) {
448 return;
449 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000450
Eric Biederman8ca8d762003-04-22 19:02:15 +0000451 /* Look through the list of setup drivers and find one for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000452 * this pci device
453 */
454 for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000455 if ((driver->vendor == dev->vendor) &&
Eric Biedermanb78c1972004-10-14 20:54:17 +0000456 (driver->device == dev->device))
457 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000458 dev->ops = driver->ops;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000459 printk_debug("%s [%04x/%04x] %sops\n",
460 dev_path(dev),
461 driver->vendor, driver->device,
462 (driver->ops->scan_bus?"bus ":""));
Eric Biederman5899fd82003-04-24 06:25:08 +0000463 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000464 }
465 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000466
Li-Ta Lo9da7ff92004-05-24 19:04:47 +0000467#if 0
468 extern struct pci_driver generic_vga_driver;
469 /* TODO: Install generic VGA driver for VGA devices, base on the
470 * class ID */
471 if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
472 printk_debug("setting up generic VGA driver\n");
473 dev->ops = generic_vga_driver.ops;
474 return;
475 }
476#endif
477
Eric Biederman8ca8d762003-04-22 19:02:15 +0000478 /* If I don't have a specific driver use the default operations */
479 switch(dev->hdr_type & 0x7f) { /* header type */
480 case PCI_HEADER_TYPE_NORMAL: /* standard header */
481 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
482 goto bad;
483 dev->ops = &default_pci_ops_dev;
484 break;
485 case PCI_HEADER_TYPE_BRIDGE:
486 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
487 goto bad;
488 dev->ops = &default_pci_ops_bus;
489 break;
490 default:
491 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000492 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000493 printk_err("%s [%04x/%04x/%06x] has unknown header "
Eric Biedermanb78c1972004-10-14 20:54:17 +0000494 "type %02x, ignoring.\n",
495 dev_path(dev),
496 dev->vendor, dev->device,
497 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000498 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000499 }
500 return;
501}
502
503/**
Li-Ta Loe5266692004-03-23 21:28:05 +0000504 * @brief Find a specific device structure on a list of device structures
505 *
506 * Given a linked list of PCI device structures and a devfn number, find the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000507 * device structure correspond to the devfn, if present.
Li-Ta Loe5266692004-03-23 21:28:05 +0000508 *
509 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000510 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000511 *
Eric Biedermanb78c1972004-10-14 20:54:17 +0000512 * @return pointer to the device structure found or null of we have not allocated
513 * a device for this devfn yet.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000514 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000515static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000516{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000517 struct device *dev;
Li-Ta Loe5266692004-03-23 21:28:05 +0000518
Eric Biedermanb78c1972004-10-14 20:54:17 +0000519 printk_spew("%s, looking for devfn: %02x.%01x\n", __FUNCTION__,
520 devfn >> 3, devfn & 7);
521 dev = 0;
522 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000523 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000524 printk_err("child %s not a pci device\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000525 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000526 continue;
527 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000528 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000529 /* Unlink from the list */
530 dev = *list;
531 *list = (*list)->sibling;
532 dev->sibling = 0;
533 break;
534 }
535 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000536 /* Just like alloc_dev add the device to the
537 * list of device on the bus. When the list of devices was formed
538 * we removed all of the parents children, and now we are interleaving
539 * static and dynamic devices in order on the bus.
540 */
541 printk_spew("%s, found dev %08x\n", __FUNCTION__, dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000542 if (dev) {
543 device_t child;
544 /* Find the last child of our parent */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000545 for(child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000546 child = child->sibling;
547 }
548 /* Place the device on the list of children of it's parent. */
549 if (child) {
550 child->sibling = dev;
551 } else {
552 dev->bus->children = dev;
553 }
554 }
555
Eric Biederman8ca8d762003-04-22 19:02:15 +0000556 return dev;
557}
558
Eric Biedermanb78c1972004-10-14 20:54:17 +0000559/**
560 * @brief Scan a PCI bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000561 *
562 * Determine the existence of devices and bridges on a PCI bus. If there are
563 * bridges on the bus, recursively scan the buses behind the bridges.
564 *
565 * This function is the default scan_bus() method for the root device
566 * 'dev_root'.
567 *
Eric Biedermane9a271e32003-09-02 03:36:25 +0000568 * @param bus pointer to the bus structure
569 * @param min_devfn minimum devfn to look at in the scan usually 0x00
570 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000571 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +0000572 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000573 * @return The maximum bus number found, after scanning all subordinate busses
574 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000575unsigned int pci_scan_bus(struct bus *bus,
576 unsigned min_devfn, unsigned max_devfn,
577 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000578{
579 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000580 device_t dev;
581 device_t old_devices;
582 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000583
584 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
585
586 old_devices = bus->children;
587 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000588
589 post_code(0x24);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000590
Li-Ta Lo9782f752004-05-05 21:15:42 +0000591 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000592 * non-existence and single funcion devices
593 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000594 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000595 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000596 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000597
Li-Ta Loe5266692004-03-23 21:28:05 +0000598 /* device structures for PCI devices associated with static
599 * devices are already created during the static device
600 * enumeration, find out if it is the case for this devfn */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000601 dev = pci_scan_get_dev(&old_devices, devfn);
Li-Ta Loe5266692004-03-23 21:28:05 +0000602
Eric Biederman8ca8d762003-04-22 19:02:15 +0000603 if (!dev) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000604 /* it's not associated with a static device, detect if
605 * this device is present */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000606 struct device dummy;
607 dummy.bus = bus;
608 dummy.path.type = DEVICE_PATH_PCI;
609 dummy.path.u.pci.devfn = devfn;
610 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
611 /* some broken boards return 0 if a slot is empty: */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000612 if ( (id == 0xffffffff) || (id == 0x00000000) ||
613 (id == 0x0000ffff) || (id == 0xffff0000))
614 {
615 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000616 if (PCI_FUNC(devfn) == 0x00) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000617 /* if this is a function 0 device and
618 * it is not present,
619 * skip to next device
620 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000621 devfn += 0x07;
622 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000623 /* This function in a multi function device is
624 * not present, skip to the next function.
625 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000626 continue;
627 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000628 dev = alloc_dev(bus, &dummy.path);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000629 }
630 else {
631 /* If at all possible enable the device, if desired
632 * we will disable the device later, once we have
633 * found it's device specific operations.
634 *
635 * This is geared toward devices that have subfunctions
636 * that do not show up by default.
637 *
638 * If a device is a stuff option on the motherboard
639 * it may be absent and enable_dev must cope.
640 *
641 */
642 if ( dev->chip && dev->chip->control &&
643 dev->chip->control->enable_dev)
644 {
Li-Ta Lo9782f752004-05-05 21:15:42 +0000645 int enabled = dev->enabled;
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000646 dev->enabled = 1;
Eric Biederman83b991a2003-10-11 06:20:25 +0000647 dev->chip->control->enable_dev(dev);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000648 dev->enabled = enabled;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000649 }
650 /* Now read the vendor and device id */
651 id = pci_read_config32(dev, PCI_VENDOR_ID);
652 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000653 /* Read the rest of the pci configuration information */
654 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
655 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000656
Eric Biedermane9a271e32003-09-02 03:36:25 +0000657 /* Store the interesting information in the device structure */
658 dev->vendor = id & 0xffff;
659 dev->device = (id >> 16) & 0xffff;
660 dev->hdr_type = hdr_type;
661 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
662 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000663
Eric Biederman8ca8d762003-04-22 19:02:15 +0000664 /* Look at the vendor and device id, or at least the
Li-Ta Loe5266692004-03-23 21:28:05 +0000665 * header type and class and figure out which set of
666 * configuration methods to use. Unless we already
667 * have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000668 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000669 set_pci_ops(dev);
670 /* Error if we don't have some pci operations for it */
Eric Biederman5cd81732004-03-11 15:01:31 +0000671 if (!dev->ops) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000672 printk_err("%s No device operations\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000673 dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000674 continue;
675 }
676
677 /* Now run the magic enable/disable sequence for the device */
678 if (dev->ops && dev->ops->enable) {
679 dev->ops->enable(dev);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000680 }
681 else if (dev->chip && dev->chip->control &&
682 dev->chip->control->enable_dev)
683 {
Eric Biederman5cd81732004-03-11 15:01:31 +0000684 dev->chip->control->enable_dev(dev);
685 }
Eric Biederman4086d162003-07-17 03:26:03 +0000686
Eric Biedermane9a271e32003-09-02 03:36:25 +0000687 printk_debug("%s [%04x/%04x] %s\n",
Li-Ta Loe5266692004-03-23 21:28:05 +0000688 dev_path(dev),
689 dev->vendor, dev->device,
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000690 dev->enabled?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000691
Eric Biederman8ca8d762003-04-22 19:02:15 +0000692 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
Eric Biedermanb78c1972004-10-14 20:54:17 +0000693 /* if this is not a multi function device,
694 * don't waste time probing another function.
695 * Skip to next device.
696 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000697 devfn += 0x07;
698 }
699 }
700 post_code(0x25);
701
Eric Biedermanb78c1972004-10-14 20:54:17 +0000702 /* For all children that implement scan_bus (i.e. bridges)
703 * scan the bus behind that child.
704 */
705 for(child = bus->children; child; child = child->sibling) {
706 if (!child->enabled ||
707 !child->ops ||
708 !child->ops->scan_bus)
709 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000710 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000711 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000712 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000713 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000714
Eric Biederman8ca8d762003-04-22 19:02:15 +0000715 /*
716 * We've scanned the bus and so we know all about what's on
717 * the other side of any bridges that may be on this bus plus
718 * any devices.
719 *
720 * Return how far we've got finding sub-buses.
721 */
722 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
723 post_code(0x55);
724 return max;
725}
726
Li-Ta Loe5266692004-03-23 21:28:05 +0000727/**
728 * @brief Scan a PCI bridge and the buses behind the bridge.
729 *
730 * Determine the existence of buses behind the bridge. Set up the bridge
731 * according to the result of the scan.
732 *
733 * This function is the default scan_bus() method for PCI bridge devices.
734 *
735 * @param dev pointer to the bridge device
736 * @param max the highest bus number assgined up to now
737 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000738 * @return The maximum bus number found, after scanning all subordinate busses
739 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000740unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000741{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000742 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000743 uint32_t buses;
744 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000745
Eric Biedermane9a271e32003-09-02 03:36:25 +0000746 bus = &dev->link[0];
747 dev->links = 1;
748
Eric Biederman8ca8d762003-04-22 19:02:15 +0000749 /* Set up the primary, secondary and subordinate bus numbers. We have
750 * no idea how many buses are behind this bridge yet, so we set the
Eric Biedermanb78c1972004-10-14 20:54:17 +0000751 * subordinate bus number to 0xff for the moment.
752 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000753 bus->secondary = ++max;
754 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +0000755
Eric Biederman8ca8d762003-04-22 19:02:15 +0000756 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000757 cr = pci_read_config16(dev, PCI_COMMAND);
758 pci_write_config16(dev, PCI_COMMAND, 0x0000);
759 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000760
Eric Biedermanb78c1972004-10-14 20:54:17 +0000761 /*
762 * Read the existing primary/secondary/subordinate bus
763 * number configuration.
764 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000765 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000766
767 /* Configure the bus numbers for this bridge: the configuration
768 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +0000769 * correctly configured.
770 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000771 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000772 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Eric Biedermanb78c1972004-10-14 20:54:17 +0000773 ((unsigned int) (bus->secondary) << 8) |
774 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000775 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000776
777 /* Now we can scan all subordinate buses
778 * i.e. the bus behind the bridge.
779 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000780 max = pci_scan_bus(bus, 0x00, 0xff, max);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000781
Eric Biederman8ca8d762003-04-22 19:02:15 +0000782 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +0000783 * bus number to its real value.
784 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000785 bus->subordinate = max;
786 buses = (buses & 0xff00ffff) |
787 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000788 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
789 pci_write_config16(dev, PCI_COMMAND, cr);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000790
791 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000792 return max;
793}
Li-Ta Loe5266692004-03-23 21:28:05 +0000794
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000795/*
796 Tell the EISA int controller this int must be level triggered
797 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
798*/
799static void pci_level_irq(unsigned char intNum)
800{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000801 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000802
Eric Biedermanb78c1972004-10-14 20:54:17 +0000803<<<<<<< pci_device.c
804 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
805=======
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000806 printk_debug("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000807>>>>>>> 1.25
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000808 intBits |= (1 << intNum);
809
Eric Biedermanb78c1972004-10-14 20:54:17 +0000810<<<<<<< pci_device.c
811 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
812=======
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000813 printk_debug("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000814>>>>>>> 1.25
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000815
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000816 // Write new values
817 outb((unsigned char) intBits, 0x4d0);
818 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000819
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000820 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000821#if 1
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000822 if (inb(0x4d0) != (intBits & 0xf)) {
823 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000824 __func__, intBits &0xf, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000825 }
826 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
827 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000828 __func__, (intBits>>8) &0xf, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000829 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000830#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000831}
832
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000833/*
834 This function assigns IRQs for all functions contained within
835 the indicated device address. If the device does not exist or does
836 not require interrupts then this function has no effect.
837
838 This function should be called for each PCI slot in your system.
839
840 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
841 this slot.
842 The particular irq #s that are passed in depend on the routing inside
843 your southbridge and on your motherboard.
844
845 -kevinh@ispiri.com
846*/
847void pci_assign_irqs(unsigned bus, unsigned slot,
848 const unsigned char pIntAtoD[4])
849{
850 unsigned functNum;
851 device_t pdev;
852 unsigned char line;
853 unsigned char irq;
854 unsigned char readback;
855
856 /* Each slot may contain up to eight functions */
857 for (functNum = 0; functNum < 8; functNum++) {
858 pdev = dev_find_slot(bus, (slot << 3) + functNum);
859
860 if (pdev) {
861 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
862
863 // PCI spec says all other values are reserved
864 if ((line >= 1) && (line <= 4)) {
865 irq = pIntAtoD[line - 1];
866
867 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
868 irq, bus, slot, functNum);
869
870 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
871 pIntAtoD[line - 1]);
872
873 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
874 printk_debug(" Readback = %d\n", readback);
875
876 // Change to level triggered
877 pci_level_irq(pIntAtoD[line - 1]);
878 }
879 }
880 }
881}