Merge master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-drm-fsl-dcu.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/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>
21 #include <asm/pci.h>
22 #include <linux/irq.h>
23
24 #include <asm/io.h>
25 #include <asm/hardware.h>
26 #include "pci_sh5.h"
27
28 static unsigned long pcicr_virt;
29 unsigned long pciio_virt;
30
31 static void __init pci_fixup_ide_bases(struct pci_dev *d)
32 {
33         int i;
34
35         /*
36          * PCI IDE controllers use non-standard I/O port decoding, respect it.
37          */
38         if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
39                 return;
40         printk("PCI: IDE base address fixup for %s\n", pci_name(d));
41         for(i=0; i<4; i++) {
42                 struct resource *r = &d->resource[i];
43                 if ((r->start & ~0x80) == 0x374) {
44                         r->start |= 2;
45                         r->end = r->start;
46                 }
47         }
48 }
49 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
50
51 char * __init pcibios_setup(char *str)
52 {
53         return str;
54 }
55
56 /* Rounds a number UP to the nearest power of two. Used for
57  * sizing the PCI window.
58  */
59 static u32 __init r2p2(u32 num)
60 {
61         int i = 31;
62         u32 tmp = num;
63
64         if (num == 0)
65                 return 0;
66
67         do {
68                 if (tmp & (1 << 31))
69                         break;
70                 i--;
71                 tmp <<= 1;
72         } while (i >= 0);
73
74         tmp = 1 << i;
75         /* If the original number isn't a power of 2, round it up */
76         if (tmp != num)
77                 tmp <<= 1;
78
79         return tmp;
80 }
81
82 extern unsigned long long memory_start, memory_end;
83
84 int __init sh5pci_init(unsigned memStart, unsigned memSize)
85 {
86         u32 lsr0;
87         u32 uval;
88
89         pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
90         if (!pcicr_virt) {
91                 panic("Unable to remap PCICR\n");
92         }
93
94         pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
95         if (!pciio_virt) {
96                 panic("Unable to remap PCIIO\n");
97         }
98
99         pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
100
101         /* Clear snoop registers */
102         SH5PCI_WRITE(CSCR0, 0);
103         SH5PCI_WRITE(CSCR1, 0);
104
105         pr_debug("Wrote to reg\n");
106
107         /* Switch off interrupts */
108         SH5PCI_WRITE(INTM,  0);
109         SH5PCI_WRITE(AINTM, 0);
110         SH5PCI_WRITE(PINTM, 0);
111
112         /* Set bus active, take it out of reset */
113         uval = SH5PCI_READ(CR);
114
115         /* Set command Register */
116         SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
117
118         uval=SH5PCI_READ(CR);
119         pr_debug("CR is actually 0x%08x\n",uval);
120
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);
126
127         /*
128         ** Set translation mapping memory in order to convert the address
129         ** used for the main bus, to the PCI internal address.
130         */
131         SH5PCI_WRITE(MBR,0x40000000);
132
133         /* Always set the max size 512M */
134         SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
135
136         /*
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
142         */
143
144         SH5PCI_WRITE(IOBR,0x0);
145
146         pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
147
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);
151
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
154          * that easy!
155          */
156         SH5PCI_WRITE(CSR_IBAR0,~0);
157         /* Set memory size value */
158         memSize = memory_end - memory_start;
159
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);
163                 return -EINVAL;
164         }
165
166         /* Set LSR 0 */
167         lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
168         SH5PCI_WRITE(LSR0, lsr0);
169
170         pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
171
172         /* Set MBAR 0 */
173         SH5PCI_WRITE(CSR_MBAR0, memory_start);
174         SH5PCI_WRITE(LAR0, memory_start);
175
176         SH5PCI_WRITE(CSR_MBAR1,0);
177         SH5PCI_WRITE(LAR1,0);
178         SH5PCI_WRITE(LSR1,0);
179
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);
182
183         /* Enable the PCI interrupts on the device */
184         SH5PCI_WRITE(INTM,  ~0);
185         SH5PCI_WRITE(AINTM, ~0);
186         SH5PCI_WRITE(PINTM, ~0);
187
188         pr_debug("Switching on all error interrupts\n");
189
190         return(0);
191 }
192
193 static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
194                         int size, u32 *val)
195 {
196         SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
197
198         switch (size) {
199                 case 1:
200                         *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
201                         break;
202                 case 2:
203                         *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
204                         break;
205                 case 4:
206                         *val = SH5PCI_READ(PDR);
207                         break;
208         }
209
210         return PCIBIOS_SUCCESSFUL;
211 }
212
213 static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
214                          int size, u32 val)
215 {
216         SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
217
218         switch (size) {
219                 case 1:
220                         SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
221                         break;
222                 case 2:
223                         SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
224                         break;
225                 case 4:
226                         SH5PCI_WRITE(PDR, val);
227                         break;
228         }
229
230         return PCIBIOS_SUCCESSFUL;
231 }
232
233 static struct pci_ops pci_config_ops = {
234         .read =         sh5pci_read,
235         .write =        sh5pci_write,
236 };
237
238 /* Everything hangs off this */
239 static struct pci_bus *pci_root_bus;
240
241
242 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
243 {
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);
247 }
248
249 static inline u8 bridge_swizzle(u8 pin, u8 slot)
250 {
251         return (((pin-1) + slot) % 4) + 1;
252 }
253
254 u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
255 {
256         if (dev->bus->number != 0) {
257                 u8 pin = *pinp;
258                 do {
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);
263                 *pinp = pin;
264
265                 /* The slot is the slot of the last bridge. */
266         }
267
268         return PCI_SLOT(dev->devfn);
269 }
270
271 /* This needs to be shunted out of here into the board specific bit */
272
273 static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
274 {
275         int result = -1;
276
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.
282
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.
286
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.
290
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.
293            */
294
295         struct slot_pin {
296                 int slot;
297                 int pin;
298         } path[4];
299         int i=0;
300
301         while (dev->bus->number > 0) {
302
303                 slot = path[i].slot = PCI_SLOT(dev->devfn);
304                 pin = path[i].pin = bridge_swizzle(pin, slot);
305                 dev = dev->bus->self;
306                 i++;
307                 if (i > 3) panic("PCI path to root bus too long!\n");
308         }
309
310         slot = PCI_SLOT(dev->devfn);
311         /* This is the slot on bus 0 through which the device is eventually
312            reachable. */
313
314         /* Now work back up. */
315         if ((slot < 3) || (i == 0)) {
316                 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
317                    swizzle now. */
318                 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
319         } else {
320                 i--;
321                 slot = path[i].slot;
322                 pin  = path[i].pin;
323                 if (slot > 0) {
324                         panic("PCI expansion bus device found - not handled!\n");
325                 } else {
326                         if (i > 0) {
327                                 /* 5V slots */
328                                 i--;
329                                 slot = path[i].slot;
330                                 pin  = path[i].pin;
331                                 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
332                                 result = IRQ_P2INTA + (pin - 1);
333                         } else {
334                                 /* IRQ for 2ary PCI-PCI bridge : unused */
335                                 result = -1;
336                         }
337                 }
338         }
339
340         return result;
341 }
342
343 irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
344 {
345         unsigned pci_int, pci_air, pci_cir, pci_aint;
346
347         pci_int = SH5PCI_READ(INT);
348         pci_cir = SH5PCI_READ(CIR);
349         pci_air = SH5PCI_READ(AIR);
350
351         if (pci_int) {
352                 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
353                 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
354                 printk("PCI AIR -> 0x%x\n", pci_air);
355                 printk("PCI CIR -> 0x%x\n", pci_cir);
356                 SH5PCI_WRITE(INT, ~0);
357         }
358
359         pci_aint = SH5PCI_READ(AINT);
360         if (pci_aint) {
361                 printk("PCI ARB INTERRUPT!\n");
362                 printk("PCI AINT -> 0x%x\n", pci_aint);
363                 printk("PCI AIR -> 0x%x\n", pci_air);
364                 printk("PCI CIR -> 0x%x\n", pci_cir);
365                 SH5PCI_WRITE(AINT, ~0);
366         }
367
368         return IRQ_HANDLED;
369 }
370
371 irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
372 {
373         printk("SERR IRQ\n");
374
375         return IRQ_NONE;
376 }
377
378 #define ROUND_UP(x, a)          (((x) + (a) - 1) & ~((a) - 1))
379
380 static void __init
381 pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
382                     struct resource *memr)
383 {
384         struct resource io_res, mem_res;
385         struct pci_dev *dev;
386         struct pci_dev *bridge = bus->self;
387         struct list_head *ln;
388
389         if (!bridge)
390                 return; /* host bridge, nothing to do */
391
392         /* set reasonable default locations for pcibios_align_resource */
393         io_res.start = PCIBIOS_MIN_IO;
394         mem_res.start = PCIBIOS_MIN_MEM;
395
396         io_res.end = io_res.start;
397         mem_res.end = mem_res.start;
398
399         /* Collect information about how our direct children are layed out. */
400         for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
401                 int i;
402                 dev = pci_dev_b(ln);
403
404                 /* Skip bridges for now */
405                 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
406                         continue;
407
408                 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
409                         struct resource res;
410                         unsigned long size;
411
412                         memcpy(&res, &dev->resource[i], sizeof(res));
413                         size = res.end - res.start + 1;
414
415                         if (res.flags & IORESOURCE_IO) {
416                                 res.start = io_res.end;
417                                 pcibios_align_resource(dev, &res, size, 0);
418                                 io_res.end = res.start + size;
419                         } else if (res.flags & IORESOURCE_MEM) {
420                                 res.start = mem_res.end;
421                                 pcibios_align_resource(dev, &res, size, 0);
422                                 mem_res.end = res.start + size;
423                         }
424                 }
425         }
426
427         /* And for all of the subordinate busses. */
428         for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
429                 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
430
431         /* turn the ending locations into sizes (subtract start) */
432         io_res.end -= io_res.start;
433         mem_res.end -= mem_res.start;
434
435         /* Align the sizes up by bridge rules */
436         io_res.end = ROUND_UP(io_res.end, 4*1024) - 1;
437         mem_res.end = ROUND_UP(mem_res.end, 1*1024*1024) - 1;
438
439         /* Adjust the bridge's allocation requirements */
440         bridge->resource[0].end = bridge->resource[0].start + io_res.end;
441         bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
442
443         bridge->resource[PCI_BRIDGE_RESOURCES].end =
444             bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
445         bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
446             bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
447
448         /* adjust parent's resource requirements */
449         if (ior) {
450                 ior->end = ROUND_UP(ior->end, 4*1024);
451                 ior->end += io_res.end;
452         }
453
454         if (memr) {
455                 memr->end = ROUND_UP(memr->end, 1*1024*1024);
456                 memr->end += mem_res.end;
457         }
458 }
459
460 #undef ROUND_UP
461
462 static void __init pcibios_size_bridges(void)
463 {
464         struct resource io_res, mem_res;
465
466         memset(&io_res, 0, sizeof(io_res));
467         memset(&mem_res, 0, sizeof(mem_res));
468
469         pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
470 }
471
472 static int __init pcibios_init(void)
473 {
474         if (request_irq(IRQ_ERR, pcish5_err_irq,
475                         IRQF_DISABLED, "PCI Error",NULL) < 0) {
476                 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
477                 return -EINVAL;
478         }
479
480         if (request_irq(IRQ_SERR, pcish5_serr_irq,
481                         IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
482                 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
483                 return -EINVAL;
484         }
485
486         /* The pci subsytem needs to know where memory is and how much
487          * of it there is. I've simply made these globals. A better mechanism
488          * is probably needed.
489          */
490         sh5pci_init(__pa(memory_start),
491                      __pa(memory_end) - __pa(memory_start));
492
493         pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
494         pcibios_size_bridges();
495         pci_assign_unassigned_resources();
496         pci_fixup_irqs(no_swizzle, map_cayman_irq);
497
498         return 0;
499 }
500
501 subsys_initcall(pcibios_init);
502
503 void __init pcibios_fixup_bus(struct pci_bus *bus)
504 {
505         struct pci_dev *dev = bus->self;
506         int i;
507
508 #if 1
509         if(dev) {
510                 for(i=0; i<3; i++) {
511                         bus->resource[i] =
512                                 &dev->resource[PCI_BRIDGE_RESOURCES+i];
513                         bus->resource[i]->name = bus->name;
514                 }
515                 bus->resource[0]->flags |= IORESOURCE_IO;
516                 bus->resource[1]->flags |= IORESOURCE_MEM;
517
518                 /* For now, propagate host limits to the bus;
519                  * we'll adjust them later. */
520
521 #if 1
522                 bus->resource[0]->end = 64*1024 - 1 ;
523                 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
524                 bus->resource[0]->start = PCIBIOS_MIN_IO;
525                 bus->resource[1]->start = PCIBIOS_MIN_MEM;
526 #else
527                 bus->resource[0]->end = 0
528                 bus->resource[1]->end = 0
529                 bus->resource[0]->start =0
530                   bus->resource[1]->start = 0;
531 #endif
532                 /* Turn off downstream PF memory address range by default */
533                 bus->resource[2]->start = 1024*1024;
534                 bus->resource[2]->end = bus->resource[2]->start - 1;
535         }
536 #endif
537
538 }
539