more changes on original files
[linux-2.4.git] / arch / mips / jmr3927 / rbhma3100 / pci_ops.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 JMR3927.
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  */
36 #include <linux/types.h>
37 #include <linux/pci.h>
38 #include <linux/kernel.h>
39 #include <linux/init.h>
40
41 #include <asm/addrspace.h>
42 #include <asm/pci_channel.h>
43 #include <asm/jmr3927/jmr3927.h>
44 #include <asm/debug.h>
45
46 struct resource pci_io_resource = {
47         "pci IO space",
48         0x1000,  /* reserve regacy I/O space */
49         0x1000 + JMR3927_PCIIO_SIZE -1,
50         IORESOURCE_IO};
51
52 struct resource pci_mem_resource = {
53         "pci memory space",
54         JMR3927_PCIMEM,
55         JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE -1,
56         IORESOURCE_MEM};
57
58 extern struct pci_ops jmr3927_pci_ops;
59
60 struct pci_channel mips_pci_channels[] = {
61         { &jmr3927_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 0xff },
62         { NULL, NULL, NULL, NULL, NULL}
63 };
64
65 unsigned int pcibios_assign_all_busses(void)
66 {
67         return 1;
68 }
69
70 static int
71 mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, int *flagsp)
72 {
73         if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
74                 return -1;
75
76         tx3927_pcicptr->ica = ((bus    & 0xff) << 0x10) |
77                               ((dev_fn & 0xff) << 0x08) |
78                               (where  & 0xfc);
79         /* clear M_ABORT and Disable M_ABORT Int. */
80         tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
81         tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
82         return 0;
83 }
84
85 static int
86 check_abort(int flags)
87 {
88         int code = PCIBIOS_SUCCESSFUL;
89         if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) {
90                 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
91                 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
92                 code =PCIBIOS_DEVICE_NOT_FOUND;
93         }
94         return code;
95 }
96
97 /*
98  * We can't address 8 and 16 bit words directly.  Instead we have to
99  * read/write a 32bit word and mask/modify the data we actually want.
100  */
101 static int jmr3927_pcibios_read_config_byte (struct pci_dev *dev,
102                                              int where,
103                                              unsigned char *val)
104 {
105         int flags;
106         unsigned char bus, func_num;
107
108         db_assert((where & 3) == 0);
109         db_assert(where < (1 << 8));
110
111         /* check if the bus is top-level */
112         if (dev->bus->parent != NULL) {
113                 bus = dev->bus->number;
114                 db_assert(bus != 0);
115         } else {
116                 bus = 0;
117         }
118
119         func_num = PCI_FUNC(dev->devfn);
120         if (mkaddr(bus, dev->devfn, where, &flags))
121                 return -1;
122         *val = *(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3));
123         return check_abort(flags);
124 }
125
126 static int jmr3927_pcibios_read_config_word (struct pci_dev *dev,
127                                              int where,
128                                              unsigned short *val)
129 {
130         int flags;
131         unsigned char bus, func_num;
132
133         if (where & 1)
134                 return PCIBIOS_BAD_REGISTER_NUMBER;
135
136         db_assert((where & 3) == 0);
137         db_assert(where < (1 << 8));
138
139         /* check if the bus is top-level */
140         if (dev->bus->parent != NULL) {
141                 bus = dev->bus->number;
142                 db_assert(bus != 0);
143         } else {
144                 bus = 0;
145         }
146
147         func_num = PCI_FUNC(dev->devfn);
148         if (mkaddr(bus, dev->devfn, where, &flags))
149                 return -1;
150         *val = le16_to_cpu(*(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3)));
151         return check_abort(flags);
152 }
153
154 static int jmr3927_pcibios_read_config_dword (struct pci_dev *dev,
155                                               int where,
156                                               unsigned int *val)
157 {
158         int flags;
159         unsigned char bus, func_num;
160
161         if (where & 3)
162                 return PCIBIOS_BAD_REGISTER_NUMBER;
163
164         db_assert((where & 3) == 0);
165         db_assert(where < (1 << 8));
166
167         /* check if the bus is top-level */
168         if (dev->bus->parent != NULL) {
169                 bus = dev->bus->number;
170                 db_assert(bus != 0);
171         } else {
172                 bus = 0;
173         }
174
175         func_num = PCI_FUNC(dev->devfn);
176         if (mkaddr(bus, dev->devfn, where, &flags))
177                 return -1;
178         *val = le32_to_cpu(tx3927_pcicptr->icd);
179         return check_abort(flags);
180 }
181
182 static int jmr3927_pcibios_write_config_byte (struct pci_dev *dev,
183                                               int where,
184                                               unsigned char val)
185 {
186         int flags;
187         unsigned char bus, func_num;
188
189         /* check if the bus is top-level */
190         if (dev->bus->parent != NULL) {
191                 bus = dev->bus->number;
192                 db_assert(bus != 0);
193         } else {
194                 bus = 0;
195         }
196
197         func_num = PCI_FUNC(dev->devfn);
198         if (mkaddr(bus, dev->devfn, where, &flags))
199                 return -1;
200         *(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = val;
201         return check_abort(flags);
202 }
203
204 static int jmr3927_pcibios_write_config_word (struct pci_dev *dev,
205                                               int where,
206                                               unsigned short val)
207 {
208         int flags;
209         unsigned char bus, func_num;
210
211         if (where & 1)
212                 return PCIBIOS_BAD_REGISTER_NUMBER;
213
214         /* check if the bus is top-level */
215         if (dev->bus->parent != NULL) {
216                 bus = dev->bus->number;
217                 db_assert(bus != 0);
218         } else {
219                 bus = 0;
220         }
221
222         func_num = PCI_FUNC(dev->devfn);
223         if (mkaddr(bus, dev->devfn, where, &flags))
224                 return -1;
225         *(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = cpu_to_le16(val);
226         return check_abort(flags);
227 }
228
229 static int jmr3927_pcibios_write_config_dword (struct pci_dev *dev,
230                                                int where,
231                                                unsigned int val)
232 {
233         int flags;
234         unsigned char bus, func_num;
235
236         if (where & 3)
237                 return PCIBIOS_BAD_REGISTER_NUMBER;
238
239         /* check if the bus is top-level */
240         if (dev->bus->parent != NULL) {
241                 bus = dev->bus->number;
242                 db_assert(bus != 0);
243         } else {
244                 bus = 0;
245         }
246
247         func_num = PCI_FUNC(dev->devfn);
248         if (mkaddr(bus, dev->devfn, where, &flags))
249                 return -1;
250         tx3927_pcicptr->icd = cpu_to_le32(val);
251         return check_abort(flags);
252 }
253 struct pci_ops jmr3927_pci_ops = {
254         jmr3927_pcibios_read_config_byte,
255         jmr3927_pcibios_read_config_word,
256         jmr3927_pcibios_read_config_dword,
257         jmr3927_pcibios_write_config_byte,
258         jmr3927_pcibios_write_config_word,
259         jmr3927_pcibios_write_config_dword
260 };
261
262 #ifndef JMR3927_INIT_INDIRECT_PCI
263 inline unsigned long tc_readl(volatile __u32 *addr)
264 {
265         return readl(addr);
266 }
267 inline void tc_writel(unsigned long data, volatile __u32 *addr)
268 {
269         writel(data, addr);
270 }
271 #else
272 unsigned long tc_readl(volatile __u32 *addr)
273 {
274         unsigned long val;
275
276         addr = PHYSADDR(addr);
277         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)addr;
278         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
279             (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG;
280         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
281         val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
282         /* clear by setting */
283         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
284         return val;
285 }
286 void tc_writel(unsigned long data, volatile __u32 *addr)
287 {
288         addr = PHYSADDR(addr);
289         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data);
290         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)addr;
291         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
292             (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT)  | PCI_IPCIBE_IBE_LONG;
293         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
294         /* clear by setting */
295         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
296 }
297 unsigned char tx_ioinb(unsigned char *addr)
298 {
299         unsigned long val;
300         __u32 ioaddr;
301         int offset;
302         int byte;
303
304         ioaddr = (unsigned long)addr;
305         offset = ioaddr & 0x3;
306         if (offset == 0)
307                 byte = 0x7;
308         else if (offset == 1)
309                 byte = 0xb;
310         else if (offset == 2)
311                 byte = 0xd;
312         else if (offset == 3)
313                 byte = 0xe;
314         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
315         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
316             (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
317         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
318         val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
319         val = val & 0xff;
320         /* clear by setting */
321         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
322         return val;
323 }
324 void tx_iooutb(unsigned long data, unsigned char *addr)
325 {
326         __u32 ioaddr;
327         int offset;
328         int byte;
329
330         data = data | (data << 8) | (data << 16) | (data << 24);
331         ioaddr = (unsigned long)addr;
332         offset = ioaddr & 0x3;
333         if (offset == 0)
334                 byte = 0x7;
335         else if (offset == 1)
336                 byte = 0xb;
337         else if (offset == 2)
338                 byte = 0xd;
339         else if (offset == 3)
340                 byte = 0xe;
341         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data;
342         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
343         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
344             (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | byte;
345         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
346         /* clear by setting */
347         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
348 }
349 unsigned short tx_ioinw(unsigned short *addr)
350 {
351         unsigned long val;
352         __u32 ioaddr;
353         int offset;
354         int byte;
355
356         ioaddr = (unsigned long)addr;
357         offset = ioaddr & 0x3;
358         if (offset == 0)
359                 byte = 0x3;
360         else if (offset == 2)
361                 byte = 0xc;
362         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
363         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
364             (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
365         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
366         val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
367         val = val & 0xffff;
368         /* clear by setting */
369         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
370         return val;
371
372 }
373 void tx_iooutw(unsigned long data, unsigned short *addr)
374 {
375         __u32 ioaddr;
376         int offset;
377         int byte;
378
379         data = data | (data << 16);
380         ioaddr = (unsigned long)addr;
381         offset = ioaddr & 0x3;
382         if (offset == 0)
383                 byte = 0x3;
384         else if (offset == 2)
385                 byte = 0xc;
386         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data;
387         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
388         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
389             (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | byte;
390         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
391         /* clear by setting */
392         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
393 }
394 unsigned long tx_ioinl(unsigned int *addr)
395 {
396         unsigned long val;
397         __u32 ioaddr;
398
399         ioaddr = (unsigned long)addr;
400         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
401         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
402             (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG;
403         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
404         val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
405         /* clear by setting */
406         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
407         return val;
408 }
409 void tx_iooutl(unsigned long data, unsigned int *addr)
410 {
411         __u32 ioaddr;
412
413         ioaddr = (unsigned long)addr;
414         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data);
415         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
416         *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =
417             (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | PCI_IPCIBE_IBE_LONG;
418         while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
419         /* clear by setting */
420         tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
421 }
422 void tx_insbyte(unsigned char *addr,void *buffer,unsigned int count)
423 {
424         unsigned char *ptr = (unsigned char *) buffer;
425
426         while (count--) {
427                 *ptr++ = tx_ioinb(addr);
428         }
429 }
430 void tx_insword(unsigned short *addr,void *buffer,unsigned int count)
431 {
432         unsigned short *ptr = (unsigned short *) buffer;
433
434         while (count--) {
435                 *ptr++ = tx_ioinw(addr);
436         }
437 }
438 void tx_inslong(unsigned int *addr,void *buffer,unsigned int count)
439 {
440         unsigned long *ptr = (unsigned long *) buffer;
441
442         while (count--) {
443                 *ptr++ = tx_ioinl(addr);
444         }
445 }
446 void tx_outsbyte(unsigned char *addr,void *buffer,unsigned int count)
447 {
448         unsigned char *ptr = (unsigned char *) buffer;
449
450         while (count--) {
451                 tx_iooutb(*ptr++,addr);
452         }
453 }
454 void tx_outsword(unsigned short *addr,void *buffer,unsigned int count)
455 {
456         unsigned short *ptr = (unsigned short *) buffer;
457
458         while (count--) {
459                 tx_iooutw(*ptr++,addr);
460         }
461 }
462 void tx_outslong(unsigned int *addr,void *buffer,unsigned int count)
463 {
464         unsigned long *ptr = (unsigned long *) buffer;
465
466         while (count--) {
467                 tx_iooutl(*ptr++,addr);
468         }
469 }
470 #endif