183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0 */
2819833afSPeter Tyser /*
3819833afSPeter Tyser * Copyright (C) 1994, 1995 Waldorf GmbH
423ff8633SDaniel Schwierzeck * Copyright (C) 1994 - 2000, 06 Ralf Baechle
5819833afSPeter Tyser * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
623ff8633SDaniel Schwierzeck * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
723ff8633SDaniel Schwierzeck * Author: Maciej W. Rozycki <macro@mips.com>
8819833afSPeter Tyser */
9819833afSPeter Tyser #ifndef _ASM_IO_H
10819833afSPeter Tyser #define _ASM_IO_H
11819833afSPeter Tyser
12d6ea6d88STom Rini #include <linux/bug.h>
1323ff8633SDaniel Schwierzeck #include <linux/compiler.h>
1423ff8633SDaniel Schwierzeck #include <linux/types.h>
1523ff8633SDaniel Schwierzeck
16819833afSPeter Tyser #include <asm/addrspace.h>
17819833afSPeter Tyser #include <asm/byteorder.h>
1823ff8633SDaniel Schwierzeck #include <asm/cpu-features.h>
1923ff8633SDaniel Schwierzeck #include <asm/pgtable-bits.h>
2023ff8633SDaniel Schwierzeck #include <asm/processor.h>
2123ff8633SDaniel Schwierzeck #include <asm/string.h>
2223ff8633SDaniel Schwierzeck
2323ff8633SDaniel Schwierzeck #include <ioremap.h>
2423ff8633SDaniel Schwierzeck #include <mangle-port.h>
2523ff8633SDaniel Schwierzeck #include <spaces.h>
26819833afSPeter Tyser
27819833afSPeter Tyser /*
2823ff8633SDaniel Schwierzeck * Raw operations are never swapped in software. OTOH values that raw
2923ff8633SDaniel Schwierzeck * operations are working on may or may not have been swapped by the bus
3023ff8633SDaniel Schwierzeck * hardware. An example use would be for flash memory that's used for
3123ff8633SDaniel Schwierzeck * execute in place.
32819833afSPeter Tyser */
3323ff8633SDaniel Schwierzeck # define __raw_ioswabb(a, x) (x)
3423ff8633SDaniel Schwierzeck # define __raw_ioswabw(a, x) (x)
3523ff8633SDaniel Schwierzeck # define __raw_ioswabl(a, x) (x)
3623ff8633SDaniel Schwierzeck # define __raw_ioswabq(a, x) (x)
3723ff8633SDaniel Schwierzeck # define ____raw_ioswabq(a, x) (x)
38819833afSPeter Tyser
3923ff8633SDaniel Schwierzeck /* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
40819833afSPeter Tyser
4123ff8633SDaniel Schwierzeck #define IO_SPACE_LIMIT 0xffff
42819833afSPeter Tyser
4305e34255SPaul Burton #ifdef CONFIG_DYNAMIC_IO_PORT_BASE
44819833afSPeter Tyser
mips_io_port_base(void)4505e34255SPaul Burton static inline ulong mips_io_port_base(void)
4605e34255SPaul Burton {
4705e34255SPaul Burton DECLARE_GLOBAL_DATA_PTR;
4805e34255SPaul Burton
4905e34255SPaul Burton return gd->arch.io_port_base;
5005e34255SPaul Burton }
5105e34255SPaul Burton
set_io_port_base(unsigned long base)52819833afSPeter Tyser static inline void set_io_port_base(unsigned long base)
53819833afSPeter Tyser {
5405e34255SPaul Burton DECLARE_GLOBAL_DATA_PTR;
5505e34255SPaul Burton
5605e34255SPaul Burton gd->arch.io_port_base = base;
5723ff8633SDaniel Schwierzeck barrier();
58819833afSPeter Tyser }
59819833afSPeter Tyser
6005e34255SPaul Burton #else /* !CONFIG_DYNAMIC_IO_PORT_BASE */
6105e34255SPaul Burton
mips_io_port_base(void)6205e34255SPaul Burton static inline ulong mips_io_port_base(void)
6305e34255SPaul Burton {
6405e34255SPaul Burton return 0;
6505e34255SPaul Burton }
6605e34255SPaul Burton
set_io_port_base(unsigned long base)6705e34255SPaul Burton static inline void set_io_port_base(unsigned long base)
6805e34255SPaul Burton {
6905e34255SPaul Burton BUG_ON(base);
7005e34255SPaul Burton }
7105e34255SPaul Burton
7205e34255SPaul Burton #endif /* !CONFIG_DYNAMIC_IO_PORT_BASE */
7305e34255SPaul Burton
74819833afSPeter Tyser /*
7523ff8633SDaniel Schwierzeck * virt_to_phys - map virtual addresses to physical
7623ff8633SDaniel Schwierzeck * @address: address to remap
7723ff8633SDaniel Schwierzeck *
7823ff8633SDaniel Schwierzeck * The returned physical address is the physical (CPU) mapping for
7923ff8633SDaniel Schwierzeck * the memory address given. It is only valid to use this function on
8023ff8633SDaniel Schwierzeck * addresses directly mapped or allocated via kmalloc.
8123ff8633SDaniel Schwierzeck *
8223ff8633SDaniel Schwierzeck * This function does not give bus mappings for DMA transfers. In
8323ff8633SDaniel Schwierzeck * almost all conceivable cases a device driver should not be using
8423ff8633SDaniel Schwierzeck * this function
85819833afSPeter Tyser */
virt_to_phys(volatile const void * address)8623ff8633SDaniel Schwierzeck static inline unsigned long virt_to_phys(volatile const void *address)
87819833afSPeter Tyser {
8823ff8633SDaniel Schwierzeck unsigned long addr = (unsigned long)address;
8923ff8633SDaniel Schwierzeck
9023ff8633SDaniel Schwierzeck /* this corresponds to kernel implementation of __pa() */
9123ff8633SDaniel Schwierzeck #ifdef CONFIG_64BIT
9223ff8633SDaniel Schwierzeck if (addr < CKSEG0)
9323ff8633SDaniel Schwierzeck return XPHYSADDR(addr);
94090854c8SZhi-zhou Zhang #endif
952e4cc1c5SPaul Burton return CPHYSADDR(addr);
96819833afSPeter Tyser }
97d1cbeafdSPaul Burton #define virt_to_phys virt_to_phys
98819833afSPeter Tyser
9923ff8633SDaniel Schwierzeck /*
10023ff8633SDaniel Schwierzeck * phys_to_virt - map physical address to virtual
10123ff8633SDaniel Schwierzeck * @address: address to remap
10223ff8633SDaniel Schwierzeck *
10323ff8633SDaniel Schwierzeck * The returned virtual address is a current CPU mapping for
10423ff8633SDaniel Schwierzeck * the memory address given. It is only valid to use this function on
10523ff8633SDaniel Schwierzeck * addresses that have a kernel mapping
10623ff8633SDaniel Schwierzeck *
10723ff8633SDaniel Schwierzeck * This function does not handle bus mappings for DMA transfers. In
10823ff8633SDaniel Schwierzeck * almost all conceivable cases a device driver should not be using
10923ff8633SDaniel Schwierzeck * this function
11023ff8633SDaniel Schwierzeck */
phys_to_virt(unsigned long address)111b11c5d1dSDaniel Schwierzeck static inline void *phys_to_virt(unsigned long address)
112819833afSPeter Tyser {
11323ff8633SDaniel Schwierzeck return (void *)(address + PAGE_OFFSET - PHYS_OFFSET);
114819833afSPeter Tyser }
115d1cbeafdSPaul Burton #define phys_to_virt phys_to_virt
116819833afSPeter Tyser
117819833afSPeter Tyser /*
11823ff8633SDaniel Schwierzeck * ISA I/O bus memory addresses are 1:1 with the physical address.
119819833afSPeter Tyser */
isa_virt_to_bus(volatile void * address)12023ff8633SDaniel Schwierzeck static inline unsigned long isa_virt_to_bus(volatile void *address)
121819833afSPeter Tyser {
12223ff8633SDaniel Schwierzeck return (unsigned long)address - PAGE_OFFSET;
123819833afSPeter Tyser }
124819833afSPeter Tyser
isa_bus_to_virt(unsigned long address)12523ff8633SDaniel Schwierzeck static inline void *isa_bus_to_virt(unsigned long address)
126819833afSPeter Tyser {
12723ff8633SDaniel Schwierzeck return (void *)(address + PAGE_OFFSET);
128819833afSPeter Tyser }
129819833afSPeter Tyser
13023ff8633SDaniel Schwierzeck #define isa_page_to_bus page_to_phys
131819833afSPeter Tyser
132819833afSPeter Tyser /*
13323ff8633SDaniel Schwierzeck * However PCI ones are not necessarily 1:1 and therefore these interfaces
13423ff8633SDaniel Schwierzeck * are forbidden in portable PCI drivers.
135819833afSPeter Tyser *
13623ff8633SDaniel Schwierzeck * Allow them for x86 for legacy drivers, though.
137819833afSPeter Tyser */
13823ff8633SDaniel Schwierzeck #define virt_to_bus virt_to_phys
13923ff8633SDaniel Schwierzeck #define bus_to_virt phys_to_virt
140819833afSPeter Tyser
__ioremap_mode(phys_addr_t offset,unsigned long size,unsigned long flags)14123ff8633SDaniel Schwierzeck static inline void __iomem *__ioremap_mode(phys_addr_t offset, unsigned long size,
14223ff8633SDaniel Schwierzeck unsigned long flags)
143819833afSPeter Tyser {
14423ff8633SDaniel Schwierzeck void __iomem *addr;
14523ff8633SDaniel Schwierzeck phys_addr_t phys_addr;
14623ff8633SDaniel Schwierzeck
14723ff8633SDaniel Schwierzeck addr = plat_ioremap(offset, size, flags);
14823ff8633SDaniel Schwierzeck if (addr)
14923ff8633SDaniel Schwierzeck return addr;
15023ff8633SDaniel Schwierzeck
15123ff8633SDaniel Schwierzeck phys_addr = fixup_bigphys_addr(offset, size);
15223ff8633SDaniel Schwierzeck return (void __iomem *)(unsigned long)CKSEG1ADDR(phys_addr);
153819833afSPeter Tyser }
154819833afSPeter Tyser
155819833afSPeter Tyser /*
15623ff8633SDaniel Schwierzeck * ioremap - map bus memory into CPU space
15723ff8633SDaniel Schwierzeck * @offset: bus address of the memory
15823ff8633SDaniel Schwierzeck * @size: size of the resource to map
15923ff8633SDaniel Schwierzeck *
16023ff8633SDaniel Schwierzeck * ioremap performs a platform specific sequence of operations to
16123ff8633SDaniel Schwierzeck * make bus memory CPU accessible via the readb/readw/readl/writeb/
16223ff8633SDaniel Schwierzeck * writew/writel functions and the other mmio helpers. The returned
16323ff8633SDaniel Schwierzeck * address is not guaranteed to be usable directly as a virtual
16423ff8633SDaniel Schwierzeck * address.
165819833afSPeter Tyser */
16623ff8633SDaniel Schwierzeck #define ioremap(offset, size) \
16723ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_UNCACHED)
16823ff8633SDaniel Schwierzeck
16923ff8633SDaniel Schwierzeck /*
17023ff8633SDaniel Schwierzeck * ioremap_nocache - map bus memory into CPU space
17123ff8633SDaniel Schwierzeck * @offset: bus address of the memory
17223ff8633SDaniel Schwierzeck * @size: size of the resource to map
17323ff8633SDaniel Schwierzeck *
17423ff8633SDaniel Schwierzeck * ioremap_nocache performs a platform specific sequence of operations to
17523ff8633SDaniel Schwierzeck * make bus memory CPU accessible via the readb/readw/readl/writeb/
17623ff8633SDaniel Schwierzeck * writew/writel functions and the other mmio helpers. The returned
17723ff8633SDaniel Schwierzeck * address is not guaranteed to be usable directly as a virtual
17823ff8633SDaniel Schwierzeck * address.
17923ff8633SDaniel Schwierzeck *
18023ff8633SDaniel Schwierzeck * This version of ioremap ensures that the memory is marked uncachable
18123ff8633SDaniel Schwierzeck * on the CPU as well as honouring existing caching rules from things like
18223ff8633SDaniel Schwierzeck * the PCI bus. Note that there are other caches and buffers on many
18323ff8633SDaniel Schwierzeck * busses. In particular driver authors should read up on PCI writes
18423ff8633SDaniel Schwierzeck *
18523ff8633SDaniel Schwierzeck * It's useful if some control registers are in such an area and
18623ff8633SDaniel Schwierzeck * write combining or read caching is not desirable:
18723ff8633SDaniel Schwierzeck */
18823ff8633SDaniel Schwierzeck #define ioremap_nocache(offset, size) \
18923ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_UNCACHED)
19023ff8633SDaniel Schwierzeck #define ioremap_uc ioremap_nocache
19123ff8633SDaniel Schwierzeck
19223ff8633SDaniel Schwierzeck /*
19323ff8633SDaniel Schwierzeck * ioremap_cachable - map bus memory into CPU space
19423ff8633SDaniel Schwierzeck * @offset: bus address of the memory
19523ff8633SDaniel Schwierzeck * @size: size of the resource to map
19623ff8633SDaniel Schwierzeck *
19723ff8633SDaniel Schwierzeck * ioremap_nocache performs a platform specific sequence of operations to
19823ff8633SDaniel Schwierzeck * make bus memory CPU accessible via the readb/readw/readl/writeb/
19923ff8633SDaniel Schwierzeck * writew/writel functions and the other mmio helpers. The returned
20023ff8633SDaniel Schwierzeck * address is not guaranteed to be usable directly as a virtual
20123ff8633SDaniel Schwierzeck * address.
20223ff8633SDaniel Schwierzeck *
20323ff8633SDaniel Schwierzeck * This version of ioremap ensures that the memory is marked cachable by
20423ff8633SDaniel Schwierzeck * the CPU. Also enables full write-combining. Useful for some
20523ff8633SDaniel Schwierzeck * memory-like regions on I/O busses.
20623ff8633SDaniel Schwierzeck */
20723ff8633SDaniel Schwierzeck #define ioremap_cachable(offset, size) \
20823ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _page_cachable_default)
20923ff8633SDaniel Schwierzeck
21023ff8633SDaniel Schwierzeck /*
21123ff8633SDaniel Schwierzeck * These two are MIPS specific ioremap variant. ioremap_cacheable_cow
21223ff8633SDaniel Schwierzeck * requests a cachable mapping, ioremap_uncached_accelerated requests a
21323ff8633SDaniel Schwierzeck * mapping using the uncached accelerated mode which isn't supported on
21423ff8633SDaniel Schwierzeck * all processors.
21523ff8633SDaniel Schwierzeck */
21623ff8633SDaniel Schwierzeck #define ioremap_cacheable_cow(offset, size) \
21723ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_CACHABLE_COW)
21823ff8633SDaniel Schwierzeck #define ioremap_uncached_accelerated(offset, size) \
21923ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED)
22023ff8633SDaniel Schwierzeck
iounmap(const volatile void __iomem * addr)22123ff8633SDaniel Schwierzeck static inline void iounmap(const volatile void __iomem *addr)
22223ff8633SDaniel Schwierzeck {
22323ff8633SDaniel Schwierzeck plat_iounmap(addr);
22423ff8633SDaniel Schwierzeck }
22523ff8633SDaniel Schwierzeck
22623ff8633SDaniel Schwierzeck #ifdef CONFIG_CPU_CAVIUM_OCTEON
22723ff8633SDaniel Schwierzeck #define war_octeon_io_reorder_wmb() wmb()
22823ff8633SDaniel Schwierzeck #else
22923ff8633SDaniel Schwierzeck #define war_octeon_io_reorder_wmb() do { } while (0)
23023ff8633SDaniel Schwierzeck #endif
23123ff8633SDaniel Schwierzeck
23223ff8633SDaniel Schwierzeck #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
23323ff8633SDaniel Schwierzeck \
23423ff8633SDaniel Schwierzeck static inline void pfx##write##bwlq(type val, \
23523ff8633SDaniel Schwierzeck volatile void __iomem *mem) \
23623ff8633SDaniel Schwierzeck { \
23723ff8633SDaniel Schwierzeck volatile type *__mem; \
23823ff8633SDaniel Schwierzeck type __val; \
23923ff8633SDaniel Schwierzeck \
24023ff8633SDaniel Schwierzeck war_octeon_io_reorder_wmb(); \
24123ff8633SDaniel Schwierzeck \
24223ff8633SDaniel Schwierzeck __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
24323ff8633SDaniel Schwierzeck \
24423ff8633SDaniel Schwierzeck __val = pfx##ioswab##bwlq(__mem, val); \
24523ff8633SDaniel Schwierzeck \
24623ff8633SDaniel Schwierzeck if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
24723ff8633SDaniel Schwierzeck *__mem = __val; \
24823ff8633SDaniel Schwierzeck else if (cpu_has_64bits) { \
24923ff8633SDaniel Schwierzeck type __tmp; \
25023ff8633SDaniel Schwierzeck \
25123ff8633SDaniel Schwierzeck __asm__ __volatile__( \
25223ff8633SDaniel Schwierzeck ".set arch=r4000" "\t\t# __writeq""\n\t" \
25323ff8633SDaniel Schwierzeck "dsll32 %L0, %L0, 0" "\n\t" \
25423ff8633SDaniel Schwierzeck "dsrl32 %L0, %L0, 0" "\n\t" \
25523ff8633SDaniel Schwierzeck "dsll32 %M0, %M0, 0" "\n\t" \
25623ff8633SDaniel Schwierzeck "or %L0, %L0, %M0" "\n\t" \
25723ff8633SDaniel Schwierzeck "sd %L0, %2" "\n\t" \
25823ff8633SDaniel Schwierzeck ".set mips0" "\n" \
25923ff8633SDaniel Schwierzeck : "=r" (__tmp) \
26023ff8633SDaniel Schwierzeck : "0" (__val), "m" (*__mem)); \
26123ff8633SDaniel Schwierzeck } else \
26223ff8633SDaniel Schwierzeck BUG(); \
26323ff8633SDaniel Schwierzeck } \
26423ff8633SDaniel Schwierzeck \
26523ff8633SDaniel Schwierzeck static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
26623ff8633SDaniel Schwierzeck { \
26723ff8633SDaniel Schwierzeck volatile type *__mem; \
26823ff8633SDaniel Schwierzeck type __val; \
26923ff8633SDaniel Schwierzeck \
27023ff8633SDaniel Schwierzeck __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
27123ff8633SDaniel Schwierzeck \
27223ff8633SDaniel Schwierzeck if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
27323ff8633SDaniel Schwierzeck __val = *__mem; \
27423ff8633SDaniel Schwierzeck else if (cpu_has_64bits) { \
27523ff8633SDaniel Schwierzeck __asm__ __volatile__( \
27623ff8633SDaniel Schwierzeck ".set arch=r4000" "\t\t# __readq" "\n\t" \
27723ff8633SDaniel Schwierzeck "ld %L0, %1" "\n\t" \
27823ff8633SDaniel Schwierzeck "dsra32 %M0, %L0, 0" "\n\t" \
27923ff8633SDaniel Schwierzeck "sll %L0, %L0, 0" "\n\t" \
28023ff8633SDaniel Schwierzeck ".set mips0" "\n" \
28123ff8633SDaniel Schwierzeck : "=r" (__val) \
28223ff8633SDaniel Schwierzeck : "m" (*__mem)); \
28323ff8633SDaniel Schwierzeck } else { \
28423ff8633SDaniel Schwierzeck __val = 0; \
28523ff8633SDaniel Schwierzeck BUG(); \
28623ff8633SDaniel Schwierzeck } \
28723ff8633SDaniel Schwierzeck \
28823ff8633SDaniel Schwierzeck return pfx##ioswab##bwlq(__mem, __val); \
28923ff8633SDaniel Schwierzeck }
29023ff8633SDaniel Schwierzeck
2918ac493cdSPaul Burton #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p) \
29223ff8633SDaniel Schwierzeck \
29323ff8633SDaniel Schwierzeck static inline void pfx##out##bwlq##p(type val, unsigned long port) \
29423ff8633SDaniel Schwierzeck { \
29523ff8633SDaniel Schwierzeck volatile type *__addr; \
29623ff8633SDaniel Schwierzeck type __val; \
29723ff8633SDaniel Schwierzeck \
29823ff8633SDaniel Schwierzeck war_octeon_io_reorder_wmb(); \
29923ff8633SDaniel Schwierzeck \
30005e34255SPaul Burton __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base() + port); \
30123ff8633SDaniel Schwierzeck \
30223ff8633SDaniel Schwierzeck __val = pfx##ioswab##bwlq(__addr, val); \
30323ff8633SDaniel Schwierzeck \
30423ff8633SDaniel Schwierzeck /* Really, we want this to be atomic */ \
30523ff8633SDaniel Schwierzeck BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
30623ff8633SDaniel Schwierzeck \
30723ff8633SDaniel Schwierzeck *__addr = __val; \
30823ff8633SDaniel Schwierzeck } \
30923ff8633SDaniel Schwierzeck \
31023ff8633SDaniel Schwierzeck static inline type pfx##in##bwlq##p(unsigned long port) \
31123ff8633SDaniel Schwierzeck { \
31223ff8633SDaniel Schwierzeck volatile type *__addr; \
31323ff8633SDaniel Schwierzeck type __val; \
31423ff8633SDaniel Schwierzeck \
31505e34255SPaul Burton __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base() + port); \
31623ff8633SDaniel Schwierzeck \
31723ff8633SDaniel Schwierzeck BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
31823ff8633SDaniel Schwierzeck \
31923ff8633SDaniel Schwierzeck __val = *__addr; \
32023ff8633SDaniel Schwierzeck \
32123ff8633SDaniel Schwierzeck return pfx##ioswab##bwlq(__addr, __val); \
32223ff8633SDaniel Schwierzeck }
32323ff8633SDaniel Schwierzeck
32423ff8633SDaniel Schwierzeck #define __BUILD_MEMORY_PFX(bus, bwlq, type) \
32523ff8633SDaniel Schwierzeck \
32623ff8633SDaniel Schwierzeck __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
32723ff8633SDaniel Schwierzeck
32823ff8633SDaniel Schwierzeck #define BUILDIO_MEM(bwlq, type) \
32923ff8633SDaniel Schwierzeck \
33023ff8633SDaniel Schwierzeck __BUILD_MEMORY_PFX(__raw_, bwlq, type) \
33123ff8633SDaniel Schwierzeck __BUILD_MEMORY_PFX(, bwlq, type) \
33223ff8633SDaniel Schwierzeck __BUILD_MEMORY_PFX(__mem_, bwlq, type) \
33323ff8633SDaniel Schwierzeck
BUILDIO_MEM(b,u8)33423ff8633SDaniel Schwierzeck BUILDIO_MEM(b, u8)
33523ff8633SDaniel Schwierzeck BUILDIO_MEM(w, u16)
33623ff8633SDaniel Schwierzeck BUILDIO_MEM(l, u32)
33723ff8633SDaniel Schwierzeck BUILDIO_MEM(q, u64)
33823ff8633SDaniel Schwierzeck
33923ff8633SDaniel Schwierzeck #define __BUILD_IOPORT_PFX(bus, bwlq, type) \
3408ac493cdSPaul Burton __BUILD_IOPORT_SINGLE(bus, bwlq, type, ) \
3418ac493cdSPaul Burton __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p)
34223ff8633SDaniel Schwierzeck
34323ff8633SDaniel Schwierzeck #define BUILDIO_IOPORT(bwlq, type) \
34423ff8633SDaniel Schwierzeck __BUILD_IOPORT_PFX(, bwlq, type) \
34523ff8633SDaniel Schwierzeck __BUILD_IOPORT_PFX(__mem_, bwlq, type)
34623ff8633SDaniel Schwierzeck
34723ff8633SDaniel Schwierzeck BUILDIO_IOPORT(b, u8)
34823ff8633SDaniel Schwierzeck BUILDIO_IOPORT(w, u16)
34923ff8633SDaniel Schwierzeck BUILDIO_IOPORT(l, u32)
35023ff8633SDaniel Schwierzeck #ifdef CONFIG_64BIT
35123ff8633SDaniel Schwierzeck BUILDIO_IOPORT(q, u64)
35223ff8633SDaniel Schwierzeck #endif
35323ff8633SDaniel Schwierzeck
35423ff8633SDaniel Schwierzeck #define __BUILDIO(bwlq, type) \
35523ff8633SDaniel Schwierzeck \
35623ff8633SDaniel Schwierzeck __BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
35723ff8633SDaniel Schwierzeck
35823ff8633SDaniel Schwierzeck __BUILDIO(q, u64)
35923ff8633SDaniel Schwierzeck
36023ff8633SDaniel Schwierzeck #define readb_relaxed readb
36123ff8633SDaniel Schwierzeck #define readw_relaxed readw
36223ff8633SDaniel Schwierzeck #define readl_relaxed readl
36323ff8633SDaniel Schwierzeck #define readq_relaxed readq
36423ff8633SDaniel Schwierzeck
36523ff8633SDaniel Schwierzeck #define writeb_relaxed writeb
36623ff8633SDaniel Schwierzeck #define writew_relaxed writew
36723ff8633SDaniel Schwierzeck #define writel_relaxed writel
36823ff8633SDaniel Schwierzeck #define writeq_relaxed writeq
36923ff8633SDaniel Schwierzeck
37023ff8633SDaniel Schwierzeck #define readb_be(addr) \
37123ff8633SDaniel Schwierzeck __raw_readb((__force unsigned *)(addr))
37223ff8633SDaniel Schwierzeck #define readw_be(addr) \
37323ff8633SDaniel Schwierzeck be16_to_cpu(__raw_readw((__force unsigned *)(addr)))
37423ff8633SDaniel Schwierzeck #define readl_be(addr) \
37523ff8633SDaniel Schwierzeck be32_to_cpu(__raw_readl((__force unsigned *)(addr)))
37623ff8633SDaniel Schwierzeck #define readq_be(addr) \
37723ff8633SDaniel Schwierzeck be64_to_cpu(__raw_readq((__force unsigned *)(addr)))
37823ff8633SDaniel Schwierzeck
37923ff8633SDaniel Schwierzeck #define writeb_be(val, addr) \
38023ff8633SDaniel Schwierzeck __raw_writeb((val), (__force unsigned *)(addr))
38123ff8633SDaniel Schwierzeck #define writew_be(val, addr) \
38223ff8633SDaniel Schwierzeck __raw_writew(cpu_to_be16((val)), (__force unsigned *)(addr))
38323ff8633SDaniel Schwierzeck #define writel_be(val, addr) \
38423ff8633SDaniel Schwierzeck __raw_writel(cpu_to_be32((val)), (__force unsigned *)(addr))
38523ff8633SDaniel Schwierzeck #define writeq_be(val, addr) \
38623ff8633SDaniel Schwierzeck __raw_writeq(cpu_to_be64((val)), (__force unsigned *)(addr))
38723ff8633SDaniel Schwierzeck
38823ff8633SDaniel Schwierzeck /*
38923ff8633SDaniel Schwierzeck * Some code tests for these symbols
39023ff8633SDaniel Schwierzeck */
39123ff8633SDaniel Schwierzeck #define readq readq
39223ff8633SDaniel Schwierzeck #define writeq writeq
39323ff8633SDaniel Schwierzeck
39423ff8633SDaniel Schwierzeck #define __BUILD_MEMORY_STRING(bwlq, type) \
39523ff8633SDaniel Schwierzeck \
39623ff8633SDaniel Schwierzeck static inline void writes##bwlq(volatile void __iomem *mem, \
39723ff8633SDaniel Schwierzeck const void *addr, unsigned int count) \
39823ff8633SDaniel Schwierzeck { \
39923ff8633SDaniel Schwierzeck const volatile type *__addr = addr; \
40023ff8633SDaniel Schwierzeck \
40123ff8633SDaniel Schwierzeck while (count--) { \
40223ff8633SDaniel Schwierzeck __mem_write##bwlq(*__addr, mem); \
40323ff8633SDaniel Schwierzeck __addr++; \
40423ff8633SDaniel Schwierzeck } \
40523ff8633SDaniel Schwierzeck } \
40623ff8633SDaniel Schwierzeck \
40723ff8633SDaniel Schwierzeck static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
40823ff8633SDaniel Schwierzeck unsigned int count) \
40923ff8633SDaniel Schwierzeck { \
41023ff8633SDaniel Schwierzeck volatile type *__addr = addr; \
41123ff8633SDaniel Schwierzeck \
41223ff8633SDaniel Schwierzeck while (count--) { \
41323ff8633SDaniel Schwierzeck *__addr = __mem_read##bwlq(mem); \
41423ff8633SDaniel Schwierzeck __addr++; \
41523ff8633SDaniel Schwierzeck } \
41623ff8633SDaniel Schwierzeck }
41723ff8633SDaniel Schwierzeck
41823ff8633SDaniel Schwierzeck #define __BUILD_IOPORT_STRING(bwlq, type) \
41923ff8633SDaniel Schwierzeck \
42023ff8633SDaniel Schwierzeck static inline void outs##bwlq(unsigned long port, const void *addr, \
42123ff8633SDaniel Schwierzeck unsigned int count) \
42223ff8633SDaniel Schwierzeck { \
42323ff8633SDaniel Schwierzeck const volatile type *__addr = addr; \
42423ff8633SDaniel Schwierzeck \
42523ff8633SDaniel Schwierzeck while (count--) { \
42623ff8633SDaniel Schwierzeck __mem_out##bwlq(*__addr, port); \
42723ff8633SDaniel Schwierzeck __addr++; \
42823ff8633SDaniel Schwierzeck } \
42923ff8633SDaniel Schwierzeck } \
43023ff8633SDaniel Schwierzeck \
43123ff8633SDaniel Schwierzeck static inline void ins##bwlq(unsigned long port, void *addr, \
43223ff8633SDaniel Schwierzeck unsigned int count) \
43323ff8633SDaniel Schwierzeck { \
43423ff8633SDaniel Schwierzeck volatile type *__addr = addr; \
43523ff8633SDaniel Schwierzeck \
43623ff8633SDaniel Schwierzeck while (count--) { \
43723ff8633SDaniel Schwierzeck *__addr = __mem_in##bwlq(port); \
43823ff8633SDaniel Schwierzeck __addr++; \
43923ff8633SDaniel Schwierzeck } \
44023ff8633SDaniel Schwierzeck }
44123ff8633SDaniel Schwierzeck
44223ff8633SDaniel Schwierzeck #define BUILDSTRING(bwlq, type) \
44323ff8633SDaniel Schwierzeck \
44423ff8633SDaniel Schwierzeck __BUILD_MEMORY_STRING(bwlq, type) \
44523ff8633SDaniel Schwierzeck __BUILD_IOPORT_STRING(bwlq, type)
44623ff8633SDaniel Schwierzeck
44723ff8633SDaniel Schwierzeck BUILDSTRING(b, u8)
44823ff8633SDaniel Schwierzeck BUILDSTRING(w, u16)
44923ff8633SDaniel Schwierzeck BUILDSTRING(l, u32)
45023ff8633SDaniel Schwierzeck #ifdef CONFIG_64BIT
45123ff8633SDaniel Schwierzeck BUILDSTRING(q, u64)
45223ff8633SDaniel Schwierzeck #endif
45323ff8633SDaniel Schwierzeck
45423ff8633SDaniel Schwierzeck
45523ff8633SDaniel Schwierzeck #ifdef CONFIG_CPU_CAVIUM_OCTEON
45623ff8633SDaniel Schwierzeck #define mmiowb() wmb()
45723ff8633SDaniel Schwierzeck #else
45823ff8633SDaniel Schwierzeck /* Depends on MIPS II instruction set */
45923ff8633SDaniel Schwierzeck #define mmiowb() asm volatile ("sync" ::: "memory")
46023ff8633SDaniel Schwierzeck #endif
46123ff8633SDaniel Schwierzeck
46223ff8633SDaniel Schwierzeck static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
46323ff8633SDaniel Schwierzeck {
46423ff8633SDaniel Schwierzeck memset((void __force *)addr, val, count);
46523ff8633SDaniel Schwierzeck }
memcpy_fromio(void * dst,const volatile void __iomem * src,int count)46623ff8633SDaniel Schwierzeck static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
46723ff8633SDaniel Schwierzeck {
46823ff8633SDaniel Schwierzeck memcpy(dst, (void __force *)src, count);
46923ff8633SDaniel Schwierzeck }
memcpy_toio(volatile void __iomem * dst,const void * src,int count)47023ff8633SDaniel Schwierzeck static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
47123ff8633SDaniel Schwierzeck {
47223ff8633SDaniel Schwierzeck memcpy((void __force *)dst, src, count);
47323ff8633SDaniel Schwierzeck }
47423ff8633SDaniel Schwierzeck
47523ff8633SDaniel Schwierzeck /*
47623ff8633SDaniel Schwierzeck * Read a 32-bit register that requires a 64-bit read cycle on the bus.
47723ff8633SDaniel Schwierzeck * Avoid interrupt mucking, just adjust the address for 4-byte access.
47823ff8633SDaniel Schwierzeck * Assume the addresses are 8-byte aligned.
47923ff8633SDaniel Schwierzeck */
48023ff8633SDaniel Schwierzeck #ifdef __MIPSEB__
48123ff8633SDaniel Schwierzeck #define __CSR_32_ADJUST 4
48223ff8633SDaniel Schwierzeck #else
48323ff8633SDaniel Schwierzeck #define __CSR_32_ADJUST 0
48423ff8633SDaniel Schwierzeck #endif
48523ff8633SDaniel Schwierzeck
48623ff8633SDaniel Schwierzeck #define csr_out32(v, a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v))
48723ff8633SDaniel Schwierzeck #define csr_in32(a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST))
48823ff8633SDaniel Schwierzeck
48923ff8633SDaniel Schwierzeck /*
49023ff8633SDaniel Schwierzeck * U-Boot specific
49123ff8633SDaniel Schwierzeck */
49223ff8633SDaniel Schwierzeck #define sync() mmiowb()
49323ff8633SDaniel Schwierzeck
494d1cbeafdSPaul Burton #define MAP_NOCACHE 1
495819833afSPeter Tyser
496819833afSPeter Tyser static inline void *
map_physmem(phys_addr_t paddr,unsigned long len,unsigned long flags)497819833afSPeter Tyser map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
498819833afSPeter Tyser {
49923ff8633SDaniel Schwierzeck if (flags == MAP_NOCACHE)
50023ff8633SDaniel Schwierzeck return ioremap(paddr, len);
50123ff8633SDaniel Schwierzeck
5026fd596a1SPaul Burton return (void *)CKSEG0ADDR(paddr);
503819833afSPeter Tyser }
504d1cbeafdSPaul Burton #define map_physmem map_physmem
505819833afSPeter Tyser
5060e0efb40SDaniel Schwierzeck #define __BUILD_CLRBITS(bwlq, sfx, end, type) \
5070e0efb40SDaniel Schwierzeck \
5080e0efb40SDaniel Schwierzeck static inline void clrbits_##sfx(volatile void __iomem *mem, type clr) \
5090e0efb40SDaniel Schwierzeck { \
5100e0efb40SDaniel Schwierzeck type __val = __raw_read##bwlq(mem); \
5110e0efb40SDaniel Schwierzeck __val = end##_to_cpu(__val); \
5120e0efb40SDaniel Schwierzeck __val &= ~clr; \
5130e0efb40SDaniel Schwierzeck __val = cpu_to_##end(__val); \
5140e0efb40SDaniel Schwierzeck __raw_write##bwlq(__val, mem); \
5150e0efb40SDaniel Schwierzeck }
5160e0efb40SDaniel Schwierzeck
5170e0efb40SDaniel Schwierzeck #define __BUILD_SETBITS(bwlq, sfx, end, type) \
5180e0efb40SDaniel Schwierzeck \
5190e0efb40SDaniel Schwierzeck static inline void setbits_##sfx(volatile void __iomem *mem, type set) \
5200e0efb40SDaniel Schwierzeck { \
5210e0efb40SDaniel Schwierzeck type __val = __raw_read##bwlq(mem); \
5220e0efb40SDaniel Schwierzeck __val = end##_to_cpu(__val); \
5230e0efb40SDaniel Schwierzeck __val |= set; \
5240e0efb40SDaniel Schwierzeck __val = cpu_to_##end(__val); \
5250e0efb40SDaniel Schwierzeck __raw_write##bwlq(__val, mem); \
5260e0efb40SDaniel Schwierzeck }
5270e0efb40SDaniel Schwierzeck
5280e0efb40SDaniel Schwierzeck #define __BUILD_CLRSETBITS(bwlq, sfx, end, type) \
5290e0efb40SDaniel Schwierzeck \
5300e0efb40SDaniel Schwierzeck static inline void clrsetbits_##sfx(volatile void __iomem *mem, \
5310e0efb40SDaniel Schwierzeck type clr, type set) \
5320e0efb40SDaniel Schwierzeck { \
5330e0efb40SDaniel Schwierzeck type __val = __raw_read##bwlq(mem); \
5340e0efb40SDaniel Schwierzeck __val = end##_to_cpu(__val); \
5350e0efb40SDaniel Schwierzeck __val &= ~clr; \
5360e0efb40SDaniel Schwierzeck __val |= set; \
5370e0efb40SDaniel Schwierzeck __val = cpu_to_##end(__val); \
5380e0efb40SDaniel Schwierzeck __raw_write##bwlq(__val, mem); \
5390e0efb40SDaniel Schwierzeck }
5400e0efb40SDaniel Schwierzeck
5410e0efb40SDaniel Schwierzeck #define BUILD_CLRSETBITS(bwlq, sfx, end, type) \
5420e0efb40SDaniel Schwierzeck \
5430e0efb40SDaniel Schwierzeck __BUILD_CLRBITS(bwlq, sfx, end, type) \
5440e0efb40SDaniel Schwierzeck __BUILD_SETBITS(bwlq, sfx, end, type) \
5450e0efb40SDaniel Schwierzeck __BUILD_CLRSETBITS(bwlq, sfx, end, type)
5460e0efb40SDaniel Schwierzeck
5470e0efb40SDaniel Schwierzeck #define __to_cpu(v) (v)
5480e0efb40SDaniel Schwierzeck #define cpu_to__(v) (v)
5490e0efb40SDaniel Schwierzeck
550*4d9ada54SMario Six #define out_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v),a)
551*4d9ada54SMario Six #define in_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a))
552*4d9ada54SMario Six
553*4d9ada54SMario Six #define out_le64(a, v) out_arch(q, le64, a, v)
554*4d9ada54SMario Six #define out_le32(a, v) out_arch(l, le32, a, v)
555*4d9ada54SMario Six #define out_le16(a, v) out_arch(w, le16, a, v)
556*4d9ada54SMario Six
557*4d9ada54SMario Six #define in_le64(a) in_arch(q, le64, a)
558*4d9ada54SMario Six #define in_le32(a) in_arch(l, le32, a)
559*4d9ada54SMario Six #define in_le16(a) in_arch(w, le16, a)
560*4d9ada54SMario Six
561*4d9ada54SMario Six #define out_be64(a, v) out_arch(q, be64, a, v)
562*4d9ada54SMario Six #define out_be32(a, v) out_arch(l, be32, a, v)
563*4d9ada54SMario Six #define out_be16(a, v) out_arch(w, be16, a, v)
564*4d9ada54SMario Six
565*4d9ada54SMario Six #define in_be64(a) in_arch(q, be64, a)
566*4d9ada54SMario Six #define in_be32(a) in_arch(l, be32, a)
567*4d9ada54SMario Six #define in_be16(a) in_arch(w, be16, a)
568*4d9ada54SMario Six
569*4d9ada54SMario Six #define out_8(a, v) __raw_writeb(v, a)
570*4d9ada54SMario Six #define in_8(a) __raw_readb(a)
571*4d9ada54SMario Six
5720e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(b, 8, _, u8)
5730e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(w, le16, le16, u16)
5740e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(w, be16, be16, u16)
5750e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(w, 16, _, u16)
5760e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(l, le32, le32, u32)
5770e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(l, be32, be32, u32)
5780e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(l, 32, _, u32)
5790e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(q, le64, le64, u64)
5800e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(q, be64, be64, u64)
5810e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(q, 64, _, u64)
5820e0efb40SDaniel Schwierzeck
583d1cbeafdSPaul Burton #include <asm-generic/io.h>
584d1cbeafdSPaul Burton
585819833afSPeter Tyser #endif /* _ASM_IO_H */
586