blob: f87a590d0e2a53fbd0e1bc7944d76fbda972e68f [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
Li-Ta Loe5266692004-03-23 21:28:05 +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,
Li-Ta Loe5266692004-03-23 21:28:05 +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,
Li-Ta Loe5266692004-03-23 21:28:05 +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,
Li-Ta Loe5266692004-03-23 21:28:05 +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/**
226 * @brief round a number up to an alignment.
227 * @param val the starting value
228 * @param roundup Alignment as a power of two
229 * @returns rounded up number
230 */
231static unsigned long round(unsigned long val, unsigned long roundup)
232{
233 /* ROUNDUP MUST BE A POWER OF TWO. */
234 unsigned long inverse;
235 inverse = ~(roundup - 1);
236 val += (roundup - 1);
237 val &= inverse;
238 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 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000248
Eric Biederman5cd81732004-03-11 15:01:31 +0000249 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000250 printk_err("ERROR: %s %02x not allocated\n",
Li-Ta Loe5266692004-03-23 21:28:05 +0000251 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000252 return;
253 }
254
Eric Biederman5cd81732004-03-11 15:01:31 +0000255 /* If I have already stored this resource don't worry about it */
256 if (resource->flags & IORESOURCE_STORED) {
257 return;
258 }
259
Eric Biederman8ca8d762003-04-22 19:02:15 +0000260 /* Only handle PCI memory and IO resources for now */
261 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
262 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000263
Eric Biederman8ca8d762003-04-22 19:02:15 +0000264 if (resource->flags & IORESOURCE_MEM) {
265 dev->command |= PCI_COMMAND_MEMORY;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000266 }
267 if (resource->flags & IORESOURCE_IO) {
268 dev->command |= PCI_COMMAND_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000269 }
270 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
271 dev->command |= PCI_COMMAND_MASTER;
272 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000273
Eric Biederman8ca8d762003-04-22 19:02:15 +0000274 /* Get the base address */
275 base = resource->base;
Li-Ta Loe5266692004-03-23 21:28:05 +0000276
Eric Biederman5cd81732004-03-11 15:01:31 +0000277 /* Get the resource granularity */
278 gran = 1UL << resource->gran;
279
280 /* For a non bridge resource granularity and alignment are the same.
281 * For a bridge resource align is the largest needed alignment below
282 * the bridge. While the granularity is simply how many low bits of the
283 * address cannot be set.
284 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000285
286 /* Get the limit (rounded up) */
Li-Ta Loe5266692004-03-23 21:28:05 +0000287 limit = base + round(resource->size, gran) - 1UL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000288
Eric Biederman5cd81732004-03-11 15:01:31 +0000289 /* Now store the resource */
290 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000291 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000292 /* some chipsets allow us to set/clear the IO bit.
293 * (e.g. VIA 82c686a.) So set it to be safe) */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000294 limit = base + resource->size -1;
295 if (resource->flags & IORESOURCE_IO) {
296 base |= PCI_BASE_ADDRESS_SPACE_IO;
297 }
Eric Biederman7a5416a2003-06-12 19:23:51 +0000298 pci_write_config32(dev, resource->index, base & 0xffffffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000299 if (resource->flags & IORESOURCE_PCI64) {
300 /* FIXME handle real 64bit base addresses */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000301 pci_write_config32(dev, resource->index + 4, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000302 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000303 } 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,
Li-Ta Loe5266692004-03-23 21:28:05 +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);
Li-Ta Loe5266692004-03-23 21:28:05 +0000313 } else if (resource->index == PCI_MEMORY_BASE) {
314 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000315 compute_allocate_resource(&dev->link[0], resource,
Li-Ta Loe5266692004-03-23 21:28:05 +0000316 IORESOURCE_MEM | IORESOURCE_PREFETCH,
317 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000318 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
319 pci_write_config16(dev, PCI_MEMORY_LIMIT, limit >> 16);
Li-Ta Loe5266692004-03-23 21:28:05 +0000320 } else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000321 /* set the prefetchable memory range
Li-Ta Loe5266692004-03-23 21:28:05 +0000322 * WARNING: we don't really do 64-bit addressing for
323 * prefetchable memory yet! */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000324 compute_allocate_resource(&dev->link[0], resource,
Li-Ta Loe5266692004-03-23 21:28:05 +0000325 IORESOURCE_MEM | IORESOURCE_PREFETCH,
326 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000327 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
328 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, limit >> 16);
Eric Biederman5fb929e2003-07-17 02:15:46 +0000329 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, 0);
330 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, 0);
Li-Ta Loe5266692004-03-23 21:28:05 +0000331 } else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000332 /* Don't let me think I stored the resource */
333 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000334 printk_err("ERROR: invalid resource->index %x\n",
Li-Ta Loe5266692004-03-23 21:28:05 +0000335 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000336 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000337
Eric Biederman8ca8d762003-04-22 19:02:15 +0000338 buf[0] = '\0';
339 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000340 sprintf(buf, "bus %d ", dev->link[0].secondary);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000341 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000342 printk_debug("%s %02x <- [0x%08lx - 0x%08lx] %s%s\n",
343 dev_path(dev), resource->index, resource->base,
344 limit, buf,
345 (resource->flags & IORESOURCE_IO)? "io":
346 (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000347 return;
348}
349
Eric Biederman5899fd82003-04-24 06:25:08 +0000350void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000351{
352 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000353 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000354 uint8_t line;
355
356 last = &dev->resource[dev->resources];
Li-Ta Loe5266692004-03-23 21:28:05 +0000357 for (resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000358 pci_set_resource(dev, resource);
359 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000360
361 for (link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000362 struct bus *bus;
363 bus = &dev->link[link];
364 if (bus->children) {
365 assign_resources(bus);
366 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000367 }
368
369 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000370 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000371
372 /* set a default secondary latency timer */
373 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000374 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000375 }
376
377 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000378 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000379 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000380 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000381 }
382 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000383 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000384}
385
Eric Biedermane9a271e32003-09-02 03:36:25 +0000386void pci_dev_enable_resources(struct device *dev)
387{
388 uint16_t command;
389 command = pci_read_config16(dev, PCI_COMMAND);
390 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000391 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000392 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
393 pci_write_config16(dev, PCI_COMMAND, command);
394
395 enable_childrens_resources(dev);
396}
397
398void pci_bus_enable_resources(struct device *dev)
399{
400 uint16_t ctrl;
401 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
402 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000403 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000404 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
405 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
406
407 pci_dev_enable_resources(dev);
408}
409
Li-Ta Loe5266692004-03-23 21:28:05 +0000410/** Default device operation for PCI devices */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000411struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000412 .read_resources = pci_dev_read_resources,
413 .set_resources = pci_dev_set_resources,
414 .enable_resources = pci_dev_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000415 .init = 0,
416 .scan_bus = 0,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000417};
Li-Ta Loe5266692004-03-23 21:28:05 +0000418
419/** Default device operations for PCI bridges */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000420struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000421 .read_resources = pci_bus_read_resources,
422 .set_resources = pci_dev_set_resources,
423 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000424 .init = 0,
425 .scan_bus = pci_scan_bridge,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000426};
Li-Ta Loe5266692004-03-23 21:28:05 +0000427
428/**
429 * @brief Set up PCI device operation
430 *
431 *
432 * @param dev
433 *
434 * @see pci_drivers
435 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000436static void set_pci_ops(struct device *dev)
437{
438 struct pci_driver *driver;
Li-Ta Loe5266692004-03-23 21:28:05 +0000439
Eric Biederman8ca8d762003-04-22 19:02:15 +0000440 if (dev->ops) {
441 return;
442 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000443
Eric Biederman8ca8d762003-04-22 19:02:15 +0000444 /* Look through the list of setup drivers and find one for
Li-Ta Loe5266692004-03-23 21:28:05 +0000445 * this pci device */
446 for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000447 if ((driver->vendor == dev->vendor) &&
Li-Ta Loe5266692004-03-23 21:28:05 +0000448 (driver->device == dev->device)) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000449 dev->ops = driver->ops;
Li-Ta Loe5266692004-03-23 21:28:05 +0000450
451 printk_debug("%s [%04x/%04x] %sops\n", dev_path(dev),
452 driver->vendor, driver->device,
453 (driver->ops->scan_bus?"bus ":""));
454
Eric Biederman5899fd82003-04-24 06:25:08 +0000455 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000456 }
457 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000458
Li-Ta Lo9da7ff92004-05-24 19:04:47 +0000459#if 0
460 extern struct pci_driver generic_vga_driver;
461 /* TODO: Install generic VGA driver for VGA devices, base on the
462 * class ID */
463 if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
464 printk_debug("setting up generic VGA driver\n");
465 dev->ops = generic_vga_driver.ops;
466 return;
467 }
468#endif
469
Eric Biederman8ca8d762003-04-22 19:02:15 +0000470 /* If I don't have a specific driver use the default operations */
471 switch(dev->hdr_type & 0x7f) { /* header type */
472 case PCI_HEADER_TYPE_NORMAL: /* standard header */
473 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
474 goto bad;
475 dev->ops = &default_pci_ops_dev;
476 break;
477 case PCI_HEADER_TYPE_BRIDGE:
478 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
479 goto bad;
480 dev->ops = &default_pci_ops_bus;
481 break;
482 default:
483 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000484 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000485 printk_err("%s [%04x/%04x/%06x] has unknown header "
Li-Ta Loe5266692004-03-23 21:28:05 +0000486 "type %02x, ignoring.\n",
487 dev_path(dev),
488 dev->vendor, dev->device,
489 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000490 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000491 }
492 return;
493}
494
495/**
Li-Ta Loe5266692004-03-23 21:28:05 +0000496 * @brief Find a specific device structure on a list of device structures
497 *
498 * Given a linked list of PCI device structures and a devfn number, find the
499 * device structure correspond to the devfn.
500 *
501 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000502 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000503 *
504 * @return pointer to the device structure found
Eric Biederman8ca8d762003-04-22 19:02:15 +0000505 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000506static struct device *pci_scan_get_dev(struct device **list,
507 unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000508{
509 struct device *dev = 0;
Li-Ta Loe5266692004-03-23 21:28:05 +0000510
Li-Ta Lo9ab91f52004-07-08 16:54:20 +0000511 printk_debug("%s, looking for devfn: %02x.%01x\n", __FUNCTION__,
512 devfn >> 3, devfn & 7);
Li-Ta Loe5266692004-03-23 21:28:05 +0000513 for (; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000514 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000515 printk_err("child %s not a pci device\n",
516 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000517 continue;
518 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000519 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000520 /* Unlink from the list */
521 dev = *list;
522 *list = (*list)->sibling;
523 dev->sibling = 0;
524 break;
525 }
526 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000527
Li-Ta Lo9ab91f52004-07-08 16:54:20 +0000528 printk_debug("%s, found dev %08x\n", __FUNCTION__, dev);
529
Li-Ta Loe5266692004-03-23 21:28:05 +0000530 /* FIXME: why are we doing this ? Isn't there some order between the
531 * structures before ? */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000532 if (dev) {
533 device_t child;
534 /* Find the last child of our parent */
Li-Ta Loe5266692004-03-23 21:28:05 +0000535 for (child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000536 child = child->sibling;
537 }
538 /* Place the device on the list of children of it's parent. */
539 if (child) {
540 child->sibling = dev;
541 } else {
542 dev->bus->children = dev;
543 }
544 }
545
Eric Biederman8ca8d762003-04-22 19:02:15 +0000546 return dev;
547}
548
Li-Ta Loe5266692004-03-23 21:28:05 +0000549/**
550 * @brief Scan a PCI bus
551 *
552 * Determine the existence of devices and bridges on a PCI bus. If there are
553 * bridges on the bus, recursively scan the buses behind the bridges.
554 *
555 * This function is the default scan_bus() method for the root device
556 * 'dev_root'.
557 *
Eric Biedermane9a271e32003-09-02 03:36:25 +0000558 * @param bus pointer to the bus structure
559 * @param min_devfn minimum devfn to look at in the scan usually 0x00
560 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000561 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +0000562 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000563 * @return The maximum bus number found, after scanning all subordinate busses
564 */
Li-Ta Loe5266692004-03-23 21:28:05 +0000565unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn,
566 unsigned max_devfn, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000567{
568 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000569 device_t dev;
570 device_t old_devices;
571 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000572
573 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
574
575 old_devices = bus->children;
576 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000577
578 post_code(0x24);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000579
Li-Ta Lo9782f752004-05-05 21:15:42 +0000580 /* probe all devices/functions on this bus with some optimization for
Li-Ta Loe5266692004-03-23 21:28:05 +0000581 * non-existence and single funcion devices */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000582 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000583 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000584 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000585
Li-Ta Loe5266692004-03-23 21:28:05 +0000586 /* device structures for PCI devices associated with static
587 * devices are already created during the static device
588 * enumeration, find out if it is the case for this devfn */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000589 dev = pci_scan_get_dev(&old_devices, devfn);
Li-Ta Loe5266692004-03-23 21:28:05 +0000590
Eric Biederman8ca8d762003-04-22 19:02:15 +0000591 if (!dev) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000592 /* it's not associated with a static device, detect if
593 * this device is present */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000594 struct device dummy;
595 dummy.bus = bus;
596 dummy.path.type = DEVICE_PATH_PCI;
597 dummy.path.u.pci.devfn = devfn;
598 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
599 /* some broken boards return 0 if a slot is empty: */
Li-Ta Loe5266692004-03-23 21:28:05 +0000600 if ((id == 0xffffffff) || (id == 0x00000000) ||
601 (id == 0x0000ffff) || (id == 0xffff0000)) {
602 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n",
603 devfn, id);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000604 if (PCI_FUNC(devfn) == 0x00) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000605 /* if this is a function 0 device and
606 * it is not present, skip to next
607 * device */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000608 devfn += 0x07;
609 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000610 /* this function in a multi function device is
611 * not present, skip to next function */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000612 continue;
613 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000614 dev = alloc_dev(bus, &dummy.path);
Li-Ta Loe5266692004-03-23 21:28:05 +0000615 } else {
616 /* Run the magic enable/disable sequence for the
617 * device */
618 /* FIXME: What happen if this PCI device listed as
619 * static device but does not exist ? This calls
Li-Ta Lo9782f752004-05-05 21:15:42 +0000620 * some arbitray code without any justification
621 * Also, it calls the enable function regardlessly
622 * the value of dev->enabled */
Li-Ta Loe5266692004-03-23 21:28:05 +0000623 if (dev->chip && dev->chip->control &&
624 dev->chip->control->enable_dev) {
Li-Ta Lo9782f752004-05-05 21:15:42 +0000625 int enabled = dev->enabled;
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000626 dev->enabled = 1;
Eric Biederman83b991a2003-10-11 06:20:25 +0000627 dev->chip->control->enable_dev(dev);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000628 dev->enabled = enabled;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000629 }
630 /* Now read the vendor and device id */
631 id = pci_read_config32(dev, PCI_VENDOR_ID);
632 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000633 /* Read the rest of the pci configuration information */
634 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
635 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000636
Eric Biedermane9a271e32003-09-02 03:36:25 +0000637 /* Store the interesting information in the device structure */
638 dev->vendor = id & 0xffff;
639 dev->device = (id >> 16) & 0xffff;
640 dev->hdr_type = hdr_type;
641 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
642 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000643
Eric Biederman8ca8d762003-04-22 19:02:15 +0000644 /* Look at the vendor and device id, or at least the
Li-Ta Loe5266692004-03-23 21:28:05 +0000645 * header type and class and figure out which set of
646 * configuration methods to use. Unless we already
647 * have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000648 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000649 set_pci_ops(dev);
650 /* Error if we don't have some pci operations for it */
Eric Biederman5cd81732004-03-11 15:01:31 +0000651 if (!dev->ops) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000652 printk_err("%s No device operations\n",
Li-Ta Loe5266692004-03-23 21:28:05 +0000653 dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000654 continue;
655 }
656
657 /* Now run the magic enable/disable sequence for the device */
658 if (dev->ops && dev->ops->enable) {
659 dev->ops->enable(dev);
Li-Ta Lo9782f752004-05-05 21:15:42 +0000660 } else if (dev->chip && dev->chip->control &&
661 dev->chip->control->enable_dev) {
Eric Biederman5cd81732004-03-11 15:01:31 +0000662 dev->chip->control->enable_dev(dev);
663 }
Eric Biederman4086d162003-07-17 03:26:03 +0000664
Eric Biedermane9a271e32003-09-02 03:36:25 +0000665 printk_debug("%s [%04x/%04x] %s\n",
Li-Ta Loe5266692004-03-23 21:28:05 +0000666 dev_path(dev),
667 dev->vendor, dev->device,
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000668 dev->enabled?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000669
Eric Biederman8ca8d762003-04-22 19:02:15 +0000670 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000671 /* if this is not a multi function device, don't
672 * waste time probe another function.
673 * Skip to next device. */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000674 devfn += 0x07;
675 }
676 }
677 post_code(0x25);
678
Li-Ta Lo9220f912004-05-24 19:48:13 +0000679 /* if a child provides scan_bus(), for example a bridge, scan
680 * buses behind that child */
Li-Ta Loe5266692004-03-23 21:28:05 +0000681 for (child = bus->children; child; child = child->sibling) {
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000682 // make sure that we have an ops structure
683 if (!child->ops) {
684 continue;
685 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000686 if (!child->ops->scan_bus) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000687 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000688 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000689 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000690 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000691
Eric Biederman8ca8d762003-04-22 19:02:15 +0000692 /*
693 * We've scanned the bus and so we know all about what's on
694 * the other side of any bridges that may be on this bus plus
695 * any devices.
696 *
697 * Return how far we've got finding sub-buses.
698 */
699 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
700 post_code(0x55);
701 return max;
702}
703
Li-Ta Loe5266692004-03-23 21:28:05 +0000704/**
705 * @brief Scan a PCI bridge and the buses behind the bridge.
706 *
707 * Determine the existence of buses behind the bridge. Set up the bridge
708 * according to the result of the scan.
709 *
710 * This function is the default scan_bus() method for PCI bridge devices.
711 *
712 * @param dev pointer to the bridge device
713 * @param max the highest bus number assgined up to now
714 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000715 * @return The maximum bus number found, after scanning all subordinate busses
716 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000717unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000718{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000719 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000720 uint32_t buses;
721 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000722
Eric Biedermane9a271e32003-09-02 03:36:25 +0000723 bus = &dev->link[0];
724 dev->links = 1;
725
Eric Biederman8ca8d762003-04-22 19:02:15 +0000726 /* Set up the primary, secondary and subordinate bus numbers. We have
727 * no idea how many buses are behind this bridge yet, so we set the
Li-Ta Loe5266692004-03-23 21:28:05 +0000728 * subordinate bus number to 0xff for the moment. */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000729 bus->secondary = ++max;
730 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +0000731
Eric Biederman8ca8d762003-04-22 19:02:15 +0000732 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000733 cr = pci_read_config16(dev, PCI_COMMAND);
734 pci_write_config16(dev, PCI_COMMAND, 0x0000);
735 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000736
Li-Ta Loe5266692004-03-23 21:28:05 +0000737 /* Read the existing primary/secondary/subordinate bus
738 * number configuration. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000739 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000740
741 /* Configure the bus numbers for this bridge: the configuration
742 * transactions will not be propagated by the bridge if it is not
Li-Ta Loe5266692004-03-23 21:28:05 +0000743 * correctly configured */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000744 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000745 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Li-Ta Loe5266692004-03-23 21:28:05 +0000746 ((unsigned int) (bus->secondary) << 8) |
747 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000748 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Li-Ta Lo9ab91f52004-07-08 16:54:20 +0000749
Li-Ta Loe5266692004-03-23 21:28:05 +0000750 /* Now we can scan all subordinate buses i.e. the buses behind the
751 * bridge */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000752 max = pci_scan_bus(bus, 0x00, 0xff, max);
Li-Ta Lo9ab91f52004-07-08 16:54:20 +0000753
Eric Biederman8ca8d762003-04-22 19:02:15 +0000754 /* We know the number of buses behind this bridge. Set the subordinate
Li-Ta Loe5266692004-03-23 21:28:05 +0000755 * bus number to its real value */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000756 bus->subordinate = max;
757 buses = (buses & 0xff00ffff) |
758 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000759 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
760 pci_write_config16(dev, PCI_COMMAND, cr);
Li-Ta Loe5266692004-03-23 21:28:05 +0000761
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000762 printk_spew("%s returns max %d\n", __FUNCTION__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000763 return max;
764}
Li-Ta Loe5266692004-03-23 21:28:05 +0000765
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000766/*
767 Tell the EISA int controller this int must be level triggered
768 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
769*/
770static void pci_level_irq(unsigned char intNum)
771{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000772 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000773
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000774 printk_debug("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000775 intBits |= (1 << intNum);
776
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000777 printk_debug("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000778
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000779 // Write new values
780 outb((unsigned char) intBits, 0x4d0);
781 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000782
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000783 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000784#if 1
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000785 if (inb(0x4d0) != (intBits & 0xf)) {
786 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
787 __FUNCTION__, intBits &0xf, inb(0x4d0));
788 }
789 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
790 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
791 __FUNCTION__, (intBits>>8) &0xf, inb(0x4d1));
792 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +0000793#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000794}
795
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000796/*
797 This function assigns IRQs for all functions contained within
798 the indicated device address. If the device does not exist or does
799 not require interrupts then this function has no effect.
800
801 This function should be called for each PCI slot in your system.
802
803 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
804 this slot.
805 The particular irq #s that are passed in depend on the routing inside
806 your southbridge and on your motherboard.
807
808 -kevinh@ispiri.com
809*/
810void pci_assign_irqs(unsigned bus, unsigned slot,
811 const unsigned char pIntAtoD[4])
812{
813 unsigned functNum;
814 device_t pdev;
815 unsigned char line;
816 unsigned char irq;
817 unsigned char readback;
818
819 /* Each slot may contain up to eight functions */
820 for (functNum = 0; functNum < 8; functNum++) {
821 pdev = dev_find_slot(bus, (slot << 3) + functNum);
822
823 if (pdev) {
824 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
825
826 // PCI spec says all other values are reserved
827 if ((line >= 1) && (line <= 4)) {
828 irq = pIntAtoD[line - 1];
829
830 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
831 irq, bus, slot, functNum);
832
833 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
834 pIntAtoD[line - 1]);
835
836 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
837 printk_debug(" Readback = %d\n", readback);
838
839 // Change to level triggered
840 pci_level_irq(pIntAtoD[line - 1]);
841 }
842 }
843 }
844}