Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __SPARC64_IO_H
0003 #define __SPARC64_IO_H
0004 
0005 #include <linux/kernel.h>
0006 #include <linux/compiler.h>
0007 #include <linux/types.h>
0008 
0009 #include <asm/page.h>      /* IO address mapping routines need this */
0010 #include <asm/asi.h>
0011 #include <asm-generic/pci_iomap.h>
0012 
0013 /* BIO layer definitions. */
0014 extern unsigned long kern_base, kern_size;
0015 
0016 /* __raw_{read,write}{b,w,l,q} uses direct access.
0017  * Access the memory as big endian bypassing the cache
0018  * by using ASI_PHYS_BYPASS_EC_E
0019  */
0020 #define __raw_readb __raw_readb
0021 static inline u8 __raw_readb(const volatile void __iomem *addr)
0022 {
0023     u8 ret;
0024 
0025     __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
0026                  : "=r" (ret)
0027                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0028 
0029     return ret;
0030 }
0031 
0032 #define __raw_readw __raw_readw
0033 static inline u16 __raw_readw(const volatile void __iomem *addr)
0034 {
0035     u16 ret;
0036 
0037     __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
0038                  : "=r" (ret)
0039                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0040 
0041     return ret;
0042 }
0043 
0044 #define __raw_readl __raw_readl
0045 static inline u32 __raw_readl(const volatile void __iomem *addr)
0046 {
0047     u32 ret;
0048 
0049     __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
0050                  : "=r" (ret)
0051                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0052 
0053     return ret;
0054 }
0055 
0056 #define __raw_readq __raw_readq
0057 static inline u64 __raw_readq(const volatile void __iomem *addr)
0058 {
0059     u64 ret;
0060 
0061     __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
0062                  : "=r" (ret)
0063                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0064 
0065     return ret;
0066 }
0067 
0068 #define __raw_writeb __raw_writeb
0069 static inline void __raw_writeb(u8 b, const volatile void __iomem *addr)
0070 {
0071     __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
0072                  : /* no outputs */
0073                  : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0074 }
0075 
0076 #define __raw_writew __raw_writew
0077 static inline void __raw_writew(u16 w, const volatile void __iomem *addr)
0078 {
0079     __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
0080                  : /* no outputs */
0081                  : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0082 }
0083 
0084 #define __raw_writel __raw_writel
0085 static inline void __raw_writel(u32 l, const volatile void __iomem *addr)
0086 {
0087     __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
0088                  : /* no outputs */
0089                  : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0090 }
0091 
0092 #define __raw_writeq __raw_writeq
0093 static inline void __raw_writeq(u64 q, const volatile void __iomem *addr)
0094 {
0095     __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
0096                  : /* no outputs */
0097                  : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
0098 }
0099 
0100 /* Memory functions, same as I/O accesses on Ultra.
0101  * Access memory as little endian bypassing
0102  * the cache by using ASI_PHYS_BYPASS_EC_E_L
0103  */
0104 #define readb readb
0105 #define readb_relaxed readb
0106 static inline u8 readb(const volatile void __iomem *addr)
0107 {   u8 ret;
0108 
0109     __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
0110                  : "=r" (ret)
0111                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0112                  : "memory");
0113     return ret;
0114 }
0115 
0116 #define readw readw
0117 #define readw_relaxed readw
0118 static inline u16 readw(const volatile void __iomem *addr)
0119 {   u16 ret;
0120 
0121     __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
0122                  : "=r" (ret)
0123                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0124                  : "memory");
0125 
0126     return ret;
0127 }
0128 
0129 #define readl readl
0130 #define readl_relaxed readl
0131 static inline u32 readl(const volatile void __iomem *addr)
0132 {   u32 ret;
0133 
0134     __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
0135                  : "=r" (ret)
0136                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0137                  : "memory");
0138 
0139     return ret;
0140 }
0141 
0142 #define readq readq
0143 #define readq_relaxed readq
0144 static inline u64 readq(const volatile void __iomem *addr)
0145 {   u64 ret;
0146 
0147     __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
0148                  : "=r" (ret)
0149                  : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0150                  : "memory");
0151 
0152     return ret;
0153 }
0154 
0155 #define writeb writeb
0156 #define writeb_relaxed writeb
0157 static inline void writeb(u8 b, volatile void __iomem *addr)
0158 {
0159     __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
0160                  : /* no outputs */
0161                  : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0162                  : "memory");
0163 }
0164 
0165 #define writew writew
0166 #define writew_relaxed writew
0167 static inline void writew(u16 w, volatile void __iomem *addr)
0168 {
0169     __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
0170                  : /* no outputs */
0171                  : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0172                  : "memory");
0173 }
0174 
0175 #define writel writel
0176 #define writel_relaxed writel
0177 static inline void writel(u32 l, volatile void __iomem *addr)
0178 {
0179     __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
0180                  : /* no outputs */
0181                  : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0182                  : "memory");
0183 }
0184 
0185 #define writeq writeq
0186 #define writeq_relaxed writeq
0187 static inline void writeq(u64 q, volatile void __iomem *addr)
0188 {
0189     __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
0190                  : /* no outputs */
0191                  : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
0192                  : "memory");
0193 }
0194 
0195 #define inb inb
0196 static inline u8 inb(unsigned long addr)
0197 {
0198     return readb((volatile void __iomem *)addr);
0199 }
0200 
0201 #define inw inw
0202 static inline u16 inw(unsigned long addr)
0203 {
0204     return readw((volatile void __iomem *)addr);
0205 }
0206 
0207 #define inl inl
0208 static inline u32 inl(unsigned long addr)
0209 {
0210     return readl((volatile void __iomem *)addr);
0211 }
0212 
0213 #define outb outb
0214 static inline void outb(u8 b, unsigned long addr)
0215 {
0216     writeb(b, (volatile void __iomem *)addr);
0217 }
0218 
0219 #define outw outw
0220 static inline void outw(u16 w, unsigned long addr)
0221 {
0222     writew(w, (volatile void __iomem *)addr);
0223 }
0224 
0225 #define outl outl
0226 static inline void outl(u32 l, unsigned long addr)
0227 {
0228     writel(l, (volatile void __iomem *)addr);
0229 }
0230 
0231 
0232 #define inb_p(__addr)       inb(__addr)
0233 #define outb_p(__b, __addr) outb(__b, __addr)
0234 #define inw_p(__addr)       inw(__addr)
0235 #define outw_p(__w, __addr) outw(__w, __addr)
0236 #define inl_p(__addr)       inl(__addr)
0237 #define outl_p(__l, __addr) outl(__l, __addr)
0238 
0239 void outsb(unsigned long, const void *, unsigned long);
0240 void outsw(unsigned long, const void *, unsigned long);
0241 void outsl(unsigned long, const void *, unsigned long);
0242 void insb(unsigned long, void *, unsigned long);
0243 void insw(unsigned long, void *, unsigned long);
0244 void insl(unsigned long, void *, unsigned long);
0245 
0246 static inline void readsb(void __iomem *port, void *buf, unsigned long count)
0247 {
0248     insb((unsigned long __force)port, buf, count);
0249 }
0250 static inline void readsw(void __iomem *port, void *buf, unsigned long count)
0251 {
0252     insw((unsigned long __force)port, buf, count);
0253 }
0254 
0255 static inline void readsl(void __iomem *port, void *buf, unsigned long count)
0256 {
0257     insl((unsigned long __force)port, buf, count);
0258 }
0259 
0260 static inline void writesb(void __iomem *port, const void *buf, unsigned long count)
0261 {
0262     outsb((unsigned long __force)port, buf, count);
0263 }
0264 
0265 static inline void writesw(void __iomem *port, const void *buf, unsigned long count)
0266 {
0267     outsw((unsigned long __force)port, buf, count);
0268 }
0269 
0270 static inline void writesl(void __iomem *port, const void *buf, unsigned long count)
0271 {
0272     outsl((unsigned long __force)port, buf, count);
0273 }
0274 
0275 #define ioread8_rep(p,d,l)  readsb(p,d,l)
0276 #define ioread16_rep(p,d,l) readsw(p,d,l)
0277 #define ioread32_rep(p,d,l) readsl(p,d,l)
0278 #define iowrite8_rep(p,d,l) writesb(p,d,l)
0279 #define iowrite16_rep(p,d,l)    writesw(p,d,l)
0280 #define iowrite32_rep(p,d,l)    writesl(p,d,l)
0281 
0282 /* Valid I/O Space regions are anywhere, because each PCI bus supported
0283  * can live in an arbitrary area of the physical address range.
0284  */
0285 #define IO_SPACE_LIMIT 0xffffffffffffffffUL
0286 
0287 /* Now, SBUS variants, only difference from PCI is that we do
0288  * not use little-endian ASIs.
0289  */
0290 static inline u8 sbus_readb(const volatile void __iomem *addr)
0291 {
0292     return __raw_readb(addr);
0293 }
0294 
0295 static inline u16 sbus_readw(const volatile void __iomem *addr)
0296 {
0297     return __raw_readw(addr);
0298 }
0299 
0300 static inline u32 sbus_readl(const volatile void __iomem *addr)
0301 {
0302     return __raw_readl(addr);
0303 }
0304 
0305 static inline u64 sbus_readq(const volatile void __iomem *addr)
0306 {
0307     return __raw_readq(addr);
0308 }
0309 
0310 static inline void sbus_writeb(u8 b, volatile void __iomem *addr)
0311 {
0312     __raw_writeb(b, addr);
0313 }
0314 
0315 static inline void sbus_writew(u16 w, volatile void __iomem *addr)
0316 {
0317     __raw_writew(w, addr);
0318 }
0319 
0320 static inline void sbus_writel(u32 l, volatile void __iomem *addr)
0321 {
0322     __raw_writel(l, addr);
0323 }
0324 
0325 static inline void sbus_writeq(u64 q, volatile void __iomem *addr)
0326 {
0327     __raw_writeq(q, addr);
0328 }
0329 
0330 static inline void sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
0331 {
0332     while(n--) {
0333         sbus_writeb(c, dst);
0334         dst++;
0335     }
0336 }
0337 
0338 static inline void memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
0339 {
0340     volatile void __iomem *d = dst;
0341 
0342     while (n--) {
0343         writeb(c, d);
0344         d++;
0345     }
0346 }
0347 
0348 static inline void sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
0349                       __kernel_size_t n)
0350 {
0351     char *d = dst;
0352 
0353     while (n--) {
0354         char tmp = sbus_readb(src);
0355         *d++ = tmp;
0356         src++;
0357     }
0358 }
0359 
0360 
0361 static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
0362                  __kernel_size_t n)
0363 {
0364     char *d = dst;
0365 
0366     while (n--) {
0367         char tmp = readb(src);
0368         *d++ = tmp;
0369         src++;
0370     }
0371 }
0372 
0373 static inline void sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
0374                     __kernel_size_t n)
0375 {
0376     const char *s = src;
0377     volatile void __iomem *d = dst;
0378 
0379     while (n--) {
0380         char tmp = *s++;
0381         sbus_writeb(tmp, d);
0382         d++;
0383     }
0384 }
0385 
0386 static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
0387                    __kernel_size_t n)
0388 {
0389     const char *s = src;
0390     volatile void __iomem *d = dst;
0391 
0392     while (n--) {
0393         char tmp = *s++;
0394         writeb(tmp, d);
0395         d++;
0396     }
0397 }
0398 
0399 #ifdef __KERNEL__
0400 
0401 /* On sparc64 we have the whole physical IO address space accessible
0402  * using physically addressed loads and stores, so this does nothing.
0403  */
0404 static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
0405 {
0406     return (void __iomem *)offset;
0407 }
0408 
0409 #define ioremap_uc(X,Y)         ioremap((X),(Y))
0410 #define ioremap_wc(X,Y)         ioremap((X),(Y))
0411 #define ioremap_wt(X,Y)         ioremap((X),(Y))
0412 static inline void __iomem *ioremap_np(unsigned long offset, unsigned long size)
0413 {
0414     return NULL;
0415 }
0416 
0417 static inline void iounmap(volatile void __iomem *addr)
0418 {
0419 }
0420 
0421 #define ioread8         readb
0422 #define ioread16        readw
0423 #define ioread16be      __raw_readw
0424 #define ioread32        readl
0425 #define ioread32be      __raw_readl
0426 #define iowrite8        writeb
0427 #define iowrite16       writew
0428 #define iowrite16be     __raw_writew
0429 #define iowrite32       writel
0430 #define iowrite32be     __raw_writel
0431 
0432 /* Create a virtual mapping cookie for an IO port range */
0433 void __iomem *ioport_map(unsigned long port, unsigned int nr);
0434 void ioport_unmap(void __iomem *);
0435 
0436 /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
0437 struct pci_dev;
0438 void pci_iounmap(struct pci_dev *dev, void __iomem *);
0439 
0440 static inline int sbus_can_dma_64bit(void)
0441 {
0442     return 1;
0443 }
0444 static inline int sbus_can_burst64(void)
0445 {
0446     return 1;
0447 }
0448 struct device;
0449 void sbus_set_sbus64(struct device *, int);
0450 
0451 /*
0452  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
0453  * access
0454  */
0455 #define xlate_dev_mem_ptr(p)    __va(p)
0456 
0457 #endif
0458 
0459 #endif /* !(__SPARC64_IO_H) */