blob: 80b54b326d4983f5c2ccdd48557276d459c5fb62 [file] [log] [blame]
Sam Ravnborgf5e706a2008-07-17 21:55:51 -07001#ifndef __SPARC64_IO_H
2#define __SPARC64_IO_H
3
4#include <linux/kernel.h>
5#include <linux/compiler.h>
6#include <linux/types.h>
7
8#include <asm/page.h> /* IO address mapping routines need this */
Sam Ravnborgf5e706a2008-07-17 21:55:51 -07009#include <asm/asi.h>
Michael S. Tsirkina21a2fd2011-11-24 21:10:12 +020010#include <asm-generic/pci_iomap.h>
Sam Ravnborgf5e706a2008-07-17 21:55:51 -070011
Sam Ravnborgf5e706a2008-07-17 21:55:51 -070012/* BIO layer definitions. */
13extern unsigned long kern_base, kern_size;
Sam Ravnborgf5e706a2008-07-17 21:55:51 -070014
Sam Ravnborgadd79d62014-07-20 13:39:02 +020015/* __raw_{read,write}{b,w,l,q} uses direct access.
16 * Access the memory as big endian bypassing the cache
17 * by using ASI_PHYS_BYPASS_EC_E
18 */
19#define __raw_readb __raw_readb
20static inline u8 __raw_readb(const volatile void __iomem *addr)
21{
22 u8 ret;
23
24 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
25 : "=r" (ret)
26 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
27
28 return ret;
29}
30
31#define __raw_readw __raw_readw
32static inline u16 __raw_readw(const volatile void __iomem *addr)
33{
34 u16 ret;
35
36 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
37 : "=r" (ret)
38 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
39
40 return ret;
41}
42
43#define __raw_readl __raw_readl
44static inline u32 __raw_readl(const volatile void __iomem *addr)
45{
46 u32 ret;
47
48 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
49 : "=r" (ret)
50 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
51
52 return ret;
53}
54
55#define __raw_readq __raw_readq
56static inline u64 __raw_readq(const volatile void __iomem *addr)
57{
58 u64 ret;
59
60 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
61 : "=r" (ret)
62 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
63
64 return ret;
65}
66
67#define __raw_writeb __raw_writeb
68static inline void __raw_writeb(u8 b, const volatile void __iomem *addr)
69{
70 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
71 : /* no outputs */
72 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
73}
74
75#define __raw_writew __raw_writew
76static inline void __raw_writew(u16 w, const volatile void __iomem *addr)
77{
78 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
79 : /* no outputs */
80 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
81}
82
83#define __raw_writel __raw_writel
84static inline void __raw_writel(u32 l, const volatile void __iomem *addr)
85{
86 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
87 : /* no outputs */
88 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
89}
90
91#define __raw_writeq __raw_writeq
92static inline void __raw_writeq(u64 q, const volatile void __iomem *addr)
93{
94 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
95 : /* no outputs */
96 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
97}
98
99/* Memory functions, same as I/O accesses on Ultra.
100 * Access memory as little endian bypassing
101 * the cache by using ASI_PHYS_BYPASS_EC_E_L
102 */
103#define readb readb
104static inline u8 readb(const volatile void __iomem *addr)
105{ u8 ret;
106
107 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
108 : "=r" (ret)
109 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
110 : "memory");
111 return ret;
112}
113
114#define readw readw
115static inline u16 readw(const volatile void __iomem *addr)
116{ u16 ret;
117
118 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
119 : "=r" (ret)
120 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
121 : "memory");
122
123 return ret;
124}
125
126#define readl readl
127static inline u32 readl(const volatile void __iomem *addr)
128{ u32 ret;
129
130 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
131 : "=r" (ret)
132 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
133 : "memory");
134
135 return ret;
136}
137
138#define readq readq
139static inline u64 readq(const volatile void __iomem *addr)
140{ u64 ret;
141
142 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
143 : "=r" (ret)
144 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
145 : "memory");
146
147 return ret;
148}
149
150#define writeb writeb
151static inline void writeb(u8 b, volatile void __iomem *addr)
152{
153 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
154 : /* no outputs */
155 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
156 : "memory");
157}
158
159#define writew writew
160static inline void writew(u16 w, volatile void __iomem *addr)
161{
162 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
163 : /* no outputs */
164 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
165 : "memory");
166}
167
168#define writel writel
169static inline void writel(u32 l, volatile void __iomem *addr)
170{
171 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
172 : /* no outputs */
173 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
174 : "memory");
175}
176
177#define writeq writeq
178static inline void writeq(u64 q, volatile void __iomem *addr)
179{
180 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
181 : /* no outputs */
182 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
183 : "memory");
184}
185
186
Sam Ravnborg79294d72014-07-20 13:39:00 +0200187#define inb inb
188static inline u8 inb(unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700189{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200190 return readb((volatile void __iomem *)addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700191}
192
Sam Ravnborg79294d72014-07-20 13:39:00 +0200193#define inw inw
194static inline u16 inw(unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700195{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200196 return readw((volatile void __iomem *)addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700197}
198
Sam Ravnborg79294d72014-07-20 13:39:00 +0200199#define inl inl
200static inline u32 inl(unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700201{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200202 return readl((volatile void __iomem *)addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700203}
204
Sam Ravnborg79294d72014-07-20 13:39:00 +0200205#define outb outb
206static inline void outb(u8 b, unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700207{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200208 writeb(b, (volatile void __iomem *)addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700209}
210
Sam Ravnborg79294d72014-07-20 13:39:00 +0200211#define outw outw
212static inline void outw(u16 w, unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700213{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200214 writew(w, (volatile void __iomem *)addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700215}
216
Sam Ravnborg79294d72014-07-20 13:39:00 +0200217#define outl outl
218static inline void outl(u32 l, unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700219{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200220 writel(l, (volatile void __iomem *)addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700221}
222
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700223
224#define inb_p(__addr) inb(__addr)
225#define outb_p(__b, __addr) outb(__b, __addr)
226#define inw_p(__addr) inw(__addr)
227#define outw_p(__w, __addr) outw(__w, __addr)
228#define inl_p(__addr) inl(__addr)
229#define outl_p(__l, __addr) outl(__l, __addr)
230
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200231void outsb(unsigned long, const void *, unsigned long);
232void outsw(unsigned long, const void *, unsigned long);
233void outsl(unsigned long, const void *, unsigned long);
234void insb(unsigned long, void *, unsigned long);
235void insw(unsigned long, void *, unsigned long);
236void insl(unsigned long, void *, unsigned long);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700237
238static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
239{
240 insb((unsigned long __force)port, buf, count);
241}
242static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
243{
244 insw((unsigned long __force)port, buf, count);
245}
246
247static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
248{
249 insl((unsigned long __force)port, buf, count);
250}
251
252static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
253{
254 outsb((unsigned long __force)port, buf, count);
255}
256
257static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
258{
259 outsw((unsigned long __force)port, buf, count);
260}
261
262static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
263{
264 outsl((unsigned long __force)port, buf, count);
265}
266
Sam Ravnborg79294d72014-07-20 13:39:00 +0200267#define readb_relaxed(__addr) readb(__addr)
268#define readw_relaxed(__addr) readw(__addr)
269#define readl_relaxed(__addr) readl(__addr)
270#define readq_relaxed(__addr) readq(__addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700271
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700272/* Valid I/O Space regions are anywhere, because each PCI bus supported
273 * can live in an arbitrary area of the physical address range.
274 */
275#define IO_SPACE_LIMIT 0xffffffffffffffffUL
276
277/* Now, SBUS variants, only difference from PCI is that we do
278 * not use little-endian ASIs.
279 */
Sam Ravnborg79294d72014-07-20 13:39:00 +0200280static inline u8 sbus_readb(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700281{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200282 return __raw_readb(addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700283}
284
Sam Ravnborg79294d72014-07-20 13:39:00 +0200285static inline u16 sbus_readw(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700286{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200287 return __raw_readw(addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700288}
289
Sam Ravnborg79294d72014-07-20 13:39:00 +0200290static inline u32 sbus_readl(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700291{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200292 return __raw_readl(addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700293}
294
Sam Ravnborg79294d72014-07-20 13:39:00 +0200295static inline u64 sbus_readq(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700296{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200297 return __raw_readq(addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700298}
299
Sam Ravnborg79294d72014-07-20 13:39:00 +0200300static inline void sbus_writeb(u8 b, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700301{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200302 __raw_writeb(b, addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700303}
304
Sam Ravnborg79294d72014-07-20 13:39:00 +0200305static inline void sbus_writew(u16 w, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700306{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200307 __raw_writew(w, addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700308}
309
Sam Ravnborg79294d72014-07-20 13:39:00 +0200310static inline void sbus_writel(u32 l, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700311{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200312 __raw_writel(l, addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700313}
314
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200315static inline void sbus_writeq(u64 q, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700316{
Sam Ravnborg453c9ab2014-07-20 13:39:03 +0200317 __raw_writeq(q, addr);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700318}
319
Sam Ravnborg79294d72014-07-20 13:39:00 +0200320static inline void sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700321{
322 while(n--) {
323 sbus_writeb(c, dst);
324 dst++;
325 }
326}
327
Sam Ravnborg79294d72014-07-20 13:39:00 +0200328static inline void memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700329{
330 volatile void __iomem *d = dst;
331
332 while (n--) {
333 writeb(c, d);
334 d++;
335 }
336}
337
Sam Ravnborg79294d72014-07-20 13:39:00 +0200338static inline void sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
339 __kernel_size_t n)
James Hoganf11b478d2010-10-27 15:33:28 -0700340{
341 char *d = dst;
342
343 while (n--) {
344 char tmp = sbus_readb(src);
345 *d++ = tmp;
346 src++;
347 }
348}
349
James Hoganf11b478d2010-10-27 15:33:28 -0700350
Sam Ravnborg79294d72014-07-20 13:39:00 +0200351static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
352 __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700353{
354 char *d = dst;
355
356 while (n--) {
357 char tmp = readb(src);
358 *d++ = tmp;
359 src++;
360 }
361}
362
Sam Ravnborg79294d72014-07-20 13:39:00 +0200363static inline void sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
364 __kernel_size_t n)
James Hoganf11b478d2010-10-27 15:33:28 -0700365{
366 const char *s = src;
367 volatile void __iomem *d = dst;
368
369 while (n--) {
370 char tmp = *s++;
371 sbus_writeb(tmp, d);
372 d++;
373 }
374}
375
Sam Ravnborg79294d72014-07-20 13:39:00 +0200376static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
377 __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700378{
379 const char *s = src;
380 volatile void __iomem *d = dst;
381
382 while (n--) {
383 char tmp = *s++;
384 writeb(tmp, d);
385 d++;
386 }
387}
388
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700389#define mmiowb()
390
391#ifdef __KERNEL__
392
393/* On sparc64 we have the whole physical IO address space accessible
394 * using physically addressed loads and stores, so this does nothing.
395 */
396static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
397{
398 return (void __iomem *)offset;
399}
400
401#define ioremap_nocache(X,Y) ioremap((X),(Y))
David S. Miller428695b2008-07-22 14:30:55 -0700402#define ioremap_wc(X,Y) ioremap((X),(Y))
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700403
404static inline void iounmap(volatile void __iomem *addr)
405{
406}
407
408#define ioread8(X) readb(X)
409#define ioread16(X) readw(X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800410#define ioread16be(X) __raw_readw(X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700411#define ioread32(X) readl(X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800412#define ioread32be(X) __raw_readl(X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700413#define iowrite8(val,X) writeb(val,X)
414#define iowrite16(val,X) writew(val,X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800415#define iowrite16be(val,X) __raw_writew(val,X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700416#define iowrite32(val,X) writel(val,X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800417#define iowrite32be(val,X) __raw_writel(val,X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700418
419/* Create a virtual mapping cookie for an IO port range */
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200420void __iomem *ioport_map(unsigned long port, unsigned int nr);
421void ioport_unmap(void __iomem *);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700422
423/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
424struct pci_dev;
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200425void pci_iounmap(struct pci_dev *dev, void __iomem *);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700426
David S. Miller63237ee2008-08-26 23:33:42 -0700427static inline int sbus_can_dma_64bit(void)
428{
429 return 1;
430}
431static inline int sbus_can_burst64(void)
432{
433 return 1;
434}
435struct device;
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200436void sbus_set_sbus64(struct device *, int);
David S. Miller63237ee2008-08-26 23:33:42 -0700437
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700438/*
439 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
440 * access
441 */
442#define xlate_dev_mem_ptr(p) __va(p)
443
444/*
445 * Convert a virtual cached pointer to an uncached pointer
446 */
447#define xlate_dev_kmem_ptr(p) p
448
449#endif
450
451#endif /* !(__SPARC64_IO_H) */