blob: ffa420739ab9bf16942424374116b92c99f79646 [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 */
30static void pci_get_resource(struct device *dev, struct resource *resource, unsigned long index)
31{
32 uint32_t addr, size, base;
33 unsigned long type;
34
35 /* Initialize the resources to nothing */
36 resource->base = 0;
37 resource->size = 0;
38 resource->align = 0;
39 resource->gran = 0;
40 resource->limit = 0;
41 resource->flags = 0;
42 resource->index = index;
43
Eric Biederman7a5416a2003-06-12 19:23:51 +000044 addr = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +000045
46 /* FIXME: more consideration for 64-bit PCI devices,
47 * we currently detect their size but otherwise
48 * treat them as 32-bit resources
49 */
50 /* get the size */
Eric Biederman7a5416a2003-06-12 19:23:51 +000051 pci_write_config32(dev, index, ~0);
52 size = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +000053
54 /* get the minimum value the bar can be set to */
Eric Biederman7a5416a2003-06-12 19:23:51 +000055 pci_write_config32(dev, index, 0);
56 base = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +000057
58 /* restore addr */
Eric Biederman7a5416a2003-06-12 19:23:51 +000059 pci_write_config32(dev, index, addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +000060
61 /*
62 * some broken hardware has read-only registers that do not
63 * really size correctly. You can tell this if addr == size
64 * Example: the acer m7229 has BARs 1-4 normally read-only.
65 * so BAR1 at offset 0x10 reads 0x1f1. If you size that register
66 * by writing 0xffffffff to it, it will read back as 0x1f1 -- a
67 * violation of the spec.
68 * We catch this case and ignore it by settting size and type to 0.
69 * This incidentally catches the common case where registers
70 * read back as 0 for both address and size.
71 */
72 if ((addr == size) && (addr == base)) {
73 if (size != 0) {
74 printk_debug(
Eric Biedermane9a271e32003-09-02 03:36:25 +000075 "%s register %02x(%08x), read-only ignoring it\n",
76 dev_path(dev),
Eric Biederman8ca8d762003-04-22 19:02:15 +000077 index, addr);
78 }
79 resource->flags = 0;
80 }
81 /* Now compute the actual size, See PCI Spec 6.2.5.1 ... */
82 else if (size & PCI_BASE_ADDRESS_SPACE_IO) {
83 type = size & (~PCI_BASE_ADDRESS_IO_MASK);
84 /* BUG! Top 16 bits can be zero (or not)
85 * So set them to 0xffff so they go away ...
86 */
87 resource->size = (~((size | 0xffff0000) & PCI_BASE_ADDRESS_IO_MASK)) +1;
88 resource->align = log2(resource->size);
89 resource->gran = resource->align;
90 resource->flags = IORESOURCE_IO;
91 resource->limit = 0xffff;
92 }
93 else {
94 /* A Memory mapped base address */
95 type = size & (~PCI_BASE_ADDRESS_MEM_MASK);
96 resource->size = (~(size &PCI_BASE_ADDRESS_MEM_MASK)) +1;
97 resource->align = log2(resource->size);
98 resource->gran = resource->align;
99 resource->flags = IORESOURCE_MEM;
100 if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
101 resource->flags |= IORESOURCE_PREFETCH;
102 }
103 type &= PCI_BASE_ADDRESS_MEM_TYPE_MASK;
104 if (type == PCI_BASE_ADDRESS_MEM_TYPE_32) {
105 /* 32bit limit */
106 resource->limit = 0xffffffffUL;
107 }
108 else if (type == PCI_BASE_ADDRESS_MEM_TYPE_1M) {
109 /* 1MB limit */
110 resource->limit = 0x000fffffUL;
111 }
112 else if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
113 unsigned long index_hi;
114 /* 64bit limit
115 * For now just treat this as a 32bit limit
116 */
117 index_hi = index + 4;
118 resource->limit = 0xffffffffUL;
119 resource->flags |= IORESOURCE_PCI64;
Eric Biederman7a5416a2003-06-12 19:23:51 +0000120 addr = pci_read_config32( dev, index_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000121 /* get the extended size */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000122 pci_write_config32(dev, index_hi, 0xffffffffUL);
123 size = pci_read_config32( dev, index_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000124
125 /* get the minimum value the bar can be set to */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000126 pci_write_config32(dev, index_hi, 0);
127 base = pci_read_config32(dev, index_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000128
129 /* restore addr */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000130 pci_write_config32(dev, index_hi, addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000131
132 if ((size == 0xffffffff) && (base == 0)) {
133 /* Clear the top half of the bar */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000134 pci_write_config32(dev, index_hi, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000135 }
136 else {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000137 printk_err("%s Unable to handle 64-bit address\n",
138 dev_path(dev));
Eric Biederman8ca8d762003-04-22 19:02:15 +0000139 resource->flags = IORESOURCE_PCI64;
140 }
141 }
142 else {
143 /* Invalid value */
144 resource->flags = 0;
145 }
146 }
147 /* dev->size holds the flags... */
148 return;
149}
150
151/** Read the base address registers for a given device.
152 * @param dev Pointer to the dev structure
153 * @param howmany How many registers to read (6 for device, 2 for bridge)
154 */
155static void pci_read_bases(struct device *dev, unsigned int howmany)
156{
157 unsigned int reg;
158 unsigned long index;
159
160 reg = dev->resources;
161 for(index = PCI_BASE_ADDRESS_0;
162 (reg < MAX_RESOURCES) && (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
163 struct resource *resource;
164 resource = &dev->resource[reg];
165 pci_get_resource(dev, resource, index);
166 reg += (resource->flags & (IORESOURCE_IO | IORESOURCE_MEM))? 1:0;
167 index += (resource->flags & IORESOURCE_PCI64)?8:4;
168 }
169 dev->resources = reg;
170}
171
172
173static void pci_bridge_read_bases(struct device *dev)
174{
175 unsigned int reg = dev->resources;
176
177 /* FIXME handle bridges without some of the optional resources */
178
179 /* Initialize the io space constraints on the current bus */
180 dev->resource[reg].base = 0;
181 dev->resource[reg].size = 0;
182 dev->resource[reg].align = log2(PCI_IO_BRIDGE_ALIGN);
183 dev->resource[reg].gran = log2(PCI_IO_BRIDGE_ALIGN);
184 dev->resource[reg].limit = 0xffffUL;
185 dev->resource[reg].flags = IORESOURCE_IO | IORESOURCE_PCI_BRIDGE;
186 dev->resource[reg].index = PCI_IO_BASE;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000187 compute_allocate_resource(&dev->link[0], &dev->resource[reg],
Eric Biederman8ca8d762003-04-22 19:02:15 +0000188 IORESOURCE_IO, IORESOURCE_IO);
189 reg++;
190
191 /* Initiliaze the prefetchable memory constraints on the current bus */
192 dev->resource[reg].base = 0;
193 dev->resource[reg].size = 0;
194 dev->resource[reg].align = log2(PCI_MEM_BRIDGE_ALIGN);
195 dev->resource[reg].gran = log2(PCI_MEM_BRIDGE_ALIGN);
196 dev->resource[reg].limit = 0xffffffffUL;
197 dev->resource[reg].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_PCI_BRIDGE;
198 dev->resource[reg].index = PCI_PREF_MEMORY_BASE;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000199 compute_allocate_resource(&dev->link[0], &dev->resource[reg],
Eric Biederman8ca8d762003-04-22 19:02:15 +0000200 IORESOURCE_MEM | IORESOURCE_PREFETCH,
201 IORESOURCE_MEM | IORESOURCE_PREFETCH);
202 reg++;
203
204 /* Initialize the memory resources on the current bus */
205 dev->resource[reg].base = 0;
206 dev->resource[reg].size = 0;
207 dev->resource[reg].align = log2(PCI_MEM_BRIDGE_ALIGN);
208 dev->resource[reg].gran = log2(PCI_MEM_BRIDGE_ALIGN);
209 dev->resource[reg].limit = 0xffffffffUL;
210 dev->resource[reg].flags = IORESOURCE_MEM | IORESOURCE_PCI_BRIDGE;
211 dev->resource[reg].index = PCI_MEMORY_BASE;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000212 compute_allocate_resource(&dev->link[0], &dev->resource[reg],
Eric Biederman8ca8d762003-04-22 19:02:15 +0000213 IORESOURCE_MEM | IORESOURCE_PREFETCH,
214 IORESOURCE_MEM);
215 reg++;
216
217 dev->resources = reg;
218}
219
220
Eric Biederman5899fd82003-04-24 06:25:08 +0000221void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000222{
223 uint32_t addr;
224 dev->resources = 0;
225 memset(&dev->resource[0], 0, sizeof(dev->resource));
226 pci_read_bases(dev, 6);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000227 addr = pci_read_config32(dev, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000228 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
229}
230
Eric Biederman5899fd82003-04-24 06:25:08 +0000231void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000232{
233 uint32_t addr;
234 dev->resources = 0;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000235 memset(&dev->resource, 0, sizeof(dev->resource));
Eric Biederman8ca8d762003-04-22 19:02:15 +0000236 pci_bridge_read_bases(dev);
237 pci_read_bases(dev, 2);
238
Eric Biederman7a5416a2003-06-12 19:23:51 +0000239 addr = pci_read_config32(dev, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000240 dev->rom_address = (addr == 0xffffffff)? 0 : addr;
241
242}
243
244
245static void pci_set_resource(struct device *dev, struct resource *resource)
246{
247 unsigned long base, limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000248 unsigned char buf[10];
Eric Biedermane9a271e32003-09-02 03:36:25 +0000249 unsigned long align;
250
Eric Biederman8ca8d762003-04-22 19:02:15 +0000251 /* Make certain the resource has actually been set */
252 if (!(resource->flags & IORESOURCE_SET)) {
253#if 1
Eric Biedermane9a271e32003-09-02 03:36:25 +0000254 printk_err("ERROR: %s %02x not allocated\n",
255 dev_path(dev), resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000256#endif
257 return;
258 }
259
260 /* 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 }
273 /* Get the base address */
274 base = resource->base;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000275 /* Get the resource alignment */
276 align = 1UL << resource->align;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000277
278 /* Get the limit (rounded up) */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000279 limit = base + ((resource->size + align - 1UL) & ~(align - 1UL)) -1UL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000280
281 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
282 /*
283 * some chipsets allow us to set/clear the IO bit.
284 * (e.g. VIA 82c686a.) So set it to be safe)
285 */
286 limit = base + resource->size -1;
287 if (resource->flags & IORESOURCE_IO) {
288 base |= PCI_BASE_ADDRESS_SPACE_IO;
289 }
Eric Biederman7a5416a2003-06-12 19:23:51 +0000290 pci_write_config32(dev, resource->index, base & 0xffffffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000291 if (resource->flags & IORESOURCE_PCI64) {
292 /* FIXME handle real 64bit base addresses */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000293 pci_write_config32(dev, resource->index + 4, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000294 }
295 }
296 else if (resource->index == PCI_IO_BASE) {
297 /* set the IO ranges
298 * WARNING: we don't really do 32-bit addressing for IO yet!
299 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000300 compute_allocate_resource(&dev->link[0], resource,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000301 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000302 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
303 pci_write_config8(dev, PCI_IO_LIMIT, limit >> 8);
Eric Biederman5fb929e2003-07-17 02:15:46 +0000304 pci_write_config16(dev, PCI_IO_BASE_UPPER16, 0);
305 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000306 }
307 else if (resource->index == PCI_MEMORY_BASE) {
308 /* set the memory range
309 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000310 compute_allocate_resource(&dev->link[0], resource,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000311 IORESOURCE_MEM | IORESOURCE_PREFETCH,
312 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000313 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
314 pci_write_config16(dev, PCI_MEMORY_LIMIT, limit >> 16);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000315 }
316 else if (resource->index == PCI_PREF_MEMORY_BASE) {
317 /* set the prefetchable memory range
318 * WARNING: we don't really do 64-bit addressing for prefetchable memory yet!
319 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000320 compute_allocate_resource(&dev->link[0], resource,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000321 IORESOURCE_MEM | IORESOURCE_PREFETCH,
322 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000323 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
324 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, limit >> 16);
Eric Biederman5fb929e2003-07-17 02:15:46 +0000325 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, 0);
326 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000327 }
328 else {
329 printk_err("ERROR: invalid resource->index %x\n",
330 resource->index);
331 }
332 buf[0] = '\0';
333 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000334 sprintf(buf, "bus %d ", dev->link[0].secondary);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000335 }
336
337 printk_debug(
Eric Biedermane9a271e32003-09-02 03:36:25 +0000338 "%s %02x <- [0x%08lx - 0x%08lx] %s%s\n",
339 dev_path(dev),
Eric Biederman8ca8d762003-04-22 19:02:15 +0000340 resource->index,
341 resource->base, limit,
342 buf,
343 (resource->flags & IORESOURCE_IO)? "io":
344 (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem");
345 return;
346}
347
Eric Biederman5899fd82003-04-24 06:25:08 +0000348void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000349{
350 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000351 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000352 uint8_t line;
353
354 last = &dev->resource[dev->resources];
355
356 for(resource = &dev->resource[0]; resource < last; resource++) {
357 pci_set_resource(dev, resource);
358 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000359 for(link = 0; link < dev->links; link++) {
360 struct bus *bus;
361 bus = &dev->link[link];
362 if (bus->children) {
363 assign_resources(bus);
364 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000365 }
366
367 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000368 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000369
370 /* set a default secondary latency timer */
371 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000372 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000373 }
374
375 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000376 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000377 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000378 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000379 }
380 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000381 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000382}
383
Eric Biedermane9a271e32003-09-02 03:36:25 +0000384void pci_dev_enable_resources(struct device *dev)
385{
386 uint16_t command;
387 command = pci_read_config16(dev, PCI_COMMAND);
388 command |= dev->command;
389 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
390 pci_write_config16(dev, PCI_COMMAND, command);
391
392 enable_childrens_resources(dev);
393}
394
395void pci_bus_enable_resources(struct device *dev)
396{
397 uint16_t ctrl;
398 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
399 ctrl |= dev->link[0].bridge_ctrl;
400 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
401 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
402
403 pci_dev_enable_resources(dev);
404}
405
Eric Biederman8ca8d762003-04-22 19:02:15 +0000406struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000407 .read_resources = pci_dev_read_resources,
408 .set_resources = pci_dev_set_resources,
409 .enable_resources = pci_dev_enable_resources,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000410 .init = 0,
411 .scan_bus = 0,
412};
413struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000414 .read_resources = pci_bus_read_resources,
415 .set_resources = pci_dev_set_resources,
416 .enable_resources = pci_bus_enable_resources,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000417 .init = 0,
418 .scan_bus = pci_scan_bridge,
419};
420static void set_pci_ops(struct device *dev)
421{
422 struct pci_driver *driver;
423 if (dev->ops) {
424 return;
425 }
426 /* Look through the list of setup drivers and find one for
427 * this pci device
428 */
429 for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
430 if ((driver->vendor == dev->vendor) &&
Eric Biederman5899fd82003-04-24 06:25:08 +0000431 (driver->device == dev->device)) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000432 dev->ops = driver->ops;
Eric Biederman5899fd82003-04-24 06:25:08 +0000433#if 1
Eric Biedermane9a271e32003-09-02 03:36:25 +0000434 printk_debug("%s [%04x/%04x] %sops\n",
435 dev_path(dev),
436 driver->vendor, driver->device,
437 (driver->ops->scan_bus?"bus ":"")
Eric Biederman5899fd82003-04-24 06:25:08 +0000438 );
439#endif
440 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000441 }
442 }
443 /* If I don't have a specific driver use the default operations */
444 switch(dev->hdr_type & 0x7f) { /* header type */
445 case PCI_HEADER_TYPE_NORMAL: /* standard header */
446 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
447 goto bad;
448 dev->ops = &default_pci_ops_dev;
449 break;
450 case PCI_HEADER_TYPE_BRIDGE:
451 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
452 goto bad;
453 dev->ops = &default_pci_ops_bus;
454 break;
455 default:
456 bad:
Eric Biederman83b991a2003-10-11 06:20:25 +0000457 if (dev->enable) {
458 printk_err("%s [%04x/%04x/%06x] has unknown header "
459 "type %02x, ignoring.\n",
460 dev_path(dev),
461 dev->vendor, dev->device,
462 dev->class >> 8, dev->hdr_type);
463 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000464 }
465 return;
466}
467
468/**
469 * Given a bus and a devfn number, find the device structure
470 * @param bus The bus structure
471 * @param devfn a device/function number
472 * @return pointer to the device structure
473 */
474static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
475{
476 struct device *dev = 0;
477 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000478 if ((*list)->path.type != DEVICE_PATH_PCI) {
479 printk_err("child %s not a pci device\n", dev_path(*list));
480 continue;
481 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000482 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000483 /* Unlink from the list */
484 dev = *list;
485 *list = (*list)->sibling;
486 dev->sibling = 0;
487 break;
488 }
489 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000490 if (dev) {
491 device_t child;
492 /* Find the last child of our parent */
493 for(child = dev->bus->children; child && child->sibling; ) {
494 child = child->sibling;
495 }
496 /* Place the device on the list of children of it's parent. */
497 if (child) {
498 child->sibling = dev;
499 } else {
500 dev->bus->children = dev;
501 }
502 }
503
Eric Biederman8ca8d762003-04-22 19:02:15 +0000504 return dev;
505}
506
Eric Biederman8ca8d762003-04-22 19:02:15 +0000507/** Scan the pci bus devices and bridges.
Eric Biedermane9a271e32003-09-02 03:36:25 +0000508 * @param bus pointer to the bus structure
509 * @param min_devfn minimum devfn to look at in the scan usually 0x00
510 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +0000511 * @param max current bus number
512 * @return The maximum bus number found, after scanning all subordinate busses
513 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000514unsigned int pci_scan_bus(struct bus *bus,
515 unsigned min_devfn, unsigned max_devfn,
516 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000517{
518 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000519 device_t dev;
520 device_t old_devices;
521 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000522
523 printk_debug("PCI: pci_scan_bus for bus %d\n", bus->secondary);
524
525 old_devices = bus->children;
526 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000527
528 post_code(0x24);
529
530
531 /* probe all devices on this bus with some optimization for non-existance and
532 single funcion devices */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000533 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000534 uint32_t id, class;
Eric Biederman30e143a2003-09-01 23:45:32 +0000535 uint8_t hdr_type;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000536
537 /* First thing setup the device structure */
538 dev = pci_scan_get_dev(&old_devices, devfn);
539
Eric Biedermane9a271e32003-09-02 03:36:25 +0000540 /* Detect if a device is present */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000541 if (!dev) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000542 struct device dummy;
543 dummy.bus = bus;
544 dummy.path.type = DEVICE_PATH_PCI;
545 dummy.path.u.pci.devfn = devfn;
546 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
547 /* some broken boards return 0 if a slot is empty: */
548 if ( (id == 0xffffffff) || (id == 0x00000000) ||
549 (id == 0x0000ffff) || (id == 0xffff0000))
550 {
551 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
552 if (PCI_FUNC(devfn) == 0x00) {
553 /* if this is a function 0 device and it is not present,
554 skip to next device */
555 devfn += 0x07;
556 }
557 /* multi function device, skip to next function */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000558 continue;
559 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000560 dev = alloc_dev(bus, &dummy.path);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000561 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000562 else {
563 /* Run the magic enable/disable sequence for the device */
Eric Biederman83b991a2003-10-11 06:20:25 +0000564 if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
565 dev->chip->control->enable_dev(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000566 }
567 /* Now read the vendor and device id */
568 id = pci_read_config32(dev, PCI_VENDOR_ID);
569 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000570 /* Read the rest of the pci configuration information */
571 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
572 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Eric Biederman83b991a2003-10-11 06:20:25 +0000573
Eric Biedermane9a271e32003-09-02 03:36:25 +0000574 /* Store the interesting information in the device structure */
575 dev->vendor = id & 0xffff;
576 dev->device = (id >> 16) & 0xffff;
577 dev->hdr_type = hdr_type;
578 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
579 dev->class = class >> 8;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000580
Eric Biederman8ca8d762003-04-22 19:02:15 +0000581 /* Look at the vendor and device id, or at least the
582 * header type and class and figure out which set of configuration
Eric Biederman83b991a2003-10-11 06:20:25 +0000583 * methods to use. Unless we already have some pci ops.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000584 */
Eric Biederman83b991a2003-10-11 06:20:25 +0000585 set_pci_ops(dev);
586 /* Error if we don't have some pci operations for it */
587 if (dev->enable && !dev->ops) {
588 printk_err("%s No device operations\n",
589 dev_path(dev));
590 continue;
591 }
592
593 /* Now run the magic enable/disable sequence for the device */
594 if (dev->ops && dev->ops->enable) {
595 dev->ops->enable(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000596 }
Eric Biederman4086d162003-07-17 03:26:03 +0000597
Eric Biedermane9a271e32003-09-02 03:36:25 +0000598 printk_debug("%s [%04x/%04x] %s\n",
599 dev_path(dev),
Eric Biederman4086d162003-07-17 03:26:03 +0000600 dev->vendor, dev->device,
601 dev->enable?"enabled": "disabled");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000602
Eric Biederman8ca8d762003-04-22 19:02:15 +0000603 if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
604 /* if this is not a multi function device, don't waste time probe
605 another function. Skip to next device. */
606 devfn += 0x07;
607 }
608 }
609 post_code(0x25);
610
611 for(child = bus->children; child; child = child->sibling) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000612 if (!child->ops->scan_bus) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000613 continue;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000614 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000615 max = child->ops->scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000616 }
617 /*
618 * We've scanned the bus and so we know all about what's on
619 * the other side of any bridges that may be on this bus plus
620 * any devices.
621 *
622 * Return how far we've got finding sub-buses.
623 */
624 printk_debug("PCI: pci_scan_bus returning with max=%02x\n", max);
625 post_code(0x55);
626 return max;
627}
628
629/** Scan the bus, first for bridges and next for devices.
630 * @param pci_bus pointer to the bus structure
631 * @return The maximum bus number found, after scanning all subordinate busses
632 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000633unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000634{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000635 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000636 uint32_t buses;
637 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +0000638
Eric Biedermane9a271e32003-09-02 03:36:25 +0000639 bus = &dev->link[0];
640 dev->links = 1;
641
Eric Biederman8ca8d762003-04-22 19:02:15 +0000642 /* Set up the primary, secondary and subordinate bus numbers. We have
643 * no idea how many buses are behind this bridge yet, so we set the
644 * subordinate bus number to 0xff for the moment
645 */
646 bus->secondary = ++max;
647 bus->subordinate = 0xff;
648
649 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000650 cr = pci_read_config16(dev, PCI_COMMAND);
651 pci_write_config16(dev, PCI_COMMAND, 0x0000);
652 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000653
654 /*
655 * Read the existing primary/secondary/subordinate bus
656 * number configuration.
657 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000658 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000659
660 /* Configure the bus numbers for this bridge: the configuration
661 * transactions will not be propagated by the bridge if it is not
662 * correctly configured
663 */
664 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000665 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Eric Biederman8ca8d762003-04-22 19:02:15 +0000666 ((unsigned int) (bus->secondary) << 8) |
667 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000668 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000669
670 /* Now we can scan all subordinate buses i.e. the bus hehind the bridge */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000671 max = pci_scan_bus(bus, 0x00, 0xff, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000672
673 /* We know the number of buses behind this bridge. Set the subordinate
674 * bus number to its real value
675 */
676 bus->subordinate = max;
677 buses = (buses & 0xff00ffff) |
678 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000679 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
680 pci_write_config16(dev, PCI_COMMAND, cr);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000681
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000682 printk_spew("%s returns max %d\n", __FUNCTION__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000683 return max;
684}
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000685/*
686 Tell the EISA int controller this int must be level triggered
687 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
688*/
689static void pci_level_irq(unsigned char intNum)
690{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000691 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000692
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000693 printk_spew("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000694 intBits |= (1 << intNum);
695
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000696 printk_spew("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
697
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000698 // Write new values
699 outb((unsigned char) intBits, 0x4d0);
700 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +0000701
702 if (inb(0x4d0) != (intBits & 0xf)) {
703 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
704 __FUNCTION__, intBits &0xf, inb(0x4d0));
705 }
706 if (inb(0x4d1) != ((intBits >> 8) & 0xf)) {
707 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
708 __FUNCTION__, (intBits>>8) &0xf, inb(0x4d1));
709 }
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000710}
711
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +0000712/*
713 This function assigns IRQs for all functions contained within
714 the indicated device address. If the device does not exist or does
715 not require interrupts then this function has no effect.
716
717 This function should be called for each PCI slot in your system.
718
719 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
720 this slot.
721 The particular irq #s that are passed in depend on the routing inside
722 your southbridge and on your motherboard.
723
724 -kevinh@ispiri.com
725*/
726void pci_assign_irqs(unsigned bus, unsigned slot,
727 const unsigned char pIntAtoD[4])
728{
729 unsigned functNum;
730 device_t pdev;
731 unsigned char line;
732 unsigned char irq;
733 unsigned char readback;
734
735 /* Each slot may contain up to eight functions */
736 for (functNum = 0; functNum < 8; functNum++) {
737 pdev = dev_find_slot(bus, (slot << 3) + functNum);
738
739 if (pdev) {
740 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
741
742 // PCI spec says all other values are reserved
743 if ((line >= 1) && (line <= 4)) {
744 irq = pIntAtoD[line - 1];
745
746 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
747 irq, bus, slot, functNum);
748
749 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
750 pIntAtoD[line - 1]);
751
752 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
753 printk_debug(" Readback = %d\n", readback);
754
755 // Change to level triggered
756 pci_level_irq(pIntAtoD[line - 1]);
757 }
758 }
759 }
760}