blob: 1c5df7a3ac7eb45f03daac9139165d353673766d [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Uwe Hermannb80dbf02007-04-22 19:08:13 +00003 *
4 * It was originally based on the Linux kernel (drivers/pci/pci.c).
5 *
6 * Modifications are:
7 * Copyright (C) 2003-2004 Linux Networx
8 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
9 * Copyright (C) 2003-2006 Ronald G. Minnich <rminnich@gmail.com>
10 * Copyright (C) 2004-2005 Li-Ta Lo <ollie@lanl.gov>
11 * Copyright (C) 2005-2006 Tyan
12 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
Patrick Georgi16cdbb22009-04-21 20:14:31 +000013 * Copyright (C) 2005-2009 coresystems GmbH
14 * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
Uwe Hermannb80dbf02007-04-22 19:08:13 +000015 */
16
17/*
Eric Biederman8ca8d762003-04-22 19:02:15 +000018 * PCI Bus Services, see include/linux/pci.h for further explanation.
19 *
20 * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
21 * David Mosberger-Tang
22 *
23 * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
Eric Biederman8ca8d762003-04-22 19:02:15 +000024 */
25
26#include <console/console.h>
27#include <stdlib.h>
28#include <stdint.h>
29#include <bitops.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000030#include <string.h>
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +000031#include <arch/io.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000032#include <device/device.h>
33#include <device/pci.h>
34#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000035#include <part/hard_reset.h>
Eric Biederman30e143a2003-09-01 23:45:32 +000036#include <part/fallback_boot.h>
Eric Biederman03acab62004-10-14 21:25:53 +000037#include <delay.h>
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000038#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
39#include <device/hypertransport.h>
40#endif
41#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
42#include <device/pcix.h>
43#endif
44#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
45#include <device/pciexp.h>
46#endif
Stefan Reinauerec75a572009-03-16 15:27:00 +000047#if CONFIG_AGP_PLUGIN_SUPPORT == 1
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000048#include <device/agp.h>
49#endif
50#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
51#include <device/cardbus.h>
52#endif
Eric Biederman03acab62004-10-14 21:25:53 +000053
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000054uint8_t pci_moving_config8(struct device *dev, unsigned reg)
Eric Biederman03acab62004-10-14 21:25:53 +000055{
56 uint8_t value, ones, zeroes;
57 value = pci_read_config8(dev, reg);
Myles Watson032a9652009-05-11 22:24:53 +000058
Eric Biederman03acab62004-10-14 21:25:53 +000059 pci_write_config8(dev, reg, 0xff);
60 ones = pci_read_config8(dev, reg);
61
62 pci_write_config8(dev, reg, 0x00);
63 zeroes = pci_read_config8(dev, reg);
64
65 pci_write_config8(dev, reg, value);
66
67 return ones ^ zeroes;
68}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +000069
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000070uint16_t pci_moving_config16(struct device *dev, unsigned reg)
Eric Biederman03acab62004-10-14 21:25:53 +000071{
72 uint16_t value, ones, zeroes;
73 value = pci_read_config16(dev, reg);
Myles Watson032a9652009-05-11 22:24:53 +000074
Eric Biederman03acab62004-10-14 21:25:53 +000075 pci_write_config16(dev, reg, 0xffff);
76 ones = pci_read_config16(dev, reg);
77
78 pci_write_config16(dev, reg, 0x0000);
79 zeroes = pci_read_config16(dev, reg);
80
81 pci_write_config16(dev, reg, value);
82
83 return ones ^ zeroes;
84}
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +000085
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000086uint32_t pci_moving_config32(struct device *dev, unsigned reg)
Eric Biederman03acab62004-10-14 21:25:53 +000087{
88 uint32_t value, ones, zeroes;
89 value = pci_read_config32(dev, reg);
Myles Watson032a9652009-05-11 22:24:53 +000090
Eric Biederman03acab62004-10-14 21:25:53 +000091 pci_write_config32(dev, reg, 0xffffffff);
92 ones = pci_read_config32(dev, reg);
93
94 pci_write_config32(dev, reg, 0x00000000);
95 zeroes = pci_read_config32(dev, reg);
96
97 pci_write_config32(dev, reg, value);
98
99 return ones ^ zeroes;
100}
101
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000102unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
Eric Biederman03acab62004-10-14 21:25:53 +0000103{
104 unsigned pos;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000105 unsigned status;
106 unsigned reps = 48;
Eric Biederman03acab62004-10-14 21:25:53 +0000107 pos = 0;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000108 status = pci_read_config16(dev, PCI_STATUS);
109 if (!(status & PCI_STATUS_CAP_LIST)) {
110 return 0;
111 }
Eric Biederman03acab62004-10-14 21:25:53 +0000112 switch(dev->hdr_type & 0x7f) {
113 case PCI_HEADER_TYPE_NORMAL:
114 case PCI_HEADER_TYPE_BRIDGE:
115 pos = PCI_CAPABILITY_LIST;
116 break;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000117 case PCI_HEADER_TYPE_CARDBUS:
118 pos = PCI_CB_CAPABILITY_LIST;
119 break;
120 default:
121 return 0;
Eric Biederman03acab62004-10-14 21:25:53 +0000122 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000123 pos = pci_read_config8(dev, pos);
124 while(reps-- && (pos >= 0x40)) { /* loop through the linked list */
Eric Biederman03acab62004-10-14 21:25:53 +0000125 int this_cap;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000126 pos &= ~3;
Eric Biederman03acab62004-10-14 21:25:53 +0000127 this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000128 printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
129 if (this_cap == 0xff) {
130 break;
131 }
132 if (!last && (this_cap == cap)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000133 return pos;
134 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000135 if (last == pos) {
136 last = 0;
137 }
138 pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
Eric Biederman03acab62004-10-14 21:25:53 +0000139 }
140 return 0;
141}
142
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000143unsigned pci_find_capability(device_t dev, unsigned cap)
144{
145 return pci_find_next_capability(dev, cap, 0);
146
147}
148
Myles Watson032a9652009-05-11 22:24:53 +0000149/** Given a device and register, read the size of the BAR for that register.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000150 * @param dev Pointer to the device structure
151 * @param resource Pointer to the resource structure
152 * @param index Address of the pci configuration register
153 */
Eric Biederman03acab62004-10-14 21:25:53 +0000154struct resource *pci_get_resource(struct device *dev, unsigned long index)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000155{
Eric Biederman5cd81732004-03-11 15:01:31 +0000156 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000157 unsigned long value, attr;
158 resource_t moving, limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000159
160 /* Initialize the resources to nothing */
Eric Biederman03acab62004-10-14 21:25:53 +0000161 resource = new_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000162
Eric Biederman03acab62004-10-14 21:25:53 +0000163 /* Get the initial value */
164 value = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000165
Eric Biederman03acab62004-10-14 21:25:53 +0000166 /* See which bits move */
167 moving = pci_moving_config32(dev, index);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000168
Eric Biederman03acab62004-10-14 21:25:53 +0000169 /* Initialize attr to the bits that do not move */
170 attr = value & ~moving;
171
172 /* If it is a 64bit resource look at the high half as well */
173 if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) &&
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000174 ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
Eric Biederman03acab62004-10-14 21:25:53 +0000175 {
176 /* Find the high bits that move */
177 moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32;
178 }
Myles Watson032a9652009-05-11 22:24:53 +0000179 /* Find the resource constraints.
Eric Biederman03acab62004-10-14 21:25:53 +0000180 *
181 * Start by finding the bits that move. From there:
182 * - Size is the least significant bit of the bits that move.
183 * - Limit is all of the bits that move plus all of the lower bits.
184 * See PCI Spec 6.2.5.1 ...
Eric Biederman8ca8d762003-04-22 19:02:15 +0000185 */
Eric Biederman03acab62004-10-14 21:25:53 +0000186 limit = 0;
187 if (moving) {
188 resource->size = 1;
189 resource->align = resource->gran = 0;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000190 while(!(moving & resource->size)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000191 resource->size <<= 1;
192 resource->align += 1;
193 resource->gran += 1;
194 }
195 resource->limit = limit = moving | (resource->size - 1);
196 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000197 /*
Myles Watson032a9652009-05-11 22:24:53 +0000198 * some broken hardware has read-only registers that do not
Eric Biederman03acab62004-10-14 21:25:53 +0000199 * really size correctly.
Myles Watson032a9652009-05-11 22:24:53 +0000200 * Example: the acer m7229 has BARs 1-4 normally read-only.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000201 * so BAR1 at offset 0x10 reads 0x1f1. If you size that register
Myles Watson032a9652009-05-11 22:24:53 +0000202 * by writing 0xffffffff to it, it will read back as 0x1f1 -- a
203 * violation of the spec.
Eric Biederman03acab62004-10-14 21:25:53 +0000204 * We catch this case and ignore it by observing which bits move,
205 * This also catches the common case unimplemented registers
206 * that always read back as 0.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000207 */
Eric Biederman03acab62004-10-14 21:25:53 +0000208 if (moving == 0) {
209 if (value != 0) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000210 printk_debug(
Myles Watsonc4ddbff2009-02-09 17:52:54 +0000211 "%s register %02lx(%08lx), read-only ignoring it\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000212 dev_path(dev), index, value);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000213 }
214 resource->flags = 0;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000215 }
216 else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000217 /* An I/O mapped base address */
218 attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000219 resource->flags |= IORESOURCE_IO;
Eric Biederman03acab62004-10-14 21:25:53 +0000220 /* I don't want to deal with 32bit I/O resources */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000221 resource->limit = 0xffff;
Myles Watson032a9652009-05-11 22:24:53 +0000222 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000223 else {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000224 /* A Memory mapped base address */
Eric Biederman03acab62004-10-14 21:25:53 +0000225 attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000226 resource->flags |= IORESOURCE_MEM;
Eric Biederman03acab62004-10-14 21:25:53 +0000227 if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000228 resource->flags |= IORESOURCE_PREFETCH;
229 }
Eric Biederman03acab62004-10-14 21:25:53 +0000230 attr &= PCI_BASE_ADDRESS_MEM_LIMIT_MASK;
231 if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000232 /* 32bit limit */
233 resource->limit = 0xffffffffUL;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000234 }
235 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000236 /* 1MB limit */
237 resource->limit = 0x000fffffUL;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000238 }
239 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000240 /* 64bit limit */
241 resource->limit = 0xffffffffffffffffULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000242 resource->flags |= IORESOURCE_PCI64;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000243 }
244 else {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000245 /* Invalid value */
246 resource->flags = 0;
247 }
248 }
Eric Biederman03acab62004-10-14 21:25:53 +0000249 /* Don't let the limit exceed which bits can move */
250 if (resource->limit > limit) {
251 resource->limit = limit;
252 }
253#if 0
254 if (resource->flags) {
255 printk_debug("%s %02x ->",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000256 dev_path(dev), resource->index);
Eric Biederman03acab62004-10-14 21:25:53 +0000257 printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000258 value, zeroes, ones, attr);
Eric Biederman03acab62004-10-14 21:25:53 +0000259 printk_debug(
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000260 "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s\n ",
Eric Biederman03acab62004-10-14 21:25:53 +0000261 dev_path(dev),
262 resource->index,
263 resource->size, resource->limit,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000264 resource_type(resource));
Eric Biederman03acab62004-10-14 21:25:53 +0000265 }
266#endif
267
Eric Biederman5cd81732004-03-11 15:01:31 +0000268 return resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000269}
270
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000271static void pci_get_rom_resource(struct device *dev, unsigned long index)
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000272{
273 struct resource *resource;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000274 unsigned long value;
Patrick Georgi16cdbb22009-04-21 20:14:31 +0000275 resource_t moving;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000276
Li-Ta Lobec039c2005-01-19 23:19:26 +0000277 if ((dev->on_mainboard) && (dev->rom_address == 0)) {
278 //skip it if rom_address is not set in MB Config.lb
Yinghai Lubcde1612005-01-14 05:34:09 +0000279 return;
280 }
281
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000282 /* Initialize the resources to nothing */
283 resource = new_resource(dev, index);
284
285 /* Get the initial value */
286 value = pci_read_config32(dev, index);
287
288 /* See which bits move */
289 moving = pci_moving_config32(dev, index);
290 /* clear the Enable bit */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000291 moving = moving & ~PCI_ROM_ADDRESS_ENABLE;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000292
Myles Watson032a9652009-05-11 22:24:53 +0000293 /* Find the resource constraints.
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000294 *
295 * Start by finding the bits that move. From there:
296 * - Size is the least significant bit of the bits that move.
297 * - Limit is all of the bits that move plus all of the lower bits.
298 * See PCI Spec 6.2.5.1 ...
299 */
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000300 if (moving) {
301 resource->size = 1;
302 resource->align = resource->gran = 0;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000303 while (!(moving & resource->size)) {
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000304 resource->size <<= 1;
305 resource->align += 1;
306 resource->gran += 1;
307 }
Patrick Georgi16cdbb22009-04-21 20:14:31 +0000308 resource->limit = moving | (resource->size - 1);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000309 }
310
311 if (moving == 0) {
312 if (value != 0) {
Myles Watsonc4ddbff2009-02-09 17:52:54 +0000313 printk_debug("%s register %02lx(%08lx), read-only ignoring it\n",
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000314 dev_path(dev), index, value);
315 }
316 resource->flags = 0;
317 } else {
318 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY;
319 }
Yinghai Luc7870ac2005-01-13 19:14:52 +0000320
321 /* for on board device with embedded ROM image, the ROM image is at
322 * fixed address specified in the Config.lb, the dev->rom_address is
323 * inited by driver_pci_onboard_ops::enable_dev() */
Yinghai Lubcde1612005-01-14 05:34:09 +0000324 if ((dev->on_mainboard) && (dev->rom_address != 0)) {
Yinghai Luc7870ac2005-01-13 19:14:52 +0000325 resource->base = dev->rom_address;
326 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY |
327 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
Myles Watson032a9652009-05-11 22:24:53 +0000328 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000329
330 compact_resources(dev);
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000331}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000332
Myles Watson032a9652009-05-11 22:24:53 +0000333/** Read the base address registers for a given device.
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000334 * @param dev Pointer to the dev structure
335 * @param howmany How many registers to read (6 for device, 2 for bridge)
336 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000337static void pci_read_bases(struct device *dev, unsigned int howmany)
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000338{
339 unsigned long index;
340
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000341 for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000342 struct resource *resource;
343 resource = pci_get_resource(dev, index);
344 index += (resource->flags & IORESOURCE_PCI64)?8:4;
345 }
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000346
347 compact_resources(dev);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000348}
349
Eric Biederman03acab62004-10-14 21:25:53 +0000350static void pci_set_resource(struct device *dev, struct resource *resource);
351
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000352static void pci_record_bridge_resource(
353 struct device *dev, resource_t moving,
354 unsigned index, unsigned long mask, unsigned long type)
Eric Biederman03acab62004-10-14 21:25:53 +0000355{
356 /* Initiliaze the constraints on the current bus */
357 struct resource *resource;
358 resource = 0;
359 if (moving) {
360 unsigned long gran;
361 resource_t step;
362 resource = new_resource(dev, index);
363 resource->size = 0;
364 gran = 0;
365 step = 1;
366 while((moving & step) == 0) {
367 gran += 1;
368 step <<= 1;
369 }
370 resource->gran = gran;
371 resource->align = gran;
372 resource->limit = moving | (step - 1);
373 resource->flags = type | IORESOURCE_PCI_BRIDGE;
374 compute_allocate_resource(&dev->link[0], resource, mask, type);
375 /* If there is nothing behind the resource,
376 * clear it and forget it.
377 */
378 if (resource->size == 0) {
Stefan Reinauer532fd2d2008-10-29 03:15:42 +0000379#if CONFIG_PCI_64BIT_PREF_MEM == 1
Eric Biederman03acab62004-10-14 21:25:53 +0000380 resource->base = moving;
Stefan Reinauer532fd2d2008-10-29 03:15:42 +0000381#else
382 resource->base = moving & 0xffffffff;
383#endif
Eric Biederman03acab62004-10-14 21:25:53 +0000384 resource->flags |= IORESOURCE_ASSIGNED;
385 resource->flags &= ~IORESOURCE_STORED;
386 pci_set_resource(dev, resource);
387 resource->flags = 0;
388 }
389 }
390 return;
391}
392
Eric Biederman8ca8d762003-04-22 19:02:15 +0000393static void pci_bridge_read_bases(struct device *dev)
394{
Eric Biederman03acab62004-10-14 21:25:53 +0000395 resource_t moving_base, moving_limit, moving;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000396
Eric Biederman03acab62004-10-14 21:25:53 +0000397 /* See if the bridge I/O resources are implemented */
398 moving_base = ((uint32_t)pci_moving_config8(dev, PCI_IO_BASE)) << 8;
399 moving_base |= ((uint32_t)pci_moving_config16(dev, PCI_IO_BASE_UPPER16)) << 16;
400
401 moving_limit = ((uint32_t)pci_moving_config8(dev, PCI_IO_LIMIT)) << 8;
402 moving_limit |= ((uint32_t)pci_moving_config16(dev, PCI_IO_LIMIT_UPPER16)) << 16;
403
404 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000405
406 /* Initialize the io space constraints on the current bus */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000407 pci_record_bridge_resource(
Myles Watson032a9652009-05-11 22:24:53 +0000408 dev, moving, PCI_IO_BASE,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000409 IORESOURCE_IO, IORESOURCE_IO);
410
Eric Biederman03acab62004-10-14 21:25:53 +0000411
412 /* See if the bridge prefmem resources are implemented */
413 moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
414 moving_base |= ((resource_t)pci_moving_config32(dev, PCI_PREF_BASE_UPPER32)) << 32;
415
416 moving_limit = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_LIMIT)) << 16;
417 moving_limit |= ((resource_t)pci_moving_config32(dev, PCI_PREF_LIMIT_UPPER32)) << 32;
Myles Watson032a9652009-05-11 22:24:53 +0000418
Eric Biederman03acab62004-10-14 21:25:53 +0000419 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000420 /* Initiliaze the prefetchable memory constraints on the current bus */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000421 pci_record_bridge_resource(
Myles Watson032a9652009-05-11 22:24:53 +0000422 dev, moving, PCI_PREF_MEMORY_BASE,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000423 IORESOURCE_MEM | IORESOURCE_PREFETCH,
424 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Myles Watson032a9652009-05-11 22:24:53 +0000425
Eric Biederman03acab62004-10-14 21:25:53 +0000426
427 /* See if the bridge mem resources are implemented */
428 moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
429 moving_limit = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_LIMIT)) << 16;
430
431 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000432
433 /* Initialize the memory resources on the current bus */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000434 pci_record_bridge_resource(
Myles Watson032a9652009-05-11 22:24:53 +0000435 dev, moving, PCI_MEMORY_BASE,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000436 IORESOURCE_MEM | IORESOURCE_PREFETCH,
437 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000438
Eric Biederman5cd81732004-03-11 15:01:31 +0000439 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000440}
441
Eric Biederman5899fd82003-04-24 06:25:08 +0000442void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000443{
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000444 pci_read_bases(dev, 6);
445 pci_get_rom_resource(dev, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000446}
447
Eric Biederman5899fd82003-04-24 06:25:08 +0000448void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000449{
Eric Biederman8ca8d762003-04-22 19:02:15 +0000450 pci_bridge_read_bases(dev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000451 pci_read_bases(dev, 2);
452 pci_get_rom_resource(dev, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000453}
454
Eric Biederman8ca8d762003-04-22 19:02:15 +0000455static void pci_set_resource(struct device *dev, struct resource *resource)
456{
Eric Biederman03acab62004-10-14 21:25:53 +0000457 resource_t base, end;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000458
Eric Biederman8ca8d762003-04-22 19:02:15 +0000459 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000460 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Myles Watsonc4ddbff2009-02-09 17:52:54 +0000461 printk_err("ERROR: %s %02lx %s size: 0x%010Lx not assigned\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000462 dev_path(dev), resource->index,
463 resource_type(resource),
464 resource->size);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000465 return;
466 }
467
Eric Biederman5cd81732004-03-11 15:01:31 +0000468 /* If I have already stored this resource don't worry about it */
469 if (resource->flags & IORESOURCE_STORED) {
470 return;
471 }
472
Eric Biederman03acab62004-10-14 21:25:53 +0000473 /* If the resources is substractive don't worry about it */
474 if (resource->flags & IORESOURCE_SUBTRACTIVE) {
475 return;
476 }
477
Eric Biederman8ca8d762003-04-22 19:02:15 +0000478 /* Only handle PCI memory and IO resources for now */
479 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
480 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000481
Eric Biederman03acab62004-10-14 21:25:53 +0000482 /* Enable the resources in the command register */
483 if (resource->size) {
484 if (resource->flags & IORESOURCE_MEM) {
485 dev->command |= PCI_COMMAND_MEMORY;
486 }
487 if (resource->flags & IORESOURCE_IO) {
488 dev->command |= PCI_COMMAND_IO;
489 }
490 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
491 dev->command |= PCI_COMMAND_MASTER;
492 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000493 }
494 /* Get the base address */
495 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000496
Eric Biederman03acab62004-10-14 21:25:53 +0000497 /* Get the end */
498 end = resource_end(resource);
Myles Watson032a9652009-05-11 22:24:53 +0000499
Eric Biederman5cd81732004-03-11 15:01:31 +0000500 /* Now store the resource */
501 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000502 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000503 unsigned long base_lo, base_hi;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000504 /*
Myles Watson032a9652009-05-11 22:24:53 +0000505 * some chipsets allow us to set/clear the IO bit.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000506 * (e.g. VIA 82c686a.) So set it to be safe)
507 */
Eric Biederman03acab62004-10-14 21:25:53 +0000508 base_lo = base & 0xffffffff;
509 base_hi = (base >> 32) & 0xffffffff;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000510 if (resource->flags & IORESOURCE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000511 base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000512 }
Eric Biederman03acab62004-10-14 21:25:53 +0000513 pci_write_config32(dev, resource->index, base_lo);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000514 if (resource->flags & IORESOURCE_PCI64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000515 pci_write_config32(dev, resource->index + 4, base_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000516 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000517 }
518 else if (resource->index == PCI_IO_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000519 /* set the IO ranges */
Myles Watson032a9652009-05-11 22:24:53 +0000520 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000521 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000522 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
523 pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16);
524 pci_write_config8(dev, PCI_IO_LIMIT, end >> 8);
525 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000526 }
527 else if (resource->index == PCI_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000528 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000529 compute_allocate_resource(&dev->link[0], resource,
Myles Watson032a9652009-05-11 22:24:53 +0000530 IORESOURCE_MEM | IORESOURCE_PREFETCH,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000531 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000532 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
Eric Biederman03acab62004-10-14 21:25:53 +0000533 pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000534 }
535 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000536 /* set the prefetchable memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000537 compute_allocate_resource(&dev->link[0], resource,
Myles Watson032a9652009-05-11 22:24:53 +0000538 IORESOURCE_MEM | IORESOURCE_PREFETCH,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000539 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000540 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
541 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32);
542 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16);
543 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, end >> 32);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000544 }
545 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000546 /* Don't let me think I stored the resource */
547 resource->flags &= ~IORESOURCE_STORED;
Myles Watsonc4ddbff2009-02-09 17:52:54 +0000548 printk_err("ERROR: invalid resource->index %lx\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000549 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000550 }
Eric Biederman03acab62004-10-14 21:25:53 +0000551 report_resource_stored(dev, resource, "");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000552 return;
553}
554
Eric Biederman5899fd82003-04-24 06:25:08 +0000555void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000556{
557 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000558 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000559 uint8_t line;
560
561 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000562
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000563 for(resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000564 pci_set_resource(dev, resource);
565 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000566 for(link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000567 struct bus *bus;
568 bus = &dev->link[link];
569 if (bus->children) {
570 assign_resources(bus);
571 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000572 }
573
574 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000575 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000576
577 /* set a default secondary latency timer */
578 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000579 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000580 }
581
582 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000583 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000584 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000585 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000586 }
587 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000588 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000589}
590
Eric Biedermane9a271e32003-09-02 03:36:25 +0000591void pci_dev_enable_resources(struct device *dev)
592{
Eric Biedermana9e632c2004-11-18 22:38:08 +0000593 const struct pci_operations *ops;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000594 uint16_t command;
Eric Biederman03acab62004-10-14 21:25:53 +0000595
596 /* Set the subsystem vendor and device id for mainboard devices */
597 ops = ops_pci(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000598 if (dev->on_mainboard && ops && ops->set_subsystem) {
Eric Biederman03acab62004-10-14 21:25:53 +0000599 printk_debug("%s subsystem <- %02x/%02x\n",
Myles Watson032a9652009-05-11 22:24:53 +0000600 dev_path(dev),
Eric Biederman03acab62004-10-14 21:25:53 +0000601 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
602 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
Myles Watson032a9652009-05-11 22:24:53 +0000603 ops->set_subsystem(dev,
Eric Biederman03acab62004-10-14 21:25:53 +0000604 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
605 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
606 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000607 command = pci_read_config16(dev, PCI_COMMAND);
608 command |= dev->command;
609 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
610 pci_write_config16(dev, PCI_COMMAND, command);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000611}
612
613void pci_bus_enable_resources(struct device *dev)
614{
615 uint16_t ctrl;
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000616 /* enable IO in command register if there is VGA card
617 * connected with (even it does not claim IO resource) */
618 if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
619 dev->command |= PCI_COMMAND_IO;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000620 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
621 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000622 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000623 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
624 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
625
626 pci_dev_enable_resources(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000627
628 enable_childrens_resources(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000629}
630
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000631void pci_bus_reset(struct bus *bus)
632{
633 unsigned ctl;
634 ctl = pci_read_config16(bus->dev, PCI_BRIDGE_CONTROL);
635 ctl |= PCI_BRIDGE_CTL_BUS_RESET;
636 pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
637 mdelay(10);
638 ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
639 pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
640 delay(1);
641}
642
Eric Biedermandbec2d42004-10-21 10:44:08 +0000643void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
Eric Biederman03acab62004-10-14 21:25:53 +0000644{
Myles Watson032a9652009-05-11 22:24:53 +0000645 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
Eric Biederman03acab62004-10-14 21:25:53 +0000646 ((device & 0xffff) << 16) | (vendor & 0xffff));
647}
648
Torsten Duwe1f2f8002008-01-06 01:10:54 +0000649/** default handler: only runs the relevant pci bios. */
Li-Ta Lo883b8792005-01-10 23:16:22 +0000650void pci_dev_init(struct device *dev)
651{
Torsten Duwe1f2f8002008-01-06 01:10:54 +0000652#if CONFIG_PCI_ROM_RUN == 1 || CONFIG_VGA_ROM_RUN == 1
Stefan Reinauerd98cf5b2008-08-01 11:25:41 +0000653 void run_bios(struct device * dev, unsigned long addr);
Li-Ta Lo883b8792005-01-10 23:16:22 +0000654 struct rom_header *rom, *ram;
655
Roman Kononov778a42b2007-04-06 18:34:39 +0000656#if CONFIG_PCI_ROM_RUN != 1
Torsten Duwe1f2f8002008-01-06 01:10:54 +0000657 /* We want to execute VGA option ROMs when CONFIG_VGA_ROM_RUN
Roman Kononov778a42b2007-04-06 18:34:39 +0000658 * is set but CONFIG_PCI_ROM_RUN is not. In this case we skip
659 * all other option ROM types.
660 */
Ronald Hoogenboom9b6b63e2008-02-28 23:10:38 +0000661 if ((dev->class>>8)!=PCI_CLASS_DISPLAY_VGA)
Roman Kononov778a42b2007-04-06 18:34:39 +0000662 return;
663#endif
664
Li-Ta Lo883b8792005-01-10 23:16:22 +0000665 rom = pci_rom_probe(dev);
666 if (rom == NULL)
667 return;
Roman Kononov778a42b2007-04-06 18:34:39 +0000668
Li-Ta Lo883b8792005-01-10 23:16:22 +0000669 ram = pci_rom_load(dev, rom);
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000670 if (ram == NULL)
671 return;
Li-Ta Lo883b8792005-01-10 23:16:22 +0000672
Stefan Reinauerd98cf5b2008-08-01 11:25:41 +0000673 run_bios(dev, (unsigned long)ram);
Roman Kononov778a42b2007-04-06 18:34:39 +0000674
675#if CONFIG_CONSOLE_VGA == 1
Torsten Duwe1f2f8002008-01-06 01:10:54 +0000676 /* vga_inited is a trigger of the VGA console code. */
Ronald Hoogenboom9b6b63e2008-02-28 23:10:38 +0000677 if ((dev->class>>8) == PCI_CLASS_DISPLAY_VGA) {
Torsten Duwe1f2f8002008-01-06 01:10:54 +0000678 extern int vga_inited;
679 vga_inited = 1;
680 }
681#endif /* CONFIG_CONSOLE_VGA */
682#endif /* CONFIG_PCI_ROM_RUN || CONFIG_VGA_ROM_RUN */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000683}
Li-Ta Lo883b8792005-01-10 23:16:22 +0000684
Li-Ta Loe5266692004-03-23 21:28:05 +0000685/** Default device operation for PCI devices */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000686static struct pci_operations pci_dev_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000687 .set_subsystem = pci_dev_set_subsystem,
688};
689
Eric Biederman8ca8d762003-04-22 19:02:15 +0000690struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000691 .read_resources = pci_dev_read_resources,
692 .set_resources = pci_dev_set_resources,
693 .enable_resources = pci_dev_enable_resources,
Li-Ta Lo883b8792005-01-10 23:16:22 +0000694 .init = pci_dev_init,
Li-Ta Loe5266692004-03-23 21:28:05 +0000695 .scan_bus = 0,
Eric Biederman03acab62004-10-14 21:25:53 +0000696 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000697 .ops_pci = &pci_dev_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000698};
Li-Ta Loe5266692004-03-23 21:28:05 +0000699
700/** Default device operations for PCI bridges */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000701static struct pci_operations pci_bus_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000702 .set_subsystem = 0,
703};
Li-Ta Lo883b8792005-01-10 23:16:22 +0000704
Eric Biederman8ca8d762003-04-22 19:02:15 +0000705struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000706 .read_resources = pci_bus_read_resources,
707 .set_resources = pci_dev_set_resources,
708 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000709 .init = 0,
710 .scan_bus = pci_scan_bridge,
Eric Biederman03acab62004-10-14 21:25:53 +0000711 .enable = 0,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000712 .reset_bus = pci_bus_reset,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000713 .ops_pci = &pci_bus_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000714};
Li-Ta Loe5266692004-03-23 21:28:05 +0000715
716/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000717 * @brief Detect the type of downstream bridge
718 *
719 * This function is a heuristic to detect which type
720 * of bus is downstream of a pci to pci bridge. This
721 * functions by looking for various capability blocks
722 * to figure out the type of downstream bridge. PCI-X
723 * PCI-E, and Hypertransport all seem to have appropriate
724 * capabilities.
Myles Watson032a9652009-05-11 22:24:53 +0000725 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000726 * When only a PCI-Express capability is found the type
727 * is examined to see which type of bridge we have.
728 *
729 * @param dev
Myles Watson032a9652009-05-11 22:24:53 +0000730 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000731 * @return appropriate bridge operations
732 */
733static struct device_operations *get_pci_bridge_ops(device_t dev)
734{
735 unsigned pos;
736
737#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
738 pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
739 if (pos) {
740 printk_debug("%s subbordinate bus PCI-X\n", dev_path(dev));
741 return &default_pcix_ops_bus;
742 }
743#endif
744#if CONFIG_AGP_PLUGIN_SUPPORT == 1
745 /* How do I detect an PCI to AGP bridge? */
746#endif
747#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
748 pos = 0;
749 while((pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos))) {
750 unsigned flags;
751 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
752 if ((flags >> 13) == 1) {
753 /* Host or Secondary Interface */
Myles Watson032a9652009-05-11 22:24:53 +0000754 printk_debug("%s subbordinate bus Hypertransport\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000755 dev_path(dev));
756 return &default_ht_ops_bus;
757 }
758 }
759#endif
760#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
761 pos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
762 if (pos) {
763 unsigned flags;
764 flags = pci_read_config16(dev, pos + PCI_EXP_FLAGS);
765 switch((flags & PCI_EXP_FLAGS_TYPE) >> 4) {
766 case PCI_EXP_TYPE_ROOT_PORT:
767 case PCI_EXP_TYPE_UPSTREAM:
768 case PCI_EXP_TYPE_DOWNSTREAM:
Myles Watson032a9652009-05-11 22:24:53 +0000769 printk_debug("%s subbordinate bus PCI Express\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000770 dev_path(dev));
771 return &default_pciexp_ops_bus;
772 case PCI_EXP_TYPE_PCI_BRIDGE:
Myles Watson032a9652009-05-11 22:24:53 +0000773 printk_debug("%s subbordinate PCI\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000774 dev_path(dev));
775 return &default_pci_ops_bus;
776 default:
777 break;
778 }
779 }
780#endif
781 return &default_pci_ops_bus;
782}
783
784/**
Li-Ta Loe5266692004-03-23 21:28:05 +0000785 * @brief Set up PCI device operation
786 *
787 *
Myles Watson032a9652009-05-11 22:24:53 +0000788 * @param dev
Li-Ta Loe5266692004-03-23 21:28:05 +0000789 *
790 * @see pci_drivers
791 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000792static void set_pci_ops(struct device *dev)
793{
794 struct pci_driver *driver;
795 if (dev->ops) {
796 return;
797 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000798
Yinghai Lu5f9624d2006-10-04 22:56:21 +0000799 /* Look through the list of setup drivers and find one for
Myles Watson032a9652009-05-11 22:24:53 +0000800 * this pci device
Eric Biedermanb78c1972004-10-14 20:54:17 +0000801 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000802 for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000803 if ((driver->vendor == dev->vendor) &&
Myles Watson032a9652009-05-11 22:24:53 +0000804 (driver->device == dev->device))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000805 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000806 dev->ops = driver->ops;
Myles Watson032a9652009-05-11 22:24:53 +0000807 printk_spew("%s [%04x/%04x] %sops\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000808 dev_path(dev),
809 driver->vendor, driver->device,
810 (driver->ops->scan_bus?"bus ":""));
Eric Biederman5899fd82003-04-24 06:25:08 +0000811 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000812 }
813 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000814
Eric Biederman8ca8d762003-04-22 19:02:15 +0000815 /* If I don't have a specific driver use the default operations */
816 switch(dev->hdr_type & 0x7f) { /* header type */
817 case PCI_HEADER_TYPE_NORMAL: /* standard header */
818 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
819 goto bad;
820 dev->ops = &default_pci_ops_dev;
821 break;
822 case PCI_HEADER_TYPE_BRIDGE:
823 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
824 goto bad;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000825 dev->ops = get_pci_bridge_ops(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000826 break;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000827#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
828 case PCI_HEADER_TYPE_CARDBUS:
829 dev->ops = &default_cardbus_ops_bus;
830 break;
831#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000832 default:
833 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000834 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000835 printk_err("%s [%04x/%04x/%06x] has unknown header "
Eric Biedermanb78c1972004-10-14 20:54:17 +0000836 "type %02x, ignoring.\n",
837 dev_path(dev),
Myles Watson032a9652009-05-11 22:24:53 +0000838 dev->vendor, dev->device,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000839 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000840 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000841 }
842 return;
843}
844
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000845
846
Eric Biederman8ca8d762003-04-22 19:02:15 +0000847/**
Eric Biederman03acab62004-10-14 21:25:53 +0000848 * @brief See if we have already allocated a device structure for a given devfn.
Li-Ta Loe5266692004-03-23 21:28:05 +0000849 *
850 * Given a linked list of PCI device structures and a devfn number, find the
Li-Ta Lo3a812852004-12-03 22:39:34 +0000851 * device structure correspond to the devfn, if present. This function also
852 * removes the device structure from the linked list.
Li-Ta Loe5266692004-03-23 21:28:05 +0000853 *
854 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000855 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000856 *
Li-Ta Lo3a812852004-12-03 22:39:34 +0000857 * @return pointer to the device structure found or null of we have not
858 * allocated a device for this devfn yet.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000859 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000860static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000861{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000862 struct device *dev;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000863 dev = 0;
864 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000865 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000866 printk_err("child %s not a pci device\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000867 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000868 continue;
869 }
Stefan Reinauer2b34db82009-02-28 20:10:20 +0000870 if ((*list)->path.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000871 /* Unlink from the list */
872 dev = *list;
873 *list = (*list)->sibling;
874 dev->sibling = 0;
875 break;
876 }
877 }
Myles Watson032a9652009-05-11 22:24:53 +0000878 /* Just like alloc_dev add the device to the list of device on the bus.
879 * When the list of devices was formed we removed all of the parents
880 * children, and now we are interleaving static and dynamic devices in
Li-Ta Lo3a812852004-12-03 22:39:34 +0000881 * order on the bus.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000882 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000883 if (dev) {
884 device_t child;
885 /* Find the last child of our parent */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000886 for(child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000887 child = child->sibling;
888 }
889 /* Place the device on the list of children of it's parent. */
890 if (child) {
891 child->sibling = dev;
892 } else {
893 dev->bus->children = dev;
894 }
895 }
896
Eric Biederman8ca8d762003-04-22 19:02:15 +0000897 return dev;
898}
899
Myles Watson032a9652009-05-11 22:24:53 +0000900/**
Eric Biedermanb78c1972004-10-14 20:54:17 +0000901 * @brief Scan a PCI bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000902 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000903 * Determine the existence of a given PCI device.
904 *
905 * @param bus pointer to the bus structure
906 * @param devfn to look at
907 *
908 * @return The device structure for hte device (if found)
909 * or the NULL if no device is found.
910 */
911device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
912{
913 uint32_t id, class;
914 uint8_t hdr_type;
915
916 /* Detect if a device is present */
917 if (!dev) {
918 struct device dummy;
919 dummy.bus = bus;
920 dummy.path.type = DEVICE_PATH_PCI;
Stefan Reinauer2b34db82009-02-28 20:10:20 +0000921 dummy.path.pci.devfn = devfn;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000922 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
923 /* Have we found somthing?
924 * Some broken boards return 0 if a slot is empty.
925 */
926 if ( (id == 0xffffffff) || (id == 0x00000000) ||
927 (id == 0x0000ffff) || (id == 0xffff0000))
928 {
Stefan Reinauerf657d752008-09-11 06:52:22 +0000929 printk_spew("%s, bad id 0x%x\n", dev_path(&dummy), id);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000930 return NULL;
931 }
932 dev = alloc_dev(bus, &dummy.path);
933 }
934 else {
935 /* Enable/disable the device. Once we have
936 * found the device specific operations this
937 * operations we will disable the device with
938 * those as well.
Myles Watson032a9652009-05-11 22:24:53 +0000939 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000940 * This is geared toward devices that have subfunctions
941 * that do not show up by default.
Myles Watson032a9652009-05-11 22:24:53 +0000942 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000943 * If a device is a stuff option on the motherboard
944 * it may be absent and enable_dev must cope.
Myles Watson032a9652009-05-11 22:24:53 +0000945 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000946 */
947 /* Run the magice enable sequence for the device */
948 if (dev->chip_ops && dev->chip_ops->enable_dev) {
949 dev->chip_ops->enable_dev(dev);
950 }
951 /* Now read the vendor and device id */
952 id = pci_read_config32(dev, PCI_VENDOR_ID);
Myles Watson032a9652009-05-11 22:24:53 +0000953
954
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000955 /* If the device does not have a pci id disable it.
956 * Possibly this is because we have already disabled
957 * the device. But this also handles optional devices
958 * that may not always show up.
959 */
960 /* If the chain is fully enumerated quit */
961 if ( (id == 0xffffffff) || (id == 0x00000000) ||
Myles Watson032a9652009-05-11 22:24:53 +0000962 (id == 0x0000ffff) || (id == 0xffff0000))
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000963 {
964 if (dev->enabled) {
965 printk_info("Disabling static device: %s\n",
966 dev_path(dev));
967 dev->enabled = 0;
968 }
969 return dev;
970 }
971 }
972 /* Read the rest of the pci configuration information */
973 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
974 class = pci_read_config32(dev, PCI_CLASS_REVISION);
Myles Watson032a9652009-05-11 22:24:53 +0000975
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000976 /* Store the interesting information in the device structure */
977 dev->vendor = id & 0xffff;
978 dev->device = (id >> 16) & 0xffff;
979 dev->hdr_type = hdr_type;
980 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
981 dev->class = class >> 8;
Myles Watson032a9652009-05-11 22:24:53 +0000982
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000983
984 /* Architectural/System devices always need to
985 * be bus masters.
986 */
987 if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
988 dev->command |= PCI_COMMAND_MASTER;
989 }
Myles Watson032a9652009-05-11 22:24:53 +0000990 /* Look at the vendor and device id, or at least the
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000991 * header type and class and figure out which set of
992 * configuration methods to use. Unless we already
993 * have some pci ops.
994 */
995 set_pci_ops(dev);
996
997 /* Now run the magic enable/disable sequence for the device */
998 if (dev->ops && dev->ops->enable) {
999 dev->ops->enable(dev);
1000 }
Myles Watson032a9652009-05-11 22:24:53 +00001001
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001002
1003 /* Display the device and error if we don't have some pci operations
1004 * for it.
1005 */
1006 printk_debug("%s [%04x/%04x] %s%s\n",
1007 dev_path(dev),
Myles Watson032a9652009-05-11 22:24:53 +00001008 dev->vendor, dev->device,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001009 dev->enabled?"enabled": "disabled",
1010 dev->ops?"" : " No operations"
1011 );
1012
1013 return dev;
1014}
1015
Myles Watson032a9652009-05-11 22:24:53 +00001016/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001017 * @brief Scan a PCI bus.
1018 *
Li-Ta Loe5266692004-03-23 21:28:05 +00001019 * Determine the existence of devices and bridges on a PCI bus. If there are
1020 * bridges on the bus, recursively scan the buses behind the bridges.
1021 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001022 * This function is the default scan_bus() method for the root device
1023 * 'dev_root'.
1024 *
Eric Biedermane9a271e32003-09-02 03:36:25 +00001025 * @param bus pointer to the bus structure
1026 * @param min_devfn minimum devfn to look at in the scan usually 0x00
1027 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +00001028 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +00001029 *
Eric Biederman8ca8d762003-04-22 19:02:15 +00001030 * @return The maximum bus number found, after scanning all subordinate busses
1031 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001032unsigned int pci_scan_bus(struct bus *bus,
1033 unsigned min_devfn, unsigned max_devfn,
1034 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +00001035{
1036 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +00001037 device_t old_devices;
1038 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001039
Yinghai Lu5f9624d2006-10-04 22:56:21 +00001040#if PCI_BUS_SEGN_BITS
1041 printk_debug("PCI: pci_scan_bus for bus %04x:%02x\n", bus->secondary >> 8, bus->secondary & 0xff);
1042#else
1043 printk_debug("PCI: pci_scan_bus for bus %02x\n", bus->secondary);
1044#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +00001045
1046 old_devices = bus->children;
1047 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001048
1049 post_code(0x24);
Li-Ta Lo9782f752004-05-05 21:15:42 +00001050 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +00001051 * non-existence and single funcion devices
1052 */
Eric Biedermane9a271e32003-09-02 03:36:25 +00001053 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001054 device_t dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001055
Eric Biederman03acab62004-10-14 21:25:53 +00001056 /* First thing setup the device structure */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001057 dev = pci_scan_get_dev(&old_devices, devfn);
Li-Ta Lo9782f752004-05-05 21:15:42 +00001058
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001059 /* See if a device is present and setup the device
1060 * structure.
Eric Biederman03acab62004-10-14 21:25:53 +00001061 */
Myles Watson032a9652009-05-11 22:24:53 +00001062 dev = pci_probe_dev(dev, bus, devfn);
Eric Biederman03acab62004-10-14 21:25:53 +00001063
Myles Watson032a9652009-05-11 22:24:53 +00001064 /* if this is not a multi function device,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001065 * or the device is not present don't waste
Myles Watson032a9652009-05-11 22:24:53 +00001066 * time probing another function.
1067 * Skip to next device.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001068 */
Myles Watson032a9652009-05-11 22:24:53 +00001069 if ((PCI_FUNC(devfn) == 0x00) &&
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001070 (!dev || (dev->enabled && ((dev->hdr_type & 0x80) != 0x80))))
1071 {
Eric Biederman8ca8d762003-04-22 19:02:15 +00001072 devfn += 0x07;
1073 }
1074 }
1075 post_code(0x25);
1076
Myles Watson032a9652009-05-11 22:24:53 +00001077 /* Die if any left over static devices are are found.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001078 * There's probably a problem in the Config.lb.
1079 */
1080 if(old_devices) {
1081 device_t left;
1082 for(left = old_devices; left; left = left->sibling) {
Ronald G. Minniche800b912006-01-17 21:12:03 +00001083 printk_err("%s\n", dev_path(left));
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001084 }
Stefan Reinauerd98cf5b2008-08-01 11:25:41 +00001085 printk_warning("PCI: Left over static devices. Check your mainboard Config.lb\n");
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001086 }
1087
Eric Biedermanb78c1972004-10-14 20:54:17 +00001088 /* For all children that implement scan_bus (i.e. bridges)
1089 * scan the bus behind that child.
1090 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001091 for(child = bus->children; child; child = child->sibling) {
1092 max = scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001093 }
Li-Ta Loe5266692004-03-23 21:28:05 +00001094
Eric Biederman8ca8d762003-04-22 19:02:15 +00001095 /*
1096 * We've scanned the bus and so we know all about what's on
1097 * the other side of any bridges that may be on this bus plus
1098 * any devices.
1099 *
1100 * Return how far we've got finding sub-buses.
1101 */
Yinghai Lu5f9624d2006-10-04 22:56:21 +00001102 printk_debug("PCI: pci_scan_bus returning with max=%03x\n", max);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001103 post_code(0x55);
1104 return max;
1105}
1106
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001107
Li-Ta Loe5266692004-03-23 21:28:05 +00001108/**
1109 * @brief Scan a PCI bridge and the buses behind the bridge.
1110 *
1111 * Determine the existence of buses behind the bridge. Set up the bridge
1112 * according to the result of the scan.
1113 *
1114 * This function is the default scan_bus() method for PCI bridge devices.
1115 *
1116 * @param dev pointer to the bridge device
1117 * @param max the highest bus number assgined up to now
1118 *
Eric Biederman8ca8d762003-04-22 19:02:15 +00001119 * @return The maximum bus number found, after scanning all subordinate busses
1120 */
Myles Watson032a9652009-05-11 22:24:53 +00001121unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
1122 unsigned int (*do_scan_bus)(struct bus *bus,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001123 unsigned min_devfn, unsigned max_devfn, unsigned int max))
Eric Biederman8ca8d762003-04-22 19:02:15 +00001124{
Eric Biedermane9a271e32003-09-02 03:36:25 +00001125 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001126 uint32_t buses;
1127 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +00001128
Li-Ta Lo3a812852004-12-03 22:39:34 +00001129 printk_spew("%s for %s\n", __func__, dev_path(dev));
1130
Eric Biedermane9a271e32003-09-02 03:36:25 +00001131 bus = &dev->link[0];
Eric Biedermana9e632c2004-11-18 22:38:08 +00001132 bus->dev = dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +00001133 dev->links = 1;
1134
Eric Biederman8ca8d762003-04-22 19:02:15 +00001135 /* Set up the primary, secondary and subordinate bus numbers. We have
1136 * no idea how many buses are behind this bridge yet, so we set the
Myles Watson032a9652009-05-11 22:24:53 +00001137 * subordinate bus number to 0xff for the moment.
Eric Biedermanb78c1972004-10-14 20:54:17 +00001138 */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001139 bus->secondary = ++max;
1140 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +00001141
Eric Biederman8ca8d762003-04-22 19:02:15 +00001142 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +00001143 cr = pci_read_config16(dev, PCI_COMMAND);
1144 pci_write_config16(dev, PCI_COMMAND, 0x0000);
1145 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001146
Eric Biedermanb78c1972004-10-14 20:54:17 +00001147 /*
1148 * Read the existing primary/secondary/subordinate bus
1149 * number configuration.
1150 */
Eric Biedermane9a271e32003-09-02 03:36:25 +00001151 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001152
1153 /* Configure the bus numbers for this bridge: the configuration
1154 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +00001155 * correctly configured.
1156 */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001157 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +00001158 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001159 ((unsigned int) (bus->secondary) << 8) |
1160 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +00001161 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Li-Ta Lo3a812852004-12-03 22:39:34 +00001162
Myles Watson032a9652009-05-11 22:24:53 +00001163 /* Now we can scan all subordinate buses
Eric Biedermanb78c1972004-10-14 20:54:17 +00001164 * i.e. the bus behind the bridge.
1165 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001166 max = do_scan_bus(bus, 0x00, 0xff, max);
Li-Ta Lo3a812852004-12-03 22:39:34 +00001167
Eric Biederman8ca8d762003-04-22 19:02:15 +00001168 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +00001169 * bus number to its real value.
1170 */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001171 bus->subordinate = max;
1172 buses = (buses & 0xff00ffff) |
1173 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +00001174 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
1175 pci_write_config16(dev, PCI_COMMAND, cr);
Myles Watson032a9652009-05-11 22:24:53 +00001176
Eric Biedermanb78c1972004-10-14 20:54:17 +00001177 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001178 return max;
1179}
Li-Ta Loe5266692004-03-23 21:28:05 +00001180
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001181/**
1182 * @brief Scan a PCI bridge and the buses behind the bridge.
1183 *
1184 * Determine the existence of buses behind the bridge. Set up the bridge
1185 * according to the result of the scan.
1186 *
1187 * This function is the default scan_bus() method for PCI bridge devices.
1188 *
1189 * @param dev pointer to the bridge device
1190 * @param max the highest bus number assgined up to now
1191 *
1192 * @return The maximum bus number found, after scanning all subordinate busses
1193 */
1194unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
1195{
1196 return do_pci_scan_bridge(dev, max, pci_scan_bus);
1197}
1198
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001199/*
1200 Tell the EISA int controller this int must be level triggered
1201 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
1202*/
Ronald G. Minnich88fb1a62006-06-22 04:37:27 +00001203void pci_level_irq(unsigned char intNum)
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001204{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001205 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001206
Eric Biedermanb78c1972004-10-14 20:54:17 +00001207 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001208 intBits |= (1 << intNum);
1209
Eric Biedermanb78c1972004-10-14 20:54:17 +00001210 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001211
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001212 // Write new values
1213 outb((unsigned char) intBits, 0x4d0);
1214 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001215
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001216 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +00001217#if 1
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001218 if (inb(0x4d0) != (intBits & 0xff)) {
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001219 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001220 __func__, intBits &0xff, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001221 }
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001222 if (inb(0x4d1) != ((intBits >> 8) & 0xff)) {
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001223 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001224 __func__, (intBits>>8) &0xff, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001225 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001226#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001227}
1228
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001229/*
1230 This function assigns IRQs for all functions contained within
1231 the indicated device address. If the device does not exist or does
1232 not require interrupts then this function has no effect.
1233
Myles Watson032a9652009-05-11 22:24:53 +00001234 This function should be called for each PCI slot in your system.
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001235
1236 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
Myles Watson032a9652009-05-11 22:24:53 +00001237 this slot.
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001238 The particular irq #s that are passed in depend on the routing inside
1239 your southbridge and on your motherboard.
1240
1241 -kevinh@ispiri.com
1242*/
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001243void pci_assign_irqs(unsigned bus, unsigned slot,
1244 const unsigned char pIntAtoD[4])
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001245{
1246 unsigned functNum;
1247 device_t pdev;
1248 unsigned char line;
1249 unsigned char irq;
1250 unsigned char readback;
1251
1252 /* Each slot may contain up to eight functions */
1253 for (functNum = 0; functNum < 8; functNum++) {
1254 pdev = dev_find_slot(bus, (slot << 3) + functNum);
1255
1256 if (pdev) {
1257 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
1258
Myles Watson032a9652009-05-11 22:24:53 +00001259 // PCI spec says all other values are reserved
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001260 if ((line >= 1) && (line <= 4)) {
1261 irq = pIntAtoD[line - 1];
1262
1263 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
1264 irq, bus, slot, functNum);
1265
1266 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
1267 pIntAtoD[line - 1]);
1268
1269 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
1270 printk_debug(" Readback = %d\n", readback);
1271
1272 // Change to level triggered
1273 pci_level_irq(pIntAtoD[line - 1]);
1274 }
1275 }
1276 }
1277}