Merge remote-tracking branches 'asoc/topic/rl6231' and 'asoc/topic/rt5514' into asoc...
[sfrench/cifs-2.6.git] / arch / arm / mach-ebsa110 / io.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  linux/arch/arm/mach-ebsa110/isamem.c
4  *
5  *  Copyright (C) 2001 Russell King
6  *
7  * Perform "ISA" memory and IO accesses.  The EBSA110 has some "peculiarities"
8  * in the way it handles accesses to odd IO ports on 16-bit devices.  These
9  * devices have their D0-D15 lines connected to the processors D0-D15 lines.
10  * Since they expect all byte IO operations to be performed on D0-D7, and the
11  * StrongARM expects to transfer the byte to these odd addresses on D8-D15,
12  * we must use a trick to get the required behaviour.
13  *
14  * The trick employed here is to use long word stores to odd address -1.  The
15  * glue logic picks this up as a "trick" access, and asserts the LSB of the
16  * peripherals address bus, thereby accessing the odd IO port.  Meanwhile, the
17  * StrongARM transfers its data on D0-D7 as expected.
18  *
19  * Things get more interesting on the pass-1 EBSA110 - the PCMCIA controller
20  * wiring was screwed in such a way that it had limited memory space access.
21  * Luckily, the work-around for this is not too horrible.  See
22  * __isamem_convert_addr for the details.
23  */
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/types.h>
27 #include <linux/io.h>
28
29 #include <mach/hardware.h>
30 #include <asm/page.h>
31
32 static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr)
33 {
34         u32 ret, a = (u32 __force) addr;
35
36         /*
37          * The PCMCIA controller is wired up as follows:
38          *        +---------+---------+---------+---------+---------+---------+
39          * PCMCIA | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1     |         |         |
40          *        | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 |
41          *        +---------+---------+---------+---------+---------+---------+
42          *  CPU   | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1   |         |         |
43          *        | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x |
44          *        +---------+---------+---------+---------+---------+---------+
45          *
46          * This means that we can access PCMCIA regions as follows:
47          *      0x*10000 -> 0x*1ffff
48          *      0x*70000 -> 0x*7ffff
49          *      0x*90000 -> 0x*9ffff
50          *      0x*f0000 -> 0x*fffff
51          */
52         ret  = (a & 0xf803fe) << 1;
53         ret |= (a & 0x03fc00) << 2;
54
55         ret += 0xe8000000;
56
57         if ((a & 0x20000) == (a & 0x40000) >> 1)
58                 return (void __iomem *)ret;
59
60         BUG();
61         return NULL;
62 }
63
64 /*
65  * read[bwl] and write[bwl]
66  */
67 u8 __readb(const volatile void __iomem *addr)
68 {
69         void __iomem *a = __isamem_convert_addr(addr);
70         u32 ret;
71
72         if ((unsigned long)addr & 1)
73                 ret = __raw_readl(a);
74         else
75                 ret = __raw_readb(a);
76         return ret;
77 }
78
79 u16 __readw(const volatile void __iomem *addr)
80 {
81         void __iomem *a = __isamem_convert_addr(addr);
82
83         if ((unsigned long)addr & 1)
84                 BUG();
85
86         return __raw_readw(a);
87 }
88
89 u32 __readl(const volatile void __iomem *addr)
90 {
91         void __iomem *a = __isamem_convert_addr(addr);
92         u32 ret;
93
94         if ((unsigned long)addr & 3)
95                 BUG();
96
97         ret = __raw_readw(a);
98         ret |= __raw_readw(a + 4) << 16;
99         return ret;
100 }
101
102 EXPORT_SYMBOL(__readb);
103 EXPORT_SYMBOL(__readw);
104 EXPORT_SYMBOL(__readl);
105
106 void readsw(const volatile void __iomem *addr, void *data, int len)
107 {
108         void __iomem *a = __isamem_convert_addr(addr);
109
110         BUG_ON((unsigned long)addr & 1);
111
112         __raw_readsw(a, data, len);
113 }
114 EXPORT_SYMBOL(readsw);
115
116 void readsl(const volatile void __iomem *addr, void *data, int len)
117 {
118         void __iomem *a = __isamem_convert_addr(addr);
119
120         BUG_ON((unsigned long)addr & 3);
121
122         __raw_readsl(a, data, len);
123 }
124 EXPORT_SYMBOL(readsl);
125
126 void __writeb(u8 val, volatile void __iomem *addr)
127 {
128         void __iomem *a = __isamem_convert_addr(addr);
129
130         if ((unsigned long)addr & 1)
131                 __raw_writel(val, a);
132         else
133                 __raw_writeb(val, a);
134 }
135
136 void __writew(u16 val, volatile void __iomem *addr)
137 {
138         void __iomem *a = __isamem_convert_addr(addr);
139
140         if ((unsigned long)addr & 1)
141                 BUG();
142
143         __raw_writew(val, a);
144 }
145
146 void __writel(u32 val, volatile void __iomem *addr)
147 {
148         void __iomem *a = __isamem_convert_addr(addr);
149
150         if ((unsigned long)addr & 3)
151                 BUG();
152
153         __raw_writew(val, a);
154         __raw_writew(val >> 16, a + 4);
155 }
156
157 EXPORT_SYMBOL(__writeb);
158 EXPORT_SYMBOL(__writew);
159 EXPORT_SYMBOL(__writel);
160
161 void writesw(volatile void __iomem *addr, const void *data, int len)
162 {
163         void __iomem *a = __isamem_convert_addr(addr);
164
165         BUG_ON((unsigned long)addr & 1);
166
167         __raw_writesw(a, data, len);
168 }
169 EXPORT_SYMBOL(writesw);
170
171 void writesl(volatile void __iomem *addr, const void *data, int len)
172 {
173         void __iomem *a = __isamem_convert_addr(addr);
174
175         BUG_ON((unsigned long)addr & 3);
176
177         __raw_writesl(a, data, len);
178 }
179 EXPORT_SYMBOL(writesl);
180
181 /*
182  * The EBSA110 has a weird "ISA IO" region:
183  *
184  * Region 0 (addr = 0xf0000000 + io << 2)
185  * --------------------------------------------------------
186  * Physical region      IO region
187  * f0000fe0 - f0000ffc  3f8 - 3ff  ttyS0
188  * f0000e60 - f0000e64  398 - 399
189  * f0000de0 - f0000dfc  378 - 37f  lp0
190  * f0000be0 - f0000bfc  2f8 - 2ff  ttyS1
191  *
192  * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
193  * --------------------------------------------------------
194  * Physical region      IO region
195  * f00014f1             a79        pnp write data
196  * f00007c0 - f00007c1  3e0 - 3e1  pcmcia
197  * f00004f1             279        pnp address
198  * f0000440 - f000046c  220 - 236  eth0
199  * f0000405             203        pnp read data
200  */
201 #define SUPERIO_PORT(p) \
202         (((p) >> 3) == (0x3f8 >> 3) || \
203          ((p) >> 3) == (0x2f8 >> 3) || \
204          ((p) >> 3) == (0x378 >> 3))
205
206 /*
207  * We're addressing an 8 or 16-bit peripheral which tranfers
208  * odd addresses on the low ISA byte lane.
209  */
210 u8 __inb8(unsigned int port)
211 {
212         u32 ret;
213
214         /*
215          * The SuperIO registers use sane addressing techniques...
216          */
217         if (SUPERIO_PORT(port))
218                 ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2));
219         else {
220                 void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
221
222                 /*
223                  * Shame nothing else does
224                  */
225                 if (port & 1)
226                         ret = __raw_readl(a);
227                 else
228                         ret = __raw_readb(a);
229         }
230         return ret;
231 }
232
233 /*
234  * We're addressing a 16-bit peripheral which transfers odd
235  * addresses on the high ISA byte lane.
236  */
237 u8 __inb16(unsigned int port)
238 {
239         unsigned int offset;
240
241         /*
242          * The SuperIO registers use sane addressing techniques...
243          */
244         if (SUPERIO_PORT(port))
245                 offset = port << 2;
246         else
247                 offset = (port & ~1) << 1 | (port & 1);
248
249         return __raw_readb((void __iomem *)ISAIO_BASE + offset);
250 }
251
252 u16 __inw(unsigned int port)
253 {
254         unsigned int offset;
255
256         /*
257          * The SuperIO registers use sane addressing techniques...
258          */
259         if (SUPERIO_PORT(port))
260                 offset = port << 2;
261         else {
262                 offset = port << 1;
263                 BUG_ON(port & 1);
264         }
265         return __raw_readw((void __iomem *)ISAIO_BASE + offset);
266 }
267
268 /*
269  * Fake a 32-bit read with two 16-bit reads.  Needed for 3c589.
270  */
271 u32 __inl(unsigned int port)
272 {
273         void __iomem *a;
274
275         if (SUPERIO_PORT(port) || port & 3)
276                 BUG();
277
278         a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
279
280         return __raw_readw(a) | __raw_readw(a + 4) << 16;
281 }
282
283 EXPORT_SYMBOL(__inb8);
284 EXPORT_SYMBOL(__inb16);
285 EXPORT_SYMBOL(__inw);
286 EXPORT_SYMBOL(__inl);
287
288 void __outb8(u8 val, unsigned int port)
289 {
290         /*
291          * The SuperIO registers use sane addressing techniques...
292          */
293         if (SUPERIO_PORT(port))
294                 __raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2));
295         else {
296                 void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
297
298                 /*
299                  * Shame nothing else does
300                  */
301                 if (port & 1)
302                         __raw_writel(val, a);
303                 else
304                         __raw_writeb(val, a);
305         }
306 }
307
308 void __outb16(u8 val, unsigned int port)
309 {
310         unsigned int offset;
311
312         /*
313          * The SuperIO registers use sane addressing techniques...
314          */
315         if (SUPERIO_PORT(port))
316                 offset = port << 2;
317         else
318                 offset = (port & ~1) << 1 | (port & 1);
319
320         __raw_writeb(val, (void __iomem *)ISAIO_BASE + offset);
321 }
322
323 void __outw(u16 val, unsigned int port)
324 {
325         unsigned int offset;
326
327         /*
328          * The SuperIO registers use sane addressing techniques...
329          */
330         if (SUPERIO_PORT(port))
331                 offset = port << 2;
332         else {
333                 offset = port << 1;
334                 BUG_ON(port & 1);
335         }
336         __raw_writew(val, (void __iomem *)ISAIO_BASE + offset);
337 }
338
339 void __outl(u32 val, unsigned int port)
340 {
341         BUG();
342 }
343
344 EXPORT_SYMBOL(__outb8);
345 EXPORT_SYMBOL(__outb16);
346 EXPORT_SYMBOL(__outw);
347 EXPORT_SYMBOL(__outl);
348
349 void outsb(unsigned int port, const void *from, int len)
350 {
351         u32 off;
352
353         if (SUPERIO_PORT(port))
354                 off = port << 2;
355         else {
356                 off = (port & ~1) << 1;
357                 if (port & 1)
358                         BUG();
359         }
360
361         __raw_writesb((void __iomem *)ISAIO_BASE + off, from, len);
362 }
363
364 void insb(unsigned int port, void *from, int len)
365 {
366         u32 off;
367
368         if (SUPERIO_PORT(port))
369                 off = port << 2;
370         else {
371                 off = (port & ~1) << 1;
372                 if (port & 1)
373                         BUG();
374         }
375
376         __raw_readsb((void __iomem *)ISAIO_BASE + off, from, len);
377 }
378
379 EXPORT_SYMBOL(outsb);
380 EXPORT_SYMBOL(insb);
381
382 void outsw(unsigned int port, const void *from, int len)
383 {
384         u32 off;
385
386         if (SUPERIO_PORT(port))
387                 off = port << 2;
388         else {
389                 off = (port & ~1) << 1;
390                 if (port & 1)
391                         BUG();
392         }
393
394         __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len);
395 }
396
397 void insw(unsigned int port, void *from, int len)
398 {
399         u32 off;
400
401         if (SUPERIO_PORT(port))
402                 off = port << 2;
403         else {
404                 off = (port & ~1) << 1;
405                 if (port & 1)
406                         BUG();
407         }
408
409         __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len);
410 }
411
412 EXPORT_SYMBOL(outsw);
413 EXPORT_SYMBOL(insw);
414
415 /*
416  * We implement these as 16-bit insw/outsw, mainly for
417  * 3c589 cards.
418  */
419 void outsl(unsigned int port, const void *from, int len)
420 {
421         u32 off = port << 1;
422
423         if (SUPERIO_PORT(port) || port & 3)
424                 BUG();
425
426         __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1);
427 }
428
429 void insl(unsigned int port, void *from, int len)
430 {
431         u32 off = port << 1;
432
433         if (SUPERIO_PORT(port) || port & 3)
434                 BUG();
435
436         __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1);
437 }
438
439 EXPORT_SYMBOL(outsl);
440 EXPORT_SYMBOL(insl);