cleanup
[linux-2.4.21-pre4.git] / arch / ppc / platforms / pcore_pci.c
1 /*
2  * arch/ppc/platforms/pcore_pci.c
3  * 
4  * PCI support for Force PCORE boards
5  *
6  * Author: Matt Porter <mporter@mvista.com>
7  *
8  * Copyright 2001 MontaVista Software Inc.
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/pci.h>
19 #include <linux/slab.h>
20
21 #include <asm/byteorder.h>
22 #include <asm/io.h>
23 #include <asm/irq.h>
24 #include <asm/uaccess.h>
25 #include <asm/machdep.h>
26 #include <asm/pci-bridge.h>
27 #include <asm/mpc10x.h>
28
29 #include "pcore.h"
30
31 #undef DEBUG
32 #ifdef DEBUG
33 #define DBG(x...) printk(x)
34 #else
35 #define DBG(x...)
36 #endif /* DEBUG */ 
37
38 static inline int __init
39 pcore_6750_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
40 {
41         static char pci_irq_table[][4] =
42         /*
43          *      PCI IDSEL/INTPIN->INTLINE
44          *      A       B       C       D
45          */ 
46         {
47                 {9,     10,     11,     12},    /* IDSEL 24 - DEC 21554 */
48                 {10,    0,      0,      0},     /* IDSEL 25 - DEC 21143 */
49                 {11,    12,     9,      10},    /* IDSEL 26 - PMC I */
50                 {12,    9,      10,     11},    /* IDSEL 27 - PMC II */
51                 {0,     0,      0,      0},     /* IDSEL 28 - unused */
52                 {0,     0,      9,      0},     /* IDSEL 29 - unused */
53                 {0,     0,      0,      0},     /* IDSEL 30 - Winbond */
54                 };
55         const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4;
56         return PCI_IRQ_TABLE_LOOKUP;
57 };
58
59 static inline int __init
60 pcore_680_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
61 {
62         static char pci_irq_table[][4] =
63         /*
64          *      PCI IDSEL/INTPIN->INTLINE
65          *      A       B       C       D
66          */ 
67         {
68                 {9,     10,     11,     12},    /* IDSEL 24 - Sentinel */
69                 {10,    0,      0,      0},     /* IDSEL 25 - i82559 #1 */
70                 {11,    12,     9,      10},    /* IDSEL 26 - PMC I */
71                 {12,    9,      10,     11},    /* IDSEL 27 - PMC II */
72                 {9,     0,      0,      0},     /* IDSEL 28 - i82559 #2 */
73                 {0,     0,      0,      0},     /* IDSEL 29 - unused */
74                 {0,     0,      0,      0},     /* IDSEL 30 - Winbond */
75                 };
76         const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4;
77         return PCI_IRQ_TABLE_LOOKUP;
78 };
79
80 void __init
81 pcore_pcibios_fixup(void)
82 {
83         struct pci_dev *dev;
84
85         if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
86                                 PCI_DEVICE_ID_WINBOND_83C553,
87                                 0)))
88         {
89                 /* Reroute interrupts both IDE channels to 15 */
90                 pci_write_config_byte(dev,
91                                 PCORE_WINBOND_IDE_INT,
92                                 0xff); 
93
94                 /* Route INTA-D to IRQ9-12, respectively */
95                 pci_write_config_word(dev,
96                                 PCORE_WINBOND_PCI_INT,
97                                 0x9abc); 
98
99                 /*
100                  * Set up 8259 edge/level triggering
101                  */ 
102                 outb(0x00, PCORE_WINBOND_PRI_EDG_LVL);
103                 outb(0x1e, PCORE_WINBOND_SEC_EDG_LVL);
104         }
105 }
106
107 int __init
108 pcore_find_bridges(void)
109 {
110         struct pci_controller* hose;
111         int host_bridge, board_type;
112
113         hose = pcibios_alloc_controller();
114         if (!hose)
115                 return 0;
116
117         mpc10x_bridge_init(hose,
118                         MPC10X_MEM_MAP_B,
119                         MPC10X_MEM_MAP_B,
120                         MPC10X_MAPB_EUMB_BASE);
121
122         /* Determine board type */
123         early_read_config_dword(hose,
124                         0,
125                         PCI_DEVFN(0,0),
126                         PCI_VENDOR_ID,
127                         &host_bridge);
128         if (host_bridge == MPC10X_BRIDGE_106)
129                 board_type = PCORE_TYPE_6750;
130         else /* MPC10X_BRIDGE_107 */
131                 board_type = PCORE_TYPE_680;
132
133         hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
134
135         ppc_md.pcibios_fixup = pcore_pcibios_fixup;
136         ppc_md.pci_swizzle = common_swizzle;
137
138         if (board_type == PCORE_TYPE_6750)
139                 ppc_md.pci_map_irq = pcore_6750_map_irq;
140         else /* PCORE_TYPE_680 */
141                 ppc_md.pci_map_irq = pcore_680_map_irq;
142
143         return board_type;
144 }