1/* SPDX-License-Identifier: GPL-2.0 */ 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/asi.h> 11#include <asm-generic/pci_iomap.h> 12#define pci_iomap pci_iomap 13 14/* BIO layer definitions. */ 15extern unsigned long kern_base, kern_size; 16 17/* __raw_{read,write}{b,w,l,q} uses direct access. 18 * Access the memory as big endian bypassing the cache 19 * by using ASI_PHYS_BYPASS_EC_E 20 */ 21#define __raw_readb __raw_readb 22static inline u8 __raw_readb(const volatile void __iomem *addr) 23{ 24 u8 ret; 25 26 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */" 27 : "=r" (ret) 28 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 29 30 return ret; 31} 32 33#define __raw_readw __raw_readw 34static inline u16 __raw_readw(const volatile void __iomem *addr) 35{ 36 u16 ret; 37 38 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */" 39 : "=r" (ret) 40 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 41 42 return ret; 43} 44 45#define __raw_readl __raw_readl 46static inline u32 __raw_readl(const volatile void __iomem *addr) 47{ 48 u32 ret; 49 50 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */" 51 : "=r" (ret) 52 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 53 54 return ret; 55} 56 57#define __raw_readq __raw_readq 58static inline u64 __raw_readq(const volatile void __iomem *addr) 59{ 60 u64 ret; 61 62 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */" 63 : "=r" (ret) 64 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 65 66 return ret; 67} 68 69#define __raw_writeb __raw_writeb 70static inline void __raw_writeb(u8 b, const volatile void __iomem *addr) 71{ 72 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */" 73 : /* no outputs */ 74 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 75} 76 77#define __raw_writew __raw_writew 78static inline void __raw_writew(u16 w, const volatile void __iomem *addr) 79{ 80 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */" 81 : /* no outputs */ 82 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 83} 84 85#define __raw_writel __raw_writel 86static inline void __raw_writel(u32 l, const volatile void __iomem *addr) 87{ 88 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */" 89 : /* no outputs */ 90 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 91} 92 93#define __raw_writeq __raw_writeq 94static inline void __raw_writeq(u64 q, const volatile void __iomem *addr) 95{ 96 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */" 97 : /* no outputs */ 98 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 99} 100 101/* Memory functions, same as I/O accesses on Ultra. 102 * Access memory as little endian bypassing 103 * the cache by using ASI_PHYS_BYPASS_EC_E_L 104 */ 105#define readb readb 106#define readb_relaxed readb 107static inline u8 readb(const volatile void __iomem *addr) 108{ u8 ret; 109 110 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */" 111 : "=r" (ret) 112 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 113 : "memory"); 114 return ret; 115} 116 117#define readw readw 118#define readw_relaxed readw 119static inline u16 readw(const volatile void __iomem *addr) 120{ u16 ret; 121 122 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */" 123 : "=r" (ret) 124 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 125 : "memory"); 126 127 return ret; 128} 129 130#define readl readl 131#define readl_relaxed readl 132static inline u32 readl(const volatile void __iomem *addr) 133{ u32 ret; 134 135 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */" 136 : "=r" (ret) 137 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 138 : "memory"); 139 140 return ret; 141} 142 143#define readq readq 144#define readq_relaxed readq 145static inline u64 readq(const volatile void __iomem *addr) 146{ u64 ret; 147 148 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */" 149 : "=r" (ret) 150 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 151 : "memory"); 152 153 return ret; 154} 155 156#define writeb writeb 157#define writeb_relaxed writeb 158static inline void writeb(u8 b, volatile void __iomem *addr) 159{ 160 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */" 161 : /* no outputs */ 162 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 163 : "memory"); 164} 165 166#define writew writew 167#define writew_relaxed writew 168static inline void writew(u16 w, volatile void __iomem *addr) 169{ 170 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */" 171 : /* no outputs */ 172 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 173 : "memory"); 174} 175 176#define writel writel 177#define writel_relaxed writel 178static inline void writel(u32 l, volatile void __iomem *addr) 179{ 180 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */" 181 : /* no outputs */ 182 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 183 : "memory"); 184} 185 186#define writeq writeq 187#define writeq_relaxed writeq 188static inline void writeq(u64 q, volatile void __iomem *addr) 189{ 190 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */" 191 : /* no outputs */ 192 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) 193 : "memory"); 194} 195 196#define inb inb 197static inline u8 inb(unsigned long addr) 198{ 199 return readb((volatile void __iomem *)addr); 200} 201 202#define inw inw 203static inline u16 inw(unsigned long addr) 204{ 205 return readw((volatile void __iomem *)addr); 206} 207 208#define inl inl 209static inline u32 inl(unsigned long addr) 210{ 211 return readl((volatile void __iomem *)addr); 212} 213 214#define outb outb 215static inline void outb(u8 b, unsigned long addr) 216{ 217 writeb(b, (volatile void __iomem *)addr); 218} 219 220#define outw outw 221static inline void outw(u16 w, unsigned long addr) 222{ 223 writew(w, (volatile void __iomem *)addr); 224} 225 226#define outl outl 227static inline void outl(u32 l, unsigned long addr) 228{ 229 writel(l, (volatile void __iomem *)addr); 230} 231 232 233#define inb_p(__addr) inb(__addr) 234#define outb_p(__b, __addr) outb(__b, __addr) 235#define inw_p(__addr) inw(__addr) 236#define outw_p(__w, __addr) outw(__w, __addr) 237#define inl_p(__addr) inl(__addr) 238#define outl_p(__l, __addr) outl(__l, __addr) 239 240void outsb(unsigned long, const void *, unsigned long); 241void outsw(unsigned long, const void *, unsigned long); 242void outsl(unsigned long, const void *, unsigned long); 243#define outsb outsb 244#define outsw outsw 245#define outsl outsl 246void insb(unsigned long, void *, unsigned long); 247void insw(unsigned long, void *, unsigned long); 248void insl(unsigned long, void *, unsigned long); 249#define insb insb 250#define insw insw 251#define insl insl 252 253static inline void readsb(void __iomem *port, void *buf, unsigned long count) 254{ 255 insb((unsigned long __force)port, buf, count); 256} 257#define readsb readsb 258 259static inline void readsw(void __iomem *port, void *buf, unsigned long count) 260{ 261 insw((unsigned long __force)port, buf, count); 262} 263#define readsw readsw 264 265static inline void readsl(void __iomem *port, void *buf, unsigned long count) 266{ 267 insl((unsigned long __force)port, buf, count); 268} 269#define readsl readsl 270 271static inline void writesb(void __iomem *port, const void *buf, unsigned long count) 272{ 273 outsb((unsigned long __force)port, buf, count); 274} 275#define writesb writesb 276 277static inline void writesw(void __iomem *port, const void *buf, unsigned long count) 278{ 279 outsw((unsigned long __force)port, buf, count); 280} 281#define writesw writesw 282 283static inline void writesl(void __iomem *port, const void *buf, unsigned long count) 284{ 285 outsl((unsigned long __force)port, buf, count); 286} 287#define writesl writesl 288 289#define ioread8_rep(p,d,l) readsb(p,d,l) 290#define ioread16_rep(p,d,l) readsw(p,d,l) 291#define ioread32_rep(p,d,l) readsl(p,d,l) 292#define iowrite8_rep(p,d,l) writesb(p,d,l) 293#define iowrite16_rep(p,d,l) writesw(p,d,l) 294#define iowrite32_rep(p,d,l) writesl(p,d,l) 295 296/* Valid I/O Space regions are anywhere, because each PCI bus supported 297 * can live in an arbitrary area of the physical address range. 298 */ 299#define IO_SPACE_LIMIT 0xffffffffffffffffUL 300 301/* Now, SBUS variants, only difference from PCI is that we do 302 * not use little-endian ASIs. 303 */ 304static inline u8 sbus_readb(const volatile void __iomem *addr) 305{ 306 return __raw_readb(addr); 307} 308 309static inline u16 sbus_readw(const volatile void __iomem *addr) 310{ 311 return __raw_readw(addr); 312} 313 314static inline u32 sbus_readl(const volatile void __iomem *addr) 315{ 316 return __raw_readl(addr); 317} 318 319static inline u64 sbus_readq(const volatile void __iomem *addr) 320{ 321 return __raw_readq(addr); 322} 323 324static inline void sbus_writeb(u8 b, volatile void __iomem *addr) 325{ 326 __raw_writeb(b, addr); 327} 328 329static inline void sbus_writew(u16 w, volatile void __iomem *addr) 330{ 331 __raw_writew(w, addr); 332} 333 334static inline void sbus_writel(u32 l, volatile void __iomem *addr) 335{ 336 __raw_writel(l, addr); 337} 338 339static inline void sbus_writeq(u64 q, volatile void __iomem *addr) 340{ 341 __raw_writeq(q, addr); 342} 343 344static inline void sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) 345{ 346 while(n--) { 347 sbus_writeb(c, dst); 348 dst++; 349 } 350} 351 352static inline void memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) 353{ 354 volatile void __iomem *d = dst; 355 356 while (n--) { 357 writeb(c, d); 358 d++; 359 } 360} 361#define memset_io memset_io 362 363static inline void sbus_memcpy_fromio(void *dst, const volatile void __iomem *src, 364 __kernel_size_t n) 365{ 366 char *d = dst; 367 368 while (n--) { 369 char tmp = sbus_readb(src); 370 *d++ = tmp; 371 src++; 372 } 373} 374 375 376static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, 377 __kernel_size_t n) 378{ 379 char *d = dst; 380 381 while (n--) { 382 char tmp = readb(src); 383 *d++ = tmp; 384 src++; 385 } 386} 387#define memcpy_fromio memcpy_fromio 388 389static inline void sbus_memcpy_toio(volatile void __iomem *dst, const void *src, 390 __kernel_size_t n) 391{ 392 const char *s = src; 393 volatile void __iomem *d = dst; 394 395 while (n--) { 396 char tmp = *s++; 397 sbus_writeb(tmp, d); 398 d++; 399 } 400} 401 402static inline void memcpy_toio(volatile void __iomem *dst, const void *src, 403 __kernel_size_t n) 404{ 405 const char *s = src; 406 volatile void __iomem *d = dst; 407 408 while (n--) { 409 char tmp = *s++; 410 writeb(tmp, d); 411 d++; 412 } 413} 414#define memcpy_toio memcpy_toio 415 416#ifdef __KERNEL__ 417 418/* On sparc64 we have the whole physical IO address space accessible 419 * using physically addressed loads and stores, so this does nothing. 420 */ 421static inline void __iomem *ioremap(unsigned long offset, unsigned long size) 422{ 423 return (void __iomem *)offset; 424} 425 426#define ioremap_wc(X,Y) ioremap((X),(Y)) 427#define ioremap_wt(X,Y) ioremap((X),(Y)) 428static inline void __iomem *ioremap_np(unsigned long offset, unsigned long size) 429{ 430 return NULL; 431 432} 433#define ioremap_np ioremap_np 434 435static inline void iounmap(volatile void __iomem *addr) 436{ 437} 438 439#define ioread8 readb 440#define ioread16 readw 441#define ioread16be __raw_readw 442#define ioread32 readl 443#define ioread32be __raw_readl 444#define iowrite8 writeb 445#define iowrite16 writew 446#define iowrite16be __raw_writew 447#define iowrite32 writel 448#define iowrite32be __raw_writel 449 450/* Create a virtual mapping cookie for an IO port range */ 451void __iomem *ioport_map(unsigned long port, unsigned int nr); 452void ioport_unmap(void __iomem *); 453#define ioport_map ioport_map 454#define ioport_unmap ioport_unmap 455 456/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ 457struct pci_dev; 458void pci_iounmap(struct pci_dev *dev, void __iomem *); 459#define pci_iounmap pci_iounmap 460 461static inline int sbus_can_dma_64bit(void) 462{ 463 return 1; 464} 465static inline int sbus_can_burst64(void) 466{ 467 return 1; 468} 469struct device; 470void sbus_set_sbus64(struct device *, int); 471 472#endif 473 474#endif /* !(__SPARC64_IO_H) */ 475