2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 * Copyright (C) 2003, 2004 Paul Mundt
4 * Copyright (C) 2004 Richard Curnow
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
9 * Support functions for the SH5 PCI hardware.
12 #include <linux/kernel.h>
13 #include <linux/rwsem.h>
14 #include <linux/smp.h>
15 #include <linux/smp_lock.h>
16 #include <linux/interrupt.h>
17 #include <linux/init.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/delay.h>
21 #include <linux/types.h>
23 #include <linux/irq.h>
26 #include <asm/hardware.h>
29 static unsigned long pcicr_virt;
30 unsigned long pciio_virt;
32 static void __init pci_fixup_ide_bases(struct pci_dev *d)
37 * PCI IDE controllers use non-standard I/O port decoding, respect it.
39 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
41 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
43 struct resource *r = &d->resource[i];
44 if ((r->start & ~0x80) == 0x374) {
50 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
52 char * __init pcibios_setup(char *str)
57 /* Rounds a number UP to the nearest power of two. Used for
58 * sizing the PCI window.
60 static u32 __init r2p2(u32 num)
76 /* If the original number isn't a power of 2, round it up */
83 extern unsigned long long memory_start, memory_end;
85 int __init sh5pci_init(unsigned memStart, unsigned memSize)
90 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
92 panic("Unable to remap PCICR\n");
95 pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
97 panic("Unable to remap PCIIO\n");
100 pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
102 /* Clear snoop registers */
103 SH5PCI_WRITE(CSCR0, 0);
104 SH5PCI_WRITE(CSCR1, 0);
106 pr_debug("Wrote to reg\n");
108 /* Switch off interrupts */
109 SH5PCI_WRITE(INTM, 0);
110 SH5PCI_WRITE(AINTM, 0);
111 SH5PCI_WRITE(PINTM, 0);
113 /* Set bus active, take it out of reset */
114 uval = SH5PCI_READ(CR);
116 /* Set command Register */
117 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
119 uval=SH5PCI_READ(CR);
120 pr_debug("CR is actually 0x%08x\n",uval);
122 /* Allow it to be a master */
123 /* NB - WE DISABLE I/O ACCESS to stop overlap */
124 /* set WAIT bit to enable stepping, an attempt to improve stability */
125 SH5PCI_WRITE_SHORT(CSR_CMD,
126 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
129 ** Set translation mapping memory in order to convert the address
130 ** used for the main bus, to the PCI internal address.
132 SH5PCI_WRITE(MBR,0x40000000);
134 /* Always set the max size 512M */
135 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
138 ** I/O addresses are mapped at internal PCI specific address
139 ** as is described into the configuration bridge table.
140 ** These are changed to 0, to allow cards that have legacy
141 ** io such as vga to function correctly. We set the SH5 IOBAR to
142 ** 256K, which is a bit big as we can only have 64K of address space
145 SH5PCI_WRITE(IOBR,0x0);
147 pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
149 /* Set up a 256K window. Totally pointless waste of address space */
150 SH5PCI_WRITE(IOBMR,0);
151 pr_debug("PCI:Writing 0x%08x to IOBMR\n",0);
153 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally,
154 * we would want to map the I/O region somewhere, but it is so big this is not
157 SH5PCI_WRITE(CSR_IBAR0,~0);
158 /* Set memory size value */
159 memSize = memory_end - memory_start;
161 /* Now we set up the mbars so the PCI bus can see the memory of the machine */
162 if (memSize < (1024 * 1024)) {
163 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
168 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
169 SH5PCI_WRITE(LSR0, lsr0);
171 pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
174 SH5PCI_WRITE(CSR_MBAR0, memory_start);
175 SH5PCI_WRITE(LAR0, memory_start);
177 SH5PCI_WRITE(CSR_MBAR1,0);
178 SH5PCI_WRITE(LAR1,0);
179 SH5PCI_WRITE(LSR1,0);
181 pr_debug("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);
182 pr_debug("PCI:Writing 0x%08llx to LAR0\n",memory_start);
184 /* Enable the PCI interrupts on the device */
185 SH5PCI_WRITE(INTM, ~0);
186 SH5PCI_WRITE(AINTM, ~0);
187 SH5PCI_WRITE(PINTM, ~0);
189 pr_debug("Switching on all error interrupts\n");
194 static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
197 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
201 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
204 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
207 *val = SH5PCI_READ(PDR);
211 return PCIBIOS_SUCCESSFUL;
214 static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
217 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
221 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
224 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
227 SH5PCI_WRITE(PDR, val);
231 return PCIBIOS_SUCCESSFUL;
234 static struct pci_ops pci_config_ops = {
236 .write = sh5pci_write,
239 /* Everything hangs off this */
240 static struct pci_bus *pci_root_bus;
243 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
245 pr_debug("swizzle for dev %d on bus %d slot %d pin is %d\n",
246 dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
247 return PCI_SLOT(dev->devfn);
250 static inline u8 bridge_swizzle(u8 pin, u8 slot)
252 return (((pin-1) + slot) % 4) + 1;
255 u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
257 if (dev->bus->number != 0) {
260 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
261 /* Move up the chain of bridges. */
262 dev = dev->bus->self;
263 } while (dev->bus->self);
266 /* The slot is the slot of the last bridge. */
269 return PCI_SLOT(dev->devfn);
272 /* This needs to be shunted out of here into the board specific bit */
274 static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
278 /* The complication here is that the PCI IRQ lines from the Cayman's 2
279 5V slots get into the CPU via a different path from the IRQ lines
280 from the 3 3.3V slots. Thus, we have to detect whether the card's
281 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
282 at the point where we cross from 5V to 3.3V is not the normal case.
284 The added complication is that we don't know that the 5V slots are
285 always bus 2, because a card containing a PCI-PCI bridge may be
286 plugged into a 3.3V slot, and this changes the bus numbering.
288 Also, the Cayman has an intermediate PCI bus that goes a custom
289 expansion board header (and to the secondary bridge). This bus has
290 never been used in practice.
292 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
293 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge.
302 while (dev->bus->number > 0) {
304 slot = path[i].slot = PCI_SLOT(dev->devfn);
305 pin = path[i].pin = bridge_swizzle(pin, slot);
306 dev = dev->bus->self;
308 if (i > 3) panic("PCI path to root bus too long!\n");
311 slot = PCI_SLOT(dev->devfn);
312 /* This is the slot on bus 0 through which the device is eventually
315 /* Now work back up. */
316 if ((slot < 3) || (i == 0)) {
317 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
319 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
325 panic("PCI expansion bus device found - not handled!\n");
332 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
333 result = IRQ_P2INTA + (pin - 1);
335 /* IRQ for 2ary PCI-PCI bridge : unused */
344 irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
346 unsigned pci_int, pci_air, pci_cir, pci_aint;
348 pci_int = SH5PCI_READ(INT);
349 pci_cir = SH5PCI_READ(CIR);
350 pci_air = SH5PCI_READ(AIR);
353 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
354 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
355 printk("PCI AIR -> 0x%x\n", pci_air);
356 printk("PCI CIR -> 0x%x\n", pci_cir);
357 SH5PCI_WRITE(INT, ~0);
360 pci_aint = SH5PCI_READ(AINT);
362 printk("PCI ARB INTERRUPT!\n");
363 printk("PCI AINT -> 0x%x\n", pci_aint);
364 printk("PCI AIR -> 0x%x\n", pci_air);
365 printk("PCI CIR -> 0x%x\n", pci_cir);
366 SH5PCI_WRITE(AINT, ~0);
372 irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
374 printk("SERR IRQ\n");
379 #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
382 pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
383 struct resource *memr)
385 struct resource io_res, mem_res;
387 struct pci_dev *bridge = bus->self;
388 struct list_head *ln;
391 return; /* host bridge, nothing to do */
393 /* set reasonable default locations for pcibios_align_resource */
394 io_res.start = PCIBIOS_MIN_IO;
395 mem_res.start = PCIBIOS_MIN_MEM;
397 io_res.end = io_res.start;
398 mem_res.end = mem_res.start;
400 /* Collect information about how our direct children are layed out. */
401 for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
405 /* Skip bridges for now */
406 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
409 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
413 memcpy(&res, &dev->resource[i], sizeof(res));
414 size = res.end - res.start + 1;
416 if (res.flags & IORESOURCE_IO) {
417 res.start = io_res.end;
418 pcibios_align_resource(dev, &res, size, 0);
419 io_res.end = res.start + size;
420 } else if (res.flags & IORESOURCE_MEM) {
421 res.start = mem_res.end;
422 pcibios_align_resource(dev, &res, size, 0);
423 mem_res.end = res.start + size;
428 /* And for all of the subordinate busses. */
429 for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
430 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
432 /* turn the ending locations into sizes (subtract start) */
433 io_res.end -= io_res.start;
434 mem_res.end -= mem_res.start;
436 /* Align the sizes up by bridge rules */
437 io_res.end = ROUND_UP(io_res.end, 4*1024) - 1;
438 mem_res.end = ROUND_UP(mem_res.end, 1*1024*1024) - 1;
440 /* Adjust the bridge's allocation requirements */
441 bridge->resource[0].end = bridge->resource[0].start + io_res.end;
442 bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
444 bridge->resource[PCI_BRIDGE_RESOURCES].end =
445 bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
446 bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
447 bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
449 /* adjust parent's resource requirements */
451 ior->end = ROUND_UP(ior->end, 4*1024);
452 ior->end += io_res.end;
456 memr->end = ROUND_UP(memr->end, 1*1024*1024);
457 memr->end += mem_res.end;
463 static void __init pcibios_size_bridges(void)
465 struct resource io_res, mem_res;
467 memset(&io_res, 0, sizeof(io_res));
468 memset(&mem_res, 0, sizeof(mem_res));
470 pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
473 static int __init pcibios_init(void)
475 if (request_irq(IRQ_ERR, pcish5_err_irq,
476 IRQF_DISABLED, "PCI Error",NULL) < 0) {
477 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
481 if (request_irq(IRQ_SERR, pcish5_serr_irq,
482 IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
483 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
487 /* The pci subsytem needs to know where memory is and how much
488 * of it there is. I've simply made these globals. A better mechanism
489 * is probably needed.
491 sh5pci_init(__pa(memory_start),
492 __pa(memory_end) - __pa(memory_start));
494 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
495 pcibios_size_bridges();
496 pci_assign_unassigned_resources();
497 pci_fixup_irqs(no_swizzle, map_cayman_irq);
502 subsys_initcall(pcibios_init);
504 void __init pcibios_fixup_bus(struct pci_bus *bus)
506 struct pci_dev *dev = bus->self;
513 &dev->resource[PCI_BRIDGE_RESOURCES+i];
514 bus->resource[i]->name = bus->name;
516 bus->resource[0]->flags |= IORESOURCE_IO;
517 bus->resource[1]->flags |= IORESOURCE_MEM;
519 /* For now, propagate host limits to the bus;
520 * we'll adjust them later. */
523 bus->resource[0]->end = 64*1024 - 1 ;
524 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
525 bus->resource[0]->start = PCIBIOS_MIN_IO;
526 bus->resource[1]->start = PCIBIOS_MIN_MEM;
528 bus->resource[0]->end = 0
529 bus->resource[1]->end = 0
530 bus->resource[0]->start =0
531 bus->resource[1]->start = 0;
533 /* Turn off downstream PF memory address range by default */
534 bus->resource[2]->start = 1024*1024;
535 bus->resource[2]->end = bus->resource[2]->start - 1;