ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / mips / pci / ops-tx4927.c
1 /*
2  * Copyright 2001 MontaVista Software Inc.
3  * Author: MontaVista Software, Inc.
4  *              ahennessy@mvista.com       
5  *
6  * Copyright (C) 2000-2001 Toshiba Corporation 
7  *
8  * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
9  *
10  *     Define the pci_ops for the Toshiba rbtx4927
11  *
12  * Much of the code is derived from the original DDB5074 port by 
13  * Geert Uytterhoeven <geert@sonycom.com>
14  *
15  *  This program is free software; you can redistribute  it and/or modify it
16  *  under  the terms of  the GNU General  Public License as published by the
17  *  Free Software Foundation;  either version 2 of the  License, or (at your
18  *  option) any later version.
19  *
20  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
21  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
22  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
23  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
24  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
26  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
28  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  *  You should have received a copy of the  GNU General Public License along
32  *  with this program; if not, write  to the Free Software Foundation, Inc.,
33  *  675 Mass Ave, Cambridge, MA 02139, USA.
34  */
35 #include <linux/types.h>
36 #include <linux/pci.h>
37 #include <linux/kernel.h>
38 #include <linux/init.h>
39
40 #include <asm/addrspace.h>
41 #include <asm/pci_channel.h>
42 #include <asm/tx4927/tx4927_pci.h>
43 #include <asm/debug.h>
44
45 /* initialize in setup */
46 struct resource pci_io_resource = {
47         "pci IO space",
48         (PCIBIOS_MIN_IO),
49         ((PCIBIOS_MIN_IO) + (TX4927_PCIIO_SIZE)) - 1,
50         IORESOURCE_IO
51 };
52
53 /* initialize in setup */
54 struct resource pci_mem_resource = {
55         "pci memory space",
56         TX4927_PCIMEM,
57         TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1,
58         IORESOURCE_MEM
59 };
60
61 extern struct pci_ops tx4927_pci_ops;
62
63 /*
64  * h/w only supports devices 0x00 to 0x14
65  */
66 struct pci_controller tx4927_controller = {
67         .pci_ops        = &tx4927_pci_ops,
68         .io_resource    = &pci_io_resource,
69         .mem_resource   = &pci_mem_resource,
70 };
71
72 static int mkaddr(unsigned char bus, unsigned char dev_fn,
73         unsigned char where, int *flagsp)
74 {
75         if (bus > 0) {
76                 /* Type 1 configuration */
77                 tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
78                     ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
79         } else {
80                 if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0))
81                         return -1;
82
83                 /* Type 0 configuration */
84                 tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
85                     ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
86         }
87         /* clear M_ABORT and Disable M_ABORT Int. */
88         tx4927_pcicptr->pcistatus =
89             (tx4927_pcicptr->pcistatus & 0x0000ffff) |
90             (PCI_STATUS_REC_MASTER_ABORT << 16);
91         tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
92         return 0;
93 }
94
95 static int check_abort(int flags)
96 {
97         int code = PCIBIOS_SUCCESSFUL;
98         if (tx4927_pcicptr->
99             pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
100                 tx4927_pcicptr->pcistatus =
101                     (tx4927_pcicptr->
102                      pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
103                                                 << 16);
104                 tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
105                 code = PCIBIOS_DEVICE_NOT_FOUND;
106         }
107         return code;
108 }
109
110 /*
111  * We can't address 8 and 16 bit words directly.  Instead we have to
112  * read/write a 32bit word and mask/modify the data we actually want.
113  */
114 static int tx4927_pcibios_read_config_byte(struct pci_dev *dev,
115                                            int where, unsigned char *val)
116 {
117         int flags, retval;
118         unsigned char bus, func_num;
119
120         db_assert((where & 3) == 0);
121         db_assert(where < (1 << 8));
122
123         /* check if the bus is top-level */
124         if (dev->bus->parent != NULL) {
125                 bus = dev->bus->number;
126                 db_assert(bus != 0);
127         } else {
128                 bus = 0;
129         }
130
131         func_num = PCI_FUNC(dev->devfn);
132         if (mkaddr(bus, dev->devfn, where, &flags))
133                 return -1;
134 #ifdef __BIG_ENDIAN
135         *val =
136             *(volatile u8 *) ((ulong) & tx4927_pcicptr->
137                               g2pcfgdata | ((where & 3) ^ 3));
138 #else
139         *val =
140             *(volatile u8 *) ((ulong) & tx4927_pcicptr->
141                               g2pcfgdata | (where & 3));
142 #endif
143         retval = check_abort(flags);
144         if (retval == PCIBIOS_DEVICE_NOT_FOUND)
145                 *val = 0xff;
146         return retval;
147 }
148
149 static int tx4927_pcibios_read_config_word(struct pci_dev *dev,
150                                            int where, unsigned short *val)
151 {
152         int flags, retval;
153         unsigned char bus, func_num;
154
155         if (where & 1)
156                 return PCIBIOS_BAD_REGISTER_NUMBER;
157
158         db_assert((where & 3) == 0);
159         db_assert(where < (1 << 8));
160
161         /* check if the bus is top-level */
162         if (dev->bus->parent != NULL) {
163                 bus = dev->bus->number;
164                 db_assert(bus != 0);
165         } else {
166                 bus = 0;
167         }
168
169         func_num = PCI_FUNC(dev->devfn);
170         if (mkaddr(bus, dev->devfn, where, &flags))
171                 return -1;
172 #ifdef __BIG_ENDIAN
173         *val =
174             *(volatile u16 *) ((ulong) & tx4927_pcicptr->
175                                g2pcfgdata | ((where & 3) ^ 2));
176 #else
177         *val =
178             *(volatile u16 *) ((ulong) & tx4927_pcicptr->
179                                g2pcfgdata | (where & 3));
180 #endif
181         retval = check_abort(flags);
182         if (retval == PCIBIOS_DEVICE_NOT_FOUND)
183                 *val = 0xffff;
184         return retval;
185 }
186
187 static int tx4927_pcibios_read_config_dword(struct pci_dev *dev,
188                                             int where, unsigned int *val)
189 {
190         int flags, retval;
191         unsigned char bus, func_num;
192
193         if (where & 3)
194                 return PCIBIOS_BAD_REGISTER_NUMBER;
195
196         db_assert((where & 3) == 0);
197         db_assert(where < (1 << 8));
198
199         /* check if the bus is top-level */
200         if (dev->bus->parent != NULL) {
201                 bus = dev->bus->number;
202                 db_assert(bus != 0);
203         } else {
204                 bus = 0;
205         }
206
207         func_num = PCI_FUNC(dev->devfn);
208         if (mkaddr(bus, dev->devfn, where, &flags))
209                 return -1;
210         *val = tx4927_pcicptr->g2pcfgdata;
211         retval = check_abort(flags);
212         if (retval == PCIBIOS_DEVICE_NOT_FOUND)
213                 *val = 0xffffffff;
214
215         return retval;
216 }
217
218 static int tx4927_pcibios_write_config_byte(struct pci_dev *dev,
219                                             int where, unsigned char val)
220 {
221         int flags;
222         unsigned char bus, func_num;
223
224         /* check if the bus is top-level */
225         if (dev->bus->parent != NULL) {
226                 bus = dev->bus->number;
227                 db_assert(bus != 0);
228         } else {
229                 bus = 0;
230         }
231
232         func_num = PCI_FUNC(dev->devfn);
233         if (mkaddr(bus, dev->devfn, where, &flags))
234                 return -1;
235 #ifdef __BIG_ENDIAN
236         *(volatile u8 *) ((ulong) & tx4927_pcicptr->
237                           g2pcfgdata | ((where & 3) ^ 3)) = val;
238 #else
239         *(volatile u8 *) ((ulong) & tx4927_pcicptr->
240                           g2pcfgdata | (where & 3)) = val;
241 #endif
242         return check_abort(flags);
243 }
244
245 static int tx4927_pcibios_write_config_word(struct pci_dev *dev,
246                                             int where, unsigned short val)
247 {
248         int flags;
249         unsigned char bus, func_num;
250
251         if (where & 1)
252                 return PCIBIOS_BAD_REGISTER_NUMBER;
253
254         /* check if the bus is top-level */
255         if (dev->bus->parent != NULL) {
256                 bus = dev->bus->number;
257                 db_assert(bus != 0);
258         } else {
259                 bus = 0;
260         }
261
262         func_num = PCI_FUNC(dev->devfn);
263         if (mkaddr(bus, dev->devfn, where, &flags))
264                 return -1;
265 #ifdef __BIG_ENDIAN
266         *(volatile u16 *) ((ulong) & tx4927_pcicptr->
267                            g2pcfgdata | ((where & 3) ^ 2)) = val;
268 #else
269         *(volatile u16 *) ((ulong) & tx4927_pcicptr->
270                            g2pcfgdata | (where & 3)) = val;
271 #endif
272         return check_abort(flags);
273 }
274
275 static int tx4927_pcibios_write_config_dword(struct pci_dev *dev,
276                                              int where, unsigned int val)
277 {
278         int flags;
279         unsigned char bus, func_num;
280
281         if (where & 3)
282                 return PCIBIOS_BAD_REGISTER_NUMBER;
283
284         /* check if the bus is top-level */
285         if (dev->bus->parent != NULL) {
286                 bus = dev->bus->number;
287                 db_assert(bus != 0);
288         } else {
289                 bus = 0;
290         }
291
292         func_num = PCI_FUNC(dev->devfn);
293         if (mkaddr(bus, dev->devfn, where, &flags))
294                 return -1;
295         tx4927_pcicptr->g2pcfgdata = val;
296         return check_abort(flags);
297 }
298
299 struct pci_ops tx4927_pci_ops = {
300         tx4927_pcibios_read_config_byte,
301         tx4927_pcibios_read_config_word,
302         tx4927_pcibios_read_config_dword,
303         tx4927_pcibios_write_config_byte,
304         tx4927_pcibios_write_config_word,
305         tx4927_pcibios_write_config_dword
306 };