blob: cedd5375d660591b311321366539a82285dac502 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0 */
Rick Chen76c0a242017-12-26 13:55:51 +08002/*
3 * Copyright (C) 2017 Andes Technology Corporation
4 * Rick Chen, Andes Technology Corporation <rick@andestech.com>
5 *
Rick Chen76c0a242017-12-26 13:55:51 +08006 */
7#ifndef __ASM_RISCV_IO_H
8#define __ASM_RISCV_IO_H
9
Rick Chen76c0a242017-12-26 13:55:51 +080010#include <linux/types.h>
Lukas Auer78da26d2018-11-22 11:26:18 +010011#include <asm/barrier.h>
Rick Chen76c0a242017-12-26 13:55:51 +080012#include <asm/byteorder.h>
13
14static inline void sync(void)
15{
16}
17
Nick Hu579f12b2021-10-18 11:50:05 +080018#define __arch_getb(a) (*(volatile unsigned char *)(a))
19#define __arch_getw(a) (*(volatile unsigned short *)(a))
20#define __arch_getl(a) (*(volatile unsigned int *)(a))
21#define __arch_getq(a) (*(volatile unsigned long long *)(a))
Rick Chen76c0a242017-12-26 13:55:51 +080022
Nick Hu579f12b2021-10-18 11:50:05 +080023#define __arch_putb(v, a) (*(volatile unsigned char *)(a) = (v))
24#define __arch_putw(v, a) (*(volatile unsigned short *)(a) = (v))
25#define __arch_putl(v, a) (*(volatile unsigned int *)(a) = (v))
26#define __arch_putq(v, a) (*(volatile unsigned long long *)(a) = (v))
Rick Chen76c0a242017-12-26 13:55:51 +080027
28#define __raw_writeb(v, a) __arch_putb(v, a)
29#define __raw_writew(v, a) __arch_putw(v, a)
30#define __raw_writel(v, a) __arch_putl(v, a)
31#define __raw_writeq(v, a) __arch_putq(v, a)
32
33#define __raw_readb(a) __arch_getb(a)
34#define __raw_readw(a) __arch_getw(a)
35#define __raw_readl(a) __arch_getl(a)
36#define __raw_readq(a) __arch_getq(a)
37
Wei Fu2f5b8072021-10-24 00:31:12 +080038/* adding for cadence_qspi_apb.c */
39#define memcpy_fromio(a, c, l) memcpy((a), (c), (l))
40#define memcpy_toio(c, a, l) memcpy((c), (a), (l))
41
Lukas Auer78da26d2018-11-22 11:26:18 +010042#define dmb() mb()
43#define __iormb() rmb()
44#define __iowmb() wmb()
Rick Chen76c0a242017-12-26 13:55:51 +080045
46static inline void writeb(u8 val, volatile void __iomem *addr)
47{
48 __iowmb();
49 __arch_putb(val, addr);
50}
51
52static inline void writew(u16 val, volatile void __iomem *addr)
53{
54 __iowmb();
55 __arch_putw(val, addr);
56}
57
58static inline void writel(u32 val, volatile void __iomem *addr)
59{
60 __iowmb();
61 __arch_putl(val, addr);
62}
63
64static inline void writeq(u64 val, volatile void __iomem *addr)
65{
66 __iowmb();
67 __arch_putq(val, addr);
68}
69
70static inline u8 readb(const volatile void __iomem *addr)
71{
72 u8 val;
73
74 val = __arch_getb(addr);
75 __iormb();
76 return val;
77}
78
79static inline u16 readw(const volatile void __iomem *addr)
80{
81 u16 val;
82
83 val = __arch_getw(addr);
84 __iormb();
85 return val;
86}
87
88static inline u32 readl(const volatile void __iomem *addr)
89{
90 u32 val;
91
92 val = __arch_getl(addr);
93 __iormb();
94 return val;
95}
96
97static inline u64 readq(const volatile void __iomem *addr)
98{
Lukas Auere429a1e2018-11-22 11:26:17 +010099 u64 val;
Rick Chen76c0a242017-12-26 13:55:51 +0800100
101 val = __arch_getq(addr);
102 __iormb();
103 return val;
104}
105
106/*
107 * The compiler seems to be incapable of optimising constants
108 * properly. Spell it out to the compiler in some cases.
109 * These are only valid for small values of "off" (< 1<<12)
110 */
111#define __raw_base_writeb(val, base, off) __arch_base_putb(val, base, off)
112#define __raw_base_writew(val, base, off) __arch_base_putw(val, base, off)
113#define __raw_base_writel(val, base, off) __arch_base_putl(val, base, off)
114
115#define __raw_base_readb(base, off) __arch_base_getb(base, off)
116#define __raw_base_readw(base, off) __arch_base_getw(base, off)
117#define __raw_base_readl(base, off) __arch_base_getl(base, off)
118
119#define out_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v), a)
120#define in_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a))
121
122#define out_le32(a, v) out_arch(l, le32, a, v)
123#define out_le16(a, v) out_arch(w, le16, a, v)
124
125#define in_le32(a) in_arch(l, le32, a)
126#define in_le16(a) in_arch(w, le16, a)
127
128#define out_be32(a, v) out_arch(l, be32, a, v)
129#define out_be16(a, v) out_arch(w, be16, a, v)
130
131#define in_be32(a) in_arch(l, be32, a)
132#define in_be16(a) in_arch(w, be16, a)
133
134#define out_8(a, v) __raw_writeb(v, a)
135#define in_8(a) __raw_readb(a)
136
137/*
138 * Clear and set bits in one shot. These macros can be used to clear and
139 * set multiple bits in a register using a single call. These macros can
140 * also be used to set a multiple-bit bit pattern using a mask, by
141 * specifying the mask in the 'clear' parameter and the new bit pattern
142 * in the 'set' parameter.
143 */
144
145#define clrbits(type, addr, clear) \
146 out_##type((addr), in_##type(addr) & ~(clear))
147
148#define setbits(type, addr, set) \
149 out_##type((addr), in_##type(addr) | (set))
150
151#define clrsetbits(type, addr, clear, set) \
152 out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
153
154#define clrbits_be32(addr, clear) clrbits(be32, addr, clear)
155#define setbits_be32(addr, set) setbits(be32, addr, set)
156#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)
157
158#define clrbits_le32(addr, clear) clrbits(le32, addr, clear)
159#define setbits_le32(addr, set) setbits(le32, addr, set)
160#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
161
162#define clrbits_be16(addr, clear) clrbits(be16, addr, clear)
163#define setbits_be16(addr, set) setbits(be16, addr, set)
164#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set)
165
166#define clrbits_le16(addr, clear) clrbits(le16, addr, clear)
167#define setbits_le16(addr, set) setbits(le16, addr, set)
168#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set)
169
170#define clrbits_8(addr, clear) clrbits(8, addr, clear)
171#define setbits_8(addr, set) setbits(8, addr, set)
172#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
173
174/*
175 * Now, pick up the machine-defined IO definitions
176 * #include <asm/arch/io.h>
177 */
178
179/*
180 * IO port access primitives
181 * -------------------------
182 *
Bin Mengb5399d92023-04-03 11:37:32 +0800183 * The RISC-V doesn't have special IO access instructions just like ARM;
Rick Chen76c0a242017-12-26 13:55:51 +0800184 * all IO is memory mapped.
185 * Note that these are defined to perform little endian accesses
186 * only. Their primary purpose is to access PCI and ISA peripherals.
187 *
188 * Note that for a big endian machine, this implies that the following
189 * big endian mode connectivity is in place, as described by numerious
190 * ARM documents:
191 *
192 * PCI: D0-D7 D8-D15 D16-D23 D24-D31
193 * ARM: D24-D31 D16-D23 D8-D15 D0-D7
194 *
195 * The machine specific io.h include defines __io to translate an "IO"
196 * address to a memory address.
197 *
198 * Note that we prevent GCC re-ordering or caching values in expressions
199 * by introducing sequence points into the in*() definitions. Note that
200 * __raw_* do not guarantee this behaviour.
201 *
202 * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
203 */
204#ifdef __io
205#define outb(v, p) __raw_writeb(v, __io(p))
206#define outw(v, p) __raw_writew(cpu_to_le16(v), __io(p))
207#define outl(v, p) __raw_writel(cpu_to_le32(v), __io(p))
208
209#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; })
210#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; })
211#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; })
212
213#define outsb(p, d, l) writesb(__io(p), d, l)
214#define outsw(p, d, l) writesw(__io(p), d, l)
215#define outsl(p, d, l) writesl(__io(p), d, l)
216
217#define insb(p, d, l) readsb(__io(p), d, l)
218#define insw(p, d, l) readsw(__io(p), d, l)
219#define insl(p, d, l) readsl(__io(p), d, l)
220
221static inline void readsb(unsigned int *addr, void *data, int bytelen)
222{
223 unsigned char *ptr;
224 unsigned char *ptr2;
225
226 ptr = (unsigned char *)addr;
227 ptr2 = (unsigned char *)data;
228
229 while (bytelen) {
230 *ptr2 = *ptr;
231 ptr2++;
232 bytelen--;
233 }
234}
235
236static inline void readsw(unsigned int *addr, void *data, int wordlen)
237{
238 unsigned short *ptr;
239 unsigned short *ptr2;
240
241 ptr = (unsigned short *)addr;
242 ptr2 = (unsigned short *)data;
243
244 while (wordlen) {
245 *ptr2 = *ptr;
246 ptr2++;
247 wordlen--;
248 }
249}
250
251static inline void readsl(unsigned int *addr, void *data, int longlen)
252{
253 unsigned int *ptr;
254 unsigned int *ptr2;
255
256 ptr = (unsigned int *)addr;
257 ptr2 = (unsigned int *)data;
258
259 while (longlen) {
260 *ptr2 = *ptr;
261 ptr2++;
262 longlen--;
263 }
264}
265
266static inline void writesb(unsigned int *addr, const void *data, int bytelen)
267{
268 unsigned char *ptr;
269 unsigned char *ptr2;
270
271 ptr = (unsigned char *)addr;
272 ptr2 = (unsigned char *)data;
273
274 while (bytelen) {
275 *ptr = *ptr2;
276 ptr2++;
277 bytelen--;
278 }
279}
280
281static inline void writesw(unsigned int *addr, const void *data, int wordlen)
282{
283 unsigned short *ptr;
284 unsigned short *ptr2;
285
286 ptr = (unsigned short *)addr;
287 ptr2 = (unsigned short *)data;
288
289 while (wordlen) {
290 *ptr = *ptr2;
291 ptr2++;
292 wordlen--;
293 }
294}
295
296static inline void writesl(unsigned int *addr, const void *data, int longlen)
297{
298 unsigned int *ptr;
299 unsigned int *ptr2;
300
301 ptr = (unsigned int *)addr;
302 ptr2 = (unsigned int *)data;
303
304 while (longlen) {
305 *ptr = *ptr2;
306 ptr2++;
307 longlen--;
308 }
309}
Igor Prusovcde38822023-11-14 14:02:49 +0300310
311#define readsb readsb
312#define readsw readsw
313#define readsl readsl
314#define writesb writesb
315#define writesw writesw
316#define writesl writesl
317
Rick Chen76c0a242017-12-26 13:55:51 +0800318#endif
319
320#define outb_p(val, port) outb((val), (port))
321#define outw_p(val, port) outw((val), (port))
322#define outl_p(val, port) outl((val), (port))
323#define inb_p(port) inb((port))
324#define inw_p(port) inw((port))
325#define inl_p(port) inl((port))
326
327#define outsb_p(port, from, len) outsb(port, from, len)
328#define outsw_p(port, from, len) outsw(port, from, len)
329#define outsl_p(port, from, len) outsl(port, from, len)
330#define insb_p(port, to, len) insb(port, to, len)
331#define insw_p(port, to, len) insw(port, to, len)
332#define insl_p(port, to, len) insl(port, to, len)
333
Chanho Parkd1898ce2023-11-01 21:16:48 +0900334/*
335 * Unordered I/O memory access primitives. These are even more relaxed than
336 * the relaxed versions, as they don't even order accesses between successive
337 * operations to the I/O regions.
338 */
339#define readb_cpu(c) ({ u8 __r = __raw_readb(c); __r; })
340#define readw_cpu(c) ({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
341#define readl_cpu(c) ({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
342
343#define writeb_cpu(v, c) ((void)__raw_writeb((v), (c)))
344#define writew_cpu(v, c) ((void)__raw_writew((__force u16)cpu_to_le16(v), (c)))
345#define writel_cpu(v, c) ((void)__raw_writel((__force u32)cpu_to_le32(v), (c)))
346
347#ifdef CONFIG_64BIT
348#define readq_cpu(c) ({ u64 __r = le64_to_cpu((__force __le64)__raw_readq(c)); __r; })
349#define writeq_cpu(v, c) ((void)__raw_writeq((__force u64)cpu_to_le64(v), (c)))
350#endif
351
352/*
353 * Relaxed I/O memory access primitives. These follow the Device memory
354 * ordering rules but do not guarantee any ordering relative to Normal memory
355 * accesses. These are defined to order the indicated access (either a read or
356 * write) with all other I/O memory accesses to the same peripheral. Since the
357 * platform specification defines that all I/O regions are strongly ordered on
358 * channel 0, no explicit fences are required to enforce this ordering.
359 */
360/* FIXME: These are now the same as asm-generic */
361#define __io_rbr() do {} while (0)
362#define __io_rar() do {} while (0)
363#define __io_rbw() do {} while (0)
364#define __io_raw() do {} while (0)
365
366#define readb_relaxed(c) ({ u8 __v; __io_rbr(); __v = readb_cpu(c); __io_rar(); __v; })
367#define readw_relaxed(c) ({ u16 __v; __io_rbr(); __v = readw_cpu(c); __io_rar(); __v; })
368#define readl_relaxed(c) ({ u32 __v; __io_rbr(); __v = readl_cpu(c); __io_rar(); __v; })
369
370#define writeb_relaxed(v, c) ({ __io_rbw(); writeb_cpu((v), (c)); __io_raw(); })
371#define writew_relaxed(v, c) ({ __io_rbw(); writew_cpu((v), (c)); __io_raw(); })
372#define writel_relaxed(v, c) ({ __io_rbw(); writel_cpu((v), (c)); __io_raw(); })
373
374#ifdef CONFIG_64BIT
375#define readq_relaxed(c) ({ u64 __v; __io_rbr(); __v = readq_cpu(c); __io_rar(); __v; })
376#define writeq_relaxed(v, c) ({ __io_rbw(); writeq_cpu((v), (c)); __io_raw(); })
377#endif
378
Lukas Auer09db5fc2018-11-22 11:26:19 +0100379#include <asm-generic/io.h>
380
Rick Chen76c0a242017-12-26 13:55:51 +0800381#endif /* __ASM_RISCV_IO_H */