blob: 6c55c532d09afc97922fdece6afb1264ae537ae4 [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{
190 u8 ret;
191
192 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
193 : "=r" (ret)
194 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
195 : "memory");
196
197 return ret;
198}
199
Sam Ravnborg79294d72014-07-20 13:39:00 +0200200#define inw inw
201static inline u16 inw(unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700202{
203 u16 ret;
204
205 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
206 : "=r" (ret)
207 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
208 : "memory");
209
210 return ret;
211}
212
Sam Ravnborg79294d72014-07-20 13:39:00 +0200213#define inl inl
214static inline u32 inl(unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700215{
216 u32 ret;
217
218 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
219 : "=r" (ret)
220 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
221 : "memory");
222
223 return ret;
224}
225
Sam Ravnborg79294d72014-07-20 13:39:00 +0200226#define outb outb
227static inline void outb(u8 b, unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700228{
229 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
230 : /* no outputs */
231 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
232 : "memory");
233}
234
Sam Ravnborg79294d72014-07-20 13:39:00 +0200235#define outw outw
236static inline void outw(u16 w, unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700237{
238 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
239 : /* no outputs */
240 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
241 : "memory");
242}
243
Sam Ravnborg79294d72014-07-20 13:39:00 +0200244#define outl outl
245static inline void outl(u32 l, unsigned long addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700246{
247 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
248 : /* no outputs */
249 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
250 : "memory");
251}
252
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700253
254#define inb_p(__addr) inb(__addr)
255#define outb_p(__b, __addr) outb(__b, __addr)
256#define inw_p(__addr) inw(__addr)
257#define outw_p(__w, __addr) outw(__w, __addr)
258#define inl_p(__addr) inl(__addr)
259#define outl_p(__l, __addr) outl(__l, __addr)
260
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200261void outsb(unsigned long, const void *, unsigned long);
262void outsw(unsigned long, const void *, unsigned long);
263void outsl(unsigned long, const void *, unsigned long);
264void insb(unsigned long, void *, unsigned long);
265void insw(unsigned long, void *, unsigned long);
266void insl(unsigned long, void *, unsigned long);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700267
268static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
269{
270 insb((unsigned long __force)port, buf, count);
271}
272static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
273{
274 insw((unsigned long __force)port, buf, count);
275}
276
277static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
278{
279 insl((unsigned long __force)port, buf, count);
280}
281
282static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
283{
284 outsb((unsigned long __force)port, buf, count);
285}
286
287static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
288{
289 outsw((unsigned long __force)port, buf, count);
290}
291
292static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
293{
294 outsl((unsigned long __force)port, buf, count);
295}
296
Sam Ravnborg79294d72014-07-20 13:39:00 +0200297#define readb_relaxed(__addr) readb(__addr)
298#define readw_relaxed(__addr) readw(__addr)
299#define readl_relaxed(__addr) readl(__addr)
300#define readq_relaxed(__addr) readq(__addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700301
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700302/* Valid I/O Space regions are anywhere, because each PCI bus supported
303 * can live in an arbitrary area of the physical address range.
304 */
305#define IO_SPACE_LIMIT 0xffffffffffffffffUL
306
307/* Now, SBUS variants, only difference from PCI is that we do
308 * not use little-endian ASIs.
309 */
Sam Ravnborg79294d72014-07-20 13:39:00 +0200310static inline u8 sbus_readb(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700311{
312 u8 ret;
313
314 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
315 : "=r" (ret)
316 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
317 : "memory");
318
319 return ret;
320}
321
Sam Ravnborg79294d72014-07-20 13:39:00 +0200322static inline u16 sbus_readw(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700323{
324 u16 ret;
325
326 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
327 : "=r" (ret)
328 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
329 : "memory");
330
331 return ret;
332}
333
Sam Ravnborg79294d72014-07-20 13:39:00 +0200334static inline u32 sbus_readl(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700335{
336 u32 ret;
337
338 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
339 : "=r" (ret)
340 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
341 : "memory");
342
343 return ret;
344}
345
Sam Ravnborg79294d72014-07-20 13:39:00 +0200346static inline u64 sbus_readq(const volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700347{
348 u64 ret;
349
350 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */"
351 : "=r" (ret)
352 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
353 : "memory");
354
355 return ret;
356}
357
Sam Ravnborg79294d72014-07-20 13:39:00 +0200358static inline void sbus_writeb(u8 b, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700359{
360 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
361 : /* no outputs */
362 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
363 : "memory");
364}
365
Sam Ravnborg79294d72014-07-20 13:39:00 +0200366static inline void sbus_writew(u16 w, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700367{
368 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
369 : /* no outputs */
370 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
371 : "memory");
372}
373
Sam Ravnborg79294d72014-07-20 13:39:00 +0200374static inline void sbus_writel(u32 l, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700375{
376 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
377 : /* no outputs */
378 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
379 : "memory");
380}
381
Sam Ravnborg79294d72014-07-20 13:39:00 +0200382static inline void sbus_writeq(u64 l, volatile void __iomem *addr)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700383{
384 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */"
385 : /* no outputs */
386 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
387 : "memory");
388}
389
Sam Ravnborg79294d72014-07-20 13:39:00 +0200390static inline void sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700391{
392 while(n--) {
393 sbus_writeb(c, dst);
394 dst++;
395 }
396}
397
Sam Ravnborg79294d72014-07-20 13:39:00 +0200398static inline void memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700399{
400 volatile void __iomem *d = dst;
401
402 while (n--) {
403 writeb(c, d);
404 d++;
405 }
406}
407
Sam Ravnborg79294d72014-07-20 13:39:00 +0200408static inline void sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
409 __kernel_size_t n)
James Hoganf11b4782010-10-27 15:33:28 -0700410{
411 char *d = dst;
412
413 while (n--) {
414 char tmp = sbus_readb(src);
415 *d++ = tmp;
416 src++;
417 }
418}
419
James Hoganf11b4782010-10-27 15:33:28 -0700420
Sam Ravnborg79294d72014-07-20 13:39:00 +0200421static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
422 __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700423{
424 char *d = dst;
425
426 while (n--) {
427 char tmp = readb(src);
428 *d++ = tmp;
429 src++;
430 }
431}
432
Sam Ravnborg79294d72014-07-20 13:39:00 +0200433static inline void sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
434 __kernel_size_t n)
James Hoganf11b4782010-10-27 15:33:28 -0700435{
436 const char *s = src;
437 volatile void __iomem *d = dst;
438
439 while (n--) {
440 char tmp = *s++;
441 sbus_writeb(tmp, d);
442 d++;
443 }
444}
445
Sam Ravnborg79294d72014-07-20 13:39:00 +0200446static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
447 __kernel_size_t n)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700448{
449 const char *s = src;
450 volatile void __iomem *d = dst;
451
452 while (n--) {
453 char tmp = *s++;
454 writeb(tmp, d);
455 d++;
456 }
457}
458
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700459#define mmiowb()
460
461#ifdef __KERNEL__
462
463/* On sparc64 we have the whole physical IO address space accessible
464 * using physically addressed loads and stores, so this does nothing.
465 */
466static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
467{
468 return (void __iomem *)offset;
469}
470
471#define ioremap_nocache(X,Y) ioremap((X),(Y))
David S. Miller428695b2008-07-22 14:30:55 -0700472#define ioremap_wc(X,Y) ioremap((X),(Y))
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700473
474static inline void iounmap(volatile void __iomem *addr)
475{
476}
477
478#define ioread8(X) readb(X)
479#define ioread16(X) readw(X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800480#define ioread16be(X) __raw_readw(X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700481#define ioread32(X) readl(X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800482#define ioread32be(X) __raw_readl(X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700483#define iowrite8(val,X) writeb(val,X)
484#define iowrite16(val,X) writew(val,X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800485#define iowrite16be(val,X) __raw_writew(val,X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700486#define iowrite32(val,X) writel(val,X)
David S. Miller1bff4db2010-03-03 02:30:37 -0800487#define iowrite32be(val,X) __raw_writel(val,X)
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700488
489/* Create a virtual mapping cookie for an IO port range */
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200490void __iomem *ioport_map(unsigned long port, unsigned int nr);
491void ioport_unmap(void __iomem *);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700492
493/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
494struct pci_dev;
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200495void pci_iounmap(struct pci_dev *dev, void __iomem *);
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700496
David S. Miller63237ee2008-08-26 23:33:42 -0700497static inline int sbus_can_dma_64bit(void)
498{
499 return 1;
500}
501static inline int sbus_can_burst64(void)
502{
503 return 1;
504}
505struct device;
Sam Ravnborgf05a6862014-05-16 23:25:50 +0200506void sbus_set_sbus64(struct device *, int);
David S. Miller63237ee2008-08-26 23:33:42 -0700507
Sam Ravnborgf5e706a2008-07-17 21:55:51 -0700508/*
509 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
510 * access
511 */
512#define xlate_dev_mem_ptr(p) __va(p)
513
514/*
515 * Convert a virtual cached pointer to an uncached pointer
516 */
517#define xlate_dev_kmem_ptr(p) p
518
519#endif
520
521#endif /* !(__SPARC64_IO_H) */