diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sh64/kernel/pci_sh5.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/sh64/kernel/pci_sh5.c')
-rw-r--r-- | arch/sh64/kernel/pci_sh5.c | 541 |
1 files changed, 541 insertions, 0 deletions
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c new file mode 100644 index 000000000000..6197879e8578 --- /dev/null +++ b/arch/sh64/kernel/pci_sh5.c | |||
@@ -0,0 +1,541 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
3 | * Copyright (C) 2003, 2004 Paul Mundt | ||
4 | * Copyright (C) 2004 Richard Curnow | ||
5 | * | ||
6 | * May be copied or modified under the terms of the GNU General Public | ||
7 | * License. See linux/COPYING for more information. | ||
8 | * | ||
9 | * Support functions for the SH5 PCI hardware. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/rwsem.h> | ||
15 | #include <linux/smp.h> | ||
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <asm/pci.h> | ||
24 | #include <linux/irq.h> | ||
25 | |||
26 | #include <asm/io.h> | ||
27 | #include <asm/hardware.h> | ||
28 | #include "pci_sh5.h" | ||
29 | |||
30 | static unsigned long pcicr_virt; | ||
31 | unsigned long pciio_virt; | ||
32 | |||
33 | static void __init pci_fixup_ide_bases(struct pci_dev *d) | ||
34 | { | ||
35 | int i; | ||
36 | |||
37 | /* | ||
38 | * PCI IDE controllers use non-standard I/O port decoding, respect it. | ||
39 | */ | ||
40 | if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
41 | return; | ||
42 | printk("PCI: IDE base address fixup for %s\n", pci_name(d)); | ||
43 | for(i=0; i<4; i++) { | ||
44 | struct resource *r = &d->resource[i]; | ||
45 | if ((r->start & ~0x80) == 0x374) { | ||
46 | r->start |= 2; | ||
47 | r->end = r->start; | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
52 | |||
53 | char * __init pcibios_setup(char *str) | ||
54 | { | ||
55 | return str; | ||
56 | } | ||
57 | |||
58 | /* Rounds a number UP to the nearest power of two. Used for | ||
59 | * sizing the PCI window. | ||
60 | */ | ||
61 | static u32 __init r2p2(u32 num) | ||
62 | { | ||
63 | int i = 31; | ||
64 | u32 tmp = num; | ||
65 | |||
66 | if (num == 0) | ||
67 | return 0; | ||
68 | |||
69 | do { | ||
70 | if (tmp & (1 << 31)) | ||
71 | break; | ||
72 | i--; | ||
73 | tmp <<= 1; | ||
74 | } while (i >= 0); | ||
75 | |||
76 | tmp = 1 << i; | ||
77 | /* If the original number isn't a power of 2, round it up */ | ||
78 | if (tmp != num) | ||
79 | tmp <<= 1; | ||
80 | |||
81 | return tmp; | ||
82 | } | ||
83 | |||
84 | extern unsigned long long memory_start, memory_end; | ||
85 | |||
86 | int __init sh5pci_init(unsigned memStart, unsigned memSize) | ||
87 | { | ||
88 | u32 lsr0; | ||
89 | u32 uval; | ||
90 | |||
91 | pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR"); | ||
92 | if (!pcicr_virt) { | ||
93 | panic("Unable to remap PCICR\n"); | ||
94 | } | ||
95 | |||
96 | pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO"); | ||
97 | if (!pciio_virt) { | ||
98 | panic("Unable to remap PCIIO\n"); | ||
99 | } | ||
100 | |||
101 | pr_debug("Register base addres is 0x%08lx\n", pcicr_virt); | ||
102 | |||
103 | /* Clear snoop registers */ | ||
104 | SH5PCI_WRITE(CSCR0, 0); | ||
105 | SH5PCI_WRITE(CSCR1, 0); | ||
106 | |||
107 | pr_debug("Wrote to reg\n"); | ||
108 | |||
109 | /* Switch off interrupts */ | ||
110 | SH5PCI_WRITE(INTM, 0); | ||
111 | SH5PCI_WRITE(AINTM, 0); | ||
112 | SH5PCI_WRITE(PINTM, 0); | ||
113 | |||
114 | /* Set bus active, take it out of reset */ | ||
115 | uval = SH5PCI_READ(CR); | ||
116 | |||
117 | /* Set command Register */ | ||
118 | SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM); | ||
119 | |||
120 | uval=SH5PCI_READ(CR); | ||
121 | pr_debug("CR is actually 0x%08x\n",uval); | ||
122 | |||
123 | /* Allow it to be a master */ | ||
124 | /* NB - WE DISABLE I/O ACCESS to stop overlap */ | ||
125 | /* set WAIT bit to enable stepping, an attempt to improve stability */ | ||
126 | SH5PCI_WRITE_SHORT(CSR_CMD, | ||
127 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT); | ||
128 | |||
129 | /* | ||
130 | ** Set translation mapping memory in order to convert the address | ||
131 | ** used for the main bus, to the PCI internal address. | ||
132 | */ | ||
133 | SH5PCI_WRITE(MBR,0x40000000); | ||
134 | |||
135 | /* Always set the max size 512M */ | ||
136 | SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024)); | ||
137 | |||
138 | /* | ||
139 | ** I/O addresses are mapped at internal PCI specific address | ||
140 | ** as is described into the configuration bridge table. | ||
141 | ** These are changed to 0, to allow cards that have legacy | ||
142 | ** io such as vga to function correctly. We set the SH5 IOBAR to | ||
143 | ** 256K, which is a bit big as we can only have 64K of address space | ||
144 | */ | ||
145 | |||
146 | SH5PCI_WRITE(IOBR,0x0); | ||
147 | |||
148 | pr_debug("PCI:Writing 0x%08x to IOBR\n",0); | ||
149 | |||
150 | /* Set up a 256K window. Totally pointless waste of address space */ | ||
151 | SH5PCI_WRITE(IOBMR,0); | ||
152 | pr_debug("PCI:Writing 0x%08x to IOBMR\n",0); | ||
153 | |||
154 | /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally, | ||
155 | * we would want to map the I/O region somewhere, but it is so big this is not | ||
156 | * that easy! | ||
157 | */ | ||
158 | SH5PCI_WRITE(CSR_IBAR0,~0); | ||
159 | /* Set memory size value */ | ||
160 | memSize = memory_end - memory_start; | ||
161 | |||
162 | /* Now we set up the mbars so the PCI bus can see the memory of the machine */ | ||
163 | if (memSize < (1024 * 1024)) { | ||
164 | printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize); | ||
165 | return -EINVAL; | ||
166 | } | ||
167 | |||
168 | /* Set LSR 0 */ | ||
169 | lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1); | ||
170 | SH5PCI_WRITE(LSR0, lsr0); | ||
171 | |||
172 | pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0); | ||
173 | |||
174 | /* Set MBAR 0 */ | ||
175 | SH5PCI_WRITE(CSR_MBAR0, memory_start); | ||
176 | SH5PCI_WRITE(LAR0, memory_start); | ||
177 | |||
178 | SH5PCI_WRITE(CSR_MBAR1,0); | ||
179 | SH5PCI_WRITE(LAR1,0); | ||
180 | SH5PCI_WRITE(LSR1,0); | ||
181 | |||
182 | pr_debug("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start); | ||
183 | pr_debug("PCI:Writing 0x%08llx to LAR0\n",memory_start); | ||
184 | |||
185 | /* Enable the PCI interrupts on the device */ | ||
186 | SH5PCI_WRITE(INTM, ~0); | ||
187 | SH5PCI_WRITE(AINTM, ~0); | ||
188 | SH5PCI_WRITE(PINTM, ~0); | ||
189 | |||
190 | pr_debug("Switching on all error interrupts\n"); | ||
191 | |||
192 | return(0); | ||
193 | } | ||
194 | |||
195 | static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where, | ||
196 | int size, u32 *val) | ||
197 | { | ||
198 | SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where)); | ||
199 | |||
200 | switch (size) { | ||
201 | case 1: | ||
202 | *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3)); | ||
203 | break; | ||
204 | case 2: | ||
205 | *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2)); | ||
206 | break; | ||
207 | case 4: | ||
208 | *val = SH5PCI_READ(PDR); | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | return PCIBIOS_SUCCESSFUL; | ||
213 | } | ||
214 | |||
215 | static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where, | ||
216 | int size, u32 val) | ||
217 | { | ||
218 | SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where)); | ||
219 | |||
220 | switch (size) { | ||
221 | case 1: | ||
222 | SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val); | ||
223 | break; | ||
224 | case 2: | ||
225 | SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val); | ||
226 | break; | ||
227 | case 4: | ||
228 | SH5PCI_WRITE(PDR, val); | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | return PCIBIOS_SUCCESSFUL; | ||
233 | } | ||
234 | |||
235 | static struct pci_ops pci_config_ops = { | ||
236 | .read = sh5pci_read, | ||
237 | .write = sh5pci_write, | ||
238 | }; | ||
239 | |||
240 | /* Everything hangs off this */ | ||
241 | static struct pci_bus *pci_root_bus; | ||
242 | |||
243 | |||
244 | static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) | ||
245 | { | ||
246 | pr_debug("swizzle for dev %d on bus %d slot %d pin is %d\n", | ||
247 | dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin); | ||
248 | return PCI_SLOT(dev->devfn); | ||
249 | } | ||
250 | |||
251 | static inline u8 bridge_swizzle(u8 pin, u8 slot) | ||
252 | { | ||
253 | return (((pin-1) + slot) % 4) + 1; | ||
254 | } | ||
255 | |||
256 | u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) | ||
257 | { | ||
258 | if (dev->bus->number != 0) { | ||
259 | u8 pin = *pinp; | ||
260 | do { | ||
261 | pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); | ||
262 | /* Move up the chain of bridges. */ | ||
263 | dev = dev->bus->self; | ||
264 | } while (dev->bus->self); | ||
265 | *pinp = pin; | ||
266 | |||
267 | /* The slot is the slot of the last bridge. */ | ||
268 | } | ||
269 | |||
270 | return PCI_SLOT(dev->devfn); | ||
271 | } | ||
272 | |||
273 | /* This needs to be shunted out of here into the board specific bit */ | ||
274 | |||
275 | static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
276 | { | ||
277 | int result = -1; | ||
278 | |||
279 | /* The complication here is that the PCI IRQ lines from the Cayman's 2 | ||
280 | 5V slots get into the CPU via a different path from the IRQ lines | ||
281 | from the 3 3.3V slots. Thus, we have to detect whether the card's | ||
282 | interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling' | ||
283 | at the point where we cross from 5V to 3.3V is not the normal case. | ||
284 | |||
285 | The added complication is that we don't know that the 5V slots are | ||
286 | always bus 2, because a card containing a PCI-PCI bridge may be | ||
287 | plugged into a 3.3V slot, and this changes the bus numbering. | ||
288 | |||
289 | Also, the Cayman has an intermediate PCI bus that goes a custom | ||
290 | expansion board header (and to the secondary bridge). This bus has | ||
291 | never been used in practice. | ||
292 | |||
293 | The 1ary onboard PCI-PCI bridge is device 3 on bus 0 | ||
294 | The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge. | ||
295 | */ | ||
296 | |||
297 | struct slot_pin { | ||
298 | int slot; | ||
299 | int pin; | ||
300 | } path[4]; | ||
301 | int i=0; | ||
302 | |||
303 | while (dev->bus->number > 0) { | ||
304 | |||
305 | slot = path[i].slot = PCI_SLOT(dev->devfn); | ||
306 | pin = path[i].pin = bridge_swizzle(pin, slot); | ||
307 | dev = dev->bus->self; | ||
308 | i++; | ||
309 | if (i > 3) panic("PCI path to root bus too long!\n"); | ||
310 | } | ||
311 | |||
312 | slot = PCI_SLOT(dev->devfn); | ||
313 | /* This is the slot on bus 0 through which the device is eventually | ||
314 | reachable. */ | ||
315 | |||
316 | /* Now work back up. */ | ||
317 | if ((slot < 3) || (i == 0)) { | ||
318 | /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final | ||
319 | swizzle now. */ | ||
320 | result = IRQ_INTA + bridge_swizzle(pin, slot) - 1; | ||
321 | } else { | ||
322 | i--; | ||
323 | slot = path[i].slot; | ||
324 | pin = path[i].pin; | ||
325 | if (slot > 0) { | ||
326 | panic("PCI expansion bus device found - not handled!\n"); | ||
327 | } else { | ||
328 | if (i > 0) { | ||
329 | /* 5V slots */ | ||
330 | i--; | ||
331 | slot = path[i].slot; | ||
332 | pin = path[i].pin; | ||
333 | /* 'pin' was swizzled earlier wrt slot, don't do it again. */ | ||
334 | result = IRQ_P2INTA + (pin - 1); | ||
335 | } else { | ||
336 | /* IRQ for 2ary PCI-PCI bridge : unused */ | ||
337 | result = -1; | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | |||
342 | return result; | ||
343 | } | ||
344 | |||
345 | irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
346 | { | ||
347 | unsigned pci_int, pci_air, pci_cir, pci_aint; | ||
348 | |||
349 | pci_int = SH5PCI_READ(INT); | ||
350 | pci_cir = SH5PCI_READ(CIR); | ||
351 | pci_air = SH5PCI_READ(AIR); | ||
352 | |||
353 | if (pci_int) { | ||
354 | printk("PCI INTERRUPT (at %08llx)!\n", regs->pc); | ||
355 | printk("PCI INT -> 0x%x\n", pci_int & 0xffff); | ||
356 | printk("PCI AIR -> 0x%x\n", pci_air); | ||
357 | printk("PCI CIR -> 0x%x\n", pci_cir); | ||
358 | SH5PCI_WRITE(INT, ~0); | ||
359 | } | ||
360 | |||
361 | pci_aint = SH5PCI_READ(AINT); | ||
362 | if (pci_aint) { | ||
363 | printk("PCI ARB INTERRUPT!\n"); | ||
364 | printk("PCI AINT -> 0x%x\n", pci_aint); | ||
365 | printk("PCI AIR -> 0x%x\n", pci_air); | ||
366 | printk("PCI CIR -> 0x%x\n", pci_cir); | ||
367 | SH5PCI_WRITE(AINT, ~0); | ||
368 | } | ||
369 | |||
370 | return IRQ_HANDLED; | ||
371 | } | ||
372 | |||
373 | irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
374 | { | ||
375 | printk("SERR IRQ\n"); | ||
376 | |||
377 | return IRQ_NONE; | ||
378 | } | ||
379 | |||
380 | #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) | ||
381 | |||
382 | static void __init | ||
383 | pcibios_size_bridge(struct pci_bus *bus, struct resource *ior, | ||
384 | struct resource *memr) | ||
385 | { | ||
386 | struct resource io_res, mem_res; | ||
387 | struct pci_dev *dev; | ||
388 | struct pci_dev *bridge = bus->self; | ||
389 | struct list_head *ln; | ||
390 | |||
391 | if (!bridge) | ||
392 | return; /* host bridge, nothing to do */ | ||
393 | |||
394 | /* set reasonable default locations for pcibios_align_resource */ | ||
395 | io_res.start = PCIBIOS_MIN_IO; | ||
396 | mem_res.start = PCIBIOS_MIN_MEM; | ||
397 | |||
398 | io_res.end = io_res.start; | ||
399 | mem_res.end = mem_res.start; | ||
400 | |||
401 | /* Collect information about how our direct children are layed out. */ | ||
402 | for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { | ||
403 | int i; | ||
404 | dev = pci_dev_b(ln); | ||
405 | |||
406 | /* Skip bridges for now */ | ||
407 | if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) | ||
408 | continue; | ||
409 | |||
410 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
411 | struct resource res; | ||
412 | unsigned long size; | ||
413 | |||
414 | memcpy(&res, &dev->resource[i], sizeof(res)); | ||
415 | size = res.end - res.start + 1; | ||
416 | |||
417 | if (res.flags & IORESOURCE_IO) { | ||
418 | res.start = io_res.end; | ||
419 | pcibios_align_resource(dev, &res, size, 0); | ||
420 | io_res.end = res.start + size; | ||
421 | } else if (res.flags & IORESOURCE_MEM) { | ||
422 | res.start = mem_res.end; | ||
423 | pcibios_align_resource(dev, &res, size, 0); | ||
424 | mem_res.end = res.start + size; | ||
425 | } | ||
426 | } | ||
427 | } | ||
428 | |||
429 | /* And for all of the subordinate busses. */ | ||
430 | for (ln=bus->children.next; ln != &bus->children; ln=ln->next) | ||
431 | pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res); | ||
432 | |||
433 | /* turn the ending locations into sizes (subtract start) */ | ||
434 | io_res.end -= io_res.start; | ||
435 | mem_res.end -= mem_res.start; | ||
436 | |||
437 | /* Align the sizes up by bridge rules */ | ||
438 | io_res.end = ROUND_UP(io_res.end, 4*1024) - 1; | ||
439 | mem_res.end = ROUND_UP(mem_res.end, 1*1024*1024) - 1; | ||
440 | |||
441 | /* Adjust the bridge's allocation requirements */ | ||
442 | bridge->resource[0].end = bridge->resource[0].start + io_res.end; | ||
443 | bridge->resource[1].end = bridge->resource[1].start + mem_res.end; | ||
444 | |||
445 | bridge->resource[PCI_BRIDGE_RESOURCES].end = | ||
446 | bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end; | ||
447 | bridge->resource[PCI_BRIDGE_RESOURCES+1].end = | ||
448 | bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end; | ||
449 | |||
450 | /* adjust parent's resource requirements */ | ||
451 | if (ior) { | ||
452 | ior->end = ROUND_UP(ior->end, 4*1024); | ||
453 | ior->end += io_res.end; | ||
454 | } | ||
455 | |||
456 | if (memr) { | ||
457 | memr->end = ROUND_UP(memr->end, 1*1024*1024); | ||
458 | memr->end += mem_res.end; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | #undef ROUND_UP | ||
463 | |||
464 | static void __init pcibios_size_bridges(void) | ||
465 | { | ||
466 | struct resource io_res, mem_res; | ||
467 | |||
468 | memset(&io_res, 0, sizeof(io_res)); | ||
469 | memset(&mem_res, 0, sizeof(mem_res)); | ||
470 | |||
471 | pcibios_size_bridge(pci_root_bus, &io_res, &mem_res); | ||
472 | } | ||
473 | |||
474 | static int __init pcibios_init(void) | ||
475 | { | ||
476 | if (request_irq(IRQ_ERR, pcish5_err_irq, | ||
477 | SA_INTERRUPT, "PCI Error",NULL) < 0) { | ||
478 | printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n"); | ||
479 | return -EINVAL; | ||
480 | } | ||
481 | |||
482 | if (request_irq(IRQ_SERR, pcish5_serr_irq, | ||
483 | SA_INTERRUPT, "PCI SERR interrupt", NULL) < 0) { | ||
484 | printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n"); | ||
485 | return -EINVAL; | ||
486 | } | ||
487 | |||
488 | /* The pci subsytem needs to know where memory is and how much | ||
489 | * of it there is. I've simply made these globals. A better mechanism | ||
490 | * is probably needed. | ||
491 | */ | ||
492 | sh5pci_init(__pa(memory_start), | ||
493 | __pa(memory_end) - __pa(memory_start)); | ||
494 | |||
495 | pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); | ||
496 | pcibios_size_bridges(); | ||
497 | pci_assign_unassigned_resources(); | ||
498 | pci_fixup_irqs(no_swizzle, map_cayman_irq); | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | subsys_initcall(pcibios_init); | ||
504 | |||
505 | void __init pcibios_fixup_bus(struct pci_bus *bus) | ||
506 | { | ||
507 | struct pci_dev *dev = bus->self; | ||
508 | int i; | ||
509 | |||
510 | #if 1 | ||
511 | if(dev) { | ||
512 | for(i=0; i<3; i++) { | ||
513 | bus->resource[i] = | ||
514 | &dev->resource[PCI_BRIDGE_RESOURCES+i]; | ||
515 | bus->resource[i]->name = bus->name; | ||
516 | } | ||
517 | bus->resource[0]->flags |= IORESOURCE_IO; | ||
518 | bus->resource[1]->flags |= IORESOURCE_MEM; | ||
519 | |||
520 | /* For now, propagate host limits to the bus; | ||
521 | * we'll adjust them later. */ | ||
522 | |||
523 | #if 1 | ||
524 | bus->resource[0]->end = 64*1024 - 1 ; | ||
525 | bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1; | ||
526 | bus->resource[0]->start = PCIBIOS_MIN_IO; | ||
527 | bus->resource[1]->start = PCIBIOS_MIN_MEM; | ||
528 | #else | ||
529 | bus->resource[0]->end = 0 | ||
530 | bus->resource[1]->end = 0 | ||
531 | bus->resource[0]->start =0 | ||
532 | bus->resource[1]->start = 0; | ||
533 | #endif | ||
534 | /* Turn off downstream PF memory address range by default */ | ||
535 | bus->resource[2]->start = 1024*1024; | ||
536 | bus->resource[2]->end = bus->resource[2]->start - 1; | ||
537 | } | ||
538 | #endif | ||
539 | |||
540 | } | ||
541 | |||