ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / ppc / platforms / mvme5100_pci.c
1 /*
2  * arch/ppc/platforms/mvme5100_pci.c
3  *
4  * PCI setup routines for the Motorola MVME5100.
5  *
6  * Author: Matt Porter <mporter@mvista.com>
7  *
8  * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
9  * the terms of the GNU General Public License version 2.  This program
10  * is licensed "as is" without any warranty of any kind, whether express
11  * or implied.
12  */
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/pci.h>
16 #include <linux/slab.h>
17
18 #include <asm/byteorder.h>
19 #include <asm/io.h>
20 #include <asm/irq.h>
21 #include <asm/uaccess.h>
22 #include <asm/machdep.h>
23 #include <asm/pci-bridge.h>
24 #include <platforms/mvme5100.h>
25 #include <asm/pplus.h>
26
27 static inline int
28 mvme5100_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
29 {
30         int irq;
31
32         static char pci_irq_table[][4] =
33         /*
34          *      PCI IDSEL/INTPIN->INTLINE
35          *         A   B   C   D
36          */
37         {
38                 {  0,  0,  0,  0 },     /* IDSEL 11 - Winbond */
39                 {  0,  0,  0,  0 },     /* IDSEL 12 - unused */
40                 { 21, 22, 23, 24 },     /* IDSEL 13 - Universe II */
41                 { 18,  0,  0,  0 },     /* IDSEL 14 - Enet 1 */
42                 {  0,  0,  0,  0 },     /* IDSEL 15 - unused */
43                 { 25, 26, 27, 28 },     /* IDSEL 16 - PMC Slot 1 */
44                 { 28, 25, 26, 27 },     /* IDSEL 17 - PMC Slot 2 */
45                 {  0,  0,  0,  0 },     /* IDSEL 18 - unused */
46                 { 29,  0,  0,  0 },     /* IDSEL 19 - Enet 2 */
47                 {  0,  0,  0,  0 },     /* IDSEL 20 - PMCSPAN */
48         };
49
50         const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4;
51         irq = PCI_IRQ_TABLE_LOOKUP;
52         /* If lookup is zero, always return 0 */
53         if (!irq)
54                 return 0;
55         else
56 #ifdef CONFIG_MVME5100_IPMC761_PRESENT
57         /* If IPMC761 present, return table value */
58         return irq;
59 #else
60         /* If IPMC761 not present, we don't have an i8259 so adjust */
61         return (irq - NUM_8259_INTERRUPTS);
62 #endif
63 }
64
65 static void
66 mvme5100_pcibios_fixup_resources(struct pci_dev *dev)
67 {
68         int i;
69
70         if ((dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
71                         (dev->device == PCI_DEVICE_ID_MOTOROLA_HAWK))
72                 for (i=0; i<DEVICE_COUNT_RESOURCE; i++)
73                 {
74                         dev->resource[i].start = 0;
75                         dev->resource[i].end = 0;
76                 }
77 }
78
79 void __init
80 mvme5100_setup_bridge(void)
81 {
82         struct pci_controller*  hose;
83
84         hose = pcibios_alloc_controller();
85
86         if (!hose)
87                 return;
88
89         hose->first_busno = 0;
90         hose->last_busno = 0xff;
91         hose->pci_mem_offset = MVME5100_PCI_MEM_OFFSET;
92
93         pci_init_resource(&hose->io_resource,
94                         MVME5100_PCI_LOWER_IO,
95                         MVME5100_PCI_UPPER_IO,
96                         IORESOURCE_IO,
97                         "PCI host bridge");
98
99         pci_init_resource(&hose->mem_resources[0],
100                         MVME5100_PCI_LOWER_MEM,
101                         MVME5100_PCI_UPPER_MEM,
102                         IORESOURCE_MEM,
103                         "PCI host bridge");
104
105         hose->io_space.start = MVME5100_PCI_LOWER_IO;
106         hose->io_space.end = MVME5100_PCI_UPPER_IO;
107         hose->mem_space.start = MVME5100_PCI_LOWER_MEM;
108         hose->mem_space.end = MVME5100_PCI_UPPER_MEM;
109         hose->io_base_virt = (void *)MVME5100_ISA_IO_BASE;
110
111         /* Use indirect method of Hawk */
112         setup_indirect_pci(hose,
113                            MVME5100_PCI_CONFIG_ADDR,
114                            MVME5100_PCI_CONFIG_DATA);
115
116         hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
117
118         ppc_md.pcibios_fixup_resources = mvme5100_pcibios_fixup_resources;
119         ppc_md.pci_swizzle = common_swizzle;
120         ppc_md.pci_map_irq = mvme5100_map_irq;
121 }