blob: afdcea90707a7a54f004d8e519877e2dab77d3db [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $Id: io.h,v 1.47 2001/12/13 10:36:02 davem Exp $ */
2#ifndef __SPARC64_IO_H
3#define __SPARC64_IO_H
4
5#include <linux/kernel.h>
6#include <linux/compiler.h>
7#include <linux/types.h>
8
9#include <asm/page.h> /* IO address mapping routines need this */
10#include <asm/system.h>
11#include <asm/asi.h>
12
13/* PC crapola... */
14#define __SLOW_DOWN_IO do { } while (0)
15#define SLOW_DOWN_IO do { } while (0)
16
17extern unsigned long virt_to_bus_not_defined_use_pci_map(volatile void *addr);
18#define virt_to_bus virt_to_bus_not_defined_use_pci_map
19extern unsigned long bus_to_virt_not_defined_use_pci_map(volatile void *addr);
20#define bus_to_virt bus_to_virt_not_defined_use_pci_map
21
22/* BIO layer definitions. */
23extern unsigned long kern_base, kern_size;
24#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
25#define BIO_VMERGE_BOUNDARY 8192
26
27/* Different PCI controllers we support have their PCI MEM space
28 * mapped to an either 2GB (Psycho) or 4GB (Sabre) aligned area,
29 * so need to chop off the top 33 or 32 bits.
30 */
31extern unsigned long pci_memspace_mask;
32
33#define bus_dvma_to_mem(__vaddr) ((__vaddr) & pci_memspace_mask)
34
35static __inline__ u8 _inb(unsigned long addr)
36{
37 u8 ret;
38
39 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
40 : "=r" (ret)
41 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
42
43 return ret;
44}
45
46static __inline__ u16 _inw(unsigned long addr)
47{
48 u16 ret;
49
50 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
51 : "=r" (ret)
52 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
53
54 return ret;
55}
56
57static __inline__ u32 _inl(unsigned long addr)
58{
59 u32 ret;
60
61 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
62 : "=r" (ret)
63 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
64
65 return ret;
66}
67
68static __inline__ void _outb(u8 b, unsigned long addr)
69{
70 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
71 : /* no outputs */
72 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
73}
74
75static __inline__ void _outw(u16 w, unsigned long addr)
76{
77 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
78 : /* no outputs */
79 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
80}
81
82static __inline__ void _outl(u32 l, unsigned long addr)
83{
84 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
85 : /* no outputs */
86 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
87}
88
89#define inb(__addr) (_inb((unsigned long)(__addr)))
90#define inw(__addr) (_inw((unsigned long)(__addr)))
91#define inl(__addr) (_inl((unsigned long)(__addr)))
92#define outb(__b, __addr) (_outb((u8)(__b), (unsigned long)(__addr)))
93#define outw(__w, __addr) (_outw((u16)(__w), (unsigned long)(__addr)))
94#define outl(__l, __addr) (_outl((u32)(__l), (unsigned long)(__addr)))
95
96#define inb_p(__addr) inb(__addr)
97#define outb_p(__b, __addr) outb(__b, __addr)
98#define inw_p(__addr) inw(__addr)
99#define outw_p(__w, __addr) outw(__w, __addr)
100#define inl_p(__addr) inl(__addr)
101#define outl_p(__l, __addr) outl(__l, __addr)
102
103extern void outsb(void __iomem *addr, const void *src, unsigned long count);
104extern void outsw(void __iomem *addr, const void *src, unsigned long count);
105extern void outsl(void __iomem *addr, const void *src, unsigned long count);
106extern void insb(void __iomem *addr, void *dst, unsigned long count);
107extern void insw(void __iomem *addr, void *dst, unsigned long count);
108extern void insl(void __iomem *addr, void *dst, unsigned long count);
109#define ioread8_rep(a,d,c) insb(a,d,c)
110#define ioread16_rep(a,d,c) insw(a,d,c)
111#define ioread32_rep(a,d,c) insl(a,d,c)
112#define iowrite8_rep(a,s,c) outsb(a,s,c)
113#define iowrite16_rep(a,s,c) outsw(a,s,c)
114#define iowrite32_rep(a,s,c) outsl(a,s,c)
115
116/* Memory functions, same as I/O accesses on Ultra. */
117static inline u8 _readb(const volatile void __iomem *addr)
118{ u8 ret;
119
120 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
121 : "=r" (ret)
122 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
123 return ret;
124}
125
126static inline u16 _readw(const volatile void __iomem *addr)
127{ u16 ret;
128
129 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
130 : "=r" (ret)
131 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
132
133 return ret;
134}
135
136static inline u32 _readl(const volatile void __iomem *addr)
137{ u32 ret;
138
139 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
140 : "=r" (ret)
141 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
142
143 return ret;
144}
145
146static inline u64 _readq(const volatile void __iomem *addr)
147{ u64 ret;
148
149 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
150 : "=r" (ret)
151 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
152
153 return ret;
154}
155
156static inline void _writeb(u8 b, volatile void __iomem *addr)
157{
158 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
159 : /* no outputs */
160 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
161}
162
163static inline void _writew(u16 w, volatile void __iomem *addr)
164{
165 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
166 : /* no outputs */
167 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
168}
169
170static inline void _writel(u32 l, volatile void __iomem *addr)
171{
172 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
173 : /* no outputs */
174 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
175}
176
177static inline void _writeq(u64 q, volatile void __iomem *addr)
178{
179 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
180 : /* no outputs */
181 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
182}
183
184#define readb(__addr) _readb(__addr)
185#define readw(__addr) _readw(__addr)
186#define readl(__addr) _readl(__addr)
187#define readq(__addr) _readq(__addr)
188#define readb_relaxed(__addr) _readb(__addr)
189#define readw_relaxed(__addr) _readw(__addr)
190#define readl_relaxed(__addr) _readl(__addr)
191#define readq_relaxed(__addr) _readq(__addr)
192#define writeb(__b, __addr) _writeb(__b, __addr)
193#define writew(__w, __addr) _writew(__w, __addr)
194#define writel(__l, __addr) _writel(__l, __addr)
195#define writeq(__q, __addr) _writeq(__q, __addr)
196
197/* Now versions without byte-swapping. */
198static __inline__ u8 _raw_readb(unsigned long addr)
199{
200 u8 ret;
201
202 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
203 : "=r" (ret)
204 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
205
206 return ret;
207}
208
209static __inline__ u16 _raw_readw(unsigned long addr)
210{
211 u16 ret;
212
213 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
214 : "=r" (ret)
215 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
216
217 return ret;
218}
219
220static __inline__ u32 _raw_readl(unsigned long addr)
221{
222 u32 ret;
223
224 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
225 : "=r" (ret)
226 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
227
228 return ret;
229}
230
231static __inline__ u64 _raw_readq(unsigned long addr)
232{
233 u64 ret;
234
235 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
236 : "=r" (ret)
237 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
238
239 return ret;
240}
241
242static __inline__ void _raw_writeb(u8 b, unsigned long addr)
243{
244 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
245 : /* no outputs */
246 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
247}
248
249static __inline__ void _raw_writew(u16 w, unsigned long addr)
250{
251 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
252 : /* no outputs */
253 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
254}
255
256static __inline__ void _raw_writel(u32 l, unsigned long addr)
257{
258 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
259 : /* no outputs */
260 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
261}
262
263static __inline__ void _raw_writeq(u64 q, unsigned long addr)
264{
265 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
266 : /* no outputs */
267 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
268}
269
270#define __raw_readb(__addr) (_raw_readb((unsigned long)(__addr)))
271#define __raw_readw(__addr) (_raw_readw((unsigned long)(__addr)))
272#define __raw_readl(__addr) (_raw_readl((unsigned long)(__addr)))
273#define __raw_readq(__addr) (_raw_readq((unsigned long)(__addr)))
274#define __raw_writeb(__b, __addr) (_raw_writeb((u8)(__b), (unsigned long)(__addr)))
275#define __raw_writew(__w, __addr) (_raw_writew((u16)(__w), (unsigned long)(__addr)))
276#define __raw_writel(__l, __addr) (_raw_writel((u32)(__l), (unsigned long)(__addr)))
277#define __raw_writeq(__q, __addr) (_raw_writeq((u64)(__q), (unsigned long)(__addr)))
278
279/* Valid I/O Space regions are anywhere, because each PCI bus supported
280 * can live in an arbitrary area of the physical address range.
281 */
282#define IO_SPACE_LIMIT 0xffffffffffffffffUL
283
284/* Now, SBUS variants, only difference from PCI is that we do
285 * not use little-endian ASIs.
286 */
287static inline u8 _sbus_readb(const volatile void __iomem *addr)
288{
289 u8 ret;
290
291 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
292 : "=r" (ret)
293 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
294
295 return ret;
296}
297
298static inline u16 _sbus_readw(const volatile void __iomem *addr)
299{
300 u16 ret;
301
302 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
303 : "=r" (ret)
304 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
305
306 return ret;
307}
308
309static inline u32 _sbus_readl(const volatile void __iomem *addr)
310{
311 u32 ret;
312
313 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
314 : "=r" (ret)
315 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
316
317 return ret;
318}
319
320static inline u64 _sbus_readq(const volatile void __iomem *addr)
321{
322 u64 ret;
323
324 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */"
325 : "=r" (ret)
326 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
327
328 return ret;
329}
330
331static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
332{
333 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
334 : /* no outputs */
335 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
336}
337
338static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
339{
340 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
341 : /* no outputs */
342 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
343}
344
345static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
346{
347 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
348 : /* no outputs */
349 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
350}
351
352static inline void _sbus_writeq(u64 l, volatile void __iomem *addr)
353{
354 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */"
355 : /* no outputs */
356 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
357}
358
359#define sbus_readb(__addr) _sbus_readb(__addr)
360#define sbus_readw(__addr) _sbus_readw(__addr)
361#define sbus_readl(__addr) _sbus_readl(__addr)
362#define sbus_readq(__addr) _sbus_readq(__addr)
363#define sbus_writeb(__b, __addr) _sbus_writeb(__b, __addr)
364#define sbus_writew(__w, __addr) _sbus_writew(__w, __addr)
365#define sbus_writel(__l, __addr) _sbus_writel(__l, __addr)
366#define sbus_writeq(__l, __addr) _sbus_writeq(__l, __addr)
367
368static inline void _sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
369{
370 while(n--) {
371 sbus_writeb(c, dst);
372 dst++;
373 }
374}
375
376#define sbus_memset_io(d,c,sz) _sbus_memset_io(d,c,sz)
377
378static inline void
379_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
380{
381 volatile void __iomem *d = dst;
382
383 while (n--) {
384 writeb(c, d);
385 d++;
386 }
387}
388
389#define memset_io(d,c,sz) _memset_io(d,c,sz)
390
391static inline void
392_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
393{
394 char *d = dst;
395
396 while (n--) {
397 char tmp = readb(src);
398 *d++ = tmp;
399 src++;
400 }
401}
402
403#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
404
405static inline void
406_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
407{
408 const char *s = src;
409 volatile void __iomem *d = dst;
410
411 while (n--) {
412 char tmp = *s++;
413 writeb(tmp, d);
414 d++;
415 }
416}
417
418#define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz)
419
420static inline int check_signature(void __iomem *io_addr,
421 const unsigned char *signature,
422 int length)
423{
424 int retval = 0;
425 do {
426 if (readb(io_addr) != *signature++)
427 goto out;
428 io_addr++;
429 } while (--length);
430 retval = 1;
431out:
432 return retval;
433}
434
435#define mmiowb()
436
437#ifdef __KERNEL__
438
439/* On sparc64 we have the whole physical IO address space accessible
440 * using physically addressed loads and stores, so this does nothing.
441 */
442static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
443{
444 return (void __iomem *)offset;
445}
446
447#define ioremap_nocache(X,Y) ioremap((X),(Y))
448
449static inline void iounmap(volatile void __iomem *addr)
450{
451}
452
453#define ioread8(X) readb(X)
454#define ioread16(X) readw(X)
455#define ioread32(X) readl(X)
456#define iowrite8(val,X) writeb(val,X)
457#define iowrite16(val,X) writew(val,X)
458#define iowrite32(val,X) writel(val,X)
459
460/* Create a virtual mapping cookie for an IO port range */
461extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
462extern void ioport_unmap(void __iomem *);
463
464/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
465struct pci_dev;
466extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
467extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
468
469/* Similarly for SBUS. */
470#define sbus_ioremap(__res, __offset, __size, __name) \
471({ unsigned long __ret; \
472 __ret = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \
473 __ret += (unsigned long) (__offset); \
474 if (! request_region((__ret), (__size), (__name))) \
475 __ret = 0UL; \
476 (void __iomem *) __ret; \
477})
478
479#define sbus_iounmap(__addr, __size) \
480 release_region((unsigned long)(__addr), (__size))
481
482/* Nothing to do */
483
484#define dma_cache_inv(_start,_size) do { } while (0)
485#define dma_cache_wback(_start,_size) do { } while (0)
486#define dma_cache_wback_inv(_start,_size) do { } while (0)
487
488/*
489 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
490 * access
491 */
492#define xlate_dev_mem_ptr(p) __va(p)
493
494/*
495 * Convert a virtual cached pointer to an uncached pointer
496 */
497#define xlate_dev_kmem_ptr(p) p
498
499#endif
500
501#endif /* !(__SPARC64_IO_H) */