import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / mips / ite-boards / generic / it8172_pci.c
1 /*
2  *
3  * BRIEF MODULE DESCRIPTION
4  *      IT8172 system controller specific pci support.
5  *
6  * Copyright 2000 MontaVista Software Inc.
7  * Author: MontaVista Software, Inc.
8  *              ppopov@mvista.com or source@mvista.com
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  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
16  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
17  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
18  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
19  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
21  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
23  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  *  You should have received a copy of the  GNU General Public License along
27  *  with this program; if not, write  to the Free Software Foundation, Inc.,
28  *  675 Mass Ave, Cambridge, MA 02139, USA.
29  */
30 #include <linux/config.h>
31
32 #ifdef CONFIG_PCI
33
34 #include <linux/types.h>
35 #include <linux/pci.h>
36 #include <linux/kernel.h>
37 #include <linux/init.h>
38
39 #include <asm/pci_channel.h>
40 #include <asm/it8172/it8172.h>
41 #include <asm/it8172/it8172_pci.h>
42
43 #define PCI_ACCESS_READ  0
44 #define PCI_ACCESS_WRITE 1
45
46 #undef DEBUG
47 #ifdef DEBUG
48 #define DBG(x...) printk(x)
49 #else
50 #define DBG(x...)
51 #endif
52
53 static struct resource pci_mem_resource_1;
54
55 static struct resource pci_io_resource = {
56         "io pci IO space",
57         0x14018000,
58         0x17FFFFFF,
59         IORESOURCE_IO
60 };
61
62 static struct resource pci_mem_resource_0 = {
63         "ext pci memory space 0/1",
64         0x10101000,
65         0x13FFFFFF,
66         IORESOURCE_MEM,
67         &pci_mem_resource_0,
68         NULL,
69         &pci_mem_resource_1
70 };
71
72 static struct resource pci_mem_resource_1 = {
73         "ext pci memory space 2/3",
74         0x1A000000,
75         0x1FBFFFFF,
76         IORESOURCE_MEM,
77         &pci_mem_resource_0,
78         NULL,
79         NULL
80 };
81
82 extern struct pci_ops it8172_pci_ops;
83
84 struct pci_channel mips_pci_channels[] = {
85         { &it8172_pci_ops, &pci_io_resource, &pci_mem_resource_0, 0x10, 0xff },
86         { NULL, NULL, NULL, NULL, NULL}
87 };
88
89 static int
90 it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
91                            unsigned char where, u32 *data)
92 {
93         /*
94          * config cycles are on 4 byte boundary only
95          */
96         unsigned char bus = dev->bus->number;
97         unsigned char dev_fn = dev->devfn;
98
99         DBG("it config: type %d dev %x bus %d dev_fn %x data %x\n",
100                         access_type, dev, bus, dev_fn, *data);
101
102         /* Setup address */
103         IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) |
104                         (dev_fn << IT_FUNCNUM_SHF) | (where & ~0x3));
105
106
107         if (access_type == PCI_ACCESS_WRITE) {
108                 IT_WRITE(IT_CONFDATA, *data);
109         }
110         else {
111                 IT_READ(IT_CONFDATA, *data);
112         }
113
114         /*
115          * Revisit: check for master or target abort.
116          */
117         return 0;
118
119
120 }
121
122
123 /*
124  * We can't address 8 and 16 bit words directly.  Instead we have to
125  * read/write a 32bit word and mask/modify the data we actually want.
126  */
127 static int
128 read_config_byte (struct pci_dev *dev, int where, u8 *val)
129 {
130         u32 data = 0;
131
132         if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
133                 return -1;
134
135         *val = (data >> ((where & 3) << 3)) & 0xff;
136         DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n",
137                 dev->bus->number, dev->devfn, where, *val);
138
139         return PCIBIOS_SUCCESSFUL;
140 }
141
142
143 static int
144 read_config_word (struct pci_dev *dev, int where, u16 *val)
145 {
146         u32 data = 0;
147
148         if (where & 1)
149                 return PCIBIOS_BAD_REGISTER_NUMBER;
150
151         if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
152                return -1;
153
154         *val = (data >> ((where & 3) << 3)) & 0xffff;
155         DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n",
156                 dev->bus->number, dev->devfn, where, *val);
157
158         return PCIBIOS_SUCCESSFUL;
159 }
160
161 static int
162 read_config_dword (struct pci_dev *dev, int where, u32 *val)
163 {
164         u32 data = 0;
165
166         if (where & 3)
167                 return PCIBIOS_BAD_REGISTER_NUMBER;
168
169         if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
170                 return -1;
171
172         *val = data;
173         DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n",
174                 dev->bus->number, dev->devfn, where, *val);
175
176         return PCIBIOS_SUCCESSFUL;
177 }
178
179
180 static int
181 write_config_byte (struct pci_dev *dev, int where, u8 val)
182 {
183         u32 data = 0;
184
185         if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
186                 return -1;
187
188         data = (data & ~(0xff << ((where & 3) << 3))) |
189                (val << ((where & 3) << 3));
190
191         if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
192                 return -1;
193
194         return PCIBIOS_SUCCESSFUL;
195 }
196
197 static int
198 write_config_word (struct pci_dev *dev, int where, u16 val)
199 {
200         u32 data = 0;
201
202         if (where & 1)
203                 return PCIBIOS_BAD_REGISTER_NUMBER;
204
205         if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
206                return -1;
207
208         data = (data & ~(0xffff << ((where & 3) << 3))) |
209                (val << ((where & 3) << 3));
210
211         if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
212                return -1;
213
214
215         return PCIBIOS_SUCCESSFUL;
216 }
217
218 static int
219 write_config_dword(struct pci_dev *dev, int where, u32 val)
220 {
221         if (where & 3)
222                 return PCIBIOS_BAD_REGISTER_NUMBER;
223
224         if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val))
225                return -1;
226
227         return PCIBIOS_SUCCESSFUL;
228 }
229
230 struct pci_ops it8172_pci_ops = {
231         read_config_byte,
232         read_config_word,
233         read_config_dword,
234         write_config_byte,
235         write_config_word,
236         write_config_dword
237 };
238
239 unsigned __init int pcibios_assign_all_busses(void)
240 {
241        return 1;
242 }
243 #endif /* CONFIG_PCI */