This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / sh64 / kernel / pci_sh5.c
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", d->slot_name);
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
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 },
55         { 0 }
56 };
57
58 char * __init pcibios_setup(char *str)
59 {
60         return str;
61 }
62
63 /* Rounds a number UP to the nearest power of two. Used for
64  * sizing the PCI window.
65  */
66 static u32 __init r2p2(u32 num)
67 {
68         int i = 31;
69         u32 tmp = num;
70
71         if (num == 0)
72                 return 0;
73
74         do {
75                 if (tmp & (1 << 31))
76                         break;
77                 i--;
78                 tmp <<= 1;
79         } while (i >= 0);
80
81         tmp = 1 << i;
82         /* If the original number isn't a power of 2, round it up */
83         if (tmp != num)
84                 tmp <<= 1;
85
86         return tmp;
87 }
88
89 extern unsigned long long memory_start, memory_end;
90
91 int __init sh5pci_init(unsigned memStart, unsigned memSize)
92 {
93         u32 lsr0;
94         u32 uval;
95
96         pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
97         if (!pcicr_virt) {
98                 panic("Unable to remap PCICR\n");
99         }
100
101         pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
102         if (!pciio_virt) {
103                 panic("Unable to remap PCIIO\n");
104         }
105
106         pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
107
108         /* Clear snoop registers */
109         SH5PCI_WRITE(CSCR0, 0);
110         SH5PCI_WRITE(CSCR1, 0);
111
112         pr_debug("Wrote to reg\n");
113
114         /* Switch off interrupts */
115         SH5PCI_WRITE(INTM,  0);
116         SH5PCI_WRITE(AINTM, 0);
117         SH5PCI_WRITE(PINTM, 0);
118
119         /* Set bus active, take it out of reset */
120         uval = SH5PCI_READ(CR);
121
122         /* Set command Register */
123         SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
124
125         uval=SH5PCI_READ(CR);
126         pr_debug("CR is actually 0x%08x\n",uval);
127
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);
133
134         /*
135         ** Set translation mapping memory in order to convert the address
136         ** used for the main bus, to the PCI internal address.
137         */
138         SH5PCI_WRITE(MBR,0x40000000);
139
140         /* Always set the max size 512M */
141         SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
142
143         /*
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
149         */
150
151         SH5PCI_WRITE(IOBR,0x0);
152
153         pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
154
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);
158
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
161          * that easy!
162          */
163         SH5PCI_WRITE(CSR_IBAR0,~0);
164         /* Set memory size value */
165         memSize = memory_end - memory_start;
166
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);
170                 return -EINVAL;
171         }
172
173         /* Set LSR 0 */
174         lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
175         SH5PCI_WRITE(LSR0, lsr0);
176
177         pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
178
179         /* Set MBAR 0 */
180         SH5PCI_WRITE(CSR_MBAR0, memory_start);
181         SH5PCI_WRITE(LAR0, memory_start);
182
183         SH5PCI_WRITE(CSR_MBAR1,0);
184         SH5PCI_WRITE(LAR1,0);
185         SH5PCI_WRITE(LSR1,0);
186
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);
189
190         /* Enable the PCI interrupts on the device */
191         SH5PCI_WRITE(INTM,  ~0);
192         SH5PCI_WRITE(AINTM, ~0);
193         SH5PCI_WRITE(PINTM, ~0);
194
195         pr_debug("Switching on all error interrupts\n");
196
197         return(0);
198 }
199
200 static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
201                         int size, u32 *val)
202 {
203         SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
204
205         switch (size) {
206                 case 1:
207                         *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
208                         break;
209                 case 2:
210                         *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
211                         break;
212                 case 4:
213                         *val = SH5PCI_READ(PDR);
214                         break;
215         }
216
217         return PCIBIOS_SUCCESSFUL;
218 }
219
220 static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
221                          int size, u32 val)
222 {
223         SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
224
225         switch (size) {
226                 case 1:
227                         SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
228                         break;
229                 case 2:
230                         SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
231                         break;
232                 case 4:
233                         SH5PCI_WRITE(PDR, val);
234                         break;
235         }
236
237         return PCIBIOS_SUCCESSFUL;
238 }
239
240 static struct pci_ops pci_config_ops = {
241         .read =         sh5pci_read,
242         .write =        sh5pci_write,
243 };
244
245 /* Everything hangs off this */
246 static struct pci_bus *pci_root_bus;
247
248
249 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
250 {
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);
254 }
255
256 static inline u8 bridge_swizzle(u8 pin, u8 slot)
257 {
258         return (((pin-1) + slot) % 4) + 1;
259 }
260
261 u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
262 {
263         if (dev->bus->number != 0) {
264                 u8 pin = *pinp;
265                 do {
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);
270                 *pinp = pin;
271
272                 /* The slot is the slot of the last bridge. */
273         }
274
275         return PCI_SLOT(dev->devfn);
276 }
277
278 /* This needs to be shunted out of here into the board specific bit */
279
280 static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
281 {
282         int result = -1;
283
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.
289
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.
293
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.
297
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.
300            */
301
302         struct slot_pin {
303                 int slot;
304                 int pin;
305         } path[4];
306         int i=0;
307
308         while (dev->bus->number > 0) {
309
310                 slot = path[i].slot = PCI_SLOT(dev->devfn);
311                 pin = path[i].pin = bridge_swizzle(pin, slot);
312                 dev = dev->bus->self;
313                 i++;
314                 if (i > 3) panic("PCI path to root bus too long!\n");
315         }
316
317         slot = PCI_SLOT(dev->devfn);
318         /* This is the slot on bus 0 through which the device is eventually
319            reachable. */
320
321         /* Now work back up. */
322         if ((slot < 3) || (i == 0)) {
323                 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
324                    swizzle now. */
325                 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
326         } else {
327                 i--;
328                 slot = path[i].slot;
329                 pin  = path[i].pin;
330                 if (slot > 0) {
331                         panic("PCI expansion bus device found - not handled!\n");
332                 } else {
333                         if (i > 0) {
334                                 /* 5V slots */
335                                 i--;
336                                 slot = path[i].slot;
337                                 pin  = path[i].pin;
338                                 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
339                                 result = IRQ_P2INTA + (pin - 1);
340                         } else {
341                                 /* IRQ for 2ary PCI-PCI bridge : unused */
342                                 result = -1;
343                         }
344                 }
345         }
346
347         return result;
348 }
349
350 irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
351 {
352         unsigned pci_int, pci_air, pci_cir, pci_aint;
353
354         pci_int = SH5PCI_READ(INT);
355         pci_cir = SH5PCI_READ(CIR);
356         pci_air = SH5PCI_READ(AIR);
357
358         if (pci_int) {
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);
364         }
365
366         pci_aint = SH5PCI_READ(AINT);
367         if (pci_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);
373         }
374
375         return IRQ_HANDLED;
376 }
377
378 irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
379 {
380         printk("SERR IRQ\n");
381
382         return IRQ_NONE;
383 }
384
385 #define ROUND_UP(x, a)          (((x) + (a) - 1) & ~((a) - 1))
386
387 static void __init
388 pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
389                     struct resource *memr)
390 {
391         struct resource io_res, mem_res;
392         struct pci_dev *dev;
393         struct pci_dev *bridge = bus->self;
394         struct list_head *ln;
395
396         if (!bridge)
397                 return; /* host bridge, nothing to do */
398
399         /* set reasonable default locations for pcibios_align_resource */
400         io_res.start = PCIBIOS_MIN_IO;
401         mem_res.start = PCIBIOS_MIN_MEM;
402
403         io_res.end = io_res.start;
404         mem_res.end = mem_res.start;
405
406         /* Collect information about how our direct children are layed out. */
407         for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
408                 int i;
409                 dev = pci_dev_b(ln);
410
411                 /* Skip bridges for now */
412                 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
413                         continue;
414
415                 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
416                         struct resource res;
417                         unsigned long size;
418
419                         memcpy(&res, &dev->resource[i], sizeof(res));
420                         size = res.end - res.start + 1;
421
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;
430                         }
431                 }
432         }
433
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);
437
438         /* turn the ending locations into sizes (subtract start) */
439         io_res.end -= io_res.start;
440         mem_res.end -= mem_res.start;
441
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;
445
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;
449
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;
454
455         /* adjust parent's resource requirements */
456         if (ior) {
457                 ior->end = ROUND_UP(ior->end, 4*1024);
458                 ior->end += io_res.end;
459         }
460
461         if (memr) {
462                 memr->end = ROUND_UP(memr->end, 1*1024*1024);
463                 memr->end += mem_res.end;
464         }
465 }
466
467 #undef ROUND_UP
468
469 static void __init pcibios_size_bridges(void)
470 {
471         struct resource io_res, mem_res;
472
473         memset(&io_res, 0, sizeof(io_res));
474         memset(&mem_res, 0, sizeof(mem_res));
475
476         pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
477 }
478
479 static int __init pcibios_init(void)
480 {
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");
484                 return -EINVAL;
485         }
486
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");
490                 return -EINVAL;
491         }
492
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.
496          */
497         sh5pci_init(__pa(memory_start),
498                      __pa(memory_end) - __pa(memory_start));
499
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);
504
505         return 0;
506 }
507
508 subsys_initcall(pcibios_init);
509
510 void __init pcibios_fixup_bus(struct pci_bus *bus)
511 {
512         struct pci_dev *dev = bus->self;
513         int i;
514
515 #if 1
516         if(dev) {
517                 for(i=0; i<3; i++) {
518                         bus->resource[i] =
519                                 &dev->resource[PCI_BRIDGE_RESOURCES+i];
520                         bus->resource[i]->name = bus->name;
521                 }
522                 bus->resource[0]->flags |= IORESOURCE_IO;
523                 bus->resource[1]->flags |= IORESOURCE_MEM;
524
525                 /* For now, propogate host limits to the bus;
526                  * we'll adjust them later. */
527
528 #if 1
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;
533 #else
534                 bus->resource[0]->end = 0
535                 bus->resource[1]->end = 0
536                 bus->resource[0]->start =0
537                   bus->resource[1]->start = 0;
538 #endif
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;
542         }
543 #endif
544
545 }
546