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. */ 15 extern 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 22 static 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 34 static 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 46 static 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 58 static 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 70 static 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 78 static 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 86 static 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 94 static 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 107 static 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 119 static 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 132 static 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 145 static 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 158 static 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 168 static 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 178 static 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 188 static 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 197 static inline u8 inb(unsigned long addr) 198 { 199 return readb((volatile void __iomem *)addr); 200 } 201 202 #define inw inw 203 static inline u16 inw(unsigned long addr) 204 { 205 return readw((volatile void __iomem *)addr); 206 } 207 208 #define inl inl 209 static inline u32 inl(unsigned long addr) 210 { 211 return readl((volatile void __iomem *)addr); 212 } 213 214 #define outb outb 215 static inline void outb(u8 b, unsigned long addr) 216 { 217 writeb(b, (volatile void __iomem *)addr); 218 } 219 220 #define outw outw 221 static inline void outw(u16 w, unsigned long addr) 222 { 223 writew(w, (volatile void __iomem *)addr); 224 } 225 226 #define outl outl 227 static 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 240 void outsb(unsigned long, const void *, unsigned long); 241 void outsw(unsigned long, const void *, unsigned long); 242 void outsl(unsigned long, const void *, unsigned long); 243 #define outsb outsb 244 #define outsw outsw 245 #define outsl outsl 246 void insb(unsigned long, void *, unsigned long); 247 void insw(unsigned long, void *, unsigned long); 248 void insl(unsigned long, void *, unsigned long); 249 #define insb insb 250 #define insw insw 251 #define insl insl 252 253 static 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 259 static 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 265 static 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 271 static 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 277 static 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 283 static 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 */ 304 static inline u8 sbus_readb(const volatile void __iomem *addr) 305 { 306 return __raw_readb(addr); 307 } 308 309 static inline u16 sbus_readw(const volatile void __iomem *addr) 310 { 311 return __raw_readw(addr); 312 } 313 314 static inline u32 sbus_readl(const volatile void __iomem *addr) 315 { 316 return __raw_readl(addr); 317 } 318 319 static inline u64 sbus_readq(const volatile void __iomem *addr) 320 { 321 return __raw_readq(addr); 322 } 323 324 static inline void sbus_writeb(u8 b, volatile void __iomem *addr) 325 { 326 __raw_writeb(b, addr); 327 } 328 329 static inline void sbus_writew(u16 w, volatile void __iomem *addr) 330 { 331 __raw_writew(w, addr); 332 } 333 334 static inline void sbus_writel(u32 l, volatile void __iomem *addr) 335 { 336 __raw_writel(l, addr); 337 } 338 339 static inline void sbus_writeq(u64 q, volatile void __iomem *addr) 340 { 341 __raw_writeq(q, addr); 342 } 343 344 static 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 352 static 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 363 static 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 376 static 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 389 static 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 402 static 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 */ 421 static 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)) 428 static inline void __iomem *ioremap_np(unsigned long offset, unsigned long size) 429 { 430 return NULL; 431 432 } 433 #define ioremap_np ioremap_np 434 435 static 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 */ 451 void __iomem *ioport_map(unsigned long port, unsigned int nr); 452 void 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) */ 457 struct pci_dev; 458 void pci_iounmap(struct pci_dev *dev, void __iomem *); 459 #define pci_iounmap pci_iounmap 460 461 static inline int sbus_can_dma_64bit(void) 462 { 463 return 1; 464 } 465 static inline int sbus_can_burst64(void) 466 { 467 return 1; 468 } 469 struct device; 470 void sbus_set_sbus64(struct device *, int); 471 472 #endif 473 474 #endif /* !(__SPARC64_IO_H) */ 475
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.