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/interrupt.h>
16 #include <linux/init.h>
17 #include <linux/errno.h>
18 #include <linux/pci.h>
19 #include <linux/delay.h>
20 #include <linux/types.h>
22 #include <linux/irq.h>
25 #include <asm/hardware.h>
28 static unsigned long pcicr_virt;
29 unsigned long pciio_virt;
31 static void __init pci_fixup_ide_bases(struct pci_dev *d)
36 * PCI IDE controllers use non-standard I/O port decoding, respect it.
38 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
40 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
42 struct resource *r = &d->resource[i];
43 if ((r->start & ~0x80) == 0x374) {
49 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
51 char * __init pcibios_setup(char *str)
56 /* Rounds a number UP to the nearest power of two. Used for
57 * sizing the PCI window.
59 static u32 __init r2p2(u32 num)
75 /* If the original number isn't a power of 2, round it up */
82 extern unsigned long long memory_start, memory_end;
84 int __init sh5pci_init(unsigned memStart, unsigned memSize)
89 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
91 panic("Unable to remap PCICR\n");
94 pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
96 panic("Unable to remap PCIIO\n");
99 pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
101 /* Clear snoop registers */
102 SH5PCI_WRITE(CSCR0, 0);
103 SH5PCI_WRITE(CSCR1, 0);
105 pr_debug("Wrote to reg\n");
107 /* Switch off interrupts */
108 SH5PCI_WRITE(INTM, 0);
109 SH5PCI_WRITE(AINTM, 0);
110 SH5PCI_WRITE(PINTM, 0);
112 /* Set bus active, take it out of reset */
113 uval = SH5PCI_READ(CR);
115 /* Set command Register */
116 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
118 uval=SH5PCI_READ(CR);
119 pr_debug("CR is actually 0x%08x\n",uval);
121 /* Allow it to be a master */
122 /* NB - WE DISABLE I/O ACCESS to stop overlap */
123 /* set WAIT bit to enable stepping, an attempt to improve stability */
124 SH5PCI_WRITE_SHORT(CSR_CMD,
125 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
128 ** Set translation mapping memory in order to convert the address
129 ** used for the main bus, to the PCI internal address.
131 SH5PCI_WRITE(MBR,0x40000000);
133 /* Always set the max size 512M */
134 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
137 ** I/O addresses are mapped at internal PCI specific address
138 ** as is described into the configuration bridge table.
139 ** These are changed to 0, to allow cards that have legacy
140 ** io such as vga to function correctly. We set the SH5 IOBAR to
141 ** 256K, which is a bit big as we can only have 64K of address space
144 SH5PCI_WRITE(IOBR,0x0);
146 pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
148 /* Set up a 256K window. Totally pointless waste of address space */
149 SH5PCI_WRITE(IOBMR,0);
150 pr_debug("PCI:Writing 0x%08x to IOBMR\n",0);
152 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally,
153 * we would want to map the I/O region somewhere, but it is so big this is not
156 SH5PCI_WRITE(CSR_IBAR0,~0);
157 /* Set memory size value */
158 memSize = memory_end - memory_start;
160 /* Now we set up the mbars so the PCI bus can see the memory of the machine */
161 if (memSize < (1024 * 1024)) {
162 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
167 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
168 SH5PCI_WRITE(LSR0, lsr0);
170 pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
173 SH5PCI_WRITE(CSR_MBAR0, memory_start);
174 SH5PCI_WRITE(LAR0, memory_start);
176 SH5PCI_WRITE(CSR_MBAR1,0);
177 SH5PCI_WRITE(LAR1,0);
178 SH5PCI_WRITE(LSR1,0);
180 pr_debug("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);
181 pr_debug("PCI:Writing 0x%08llx to LAR0\n",memory_start);
183 /* Enable the PCI interrupts on the device */
184 SH5PCI_WRITE(INTM, ~0);
185 SH5PCI_WRITE(AINTM, ~0);
186 SH5PCI_WRITE(PINTM, ~0);
188 pr_debug("Switching on all error interrupts\n");
193 static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
196 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
200 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
203 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
206 *val = SH5PCI_READ(PDR);
210 return PCIBIOS_SUCCESSFUL;
213 static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
216 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
220 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
223 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
226 SH5PCI_WRITE(PDR, val);
230 return PCIBIOS_SUCCESSFUL;
233 static struct pci_ops pci_config_ops = {
235 .write = sh5pci_write,
238 /* Everything hangs off this */
239 static struct pci_bus *pci_root_bus;
242 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
244 pr_debug("swizzle for dev %d on bus %d slot %d pin is %d\n",
245 dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
246 return PCI_SLOT(dev->devfn);
249 static inline u8 bridge_swizzle(u8 pin, u8 slot)
251 return (((pin-1) + slot) % 4) + 1;
254 u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
256 if (dev->bus->number != 0) {
259 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
260 /* Move up the chain of bridges. */
261 dev = dev->bus->self;
262 } while (dev->bus->self);
265 /* The slot is the slot of the last bridge. */
268 return PCI_SLOT(dev->devfn);
271 /* This needs to be shunted out of here into the board specific bit */
273 static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
277 /* The complication here is that the PCI IRQ lines from the Cayman's 2
278 5V slots get into the CPU via a different path from the IRQ lines
279 from the 3 3.3V slots. Thus, we have to detect whether the card's
280 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
281 at the point where we cross from 5V to 3.3V is not the normal case.
283 The added complication is that we don't know that the 5V slots are
284 always bus 2, because a card containing a PCI-PCI bridge may be
285 plugged into a 3.3V slot, and this changes the bus numbering.
287 Also, the Cayman has an intermediate PCI bus that goes a custom
288 expansion board header (and to the secondary bridge). This bus has
289 never been used in practice.
291 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
292 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge.
301 while (dev->bus->number > 0) {
303 slot = path[i].slot = PCI_SLOT(dev->devfn);
304 pin = path[i].pin = bridge_swizzle(pin, slot);
305 dev = dev->bus->self;
307 if (i > 3) panic("PCI path to root bus too long!\n");
310 slot = PCI_SLOT(dev->devfn);
311 /* This is the slot on bus 0 through which the device is eventually
314 /* Now work back up. */
315 if ((slot < 3) || (i == 0)) {
316 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
318 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
324 panic("PCI expansion bus device found - not handled!\n");
331 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
332 result = IRQ_P2INTA + (pin - 1);
334 /* IRQ for 2ary PCI-PCI bridge : unused */
343 static irqreturn_t pcish5_err_irq(int irq, void *dev_id)
345 struct pt_regs *regs = get_irq_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 static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
374 printk("SERR IRQ\n");
380 pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
381 struct resource *memr)
383 struct resource io_res, mem_res;
385 struct pci_dev *bridge = bus->self;
386 struct list_head *ln;
389 return; /* host bridge, nothing to do */
391 /* set reasonable default locations for pcibios_align_resource */
392 io_res.start = PCIBIOS_MIN_IO;
393 mem_res.start = PCIBIOS_MIN_MEM;
395 io_res.end = io_res.start;
396 mem_res.end = mem_res.start;
398 /* Collect information about how our direct children are layed out. */
399 for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
403 /* Skip bridges for now */
404 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
407 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
411 memcpy(&res, &dev->resource[i], sizeof(res));
412 size = res.end - res.start + 1;
414 if (res.flags & IORESOURCE_IO) {
415 res.start = io_res.end;
416 pcibios_align_resource(dev, &res, size, 0);
417 io_res.end = res.start + size;
418 } else if (res.flags & IORESOURCE_MEM) {
419 res.start = mem_res.end;
420 pcibios_align_resource(dev, &res, size, 0);
421 mem_res.end = res.start + size;
426 /* And for all of the subordinate busses. */
427 for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
428 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
430 /* turn the ending locations into sizes (subtract start) */
431 io_res.end -= io_res.start;
432 mem_res.end -= mem_res.start;
434 /* Align the sizes up by bridge rules */
435 io_res.end = ALIGN(io_res.end, 4*1024) - 1;
436 mem_res.end = ALIGN(mem_res.end, 1*1024*1024) - 1;
438 /* Adjust the bridge's allocation requirements */
439 bridge->resource[0].end = bridge->resource[0].start + io_res.end;
440 bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
442 bridge->resource[PCI_BRIDGE_RESOURCES].end =
443 bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
444 bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
445 bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
447 /* adjust parent's resource requirements */
449 ior->end = ALIGN(ior->end, 4*1024);
450 ior->end += io_res.end;
454 memr->end = ALIGN(memr->end, 1*1024*1024);
455 memr->end += mem_res.end;
459 static void __init pcibios_size_bridges(void)
461 struct resource io_res, mem_res;
463 memset(&io_res, 0, sizeof(io_res));
464 memset(&mem_res, 0, sizeof(mem_res));
466 pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
469 static int __init pcibios_init(void)
471 if (request_irq(IRQ_ERR, pcish5_err_irq,
472 IRQF_DISABLED, "PCI Error",NULL) < 0) {
473 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
477 if (request_irq(IRQ_SERR, pcish5_serr_irq,
478 IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
479 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
483 /* The pci subsytem needs to know where memory is and how much
484 * of it there is. I've simply made these globals. A better mechanism
485 * is probably needed.
487 sh5pci_init(__pa(memory_start),
488 __pa(memory_end) - __pa(memory_start));
490 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
491 pcibios_size_bridges();
492 pci_assign_unassigned_resources();
493 pci_fixup_irqs(no_swizzle, map_cayman_irq);
498 subsys_initcall(pcibios_init);
500 void __init pcibios_fixup_bus(struct pci_bus *bus)
502 struct pci_dev *dev = bus->self;
509 &dev->resource[PCI_BRIDGE_RESOURCES+i];
510 bus->resource[i]->name = bus->name;
512 bus->resource[0]->flags |= IORESOURCE_IO;
513 bus->resource[1]->flags |= IORESOURCE_MEM;
515 /* For now, propagate host limits to the bus;
516 * we'll adjust them later. */
519 bus->resource[0]->end = 64*1024 - 1 ;
520 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
521 bus->resource[0]->start = PCIBIOS_MIN_IO;
522 bus->resource[1]->start = PCIBIOS_MIN_MEM;
524 bus->resource[0]->end = 0;
525 bus->resource[1]->end = 0;
526 bus->resource[0]->start =0;
527 bus->resource[1]->start = 0;
529 /* Turn off downstream PF memory address range by default */
530 bus->resource[2]->start = 1024*1024;
531 bus->resource[2]->end = bus->resource[2]->start - 1;