import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / sh64 / kernel / pci_sh5.c
1 /* 
2  * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3  *
4  * May be copied or modified under the terms of the GNU General Public
5  * License.  See linux/COPYING for more information.                            
6  *
7  * Support functions for the SH5 PCI hardware.
8  */
9
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>
19 #include <asm/pci.h>
20 #include <linux/irq.h>
21
22 #include <asm/io.h>
23 #include <asm/hardware.h>
24 #include "pci_sh5.h"
25
26 #undef DEBUG
27
28 #ifdef DEBUG
29 #  define dprintk(x...)  printk(KERN_DEBUG x)
30 #else
31 #  define dprintk(x...)  do { } while (0)
32 #endif /* DEBUG */
33
34 static unsigned long pcicr_virt;
35 unsigned long pciio_virt;
36
37 static void __init pci_fixup_ide_bases(struct pci_dev *d)
38 {
39         int i;
40
41         /*
42          * PCI IDE controllers use non-standard I/O port decoding, respect it.
43          */
44         if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
45                 return;
46         printk("PCI: IDE base address fixup for %s\n", d->slot_name);
47         for(i=0; i<4; i++) {
48                 struct resource *r = &d->resource[i];
49                 if ((r->start & ~0x80) == 0x374) {
50                         r->start |= 2;
51                         r->end = r->start;
52                 }
53         }
54 }
55
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 },
59         { 0 }
60 };
61
62 char * __init pcibios_setup(char *str)
63 {
64         return str;
65 }
66
67 /* Rounds a number UP to the nearest power of two. Used for
68  * sizing the PCI window.
69  */
70 static u32 __init r2p2(u32 num)
71 {
72         int i = 31;
73         u32 tmp = num;
74
75         if (num == 0)
76                 return 0;
77
78         do {
79                 if (tmp & (1 << 31))
80                         break;
81                 i--;
82                 tmp <<= 1;
83         } while (i >= 0);
84
85         tmp = 1 << i;
86         /* If the original number isn't a power of 2, round it up */
87         if (tmp != num)
88                 tmp <<= 1;
89
90         return tmp;
91 }
92
93 extern unsigned long long memory_start, memory_end;
94
95 int __init sh5pci_init(unsigned memStart, unsigned memSize)
96 {
97         u32 lsr0;
98         u32 uval;
99
100         pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
101         if (!pcicr_virt) {
102                 panic("Unable to remap PCICR\n");
103         }
104
105         pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
106         if (!pciio_virt) {
107                 panic("Unable to remap PCIIO\n");
108         }
109
110         dprintk("Register base addres is 0x%08lx\n", pcicr_virt);
111
112         /* Clear snoop registers */
113         SH5PCI_WRITE(CSCR0, 0);
114         SH5PCI_WRITE(CSCR1, 0);
115
116         dprintk("Wrote to reg\n");
117
118         /* Switch off interrupts */
119         SH5PCI_WRITE(INTM,  0);
120         SH5PCI_WRITE(AINTM, 0);
121         SH5PCI_WRITE(PINTM, 0);
122
123         /* Set bus active, take it out of reset */
124         uval = SH5PCI_READ(CR);
125
126         /* Set command Register */
127         SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM );
128
129         uval=SH5PCI_READ(CR);
130         dprintk("CR is actually 0x%08x\n",uval);
131
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);
137
138         /* 
139         ** Set translation mapping memory in order to convert the address
140         ** used for the main bus, to the PCI internal address.
141         */
142         SH5PCI_WRITE(MBR,0x40000000);
143
144         /* Always set the max size 512M */
145         SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
146
147         /* 
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
153         */
154
155         SH5PCI_WRITE(IOBR,0x0);
156         
157         dprintk("PCI:Writing 0x%08x to IOBR\n",0);
158
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);
162
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
165          * that easy!
166          */
167         SH5PCI_WRITE(CSR_IBAR0,~0);
168         /* Set memory size value */
169         memSize = memory_end - memory_start;
170
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);
174                 return(-1);
175         }
176
177         /* Set LSR 0 */
178         lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
179         SH5PCI_WRITE(LSR0, lsr0);
180
181         dprintk("PCI:Writing 0x%08x to LSR0\n",lsr0);
182
183         /* Set MBAR 0 */
184         SH5PCI_WRITE(CSR_MBAR0, memory_start);
185         SH5PCI_WRITE(LAR0, memory_start);
186
187
188         SH5PCI_WRITE(CSR_MBAR1,0);
189         SH5PCI_WRITE(LAR1,0);
190         SH5PCI_WRITE(LSR1,0);
191
192         dprintk("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);         
193         dprintk("PCI:Writing 0x%08llx to LAR0\n",memory_start);         
194
195         /* Enable the PCI interrupts on the device */
196
197 #if 1
198         SH5PCI_WRITE(INTM,  ~0);
199         SH5PCI_WRITE(AINTM, ~0);
200         SH5PCI_WRITE(PINTM, ~0);
201 #endif
202
203         dprintk("Switching on all error interrupts\n");
204
205         return(0);
206 }
207
208
209
210 /* Write to config register */
211 static int sh5pci_read_config_byte(struct pci_dev *dev, int where,
212                                     u8 * val)
213 {
214         SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
215
216         *val = SH5PCI_READ_BYTE(PDR + (where & 3));
217
218         return PCIBIOS_SUCCESSFUL;
219 }
220
221 static int sh5pci_read_config_word(struct pci_dev *dev, int where,
222                                     u16 * val)
223 {
224         SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
225
226         *val = SH5PCI_READ_SHORT(PDR + (where & 2));
227
228
229         return PCIBIOS_SUCCESSFUL;
230 }
231
232 static int sh5pci_read_config_dword(struct pci_dev *dev, int where,
233                                      u32 * val)
234 {
235         SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
236
237         *val = SH5PCI_READ(PDR);
238
239         return PCIBIOS_SUCCESSFUL;
240 }
241
242 static int sh5pci_write_config_byte(struct pci_dev *dev, int where,
243                                      u8 val)
244 {
245         SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
246
247         SH5PCI_WRITE_BYTE(PDR + (where & 3), val);
248
249
250         return PCIBIOS_SUCCESSFUL;
251 }
252
253
254 static int sh5pci_write_config_word(struct pci_dev *dev, int where,
255                                      u16 val)
256 {
257         SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
258
259         SH5PCI_WRITE_SHORT(PDR + (where & 2), val);
260
261         return PCIBIOS_SUCCESSFUL;
262 }
263
264 static int sh5pci_write_config_dword(struct pci_dev *dev, int where,
265                                       u32 val)
266 {
267         SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
268
269         SH5PCI_WRITE(PDR, val);
270
271         return PCIBIOS_SUCCESSFUL;
272 }
273
274
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
282 };
283
284 /* Everything hangs off this */
285 static struct pci_bus *pci_root_bus;
286
287
288 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
289 {
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);
293 }
294
295 static inline u8 bridge_swizzle(u8 pin, u8 slot) 
296 {
297         return (((pin-1) + slot) % 4) + 1;
298 }
299
300 u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
301 {
302         if (dev->bus->number != 0) {
303                 u8 pin = *pinp;
304                 do {
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);
309                 *pinp = pin;
310
311                 /* The slot is the slot of the last bridge. */
312         }
313
314         return PCI_SLOT(dev->devfn);
315 }
316
317 /* This needs to be shunted out of here into the board specific bit */
318
319 static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
320 {
321         int result = -1;
322
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.
328
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.
332
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.
336
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.
339            */
340
341         struct slot_pin {
342                 int slot;
343                 int pin;
344         } path[4];
345         int i=0;
346         int base;
347
348         while (dev->bus->number > 0) {
349
350                 slot = path[i].slot = PCI_SLOT(dev->devfn);
351                 pin = path[i].pin = bridge_swizzle(pin, slot);
352                 dev = dev->bus->self;
353                 i++;
354                 if (i > 3) panic("PCI path to root bus too long!\n");
355         }
356
357         slot = PCI_SLOT(dev->devfn);
358         /* This is the slot on bus 0 through which the device is eventually
359            reachable. */
360
361         /* Now work back up. */
362         if ((slot < 3) || (i == 0)) {
363                 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
364                    swizzle now. */
365                 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
366         } else {
367                 i--;
368                 slot = path[i].slot;
369                 pin  = path[i].pin;
370                 if (slot > 0) {
371                         panic("PCI expansion bus device found - not handled!\n");
372                 } else {
373                         if (i > 0) {
374                                 /* 5V slots */
375                                 i--;
376                                 slot = path[i].slot;
377                                 pin  = path[i].pin;
378                                 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
379                                 result = IRQ_P2INTA + (pin - 1);
380                         } else {
381                                 /* IRQ for 2ary PCI-PCI bridge : unused */
382                                 result = -1;
383                         }
384                 }
385         }
386         
387         return result;
388 }
389
390 #ifdef DEBUG
391 void print_resource(struct resource *r) 
392 {
393         if (r == NULL)
394                 return;
395
396         //printk("Resource %s\n",r->name);
397         printk("Start 0x%lx end 0x%lx\n",r->start,r->end);
398 }
399
400 void print_set_ranges_data(struct pbus_set_ranges_data *ranges)
401 {
402
403         if (!ranges) {
404                 printk("NO RANGES\n");
405                 return;
406         }
407
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);
412 }
413 #endif /* DEBUG */
414
415 void __init
416   pcibios_fixup_pbus_ranges(struct pci_bus *bus,
417                 struct pbus_set_ranges_data *ranges)
418 {
419 #ifdef DEBUG
420         int i;
421
422         dprintk("%s, bus number %d\n",__FUNCTION__,bus->number);
423
424         print_set_ranges_data(ranges);
425
426         for (i = 0; i < 2; i++)
427                 print_resource(bus->resource[i]);
428 #endif
429 }
430
431 void  pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
432 {
433         unsigned pci_int, pci_air, pci_cir, pci_aint;
434
435         pci_int = SH5PCI_READ(INT);
436         pci_cir = SH5PCI_READ(CIR);
437         pci_air = SH5PCI_READ(AIR);
438
439         if (pci_int) {
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);
445         }
446
447         pci_aint = SH5PCI_READ(AINT);
448         if (pci_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);
454         }
455
456 }
457
458
459 void pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
460 {
461   printk("SERR IRQ\n");
462
463 }
464
465 #define ROUND_UP(x, a)          (((x) + (a) - 1) & ~((a) - 1))
466
467 static void __init
468 pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
469 {
470         struct pbus_set_ranges_data inner;
471         struct pci_dev *dev;
472         struct pci_dev *bridge = bus->self;
473         struct list_head *ln;
474
475         if (!bridge)
476                 return; /* host bridge, nothing to do */
477
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;
483
484         /* Collect information about how our direct children are layed out. */
485         for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
486                 int i;
487                 dev = pci_dev_b(ln);
488
489                 /* Skip bridges for now */
490                 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
491                         continue;
492
493                 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
494                         struct resource res;
495                         unsigned long size;
496
497                         memcpy(&res, &dev->resource[i], sizeof(res));
498                         size = res.end - res.start + 1;
499
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;
508                         }
509                 }
510         }
511
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);
515
516         /* turn the ending locations into sizes (subtract start) */
517         inner.io_end -= inner.io_start;
518         inner.mem_end -= inner.mem_start;
519
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;
523
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;
527
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;
532
533         /* adjust parent's resource requirements */
534         if (outer) {
535                 outer->io_end = ROUND_UP(outer->io_end, 4*1024);
536                 outer->io_end += inner.io_end;
537
538                 outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
539                 outer->mem_end += inner.mem_end;
540         }
541 }
542
543 #undef ROUND_UP
544
545 static void __init 
546 pcibios_size_bridges(void)
547 {
548         struct pbus_set_ranges_data outer;
549
550         memset(&outer,0,sizeof(outer));
551         pcibios_size_bridge(pci_root_bus,&outer);
552 }
553
554 void __init
555 common_init_pci(void)
556 {
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();
562 }
563
564 void __init pcibios_init(void)
565 {
566
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");
570                 return;
571         }
572
573
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");
577                 return;
578         }
579
580
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. 
584          */
585         sh5pci_init(__pa(memory_start),
586                      __pa(memory_end) - __pa(memory_start));
587
588
589         common_init_pci();
590
591 #if 0
592         pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
593
594         pci_assign_unassigned_resources();
595
596         pci_fixup_irqs(no_swizzle, map_cayman_irq);
597
598         pci_set_bus_ranges();
599 #endif
600
601 }
602
603 void __init pcibios_fixup_bus(struct pci_bus *bus)
604 {
605         struct pci_dev *dev = bus->self;
606         int i;
607
608 #if 1
609         if(dev) {
610                 for(i=0; i<3; i++) {
611                         bus->resource[i] =
612                                 &dev->resource[PCI_BRIDGE_RESOURCES+i];
613                         bus->resource[i]->name = bus->name;
614                 }
615                 bus->resource[0]->flags |= IORESOURCE_IO;
616                 bus->resource[1]->flags |= IORESOURCE_MEM;
617
618                 /* For now, propogate host limits to the bus;
619                  * we'll adjust them later. */
620
621 #if 1
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;
626 #else
627                 bus->resource[0]->end = 0
628                 bus->resource[1]->end = 0
629                 bus->resource[0]->start =0
630                   bus->resource[1]->start = 0;
631 #endif
632
633 #ifdef DEBUG
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]);
638 #endif /* DEBUG */
639                 
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;
643         }
644 #endif 
645
646 }
647