2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
7 * Support functions for the SH5 PCI hardware.
10 #include <linux/config.h>
11 #include <linux/kernel.h>
12 #include <linux/smp.h>
13 #include <linux/smp_lock.h>
14 #include <linux/init.h>
15 #include <linux/errno.h>
16 #include <linux/pci.h>
17 #include <linux/delay.h>
18 #include <linux/types.h>
20 #include <linux/irq.h>
23 #include <asm/hardware.h>
29 # define dprintk(x...) printk(KERN_DEBUG x)
31 # define dprintk(x...) do { } while (0)
34 static unsigned long pcicr_virt;
35 unsigned long pciio_virt;
37 static void __init pci_fixup_ide_bases(struct pci_dev *d)
42 * PCI IDE controllers use non-standard I/O port decoding, respect it.
44 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
46 printk("PCI: IDE base address fixup for %s\n", d->slot_name);
48 struct resource *r = &d->resource[i];
49 if ((r->start & ~0x80) == 0x374) {
56 /* Add future fixups here... */
57 struct pci_fixup pcibios_fixups[] = {
58 { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
62 char * __init pcibios_setup(char *str)
67 /* Rounds a number UP to the nearest power of two. Used for
68 * sizing the PCI window.
70 static u32 __init r2p2(u32 num)
86 /* If the original number isn't a power of 2, round it up */
93 extern unsigned long long memory_start, memory_end;
95 int __init sh5pci_init(unsigned memStart, unsigned memSize)
100 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
102 panic("Unable to remap PCICR\n");
105 pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
107 panic("Unable to remap PCIIO\n");
110 dprintk("Register base addres is 0x%08lx\n", pcicr_virt);
112 /* Clear snoop registers */
113 SH5PCI_WRITE(CSCR0, 0);
114 SH5PCI_WRITE(CSCR1, 0);
116 dprintk("Wrote to reg\n");
118 /* Switch off interrupts */
119 SH5PCI_WRITE(INTM, 0);
120 SH5PCI_WRITE(AINTM, 0);
121 SH5PCI_WRITE(PINTM, 0);
123 /* Set bus active, take it out of reset */
124 uval = SH5PCI_READ(CR);
126 /* Set command Register */
127 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM );
129 uval=SH5PCI_READ(CR);
130 dprintk("CR is actually 0x%08x\n",uval);
132 /* Allow it to be a master */
133 /* NB - WE DISABLE I/O ACCESS to stop overlap */
134 /* set WAIT bit to enable stepping, an attempt to improve stability */
135 SH5PCI_WRITE_SHORT(CSR_CMD,
136 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
139 ** Set translation mapping memory in order to convert the address
140 ** used for the main bus, to the PCI internal address.
142 SH5PCI_WRITE(MBR,0x40000000);
144 /* Always set the max size 512M */
145 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
148 ** I/O addresses are mapped at internal PCI specific address
149 ** as is described into the configuration bridge table.
150 ** These are changed to 0, to allow cards that have legacy
151 ** io such as vga to function correctly. We set the SH5 IOBAR to
152 ** 256K, which is a bit big as we can only have 64K of address space
155 SH5PCI_WRITE(IOBR,0x0);
157 dprintk("PCI:Writing 0x%08x to IOBR\n",0);
159 /* Set up a 256K window. Totally pointless waste of address space */
160 SH5PCI_WRITE(IOBMR,0);
161 dprintk("PCI:Writing 0x%08x to IOBMR\n",0);
163 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally,
164 * we would want to map the I/O region somewhere, but it is so big this is not
167 SH5PCI_WRITE(CSR_IBAR0,~0);
168 /* Set memory size value */
169 memSize = memory_end - memory_start;
171 /* Now we set up the mbars so the PCI bus can see the memory of the machine */
172 if (memSize < (1024 * 1024)) {
173 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
178 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
179 SH5PCI_WRITE(LSR0, lsr0);
181 dprintk("PCI:Writing 0x%08x to LSR0\n",lsr0);
184 SH5PCI_WRITE(CSR_MBAR0, memory_start);
185 SH5PCI_WRITE(LAR0, memory_start);
188 SH5PCI_WRITE(CSR_MBAR1,0);
189 SH5PCI_WRITE(LAR1,0);
190 SH5PCI_WRITE(LSR1,0);
192 dprintk("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);
193 dprintk("PCI:Writing 0x%08llx to LAR0\n",memory_start);
195 /* Enable the PCI interrupts on the device */
198 SH5PCI_WRITE(INTM, ~0);
199 SH5PCI_WRITE(AINTM, ~0);
200 SH5PCI_WRITE(PINTM, ~0);
203 dprintk("Switching on all error interrupts\n");
210 /* Write to config register */
211 static int sh5pci_read_config_byte(struct pci_dev *dev, int where,
214 SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
216 *val = SH5PCI_READ_BYTE(PDR + (where & 3));
218 return PCIBIOS_SUCCESSFUL;
221 static int sh5pci_read_config_word(struct pci_dev *dev, int where,
224 SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
226 *val = SH5PCI_READ_SHORT(PDR + (where & 2));
229 return PCIBIOS_SUCCESSFUL;
232 static int sh5pci_read_config_dword(struct pci_dev *dev, int where,
235 SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
237 *val = SH5PCI_READ(PDR);
239 return PCIBIOS_SUCCESSFUL;
242 static int sh5pci_write_config_byte(struct pci_dev *dev, int where,
245 SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
247 SH5PCI_WRITE_BYTE(PDR + (where & 3), val);
250 return PCIBIOS_SUCCESSFUL;
254 static int sh5pci_write_config_word(struct pci_dev *dev, int where,
257 SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
259 SH5PCI_WRITE_SHORT(PDR + (where & 2), val);
261 return PCIBIOS_SUCCESSFUL;
264 static int sh5pci_write_config_dword(struct pci_dev *dev, int where,
267 SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
269 SH5PCI_WRITE(PDR, val);
271 return PCIBIOS_SUCCESSFUL;
275 static struct pci_ops pci_config_ops = {
276 sh5pci_read_config_byte,
277 sh5pci_read_config_word,
278 sh5pci_read_config_dword,
279 sh5pci_write_config_byte,
280 sh5pci_write_config_word,
281 sh5pci_write_config_dword
284 /* Everything hangs off this */
285 static struct pci_bus *pci_root_bus;
288 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
290 dprintk("swizzle for dev %d on bus %d slot %d pin is %d\n",
291 dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
292 return PCI_SLOT(dev->devfn);
295 static inline u8 bridge_swizzle(u8 pin, u8 slot)
297 return (((pin-1) + slot) % 4) + 1;
300 u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
302 if (dev->bus->number != 0) {
305 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
306 /* Move up the chain of bridges. */
307 dev = dev->bus->self;
308 } while (dev->bus->self);
311 /* The slot is the slot of the last bridge. */
314 return PCI_SLOT(dev->devfn);
317 /* This needs to be shunted out of here into the board specific bit */
319 static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
323 /* The complication here is that the PCI IRQ lines from the Cayman's 2
324 5V slots get into the CPU via a different path from the IRQ lines
325 from the 3 3.3V slots. Thus, we have to detect whether the card's
326 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
327 at the point where we cross from 5V to 3.3V is not the normal case.
329 The added complication is that we don't know that the 5V slots are
330 always bus 2, because a card containing a PCI-PCI bridge may be
331 plugged into a 3.3V slot, and this changes the bus numbering.
333 Also, the Cayman has an intermediate PCI bus that goes a custom
334 expansion board header (and to the secondary bridge). This bus has
335 never been used in practice.
337 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
338 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge.
348 while (dev->bus->number > 0) {
350 slot = path[i].slot = PCI_SLOT(dev->devfn);
351 pin = path[i].pin = bridge_swizzle(pin, slot);
352 dev = dev->bus->self;
354 if (i > 3) panic("PCI path to root bus too long!\n");
357 slot = PCI_SLOT(dev->devfn);
358 /* This is the slot on bus 0 through which the device is eventually
361 /* Now work back up. */
362 if ((slot < 3) || (i == 0)) {
363 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
365 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
371 panic("PCI expansion bus device found - not handled!\n");
378 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
379 result = IRQ_P2INTA + (pin - 1);
381 /* IRQ for 2ary PCI-PCI bridge : unused */
391 void print_resource(struct resource *r)
396 //printk("Resource %s\n",r->name);
397 printk("Start 0x%lx end 0x%lx\n",r->start,r->end);
400 void print_set_ranges_data(struct pbus_set_ranges_data *ranges)
404 printk("NO RANGES\n");
408 printk("io_start is 0x%lx\n", ranges->io_start);
409 printk("io_end is 0x%lx\n", ranges->io_end);
410 printk("mem_start is 0x%lx\n", ranges->mem_start);
411 printk("mem_end is 0x%lx\n", ranges->mem_end);
416 pcibios_fixup_pbus_ranges(struct pci_bus *bus,
417 struct pbus_set_ranges_data *ranges)
422 dprintk("%s, bus number %d\n",__FUNCTION__,bus->number);
424 print_set_ranges_data(ranges);
426 for (i = 0; i < 2; i++)
427 print_resource(bus->resource[i]);
431 void pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
433 unsigned pci_int, pci_air, pci_cir, pci_aint;
435 pci_int = SH5PCI_READ(INT);
436 pci_cir = SH5PCI_READ(CIR);
437 pci_air = SH5PCI_READ(AIR);
440 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
441 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
442 printk("PCI AIR -> 0x%x\n", pci_air);
443 printk("PCI CIR -> 0x%x\n", pci_cir);
444 SH5PCI_WRITE(INT, ~0);
447 pci_aint = SH5PCI_READ(AINT);
449 printk("PCI ARB INTERRUPT!\n");
450 printk("PCI AINT -> 0x%x\n", pci_aint);
451 printk("PCI AIR -> 0x%x\n", pci_air);
452 printk("PCI CIR -> 0x%x\n", pci_cir);
453 SH5PCI_WRITE(AINT, ~0);
459 void pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
461 printk("SERR IRQ\n");
465 #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
468 pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
470 struct pbus_set_ranges_data inner;
472 struct pci_dev *bridge = bus->self;
473 struct list_head *ln;
476 return; /* host bridge, nothing to do */
478 /* set reasonable default locations for pcibios_align_resource */
479 inner.io_start = PCIBIOS_MIN_IO;
480 inner.mem_start = PCIBIOS_MIN_MEM;
481 inner.io_end = inner.io_start;
482 inner.mem_end = inner.mem_start;
484 /* Collect information about how our direct children are layed out. */
485 for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
489 /* Skip bridges for now */
490 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
493 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
497 memcpy(&res, &dev->resource[i], sizeof(res));
498 size = res.end - res.start + 1;
500 if (res.flags & IORESOURCE_IO) {
501 res.start = inner.io_end;
502 pcibios_align_resource(dev, &res, size, 0);
503 inner.io_end = res.start + size;
504 } else if (res.flags & IORESOURCE_MEM) {
505 res.start = inner.mem_end;
506 pcibios_align_resource(dev, &res, size, 0);
507 inner.mem_end = res.start + size;
512 /* And for all of the subordinate busses. */
513 for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
514 pcibios_size_bridge(pci_bus_b(ln), &inner);
516 /* turn the ending locations into sizes (subtract start) */
517 inner.io_end -= inner.io_start;
518 inner.mem_end -= inner.mem_start;
520 /* Align the sizes up by bridge rules */
521 inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1;
522 inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1;
524 /* Adjust the bridge's allocation requirements */
525 bridge->resource[0].end = bridge->resource[0].start + inner.io_end;
526 bridge->resource[1].end = bridge->resource[1].start + inner.mem_end;
528 bridge->resource[PCI_BRIDGE_RESOURCES].end =
529 bridge->resource[PCI_BRIDGE_RESOURCES].start + inner.io_end;
530 bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
531 bridge->resource[PCI_BRIDGE_RESOURCES+1].start + inner.mem_end;
533 /* adjust parent's resource requirements */
535 outer->io_end = ROUND_UP(outer->io_end, 4*1024);
536 outer->io_end += inner.io_end;
538 outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
539 outer->mem_end += inner.mem_end;
546 pcibios_size_bridges(void)
548 struct pbus_set_ranges_data outer;
550 memset(&outer,0,sizeof(outer));
551 pcibios_size_bridge(pci_root_bus,&outer);
555 common_init_pci(void)
557 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
558 pcibios_size_bridges();
559 pci_assign_unassigned_resources();
560 pci_fixup_irqs(no_swizzle, map_cayman_irq);
561 // pci_set_bus_ranges();
564 void __init pcibios_init(void)
567 if (request_irq(IRQ_ERR, pcish5_err_irq,
568 SA_INTERRUPT, "PCI Error",NULL) < 0) {
569 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
574 if (request_irq(IRQ_SERR, pcish5_serr_irq,
575 SA_INTERRUPT, "PCI SERR interrupt", NULL) < 0) {
576 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
581 /* The pci subsytem needs to know where memory is and how much
582 * of it there is. I've simply made these globals. A better mechanism
583 * is probably needed.
585 sh5pci_init(__pa(memory_start),
586 __pa(memory_end) - __pa(memory_start));
592 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
594 pci_assign_unassigned_resources();
596 pci_fixup_irqs(no_swizzle, map_cayman_irq);
598 pci_set_bus_ranges();
603 void __init pcibios_fixup_bus(struct pci_bus *bus)
605 struct pci_dev *dev = bus->self;
612 &dev->resource[PCI_BRIDGE_RESOURCES+i];
613 bus->resource[i]->name = bus->name;
615 bus->resource[0]->flags |= IORESOURCE_IO;
616 bus->resource[1]->flags |= IORESOURCE_MEM;
618 /* For now, propogate host limits to the bus;
619 * we'll adjust them later. */
622 bus->resource[0]->end = 64*1024 - 1 ;
623 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
624 bus->resource[0]->start = PCIBIOS_MIN_IO;
625 bus->resource[1]->start = PCIBIOS_MIN_MEM;
627 bus->resource[0]->end = 0
628 bus->resource[1]->end = 0
629 bus->resource[0]->start =0
630 bus->resource[1]->start = 0;
634 dprintk("in fixup bus resource 0 is:\n");
635 print_resource(bus->resource[0]);
636 dprintk("in fixup bus resource 1 is:\n");
637 print_resource(bus->resource[1]);
640 /* Turn off downstream PF memory address range by default */
641 bus->resource[2]->start = 1024*1024;
642 bus->resource[2]->end = bus->resource[2]->start - 1;