1819833afSPeter Tyser /*
2819833afSPeter Tyser * Copyright (C) 1994, 1995 Waldorf GmbH
323ff8633SDaniel Schwierzeck * Copyright (C) 1994 - 2000, 06 Ralf Baechle
4819833afSPeter Tyser * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
523ff8633SDaniel Schwierzeck * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
623ff8633SDaniel Schwierzeck * Author: Maciej W. Rozycki <macro@mips.com>
723ff8633SDaniel Schwierzeck *
823ff8633SDaniel Schwierzeck * SPDX-License-Identifier: GPL-2.0
9819833afSPeter Tyser */
10819833afSPeter Tyser #ifndef _ASM_IO_H
11819833afSPeter Tyser #define _ASM_IO_H
12819833afSPeter Tyser
13d6ea6d88STom Rini #include <linux/bug.h>
1423ff8633SDaniel Schwierzeck #include <linux/compiler.h>
1523ff8633SDaniel Schwierzeck #include <linux/types.h>
1623ff8633SDaniel Schwierzeck
17819833afSPeter Tyser #include <asm/addrspace.h>
18819833afSPeter Tyser #include <asm/byteorder.h>
1923ff8633SDaniel Schwierzeck #include <asm/cpu-features.h>
2023ff8633SDaniel Schwierzeck #include <asm/pgtable-bits.h>
2123ff8633SDaniel Schwierzeck #include <asm/processor.h>
2223ff8633SDaniel Schwierzeck #include <asm/string.h>
2323ff8633SDaniel Schwierzeck
2423ff8633SDaniel Schwierzeck #include <ioremap.h>
2523ff8633SDaniel Schwierzeck #include <mangle-port.h>
2623ff8633SDaniel Schwierzeck #include <spaces.h>
27819833afSPeter Tyser
28819833afSPeter Tyser /*
2923ff8633SDaniel Schwierzeck * Raw operations are never swapped in software. OTOH values that raw
3023ff8633SDaniel Schwierzeck * operations are working on may or may not have been swapped by the bus
3123ff8633SDaniel Schwierzeck * hardware. An example use would be for flash memory that's used for
3223ff8633SDaniel Schwierzeck * execute in place.
33819833afSPeter Tyser */
3423ff8633SDaniel Schwierzeck # define __raw_ioswabb(a, x) (x)
3523ff8633SDaniel Schwierzeck # define __raw_ioswabw(a, x) (x)
3623ff8633SDaniel Schwierzeck # define __raw_ioswabl(a, x) (x)
3723ff8633SDaniel Schwierzeck # define __raw_ioswabq(a, x) (x)
3823ff8633SDaniel Schwierzeck # define ____raw_ioswabq(a, x) (x)
39819833afSPeter Tyser
4023ff8633SDaniel Schwierzeck /* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
41819833afSPeter Tyser
4223ff8633SDaniel Schwierzeck #define IO_SPACE_LIMIT 0xffff
43819833afSPeter Tyser
4405e34255SPaul Burton #ifdef CONFIG_DYNAMIC_IO_PORT_BASE
45819833afSPeter Tyser
mips_io_port_base(void)4605e34255SPaul Burton static inline ulong mips_io_port_base(void)
4705e34255SPaul Burton {
4805e34255SPaul Burton DECLARE_GLOBAL_DATA_PTR;
4905e34255SPaul Burton
5005e34255SPaul Burton return gd->arch.io_port_base;
5105e34255SPaul Burton }
5205e34255SPaul Burton
set_io_port_base(unsigned long base)53819833afSPeter Tyser static inline void set_io_port_base(unsigned long base)
54819833afSPeter Tyser {
5505e34255SPaul Burton DECLARE_GLOBAL_DATA_PTR;
5605e34255SPaul Burton
5705e34255SPaul Burton gd->arch.io_port_base = base;
5823ff8633SDaniel Schwierzeck barrier();
59819833afSPeter Tyser }
60819833afSPeter Tyser
6105e34255SPaul Burton #else /* !CONFIG_DYNAMIC_IO_PORT_BASE */
6205e34255SPaul Burton
mips_io_port_base(void)6305e34255SPaul Burton static inline ulong mips_io_port_base(void)
6405e34255SPaul Burton {
6505e34255SPaul Burton return 0;
6605e34255SPaul Burton }
6705e34255SPaul Burton
set_io_port_base(unsigned long base)6805e34255SPaul Burton static inline void set_io_port_base(unsigned long base)
6905e34255SPaul Burton {
7005e34255SPaul Burton BUG_ON(base);
7105e34255SPaul Burton }
7205e34255SPaul Burton
7305e34255SPaul Burton #endif /* !CONFIG_DYNAMIC_IO_PORT_BASE */
7405e34255SPaul Burton
75819833afSPeter Tyser /*
7623ff8633SDaniel Schwierzeck * virt_to_phys - map virtual addresses to physical
7723ff8633SDaniel Schwierzeck * @address: address to remap
7823ff8633SDaniel Schwierzeck *
7923ff8633SDaniel Schwierzeck * The returned physical address is the physical (CPU) mapping for
8023ff8633SDaniel Schwierzeck * the memory address given. It is only valid to use this function on
8123ff8633SDaniel Schwierzeck * addresses directly mapped or allocated via kmalloc.
8223ff8633SDaniel Schwierzeck *
8323ff8633SDaniel Schwierzeck * This function does not give bus mappings for DMA transfers. In
8423ff8633SDaniel Schwierzeck * almost all conceivable cases a device driver should not be using
8523ff8633SDaniel Schwierzeck * this function
86819833afSPeter Tyser */
virt_to_phys(volatile const void * address)8723ff8633SDaniel Schwierzeck static inline unsigned long virt_to_phys(volatile const void *address)
88819833afSPeter Tyser {
8923ff8633SDaniel Schwierzeck unsigned long addr = (unsigned long)address;
9023ff8633SDaniel Schwierzeck
9123ff8633SDaniel Schwierzeck /* this corresponds to kernel implementation of __pa() */
9223ff8633SDaniel Schwierzeck #ifdef CONFIG_64BIT
9323ff8633SDaniel Schwierzeck if (addr < CKSEG0)
9423ff8633SDaniel Schwierzeck return XPHYSADDR(addr);
95090854c8SZhi-zhou Zhang #endif
962e4cc1c5SPaul Burton return CPHYSADDR(addr);
97819833afSPeter Tyser }
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 }
115819833afSPeter Tyser
116819833afSPeter Tyser /*
11723ff8633SDaniel Schwierzeck * ISA I/O bus memory addresses are 1:1 with the physical address.
118819833afSPeter Tyser */
isa_virt_to_bus(volatile void * address)11923ff8633SDaniel Schwierzeck static inline unsigned long isa_virt_to_bus(volatile void *address)
120819833afSPeter Tyser {
12123ff8633SDaniel Schwierzeck return (unsigned long)address - PAGE_OFFSET;
122819833afSPeter Tyser }
123819833afSPeter Tyser
isa_bus_to_virt(unsigned long address)12423ff8633SDaniel Schwierzeck static inline void *isa_bus_to_virt(unsigned long address)
125819833afSPeter Tyser {
12623ff8633SDaniel Schwierzeck return (void *)(address + PAGE_OFFSET);
127819833afSPeter Tyser }
128819833afSPeter Tyser
12923ff8633SDaniel Schwierzeck #define isa_page_to_bus page_to_phys
130819833afSPeter Tyser
131819833afSPeter Tyser /*
13223ff8633SDaniel Schwierzeck * However PCI ones are not necessarily 1:1 and therefore these interfaces
13323ff8633SDaniel Schwierzeck * are forbidden in portable PCI drivers.
134819833afSPeter Tyser *
13523ff8633SDaniel Schwierzeck * Allow them for x86 for legacy drivers, though.
136819833afSPeter Tyser */
13723ff8633SDaniel Schwierzeck #define virt_to_bus virt_to_phys
13823ff8633SDaniel Schwierzeck #define bus_to_virt phys_to_virt
139819833afSPeter Tyser
__ioremap_mode(phys_addr_t offset,unsigned long size,unsigned long flags)14023ff8633SDaniel Schwierzeck static inline void __iomem *__ioremap_mode(phys_addr_t offset, unsigned long size,
14123ff8633SDaniel Schwierzeck unsigned long flags)
142819833afSPeter Tyser {
14323ff8633SDaniel Schwierzeck void __iomem *addr;
14423ff8633SDaniel Schwierzeck phys_addr_t phys_addr;
14523ff8633SDaniel Schwierzeck
14623ff8633SDaniel Schwierzeck addr = plat_ioremap(offset, size, flags);
14723ff8633SDaniel Schwierzeck if (addr)
14823ff8633SDaniel Schwierzeck return addr;
14923ff8633SDaniel Schwierzeck
15023ff8633SDaniel Schwierzeck phys_addr = fixup_bigphys_addr(offset, size);
15123ff8633SDaniel Schwierzeck return (void __iomem *)(unsigned long)CKSEG1ADDR(phys_addr);
152819833afSPeter Tyser }
153819833afSPeter Tyser
154819833afSPeter Tyser /*
15523ff8633SDaniel Schwierzeck * ioremap - map bus memory into CPU space
15623ff8633SDaniel Schwierzeck * @offset: bus address of the memory
15723ff8633SDaniel Schwierzeck * @size: size of the resource to map
15823ff8633SDaniel Schwierzeck *
15923ff8633SDaniel Schwierzeck * ioremap performs a platform specific sequence of operations to
16023ff8633SDaniel Schwierzeck * make bus memory CPU accessible via the readb/readw/readl/writeb/
16123ff8633SDaniel Schwierzeck * writew/writel functions and the other mmio helpers. The returned
16223ff8633SDaniel Schwierzeck * address is not guaranteed to be usable directly as a virtual
16323ff8633SDaniel Schwierzeck * address.
164819833afSPeter Tyser */
16523ff8633SDaniel Schwierzeck #define ioremap(offset, size) \
16623ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_UNCACHED)
16723ff8633SDaniel Schwierzeck
16823ff8633SDaniel Schwierzeck /*
16923ff8633SDaniel Schwierzeck * ioremap_nocache - map bus memory into CPU space
17023ff8633SDaniel Schwierzeck * @offset: bus address of the memory
17123ff8633SDaniel Schwierzeck * @size: size of the resource to map
17223ff8633SDaniel Schwierzeck *
17323ff8633SDaniel Schwierzeck * ioremap_nocache performs a platform specific sequence of operations to
17423ff8633SDaniel Schwierzeck * make bus memory CPU accessible via the readb/readw/readl/writeb/
17523ff8633SDaniel Schwierzeck * writew/writel functions and the other mmio helpers. The returned
17623ff8633SDaniel Schwierzeck * address is not guaranteed to be usable directly as a virtual
17723ff8633SDaniel Schwierzeck * address.
17823ff8633SDaniel Schwierzeck *
17923ff8633SDaniel Schwierzeck * This version of ioremap ensures that the memory is marked uncachable
18023ff8633SDaniel Schwierzeck * on the CPU as well as honouring existing caching rules from things like
18123ff8633SDaniel Schwierzeck * the PCI bus. Note that there are other caches and buffers on many
18223ff8633SDaniel Schwierzeck * busses. In particular driver authors should read up on PCI writes
18323ff8633SDaniel Schwierzeck *
18423ff8633SDaniel Schwierzeck * It's useful if some control registers are in such an area and
18523ff8633SDaniel Schwierzeck * write combining or read caching is not desirable:
18623ff8633SDaniel Schwierzeck */
18723ff8633SDaniel Schwierzeck #define ioremap_nocache(offset, size) \
18823ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_UNCACHED)
18923ff8633SDaniel Schwierzeck #define ioremap_uc ioremap_nocache
19023ff8633SDaniel Schwierzeck
19123ff8633SDaniel Schwierzeck /*
19223ff8633SDaniel Schwierzeck * ioremap_cachable - map bus memory into CPU space
19323ff8633SDaniel Schwierzeck * @offset: bus address of the memory
19423ff8633SDaniel Schwierzeck * @size: size of the resource to map
19523ff8633SDaniel Schwierzeck *
19623ff8633SDaniel Schwierzeck * ioremap_nocache performs a platform specific sequence of operations to
19723ff8633SDaniel Schwierzeck * make bus memory CPU accessible via the readb/readw/readl/writeb/
19823ff8633SDaniel Schwierzeck * writew/writel functions and the other mmio helpers. The returned
19923ff8633SDaniel Schwierzeck * address is not guaranteed to be usable directly as a virtual
20023ff8633SDaniel Schwierzeck * address.
20123ff8633SDaniel Schwierzeck *
20223ff8633SDaniel Schwierzeck * This version of ioremap ensures that the memory is marked cachable by
20323ff8633SDaniel Schwierzeck * the CPU. Also enables full write-combining. Useful for some
20423ff8633SDaniel Schwierzeck * memory-like regions on I/O busses.
20523ff8633SDaniel Schwierzeck */
20623ff8633SDaniel Schwierzeck #define ioremap_cachable(offset, size) \
20723ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _page_cachable_default)
20823ff8633SDaniel Schwierzeck
20923ff8633SDaniel Schwierzeck /*
21023ff8633SDaniel Schwierzeck * These two are MIPS specific ioremap variant. ioremap_cacheable_cow
21123ff8633SDaniel Schwierzeck * requests a cachable mapping, ioremap_uncached_accelerated requests a
21223ff8633SDaniel Schwierzeck * mapping using the uncached accelerated mode which isn't supported on
21323ff8633SDaniel Schwierzeck * all processors.
21423ff8633SDaniel Schwierzeck */
21523ff8633SDaniel Schwierzeck #define ioremap_cacheable_cow(offset, size) \
21623ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_CACHABLE_COW)
21723ff8633SDaniel Schwierzeck #define ioremap_uncached_accelerated(offset, size) \
21823ff8633SDaniel Schwierzeck __ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED)
21923ff8633SDaniel Schwierzeck
iounmap(const volatile void __iomem * addr)22023ff8633SDaniel Schwierzeck static inline void iounmap(const volatile void __iomem *addr)
22123ff8633SDaniel Schwierzeck {
22223ff8633SDaniel Schwierzeck plat_iounmap(addr);
22323ff8633SDaniel Schwierzeck }
22423ff8633SDaniel Schwierzeck
22523ff8633SDaniel Schwierzeck #ifdef CONFIG_CPU_CAVIUM_OCTEON
22623ff8633SDaniel Schwierzeck #define war_octeon_io_reorder_wmb() wmb()
22723ff8633SDaniel Schwierzeck #else
22823ff8633SDaniel Schwierzeck #define war_octeon_io_reorder_wmb() do { } while (0)
22923ff8633SDaniel Schwierzeck #endif
23023ff8633SDaniel Schwierzeck
23123ff8633SDaniel Schwierzeck #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
23223ff8633SDaniel Schwierzeck \
23323ff8633SDaniel Schwierzeck static inline void pfx##write##bwlq(type val, \
23423ff8633SDaniel Schwierzeck volatile void __iomem *mem) \
23523ff8633SDaniel Schwierzeck { \
23623ff8633SDaniel Schwierzeck volatile type *__mem; \
23723ff8633SDaniel Schwierzeck type __val; \
23823ff8633SDaniel Schwierzeck \
23923ff8633SDaniel Schwierzeck war_octeon_io_reorder_wmb(); \
24023ff8633SDaniel Schwierzeck \
24123ff8633SDaniel Schwierzeck __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
24223ff8633SDaniel Schwierzeck \
24323ff8633SDaniel Schwierzeck __val = pfx##ioswab##bwlq(__mem, val); \
24423ff8633SDaniel Schwierzeck \
24523ff8633SDaniel Schwierzeck if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
24623ff8633SDaniel Schwierzeck *__mem = __val; \
24723ff8633SDaniel Schwierzeck else if (cpu_has_64bits) { \
24823ff8633SDaniel Schwierzeck type __tmp; \
24923ff8633SDaniel Schwierzeck \
25023ff8633SDaniel Schwierzeck __asm__ __volatile__( \
25123ff8633SDaniel Schwierzeck ".set arch=r4000" "\t\t# __writeq""\n\t" \
25223ff8633SDaniel Schwierzeck "dsll32 %L0, %L0, 0" "\n\t" \
25323ff8633SDaniel Schwierzeck "dsrl32 %L0, %L0, 0" "\n\t" \
25423ff8633SDaniel Schwierzeck "dsll32 %M0, %M0, 0" "\n\t" \
25523ff8633SDaniel Schwierzeck "or %L0, %L0, %M0" "\n\t" \
25623ff8633SDaniel Schwierzeck "sd %L0, %2" "\n\t" \
25723ff8633SDaniel Schwierzeck ".set mips0" "\n" \
25823ff8633SDaniel Schwierzeck : "=r" (__tmp) \
25923ff8633SDaniel Schwierzeck : "0" (__val), "m" (*__mem)); \
26023ff8633SDaniel Schwierzeck } else \
26123ff8633SDaniel Schwierzeck BUG(); \
26223ff8633SDaniel Schwierzeck } \
26323ff8633SDaniel Schwierzeck \
26423ff8633SDaniel Schwierzeck static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
26523ff8633SDaniel Schwierzeck { \
26623ff8633SDaniel Schwierzeck volatile type *__mem; \
26723ff8633SDaniel Schwierzeck type __val; \
26823ff8633SDaniel Schwierzeck \
26923ff8633SDaniel Schwierzeck __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
27023ff8633SDaniel Schwierzeck \
27123ff8633SDaniel Schwierzeck if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
27223ff8633SDaniel Schwierzeck __val = *__mem; \
27323ff8633SDaniel Schwierzeck else if (cpu_has_64bits) { \
27423ff8633SDaniel Schwierzeck __asm__ __volatile__( \
27523ff8633SDaniel Schwierzeck ".set arch=r4000" "\t\t# __readq" "\n\t" \
27623ff8633SDaniel Schwierzeck "ld %L0, %1" "\n\t" \
27723ff8633SDaniel Schwierzeck "dsra32 %M0, %L0, 0" "\n\t" \
27823ff8633SDaniel Schwierzeck "sll %L0, %L0, 0" "\n\t" \
27923ff8633SDaniel Schwierzeck ".set mips0" "\n" \
28023ff8633SDaniel Schwierzeck : "=r" (__val) \
28123ff8633SDaniel Schwierzeck : "m" (*__mem)); \
28223ff8633SDaniel Schwierzeck } else { \
28323ff8633SDaniel Schwierzeck __val = 0; \
28423ff8633SDaniel Schwierzeck BUG(); \
28523ff8633SDaniel Schwierzeck } \
28623ff8633SDaniel Schwierzeck \
28723ff8633SDaniel Schwierzeck return pfx##ioswab##bwlq(__mem, __val); \
28823ff8633SDaniel Schwierzeck }
28923ff8633SDaniel Schwierzeck
2908ac493cdSPaul Burton #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p) \
29123ff8633SDaniel Schwierzeck \
29223ff8633SDaniel Schwierzeck static inline void pfx##out##bwlq##p(type val, unsigned long port) \
29323ff8633SDaniel Schwierzeck { \
29423ff8633SDaniel Schwierzeck volatile type *__addr; \
29523ff8633SDaniel Schwierzeck type __val; \
29623ff8633SDaniel Schwierzeck \
29723ff8633SDaniel Schwierzeck war_octeon_io_reorder_wmb(); \
29823ff8633SDaniel Schwierzeck \
29905e34255SPaul Burton __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base() + port); \
30023ff8633SDaniel Schwierzeck \
30123ff8633SDaniel Schwierzeck __val = pfx##ioswab##bwlq(__addr, val); \
30223ff8633SDaniel Schwierzeck \
30323ff8633SDaniel Schwierzeck /* Really, we want this to be atomic */ \
30423ff8633SDaniel Schwierzeck BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
30523ff8633SDaniel Schwierzeck \
30623ff8633SDaniel Schwierzeck *__addr = __val; \
30723ff8633SDaniel Schwierzeck } \
30823ff8633SDaniel Schwierzeck \
30923ff8633SDaniel Schwierzeck static inline type pfx##in##bwlq##p(unsigned long port) \
31023ff8633SDaniel Schwierzeck { \
31123ff8633SDaniel Schwierzeck volatile type *__addr; \
31223ff8633SDaniel Schwierzeck type __val; \
31323ff8633SDaniel Schwierzeck \
31405e34255SPaul Burton __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base() + port); \
31523ff8633SDaniel Schwierzeck \
31623ff8633SDaniel Schwierzeck BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
31723ff8633SDaniel Schwierzeck \
31823ff8633SDaniel Schwierzeck __val = *__addr; \
31923ff8633SDaniel Schwierzeck \
32023ff8633SDaniel Schwierzeck return pfx##ioswab##bwlq(__addr, __val); \
32123ff8633SDaniel Schwierzeck }
32223ff8633SDaniel Schwierzeck
32323ff8633SDaniel Schwierzeck #define __BUILD_MEMORY_PFX(bus, bwlq, type) \
32423ff8633SDaniel Schwierzeck \
32523ff8633SDaniel Schwierzeck __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
32623ff8633SDaniel Schwierzeck
32723ff8633SDaniel Schwierzeck #define BUILDIO_MEM(bwlq, type) \
32823ff8633SDaniel Schwierzeck \
32923ff8633SDaniel Schwierzeck __BUILD_MEMORY_PFX(__raw_, bwlq, type) \
33023ff8633SDaniel Schwierzeck __BUILD_MEMORY_PFX(, bwlq, type) \
33123ff8633SDaniel Schwierzeck __BUILD_MEMORY_PFX(__mem_, bwlq, type) \
33223ff8633SDaniel Schwierzeck
BUILDIO_MEM(b,u8)33323ff8633SDaniel Schwierzeck BUILDIO_MEM(b, u8)
33423ff8633SDaniel Schwierzeck BUILDIO_MEM(w, u16)
33523ff8633SDaniel Schwierzeck BUILDIO_MEM(l, u32)
33623ff8633SDaniel Schwierzeck BUILDIO_MEM(q, u64)
33723ff8633SDaniel Schwierzeck
33823ff8633SDaniel Schwierzeck #define __BUILD_IOPORT_PFX(bus, bwlq, type) \
3398ac493cdSPaul Burton __BUILD_IOPORT_SINGLE(bus, bwlq, type, ) \
3408ac493cdSPaul Burton __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p)
34123ff8633SDaniel Schwierzeck
34223ff8633SDaniel Schwierzeck #define BUILDIO_IOPORT(bwlq, type) \
34323ff8633SDaniel Schwierzeck __BUILD_IOPORT_PFX(, bwlq, type) \
34423ff8633SDaniel Schwierzeck __BUILD_IOPORT_PFX(__mem_, bwlq, type)
34523ff8633SDaniel Schwierzeck
34623ff8633SDaniel Schwierzeck BUILDIO_IOPORT(b, u8)
34723ff8633SDaniel Schwierzeck BUILDIO_IOPORT(w, u16)
34823ff8633SDaniel Schwierzeck BUILDIO_IOPORT(l, u32)
34923ff8633SDaniel Schwierzeck #ifdef CONFIG_64BIT
35023ff8633SDaniel Schwierzeck BUILDIO_IOPORT(q, u64)
35123ff8633SDaniel Schwierzeck #endif
35223ff8633SDaniel Schwierzeck
35323ff8633SDaniel Schwierzeck #define __BUILDIO(bwlq, type) \
35423ff8633SDaniel Schwierzeck \
35523ff8633SDaniel Schwierzeck __BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
35623ff8633SDaniel Schwierzeck
35723ff8633SDaniel Schwierzeck __BUILDIO(q, u64)
35823ff8633SDaniel Schwierzeck
35923ff8633SDaniel Schwierzeck #define readb_relaxed readb
36023ff8633SDaniel Schwierzeck #define readw_relaxed readw
36123ff8633SDaniel Schwierzeck #define readl_relaxed readl
36223ff8633SDaniel Schwierzeck #define readq_relaxed readq
36323ff8633SDaniel Schwierzeck
36423ff8633SDaniel Schwierzeck #define writeb_relaxed writeb
36523ff8633SDaniel Schwierzeck #define writew_relaxed writew
36623ff8633SDaniel Schwierzeck #define writel_relaxed writel
36723ff8633SDaniel Schwierzeck #define writeq_relaxed writeq
36823ff8633SDaniel Schwierzeck
36923ff8633SDaniel Schwierzeck #define readb_be(addr) \
37023ff8633SDaniel Schwierzeck __raw_readb((__force unsigned *)(addr))
37123ff8633SDaniel Schwierzeck #define readw_be(addr) \
37223ff8633SDaniel Schwierzeck be16_to_cpu(__raw_readw((__force unsigned *)(addr)))
37323ff8633SDaniel Schwierzeck #define readl_be(addr) \
37423ff8633SDaniel Schwierzeck be32_to_cpu(__raw_readl((__force unsigned *)(addr)))
37523ff8633SDaniel Schwierzeck #define readq_be(addr) \
37623ff8633SDaniel Schwierzeck be64_to_cpu(__raw_readq((__force unsigned *)(addr)))
37723ff8633SDaniel Schwierzeck
37823ff8633SDaniel Schwierzeck #define writeb_be(val, addr) \
37923ff8633SDaniel Schwierzeck __raw_writeb((val), (__force unsigned *)(addr))
38023ff8633SDaniel Schwierzeck #define writew_be(val, addr) \
38123ff8633SDaniel Schwierzeck __raw_writew(cpu_to_be16((val)), (__force unsigned *)(addr))
38223ff8633SDaniel Schwierzeck #define writel_be(val, addr) \
38323ff8633SDaniel Schwierzeck __raw_writel(cpu_to_be32((val)), (__force unsigned *)(addr))
38423ff8633SDaniel Schwierzeck #define writeq_be(val, addr) \
38523ff8633SDaniel Schwierzeck __raw_writeq(cpu_to_be64((val)), (__force unsigned *)(addr))
38623ff8633SDaniel Schwierzeck
38723ff8633SDaniel Schwierzeck /*
38823ff8633SDaniel Schwierzeck * Some code tests for these symbols
38923ff8633SDaniel Schwierzeck */
39023ff8633SDaniel Schwierzeck #define readq readq
39123ff8633SDaniel Schwierzeck #define writeq writeq
39223ff8633SDaniel Schwierzeck
39323ff8633SDaniel Schwierzeck #define __BUILD_MEMORY_STRING(bwlq, type) \
39423ff8633SDaniel Schwierzeck \
39523ff8633SDaniel Schwierzeck static inline void writes##bwlq(volatile void __iomem *mem, \
39623ff8633SDaniel Schwierzeck const void *addr, unsigned int count) \
39723ff8633SDaniel Schwierzeck { \
39823ff8633SDaniel Schwierzeck const volatile type *__addr = addr; \
39923ff8633SDaniel Schwierzeck \
40023ff8633SDaniel Schwierzeck while (count--) { \
40123ff8633SDaniel Schwierzeck __mem_write##bwlq(*__addr, mem); \
40223ff8633SDaniel Schwierzeck __addr++; \
40323ff8633SDaniel Schwierzeck } \
40423ff8633SDaniel Schwierzeck } \
40523ff8633SDaniel Schwierzeck \
40623ff8633SDaniel Schwierzeck static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
40723ff8633SDaniel Schwierzeck unsigned int count) \
40823ff8633SDaniel Schwierzeck { \
40923ff8633SDaniel Schwierzeck volatile type *__addr = addr; \
41023ff8633SDaniel Schwierzeck \
41123ff8633SDaniel Schwierzeck while (count--) { \
41223ff8633SDaniel Schwierzeck *__addr = __mem_read##bwlq(mem); \
41323ff8633SDaniel Schwierzeck __addr++; \
41423ff8633SDaniel Schwierzeck } \
41523ff8633SDaniel Schwierzeck }
41623ff8633SDaniel Schwierzeck
41723ff8633SDaniel Schwierzeck #define __BUILD_IOPORT_STRING(bwlq, type) \
41823ff8633SDaniel Schwierzeck \
41923ff8633SDaniel Schwierzeck static inline void outs##bwlq(unsigned long port, const void *addr, \
42023ff8633SDaniel Schwierzeck unsigned int count) \
42123ff8633SDaniel Schwierzeck { \
42223ff8633SDaniel Schwierzeck const volatile type *__addr = addr; \
42323ff8633SDaniel Schwierzeck \
42423ff8633SDaniel Schwierzeck while (count--) { \
42523ff8633SDaniel Schwierzeck __mem_out##bwlq(*__addr, port); \
42623ff8633SDaniel Schwierzeck __addr++; \
42723ff8633SDaniel Schwierzeck } \
42823ff8633SDaniel Schwierzeck } \
42923ff8633SDaniel Schwierzeck \
43023ff8633SDaniel Schwierzeck static inline void ins##bwlq(unsigned long port, void *addr, \
43123ff8633SDaniel Schwierzeck unsigned int count) \
43223ff8633SDaniel Schwierzeck { \
43323ff8633SDaniel Schwierzeck volatile type *__addr = addr; \
43423ff8633SDaniel Schwierzeck \
43523ff8633SDaniel Schwierzeck while (count--) { \
43623ff8633SDaniel Schwierzeck *__addr = __mem_in##bwlq(port); \
43723ff8633SDaniel Schwierzeck __addr++; \
43823ff8633SDaniel Schwierzeck } \
43923ff8633SDaniel Schwierzeck }
44023ff8633SDaniel Schwierzeck
44123ff8633SDaniel Schwierzeck #define BUILDSTRING(bwlq, type) \
44223ff8633SDaniel Schwierzeck \
44323ff8633SDaniel Schwierzeck __BUILD_MEMORY_STRING(bwlq, type) \
44423ff8633SDaniel Schwierzeck __BUILD_IOPORT_STRING(bwlq, type)
44523ff8633SDaniel Schwierzeck
44623ff8633SDaniel Schwierzeck BUILDSTRING(b, u8)
44723ff8633SDaniel Schwierzeck BUILDSTRING(w, u16)
44823ff8633SDaniel Schwierzeck BUILDSTRING(l, u32)
44923ff8633SDaniel Schwierzeck #ifdef CONFIG_64BIT
45023ff8633SDaniel Schwierzeck BUILDSTRING(q, u64)
45123ff8633SDaniel Schwierzeck #endif
45223ff8633SDaniel Schwierzeck
45323ff8633SDaniel Schwierzeck
45423ff8633SDaniel Schwierzeck #ifdef CONFIG_CPU_CAVIUM_OCTEON
45523ff8633SDaniel Schwierzeck #define mmiowb() wmb()
45623ff8633SDaniel Schwierzeck #else
45723ff8633SDaniel Schwierzeck /* Depends on MIPS II instruction set */
45823ff8633SDaniel Schwierzeck #define mmiowb() asm volatile ("sync" ::: "memory")
45923ff8633SDaniel Schwierzeck #endif
46023ff8633SDaniel Schwierzeck
46123ff8633SDaniel Schwierzeck static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
46223ff8633SDaniel Schwierzeck {
46323ff8633SDaniel Schwierzeck memset((void __force *)addr, val, count);
46423ff8633SDaniel Schwierzeck }
memcpy_fromio(void * dst,const volatile void __iomem * src,int count)46523ff8633SDaniel Schwierzeck static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
46623ff8633SDaniel Schwierzeck {
46723ff8633SDaniel Schwierzeck memcpy(dst, (void __force *)src, count);
46823ff8633SDaniel Schwierzeck }
memcpy_toio(volatile void __iomem * dst,const void * src,int count)46923ff8633SDaniel Schwierzeck static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
47023ff8633SDaniel Schwierzeck {
47123ff8633SDaniel Schwierzeck memcpy((void __force *)dst, src, count);
47223ff8633SDaniel Schwierzeck }
47323ff8633SDaniel Schwierzeck
47423ff8633SDaniel Schwierzeck /*
47523ff8633SDaniel Schwierzeck * Read a 32-bit register that requires a 64-bit read cycle on the bus.
47623ff8633SDaniel Schwierzeck * Avoid interrupt mucking, just adjust the address for 4-byte access.
47723ff8633SDaniel Schwierzeck * Assume the addresses are 8-byte aligned.
47823ff8633SDaniel Schwierzeck */
47923ff8633SDaniel Schwierzeck #ifdef __MIPSEB__
48023ff8633SDaniel Schwierzeck #define __CSR_32_ADJUST 4
48123ff8633SDaniel Schwierzeck #else
48223ff8633SDaniel Schwierzeck #define __CSR_32_ADJUST 0
48323ff8633SDaniel Schwierzeck #endif
48423ff8633SDaniel Schwierzeck
48523ff8633SDaniel Schwierzeck #define csr_out32(v, a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v))
48623ff8633SDaniel Schwierzeck #define csr_in32(a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST))
48723ff8633SDaniel Schwierzeck
48823ff8633SDaniel Schwierzeck /*
48923ff8633SDaniel Schwierzeck * U-Boot specific
49023ff8633SDaniel Schwierzeck */
49123ff8633SDaniel Schwierzeck #define sync() mmiowb()
49223ff8633SDaniel Schwierzeck
49323ff8633SDaniel Schwierzeck #define MAP_NOCACHE (1)
494819833afSPeter Tyser #define MAP_WRCOMBINE (0)
495819833afSPeter Tyser #define MAP_WRBACK (0)
496819833afSPeter Tyser #define MAP_WRTHROUGH (0)
497819833afSPeter Tyser
498819833afSPeter Tyser static inline void *
map_physmem(phys_addr_t paddr,unsigned long len,unsigned long flags)499819833afSPeter Tyser map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
500819833afSPeter Tyser {
50123ff8633SDaniel Schwierzeck if (flags == MAP_NOCACHE)
50223ff8633SDaniel Schwierzeck return ioremap(paddr, len);
50323ff8633SDaniel Schwierzeck
504*6fd596a1SPaul Burton return (void *)CKSEG0ADDR(paddr);
505819833afSPeter Tyser }
506819833afSPeter Tyser
507819833afSPeter Tyser /*
508819833afSPeter Tyser * Take down a mapping set up by map_physmem().
509819833afSPeter Tyser */
unmap_physmem(void * vaddr,unsigned long flags)510819833afSPeter Tyser static inline void unmap_physmem(void *vaddr, unsigned long flags)
511819833afSPeter Tyser {
512819833afSPeter Tyser }
513819833afSPeter Tyser
5140e0efb40SDaniel Schwierzeck #define __BUILD_CLRBITS(bwlq, sfx, end, type) \
5150e0efb40SDaniel Schwierzeck \
5160e0efb40SDaniel Schwierzeck static inline void clrbits_##sfx(volatile void __iomem *mem, type clr) \
5170e0efb40SDaniel Schwierzeck { \
5180e0efb40SDaniel Schwierzeck type __val = __raw_read##bwlq(mem); \
5190e0efb40SDaniel Schwierzeck __val = end##_to_cpu(__val); \
5200e0efb40SDaniel Schwierzeck __val &= ~clr; \
5210e0efb40SDaniel Schwierzeck __val = cpu_to_##end(__val); \
5220e0efb40SDaniel Schwierzeck __raw_write##bwlq(__val, mem); \
5230e0efb40SDaniel Schwierzeck }
5240e0efb40SDaniel Schwierzeck
5250e0efb40SDaniel Schwierzeck #define __BUILD_SETBITS(bwlq, sfx, end, type) \
5260e0efb40SDaniel Schwierzeck \
5270e0efb40SDaniel Schwierzeck static inline void setbits_##sfx(volatile void __iomem *mem, type set) \
5280e0efb40SDaniel Schwierzeck { \
5290e0efb40SDaniel Schwierzeck type __val = __raw_read##bwlq(mem); \
5300e0efb40SDaniel Schwierzeck __val = end##_to_cpu(__val); \
5310e0efb40SDaniel Schwierzeck __val |= set; \
5320e0efb40SDaniel Schwierzeck __val = cpu_to_##end(__val); \
5330e0efb40SDaniel Schwierzeck __raw_write##bwlq(__val, mem); \
5340e0efb40SDaniel Schwierzeck }
5350e0efb40SDaniel Schwierzeck
5360e0efb40SDaniel Schwierzeck #define __BUILD_CLRSETBITS(bwlq, sfx, end, type) \
5370e0efb40SDaniel Schwierzeck \
5380e0efb40SDaniel Schwierzeck static inline void clrsetbits_##sfx(volatile void __iomem *mem, \
5390e0efb40SDaniel Schwierzeck type clr, type set) \
5400e0efb40SDaniel Schwierzeck { \
5410e0efb40SDaniel Schwierzeck type __val = __raw_read##bwlq(mem); \
5420e0efb40SDaniel Schwierzeck __val = end##_to_cpu(__val); \
5430e0efb40SDaniel Schwierzeck __val &= ~clr; \
5440e0efb40SDaniel Schwierzeck __val |= set; \
5450e0efb40SDaniel Schwierzeck __val = cpu_to_##end(__val); \
5460e0efb40SDaniel Schwierzeck __raw_write##bwlq(__val, mem); \
5470e0efb40SDaniel Schwierzeck }
5480e0efb40SDaniel Schwierzeck
5490e0efb40SDaniel Schwierzeck #define BUILD_CLRSETBITS(bwlq, sfx, end, type) \
5500e0efb40SDaniel Schwierzeck \
5510e0efb40SDaniel Schwierzeck __BUILD_CLRBITS(bwlq, sfx, end, type) \
5520e0efb40SDaniel Schwierzeck __BUILD_SETBITS(bwlq, sfx, end, type) \
5530e0efb40SDaniel Schwierzeck __BUILD_CLRSETBITS(bwlq, sfx, end, type)
5540e0efb40SDaniel Schwierzeck
5550e0efb40SDaniel Schwierzeck #define __to_cpu(v) (v)
5560e0efb40SDaniel Schwierzeck #define cpu_to__(v) (v)
5570e0efb40SDaniel Schwierzeck
5580e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(b, 8, _, u8)
5590e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(w, le16, le16, u16)
5600e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(w, be16, be16, u16)
5610e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(w, 16, _, u16)
5620e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(l, le32, le32, u32)
5630e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(l, be32, be32, u32)
5640e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(l, 32, _, u32)
5650e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(q, le64, le64, u64)
5660e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(q, be64, be64, u64)
5670e0efb40SDaniel Schwierzeck BUILD_CLRSETBITS(q, 64, _, u64)
5680e0efb40SDaniel Schwierzeck
569819833afSPeter Tyser #endif /* _ASM_IO_H */
570