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/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>
24 #include <linux/irq.h>
27 #include <asm/hardware.h>
30 static unsigned long pcicr_virt;
31 unsigned long pciio_virt;
33 static void __init pci_fixup_ide_bases(struct pci_dev *d)
38 * PCI IDE controllers use non-standard I/O port decoding, respect it.
40 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
42 printk("PCI: IDE base address fixup for %s\n", d->slot_name);
44 struct resource *r = &d->resource[i];
45 if ((r->start & ~0x80) == 0x374) {
52 /* Add future fixups here... */
53 struct pci_fixup pcibios_fixups[] = {
54 { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
58 char * __init pcibios_setup(char *str)
63 /* Rounds a number UP to the nearest power of two. Used for
64 * sizing the PCI window.
66 static u32 __init r2p2(u32 num)
82 /* If the original number isn't a power of 2, round it up */
89 extern unsigned long long memory_start, memory_end;
91 int __init sh5pci_init(unsigned memStart, unsigned memSize)
96 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
98 panic("Unable to remap PCICR\n");
101 pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
103 panic("Unable to remap PCIIO\n");
106 pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
108 /* Clear snoop registers */
109 SH5PCI_WRITE(CSCR0, 0);
110 SH5PCI_WRITE(CSCR1, 0);
112 pr_debug("Wrote to reg\n");
114 /* Switch off interrupts */
115 SH5PCI_WRITE(INTM, 0);
116 SH5PCI_WRITE(AINTM, 0);
117 SH5PCI_WRITE(PINTM, 0);
119 /* Set bus active, take it out of reset */
120 uval = SH5PCI_READ(CR);
122 /* Set command Register */
123 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
125 uval=SH5PCI_READ(CR);
126 pr_debug("CR is actually 0x%08x\n",uval);
128 /* Allow it to be a master */
129 /* NB - WE DISABLE I/O ACCESS to stop overlap */
130 /* set WAIT bit to enable stepping, an attempt to improve stability */
131 SH5PCI_WRITE_SHORT(CSR_CMD,
132 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
135 ** Set translation mapping memory in order to convert the address
136 ** used for the main bus, to the PCI internal address.
138 SH5PCI_WRITE(MBR,0x40000000);
140 /* Always set the max size 512M */
141 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
144 ** I/O addresses are mapped at internal PCI specific address
145 ** as is described into the configuration bridge table.
146 ** These are changed to 0, to allow cards that have legacy
147 ** io such as vga to function correctly. We set the SH5 IOBAR to
148 ** 256K, which is a bit big as we can only have 64K of address space
151 SH5PCI_WRITE(IOBR,0x0);
153 pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
155 /* Set up a 256K window. Totally pointless waste of address space */
156 SH5PCI_WRITE(IOBMR,0);
157 pr_debug("PCI:Writing 0x%08x to IOBMR\n",0);
159 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally,
160 * we would want to map the I/O region somewhere, but it is so big this is not
163 SH5PCI_WRITE(CSR_IBAR0,~0);
164 /* Set memory size value */
165 memSize = memory_end - memory_start;
167 /* Now we set up the mbars so the PCI bus can see the memory of the machine */
168 if (memSize < (1024 * 1024)) {
169 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
174 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
175 SH5PCI_WRITE(LSR0, lsr0);
177 pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
180 SH5PCI_WRITE(CSR_MBAR0, memory_start);
181 SH5PCI_WRITE(LAR0, memory_start);
183 SH5PCI_WRITE(CSR_MBAR1,0);
184 SH5PCI_WRITE(LAR1,0);
185 SH5PCI_WRITE(LSR1,0);
187 pr_debug("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);
188 pr_debug("PCI:Writing 0x%08llx to LAR0\n",memory_start);
190 /* Enable the PCI interrupts on the device */
191 SH5PCI_WRITE(INTM, ~0);
192 SH5PCI_WRITE(AINTM, ~0);
193 SH5PCI_WRITE(PINTM, ~0);
195 pr_debug("Switching on all error interrupts\n");
200 static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
203 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
207 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
210 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
213 *val = SH5PCI_READ(PDR);
217 return PCIBIOS_SUCCESSFUL;
220 static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
223 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
227 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
230 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
233 SH5PCI_WRITE(PDR, val);
237 return PCIBIOS_SUCCESSFUL;
240 static struct pci_ops pci_config_ops = {
242 .write = sh5pci_write,
245 /* Everything hangs off this */
246 static struct pci_bus *pci_root_bus;
249 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
251 pr_debug("swizzle for dev %d on bus %d slot %d pin is %d\n",
252 dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
253 return PCI_SLOT(dev->devfn);
256 static inline u8 bridge_swizzle(u8 pin, u8 slot)
258 return (((pin-1) + slot) % 4) + 1;
261 u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
263 if (dev->bus->number != 0) {
266 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
267 /* Move up the chain of bridges. */
268 dev = dev->bus->self;
269 } while (dev->bus->self);
272 /* The slot is the slot of the last bridge. */
275 return PCI_SLOT(dev->devfn);
278 /* This needs to be shunted out of here into the board specific bit */
280 static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
284 /* The complication here is that the PCI IRQ lines from the Cayman's 2
285 5V slots get into the CPU via a different path from the IRQ lines
286 from the 3 3.3V slots. Thus, we have to detect whether the card's
287 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
288 at the point where we cross from 5V to 3.3V is not the normal case.
290 The added complication is that we don't know that the 5V slots are
291 always bus 2, because a card containing a PCI-PCI bridge may be
292 plugged into a 3.3V slot, and this changes the bus numbering.
294 Also, the Cayman has an intermediate PCI bus that goes a custom
295 expansion board header (and to the secondary bridge). This bus has
296 never been used in practice.
298 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
299 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge.
308 while (dev->bus->number > 0) {
310 slot = path[i].slot = PCI_SLOT(dev->devfn);
311 pin = path[i].pin = bridge_swizzle(pin, slot);
312 dev = dev->bus->self;
314 if (i > 3) panic("PCI path to root bus too long!\n");
317 slot = PCI_SLOT(dev->devfn);
318 /* This is the slot on bus 0 through which the device is eventually
321 /* Now work back up. */
322 if ((slot < 3) || (i == 0)) {
323 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
325 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
331 panic("PCI expansion bus device found - not handled!\n");
338 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
339 result = IRQ_P2INTA + (pin - 1);
341 /* IRQ for 2ary PCI-PCI bridge : unused */
350 irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
352 unsigned pci_int, pci_air, pci_cir, pci_aint;
354 pci_int = SH5PCI_READ(INT);
355 pci_cir = SH5PCI_READ(CIR);
356 pci_air = SH5PCI_READ(AIR);
359 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
360 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
361 printk("PCI AIR -> 0x%x\n", pci_air);
362 printk("PCI CIR -> 0x%x\n", pci_cir);
363 SH5PCI_WRITE(INT, ~0);
366 pci_aint = SH5PCI_READ(AINT);
368 printk("PCI ARB INTERRUPT!\n");
369 printk("PCI AINT -> 0x%x\n", pci_aint);
370 printk("PCI AIR -> 0x%x\n", pci_air);
371 printk("PCI CIR -> 0x%x\n", pci_cir);
372 SH5PCI_WRITE(AINT, ~0);
378 irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
380 printk("SERR IRQ\n");
385 #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
388 pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
389 struct resource *memr)
391 struct resource io_res, mem_res;
393 struct pci_dev *bridge = bus->self;
394 struct list_head *ln;
397 return; /* host bridge, nothing to do */
399 /* set reasonable default locations for pcibios_align_resource */
400 io_res.start = PCIBIOS_MIN_IO;
401 mem_res.start = PCIBIOS_MIN_MEM;
403 io_res.end = io_res.start;
404 mem_res.end = mem_res.start;
406 /* Collect information about how our direct children are layed out. */
407 for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
411 /* Skip bridges for now */
412 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
415 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
419 memcpy(&res, &dev->resource[i], sizeof(res));
420 size = res.end - res.start + 1;
422 if (res.flags & IORESOURCE_IO) {
423 res.start = io_res.end;
424 pcibios_align_resource(dev, &res, size, 0);
425 io_res.end = res.start + size;
426 } else if (res.flags & IORESOURCE_MEM) {
427 res.start = mem_res.end;
428 pcibios_align_resource(dev, &res, size, 0);
429 mem_res.end = res.start + size;
434 /* And for all of the subordinate busses. */
435 for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
436 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
438 /* turn the ending locations into sizes (subtract start) */
439 io_res.end -= io_res.start;
440 mem_res.end -= mem_res.start;
442 /* Align the sizes up by bridge rules */
443 io_res.end = ROUND_UP(io_res.end, 4*1024) - 1;
444 mem_res.end = ROUND_UP(mem_res.end, 1*1024*1024) - 1;
446 /* Adjust the bridge's allocation requirements */
447 bridge->resource[0].end = bridge->resource[0].start + io_res.end;
448 bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
450 bridge->resource[PCI_BRIDGE_RESOURCES].end =
451 bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
452 bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
453 bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
455 /* adjust parent's resource requirements */
457 ior->end = ROUND_UP(ior->end, 4*1024);
458 ior->end += io_res.end;
462 memr->end = ROUND_UP(memr->end, 1*1024*1024);
463 memr->end += mem_res.end;
469 static void __init pcibios_size_bridges(void)
471 struct resource io_res, mem_res;
473 memset(&io_res, 0, sizeof(io_res));
474 memset(&mem_res, 0, sizeof(mem_res));
476 pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
479 static int __init pcibios_init(void)
481 if (request_irq(IRQ_ERR, pcish5_err_irq,
482 SA_INTERRUPT, "PCI Error",NULL) < 0) {
483 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
487 if (request_irq(IRQ_SERR, pcish5_serr_irq,
488 SA_INTERRUPT, "PCI SERR interrupt", NULL) < 0) {
489 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
493 /* The pci subsytem needs to know where memory is and how much
494 * of it there is. I've simply made these globals. A better mechanism
495 * is probably needed.
497 sh5pci_init(__pa(memory_start),
498 __pa(memory_end) - __pa(memory_start));
500 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
501 pcibios_size_bridges();
502 pci_assign_unassigned_resources();
503 pci_fixup_irqs(no_swizzle, map_cayman_irq);
508 subsys_initcall(pcibios_init);
510 void __init pcibios_fixup_bus(struct pci_bus *bus)
512 struct pci_dev *dev = bus->self;
519 &dev->resource[PCI_BRIDGE_RESOURCES+i];
520 bus->resource[i]->name = bus->name;
522 bus->resource[0]->flags |= IORESOURCE_IO;
523 bus->resource[1]->flags |= IORESOURCE_MEM;
525 /* For now, propogate host limits to the bus;
526 * we'll adjust them later. */
529 bus->resource[0]->end = 64*1024 - 1 ;
530 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
531 bus->resource[0]->start = PCIBIOS_MIN_IO;
532 bus->resource[1]->start = PCIBIOS_MIN_MEM;
534 bus->resource[0]->end = 0
535 bus->resource[1]->end = 0
536 bus->resource[0]->start =0
537 bus->resource[1]->start = 0;
539 /* Turn off downstream PF memory address range by default */
540 bus->resource[2]->start = 1024*1024;
541 bus->resource[2]->end = bus->resource[2]->start - 1;