]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/sh64/kernel/pci_sh5.c
sh64: ROUND_UP macro cleanup in arch/sh64/kernel/pci_sh5.c
[linux-2.6-omap-h63xx.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 static void __init
379 pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
380                     struct resource *memr)
381 {
382         struct resource io_res, mem_res;
383         struct pci_dev *dev;
384         struct pci_dev *bridge = bus->self;
385         struct list_head *ln;
386
387         if (!bridge)
388                 return; /* host bridge, nothing to do */
389
390         /* set reasonable default locations for pcibios_align_resource */
391         io_res.start = PCIBIOS_MIN_IO;
392         mem_res.start = PCIBIOS_MIN_MEM;
393
394         io_res.end = io_res.start;
395         mem_res.end = mem_res.start;
396
397         /* Collect information about how our direct children are layed out. */
398         for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
399                 int i;
400                 dev = pci_dev_b(ln);
401
402                 /* Skip bridges for now */
403                 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
404                         continue;
405
406                 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
407                         struct resource res;
408                         unsigned long size;
409
410                         memcpy(&res, &dev->resource[i], sizeof(res));
411                         size = res.end - res.start + 1;
412
413                         if (res.flags & IORESOURCE_IO) {
414                                 res.start = io_res.end;
415                                 pcibios_align_resource(dev, &res, size, 0);
416                                 io_res.end = res.start + size;
417                         } else if (res.flags & IORESOURCE_MEM) {
418                                 res.start = mem_res.end;
419                                 pcibios_align_resource(dev, &res, size, 0);
420                                 mem_res.end = res.start + size;
421                         }
422                 }
423         }
424
425         /* And for all of the subordinate busses. */
426         for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
427                 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
428
429         /* turn the ending locations into sizes (subtract start) */
430         io_res.end -= io_res.start;
431         mem_res.end -= mem_res.start;
432
433         /* Align the sizes up by bridge rules */
434         io_res.end = ALIGN(io_res.end, 4*1024) - 1;
435         mem_res.end = ALIGN(mem_res.end, 1*1024*1024) - 1;
436
437         /* Adjust the bridge's allocation requirements */
438         bridge->resource[0].end = bridge->resource[0].start + io_res.end;
439         bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
440
441         bridge->resource[PCI_BRIDGE_RESOURCES].end =
442             bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
443         bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
444             bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
445
446         /* adjust parent's resource requirements */
447         if (ior) {
448                 ior->end = ALIGN(ior->end, 4*1024);
449                 ior->end += io_res.end;
450         }
451
452         if (memr) {
453                 memr->end = ALIGN(memr->end, 1*1024*1024);
454                 memr->end += mem_res.end;
455         }
456 }
457
458 static void __init pcibios_size_bridges(void)
459 {
460         struct resource io_res, mem_res;
461
462         memset(&io_res, 0, sizeof(io_res));
463         memset(&mem_res, 0, sizeof(mem_res));
464
465         pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
466 }
467
468 static int __init pcibios_init(void)
469 {
470         if (request_irq(IRQ_ERR, pcish5_err_irq,
471                         IRQF_DISABLED, "PCI Error",NULL) < 0) {
472                 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
473                 return -EINVAL;
474         }
475
476         if (request_irq(IRQ_SERR, pcish5_serr_irq,
477                         IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
478                 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
479                 return -EINVAL;
480         }
481
482         /* The pci subsytem needs to know where memory is and how much
483          * of it there is. I've simply made these globals. A better mechanism
484          * is probably needed.
485          */
486         sh5pci_init(__pa(memory_start),
487                      __pa(memory_end) - __pa(memory_start));
488
489         pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
490         pcibios_size_bridges();
491         pci_assign_unassigned_resources();
492         pci_fixup_irqs(no_swizzle, map_cayman_irq);
493
494         return 0;
495 }
496
497 subsys_initcall(pcibios_init);
498
499 void __init pcibios_fixup_bus(struct pci_bus *bus)
500 {
501         struct pci_dev *dev = bus->self;
502         int i;
503
504 #if 1
505         if(dev) {
506                 for(i=0; i<3; i++) {
507                         bus->resource[i] =
508                                 &dev->resource[PCI_BRIDGE_RESOURCES+i];
509                         bus->resource[i]->name = bus->name;
510                 }
511                 bus->resource[0]->flags |= IORESOURCE_IO;
512                 bus->resource[1]->flags |= IORESOURCE_MEM;
513
514                 /* For now, propagate host limits to the bus;
515                  * we'll adjust them later. */
516
517 #if 1
518                 bus->resource[0]->end = 64*1024 - 1 ;
519                 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
520                 bus->resource[0]->start = PCIBIOS_MIN_IO;
521                 bus->resource[1]->start = PCIBIOS_MIN_MEM;
522 #else
523                 bus->resource[0]->end = 0
524                 bus->resource[1]->end = 0
525                 bus->resource[0]->start =0
526                   bus->resource[1]->start = 0;
527 #endif
528                 /* Turn off downstream PF memory address range by default */
529                 bus->resource[2]->start = 1024*1024;
530                 bus->resource[2]->end = bus->resource[2]->start - 1;
531         }
532 #endif
533
534 }
535