sh: Consolidated SH7751/SH7780 PCI support.
[linux-2.6.git] / arch / sh / boards / renesas / rts7751r2d / io.c
1 /*
2  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
3  * Based largely on io_se.c.
4  *
5  * I/O routine for Renesas Technology sales RTS7751R2D.
6  *
7  * Initial version only to support LAN access; some
8  * placeholder code from io_rts7751r2d.c left in with the
9  * expectation of later SuperIO and PCMCIA access.
10  */
11 #include <linux/kernel.h>
12 #include <linux/types.h>
13 #include <linux/pci.h>
14 #include <asm/rts7751r2d/rts7751r2d.h>
15 #include <asm/io.h>
16 #include <asm/addrspace.h>
17
18 /*
19  * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC)
20  * of the 7751R processor, and has a SuperIO accessible via the PCI.
21  * The board also includes a PCMCIA controller on its memory bus,
22  * like the other Solution Engine boards.
23  */
24
25 static inline unsigned long port2adr(unsigned int port)
26 {
27         if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
28                 if (port == 0x3f6)
29                         return (PA_AREA5_IO + 0x80c);
30                 else
31                         return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
32         else
33                 maybebadio((unsigned long)port);
34
35         return port;
36 }
37
38 static inline unsigned long port88796l(unsigned int port, int flag)
39 {
40         unsigned long addr;
41
42         if (flag)
43                 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
44         else
45                 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
46
47         return addr;
48 }
49
50 /* The 7751R RTS7751R2D seems to have everything hooked */
51 /* up pretty normally (nothing on high-bytes only...) so this */
52 /* shouldn't be needed */
53 static inline int shifted_port(unsigned long port)
54 {
55         /* For IDE registers, value is not shifted */
56         if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
57                 return 0;
58         else
59                 return 1;
60 }
61
62 #if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
63 #define CHECK_AX88796L_PORT(port) \
64   ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
65 #else
66 #define CHECK_AX88796L_PORT(port) (0)
67 #endif
68
69 /*
70  * General outline: remap really low stuff [eventually] to SuperIO,
71  * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
72  * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
73  * should be way beyond the window, and is used  w/o translation for
74  * compatibility.
75  */
76 unsigned char rts7751r2d_inb(unsigned long port)
77 {
78         if (CHECK_AX88796L_PORT(port))
79                 return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
80         else if (PXSEG(port))
81                 return *(volatile unsigned char *)port;
82         else if (is_pci_ioaddr(port) || shifted_port(port))
83                 return *(volatile unsigned char *)pci_ioaddr(port);
84         else
85                 return (*(volatile unsigned short *)port2adr(port) & 0xff);
86 }
87
88 unsigned char rts7751r2d_inb_p(unsigned long port)
89 {
90         unsigned char v;
91
92         if (CHECK_AX88796L_PORT(port))
93                 v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
94         else if (PXSEG(port))
95                 v = *(volatile unsigned char *)port;
96         else if (is_pci_ioaddr(port) || shifted_port(port))
97                 v = *(volatile unsigned char *)pci_ioaddr(port);
98         else
99                 v = (*(volatile unsigned short *)port2adr(port) & 0xff);
100
101         ctrl_delay();
102
103         return v;
104 }
105
106 unsigned short rts7751r2d_inw(unsigned long port)
107 {
108         if (CHECK_AX88796L_PORT(port))
109                 maybebadio(port);
110         else if (PXSEG(port))
111                 return *(volatile unsigned short *)port;
112         else if (is_pci_ioaddr(port) || shifted_port(port))
113                 return *(volatile unsigned short *)pci_ioaddr(port);
114         else
115                 maybebadio(port);
116
117         return 0;
118 }
119
120 unsigned int rts7751r2d_inl(unsigned long port)
121 {
122         if (CHECK_AX88796L_PORT(port))
123                 maybebadio(port);
124         else if (PXSEG(port))
125                 return *(volatile unsigned long *)port;
126         else if (is_pci_ioaddr(port) || shifted_port(port))
127                 return *(volatile unsigned long *)pci_ioaddr(port);
128         else
129                 maybebadio(port);
130
131         return 0;
132 }
133
134 void rts7751r2d_outb(unsigned char value, unsigned long port)
135 {
136         if (CHECK_AX88796L_PORT(port))
137                 *((volatile unsigned short *)port88796l(port, 0)) = value;
138         else if (PXSEG(port))
139                 *(volatile unsigned char *)port = value;
140         else if (is_pci_ioaddr(port) || shifted_port(port))
141                 *(volatile unsigned char *)pci_ioaddr(port) = value;
142         else
143                 *(volatile unsigned short *)port2adr(port) = value;
144 }
145
146 void rts7751r2d_outb_p(unsigned char value, unsigned long port)
147 {
148         if (CHECK_AX88796L_PORT(port))
149                 *((volatile unsigned short *)port88796l(port, 0)) = value;
150         else if (PXSEG(port))
151                 *(volatile unsigned char *)port = value;
152         else if (is_pci_ioaddr(port) || shifted_port(port))
153                 *(volatile unsigned char *)pci_ioaddr(port) = value;
154         else
155                 *(volatile unsigned short *)port2adr(port) = value;
156
157         ctrl_delay();
158 }
159
160 void rts7751r2d_outw(unsigned short value, unsigned long port)
161 {
162         if (CHECK_AX88796L_PORT(port))
163                 maybebadio(port);
164         else if (PXSEG(port))
165                 *(volatile unsigned short *)port = value;
166         else if (is_pci_ioaddr(port) || shifted_port(port))
167                 *(volatile unsigned short *)pci_ioaddr(port) = value;
168         else
169                 maybebadio(port);
170 }
171
172 void rts7751r2d_outl(unsigned int value, unsigned long port)
173 {
174         if (CHECK_AX88796L_PORT(port))
175                 maybebadio(port);
176         else if (PXSEG(port))
177                 *(volatile unsigned long *)port = value;
178         else if (is_pci_ioaddr(port) || shifted_port(port))
179                 *(volatile unsigned long *)pci_ioaddr(port) = value;
180         else
181                 maybebadio(port);
182 }
183
184 void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count)
185 {
186         unsigned long a = (unsigned long)addr;
187         volatile __u8 *bp;
188         volatile __u16 *p;
189
190         if (CHECK_AX88796L_PORT(port)) {
191                 p = (volatile unsigned short *)port88796l(port, 0);
192                 while (count--)
193                         ctrl_outb(*p & 0xff, a++);
194         } else if (PXSEG(port))
195                 while (count--)
196                         ctrl_outb(ctrl_inb(port), a++);
197         else if (is_pci_ioaddr(port) || shifted_port(port)) {
198                 bp = (__u8 *)pci_ioaddr(port);
199                 while (count--)
200                         ctrl_outb(*bp, a++);
201         } else {
202                 p = (volatile unsigned short *)port2adr(port);
203                 while (count--)
204                         ctrl_outb(*p & 0xff, a++);
205         }
206 }
207
208 void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
209 {
210         unsigned long a = (unsigned long)addr;
211         volatile __u16 *p;
212
213         if (CHECK_AX88796L_PORT(port))
214                 p = (volatile unsigned short *)port88796l(port, 1);
215         else if (PXSEG(port))
216                 p = (volatile unsigned short *)port;
217         else if (is_pci_ioaddr(port) || shifted_port(port))
218                 p = (volatile unsigned short *)pci_ioaddr(port);
219         else
220                 p = (volatile unsigned short *)port2adr(port);
221         while (count--)
222                 ctrl_outw(*p, a++);
223 }
224
225 void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
226 {
227         if (CHECK_AX88796L_PORT(port))
228                 maybebadio(port);
229         else if (is_pci_ioaddr(port) || shifted_port(port)) {
230                 unsigned long a = (unsigned long)addr;
231
232                 while (count--) {
233                         ctrl_outl(ctrl_inl(pci_ioaddr(port)), a);
234                         a += 4;
235                 }
236         } else
237                 maybebadio(port);
238 }
239
240 void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
241 {
242         unsigned long a = (unsigned long)addr;
243         volatile __u8 *bp;
244         volatile __u16 *p;
245
246         if (CHECK_AX88796L_PORT(port)) {
247                 p = (volatile unsigned short *)port88796l(port, 0);
248                 while (count--)
249                         *p = ctrl_inb(a++);
250         } else if (PXSEG(port))
251                 while (count--)
252                         ctrl_outb(a++, port);
253         else if (is_pci_ioaddr(port) || shifted_port(port)) {
254                 bp = (__u8 *)pci_ioaddr(port);
255                 while (count--)
256                         *bp = ctrl_inb(a++);
257         } else {
258                 p = (volatile unsigned short *)port2adr(port);
259                 while (count--)
260                         *p = ctrl_inb(a++);
261         }
262 }
263
264 void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
265 {
266         unsigned long a = (unsigned long)addr;
267         volatile __u16 *p;
268
269         if (CHECK_AX88796L_PORT(port))
270                 p = (volatile unsigned short *)port88796l(port, 1);
271         else if (PXSEG(port))
272                 p = (volatile unsigned short *)port;
273         else if (is_pci_ioaddr(port) || shifted_port(port))
274                 p = (volatile unsigned short *)pci_ioaddr(port);
275         else
276                 p = (volatile unsigned short *)port2adr(port);
277
278         while (count--) {
279                 ctrl_outw(*p, a);
280                 a += 2;
281         }
282 }
283
284 void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
285 {
286         if (CHECK_AX88796L_PORT(port))
287                 maybebadio(port);
288         else if (is_pci_ioaddr(port) || shifted_port(port)) {
289                 unsigned long a = (unsigned long)addr;
290
291                 while (count--) {
292                         ctrl_outl(ctrl_inl(a), pci_ioaddr(port));
293                         a += 4;
294                 }
295         } else
296                 maybebadio(port);
297 }
298
299 unsigned long rts7751r2d_isa_port2addr(unsigned long offset)
300 {
301         return port2adr(offset);
302 }