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