aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-mips/io.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-mips/io.h')
-rw-r--r--include/asm-mips/io.h164
1 files changed, 109 insertions, 55 deletions
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 039845f2e6b0..3061870b7f6c 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -25,7 +25,9 @@
25#include <asm/page.h> 25#include <asm/page.h>
26#include <asm/pgtable-bits.h> 26#include <asm/pgtable-bits.h>
27#include <asm/processor.h> 27#include <asm/processor.h>
28#include <asm/string.h>
28 29
30#include <ioremap.h>
29#include <mangle-port.h> 31#include <mangle-port.h>
30 32
31/* 33/*
@@ -34,7 +36,7 @@
34#undef CONF_SLOWDOWN_IO 36#undef CONF_SLOWDOWN_IO
35 37
36/* 38/*
37 * Raw operations are never swapped in software. Otoh values that raw 39 * Raw operations are never swapped in software. OTOH values that raw
38 * operations are working on may or may not have been swapped by the bus 40 * operations are working on may or may not have been swapped by the bus
39 * hardware. An example use would be for flash memory that's used for 41 * hardware. An example use would be for flash memory that's used for
40 * execute in place. 42 * execute in place.
@@ -43,45 +45,53 @@
43# define __raw_ioswabw(x) (x) 45# define __raw_ioswabw(x) (x)
44# define __raw_ioswabl(x) (x) 46# define __raw_ioswabl(x) (x)
45# define __raw_ioswabq(x) (x) 47# define __raw_ioswabq(x) (x)
48# define ____raw_ioswabq(x) (x)
46 49
47/* 50/*
48 * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; 51 * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
49 * less sane hardware forces software to fiddle with this... 52 * less sane hardware forces software to fiddle with this...
53 *
54 * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
55 * you can't have the numerical value of data and byte addresses within
56 * multibyte quantities both preserved at the same time. Hence two
57 * variations of functions: non-prefixed ones that preserve the value
58 * and prefixed ones that preserve byte addresses. The latters are
59 * typically used for moving raw data between a peripheral and memory (cf.
60 * string I/O functions), hence the "mem_" prefix.
50 */ 61 */
51#if defined(CONFIG_SWAP_IO_SPACE) 62#if defined(CONFIG_SWAP_IO_SPACE)
52 63
53# define ioswabb(x) (x) 64# define ioswabb(x) (x)
65# define mem_ioswabb(x) (x)
54# ifdef CONFIG_SGI_IP22 66# ifdef CONFIG_SGI_IP22
55/* 67/*
56 * IP22 seems braindead enough to swap 16bits values in hardware, but 68 * IP22 seems braindead enough to swap 16bits values in hardware, but
57 * not 32bits. Go figure... Can't tell without documentation. 69 * not 32bits. Go figure... Can't tell without documentation.
58 */ 70 */
59# define ioswabw(x) (x) 71# define ioswabw(x) (x)
72# define mem_ioswabw(x) le16_to_cpu(x)
60# else 73# else
61# define ioswabw(x) le16_to_cpu(x) 74# define ioswabw(x) le16_to_cpu(x)
75# define mem_ioswabw(x) (x)
62# endif 76# endif
63# define ioswabl(x) le32_to_cpu(x) 77# define ioswabl(x) le32_to_cpu(x)
78# define mem_ioswabl(x) (x)
64# define ioswabq(x) le64_to_cpu(x) 79# define ioswabq(x) le64_to_cpu(x)
80# define mem_ioswabq(x) (x)
65 81
66#else 82#else
67 83
68# define ioswabb(x) (x) 84# define ioswabb(x) (x)
85# define mem_ioswabb(x) (x)
69# define ioswabw(x) (x) 86# define ioswabw(x) (x)
87# define mem_ioswabw(x) cpu_to_le16(x)
70# define ioswabl(x) (x) 88# define ioswabl(x) (x)
89# define mem_ioswabl(x) cpu_to_le32(x)
71# define ioswabq(x) (x) 90# define ioswabq(x) (x)
91# define mem_ioswabq(x) cpu_to_le32(x)
72 92
73#endif 93#endif
74 94
75/*
76 * Native bus accesses never swapped.
77 */
78#define bus_ioswabb(x) (x)
79#define bus_ioswabw(x) (x)
80#define bus_ioswabl(x) (x)
81#define bus_ioswabq(x) (x)
82
83#define __bus_ioswabq bus_ioswabq
84
85#define IO_SPACE_LIMIT 0xffff 95#define IO_SPACE_LIMIT 0xffff
86 96
87/* 97/*
@@ -194,12 +204,14 @@ extern unsigned long isa_slot_offset;
194 */ 204 */
195#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) 205#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
196 206
197extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags); 207extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
198extern void __iounmap(volatile void __iomem *addr); 208extern void __iounmap(volatile void __iomem *addr);
199 209
200static inline void * __ioremap_mode(phys_t offset, unsigned long size, 210static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
201 unsigned long flags) 211 unsigned long flags)
202{ 212{
213#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
214
203 if (cpu_has_64bit_addresses) { 215 if (cpu_has_64bit_addresses) {
204 u64 base = UNCAC_BASE; 216 u64 base = UNCAC_BASE;
205 217
@@ -209,10 +221,30 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size,
209 */ 221 */
210 if (flags == _CACHE_UNCACHED) 222 if (flags == _CACHE_UNCACHED)
211 base = (u64) IO_BASE; 223 base = (u64) IO_BASE;
212 return (void *) (unsigned long) (base + offset); 224 return (void __iomem *) (unsigned long) (base + offset);
225 } else if (__builtin_constant_p(offset) &&
226 __builtin_constant_p(size) && __builtin_constant_p(flags)) {
227 phys_t phys_addr, last_addr;
228
229 phys_addr = fixup_bigphys_addr(offset, size);
230
231 /* Don't allow wraparound or zero size. */
232 last_addr = phys_addr + size - 1;
233 if (!size || last_addr < phys_addr)
234 return NULL;
235
236 /*
237 * Map uncached objects in the low 512MB of address
238 * space using KSEG1.
239 */
240 if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
241 flags == _CACHE_UNCACHED)
242 return (void __iomem *)CKSEG1ADDR(phys_addr);
213 } 243 }
214 244
215 return __ioremap(offset, size, flags); 245 return __ioremap(offset, size, flags);
246
247#undef __IS_LOW512
216} 248}
217 249
218/* 250/*
@@ -264,12 +296,16 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size,
264 296
265static inline void iounmap(volatile void __iomem *addr) 297static inline void iounmap(volatile void __iomem *addr)
266{ 298{
267 if (cpu_has_64bit_addresses) 299#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
300
301 if (cpu_has_64bit_addresses ||
302 (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
268 return; 303 return;
269 304
270 __iounmap(addr); 305 __iounmap(addr);
271}
272 306
307#undef __IS_KSEG1
308}
273 309
274#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ 310#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
275 \ 311 \
@@ -319,7 +355,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \
319 else if (cpu_has_64bits) { \ 355 else if (cpu_has_64bits) { \
320 unsigned long __flags; \ 356 unsigned long __flags; \
321 \ 357 \
322 local_irq_save(__flags); \ 358 if (irq) \
359 local_irq_save(__flags); \
323 __asm__ __volatile__( \ 360 __asm__ __volatile__( \
324 ".set mips3" "\t\t# __readq" "\n\t" \ 361 ".set mips3" "\t\t# __readq" "\n\t" \
325 "ld %L0, %1" "\n\t" \ 362 "ld %L0, %1" "\n\t" \
@@ -328,7 +365,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \
328 ".set mips0" "\n" \ 365 ".set mips0" "\n" \
329 : "=r" (__val) \ 366 : "=r" (__val) \
330 : "m" (*__mem)); \ 367 : "m" (*__mem)); \
331 local_irq_restore(__flags); \ 368 if (irq) \
369 local_irq_restore(__flags); \
332 } else { \ 370 } else { \
333 __val = 0; \ 371 __val = 0; \
334 BUG(); \ 372 BUG(); \
@@ -349,11 +387,11 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
349 \ 387 \
350 __val = pfx##ioswab##bwlq(val); \ 388 __val = pfx##ioswab##bwlq(val); \
351 \ 389 \
352 if (sizeof(type) != sizeof(u64)) { \ 390 /* Really, we want this to be atomic */ \
353 *__addr = __val; \ 391 BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
354 slow; \ 392 \
355 } else \ 393 *__addr = __val; \
356 BUILD_BUG(); \ 394 slow; \
357} \ 395} \
358 \ 396 \
359static inline type pfx##in##bwlq##p(unsigned long port) \ 397static inline type pfx##in##bwlq##p(unsigned long port) \
@@ -364,13 +402,10 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
364 port = __swizzle_addr_##bwlq(port); \ 402 port = __swizzle_addr_##bwlq(port); \
365 __addr = (void *)(mips_io_port_base + port); \ 403 __addr = (void *)(mips_io_port_base + port); \
366 \ 404 \
367 if (sizeof(type) != sizeof(u64)) { \ 405 BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
368 __val = *__addr; \ 406 \
369 slow; \ 407 __val = *__addr; \
370 } else { \ 408 slow; \
371 __val = 0; \
372 BUILD_BUG(); \
373 } \
374 \ 409 \
375 return pfx##ioswab##bwlq(__val); \ 410 return pfx##ioswab##bwlq(__val); \
376} 411}
@@ -379,27 +414,35 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
379 \ 414 \
380__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1) 415__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
381 416
382#define __BUILD_IOPORT_PFX(bus, bwlq, type) \ 417#define BUILDIO_MEM(bwlq, type) \
383 \
384__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
385__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
386
387#define BUILDIO(bwlq, type) \
388 \ 418 \
389__BUILD_MEMORY_PFX(, bwlq, type) \
390__BUILD_MEMORY_PFX(__raw_, bwlq, type) \ 419__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
391__BUILD_MEMORY_PFX(bus_, bwlq, type) \ 420__BUILD_MEMORY_PFX(, bwlq, type) \
392__BUILD_IOPORT_PFX(, bwlq, type) \ 421__BUILD_MEMORY_PFX(mem_, bwlq, type) \
393__BUILD_IOPORT_PFX(__raw_, bwlq, type) 422
423BUILDIO_MEM(b, u8)
424BUILDIO_MEM(w, u16)
425BUILDIO_MEM(l, u32)
426BUILDIO_MEM(q, u64)
427
428#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
429 __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
430 __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
431
432#define BUILDIO_IOPORT(bwlq, type) \
433 __BUILD_IOPORT_PFX(, bwlq, type) \
434 __BUILD_IOPORT_PFX(mem_, bwlq, type)
435
436BUILDIO_IOPORT(b, u8)
437BUILDIO_IOPORT(w, u16)
438BUILDIO_IOPORT(l, u32)
439#ifdef CONFIG_64BIT
440BUILDIO_IOPORT(q, u64)
441#endif
394 442
395#define __BUILDIO(bwlq, type) \ 443#define __BUILDIO(bwlq, type) \
396 \ 444 \
397__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0) 445__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
398
399BUILDIO(b, u8)
400BUILDIO(w, u16)
401BUILDIO(l, u32)
402BUILDIO(q, u64)
403 446
404__BUILDIO(q, u64) 447__BUILDIO(q, u64)
405 448
@@ -422,7 +465,7 @@ static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \
422 volatile type *__addr = addr; \ 465 volatile type *__addr = addr; \
423 \ 466 \
424 while (count--) { \ 467 while (count--) { \
425 __raw_write##bwlq(*__addr, mem); \ 468 mem_write##bwlq(*__addr, mem); \
426 __addr++; \ 469 __addr++; \
427 } \ 470 } \
428} \ 471} \
@@ -433,20 +476,20 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
433 volatile type *__addr = addr; \ 476 volatile type *__addr = addr; \
434 \ 477 \
435 while (count--) { \ 478 while (count--) { \
436 *__addr = __raw_read##bwlq(mem); \ 479 *__addr = mem_read##bwlq(mem); \
437 __addr++; \ 480 __addr++; \
438 } \ 481 } \
439} 482}
440 483
441#define __BUILD_IOPORT_STRING(bwlq, type) \ 484#define __BUILD_IOPORT_STRING(bwlq, type) \
442 \ 485 \
443static inline void outs##bwlq(unsigned long port, void *addr, \ 486static inline void outs##bwlq(unsigned long port, const void *addr, \
444 unsigned int count) \ 487 unsigned int count) \
445{ \ 488{ \
446 volatile type *__addr = addr; \ 489 const volatile type *__addr = addr; \
447 \ 490 \
448 while (count--) { \ 491 while (count--) { \
449 __raw_out##bwlq(*__addr, port); \ 492 mem_out##bwlq(*__addr, port); \
450 __addr++; \ 493 __addr++; \
451 } \ 494 } \
452} \ 495} \
@@ -457,7 +500,7 @@ static inline void ins##bwlq(unsigned long port, void *addr, \
457 volatile type *__addr = addr; \ 500 volatile type *__addr = addr; \
458 \ 501 \
459 while (count--) { \ 502 while (count--) { \
460 *__addr = __raw_in##bwlq(port); \ 503 *__addr = mem_in##bwlq(port); \
461 __addr++; \ 504 __addr++; \
462 } \ 505 } \
463} 506}
@@ -470,15 +513,26 @@ __BUILD_IOPORT_STRING(bwlq, type)
470BUILDSTRING(b, u8) 513BUILDSTRING(b, u8)
471BUILDSTRING(w, u16) 514BUILDSTRING(w, u16)
472BUILDSTRING(l, u32) 515BUILDSTRING(l, u32)
516#ifdef CONFIG_64BIT
473BUILDSTRING(q, u64) 517BUILDSTRING(q, u64)
518#endif
474 519
475 520
476/* Depends on MIPS II instruction set */ 521/* Depends on MIPS II instruction set */
477#define mmiowb() asm volatile ("sync" ::: "memory") 522#define mmiowb() asm volatile ("sync" ::: "memory")
478 523
479#define memset_io(a,b,c) memset((void *)(a),(b),(c)) 524static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
480#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) 525{
481#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) 526 memset((void __force *) addr, val, count);
527}
528static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
529{
530 memcpy(dst, (void __force *) src, count);
531}
532static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
533{
534 memcpy((void __force *) dst, src, count);
535}
482 536
483/* 537/*
484 * Memory Mapped I/O 538 * Memory Mapped I/O