1*a47a12beSStefan Roese /* originally from linux source. 2*a47a12beSStefan Roese * removed the dependencies on CONFIG_ values 3*a47a12beSStefan Roese * removed virt_to_phys stuff (and in fact everything surrounded by #if __KERNEL__) 4*a47a12beSStefan Roese * Modified By Rob Taylor, Flying Pig Systems, 2000 5*a47a12beSStefan Roese */ 6*a47a12beSStefan Roese 7*a47a12beSStefan Roese #ifndef _PPC_IO_H 8*a47a12beSStefan Roese #define _PPC_IO_H 9*a47a12beSStefan Roese 10*a47a12beSStefan Roese #include <linux/config.h> 11*a47a12beSStefan Roese #include <asm/byteorder.h> 12*a47a12beSStefan Roese 13*a47a12beSStefan Roese #ifdef CONFIG_ADDR_MAP 14*a47a12beSStefan Roese #include <addr_map.h> 15*a47a12beSStefan Roese #endif 16*a47a12beSStefan Roese 17*a47a12beSStefan Roese #define SIO_CONFIG_RA 0x398 18*a47a12beSStefan Roese #define SIO_CONFIG_RD 0x399 19*a47a12beSStefan Roese 20*a47a12beSStefan Roese #ifndef _IO_BASE 21*a47a12beSStefan Roese #define _IO_BASE 0 22*a47a12beSStefan Roese #endif 23*a47a12beSStefan Roese 24*a47a12beSStefan Roese #define readb(addr) in_8((volatile u8 *)(addr)) 25*a47a12beSStefan Roese #define writeb(b,addr) out_8((volatile u8 *)(addr), (b)) 26*a47a12beSStefan Roese #if !defined(__BIG_ENDIAN) 27*a47a12beSStefan Roese #define readw(addr) (*(volatile u16 *) (addr)) 28*a47a12beSStefan Roese #define readl(addr) (*(volatile u32 *) (addr)) 29*a47a12beSStefan Roese #define writew(b,addr) ((*(volatile u16 *) (addr)) = (b)) 30*a47a12beSStefan Roese #define writel(b,addr) ((*(volatile u32 *) (addr)) = (b)) 31*a47a12beSStefan Roese #else 32*a47a12beSStefan Roese #define readw(addr) in_le16((volatile u16 *)(addr)) 33*a47a12beSStefan Roese #define readl(addr) in_le32((volatile u32 *)(addr)) 34*a47a12beSStefan Roese #define writew(b,addr) out_le16((volatile u16 *)(addr),(b)) 35*a47a12beSStefan Roese #define writel(b,addr) out_le32((volatile u32 *)(addr),(b)) 36*a47a12beSStefan Roese #endif 37*a47a12beSStefan Roese 38*a47a12beSStefan Roese /* 39*a47a12beSStefan Roese * The insw/outsw/insl/outsl macros don't do byte-swapping. 40*a47a12beSStefan Roese * They are only used in practice for transferring buffers which 41*a47a12beSStefan Roese * are arrays of bytes, and byte-swapping is not appropriate in 42*a47a12beSStefan Roese * that case. - paulus 43*a47a12beSStefan Roese */ 44*a47a12beSStefan Roese #define insb(port, buf, ns) _insb((u8 *)((port)+_IO_BASE), (buf), (ns)) 45*a47a12beSStefan Roese #define outsb(port, buf, ns) _outsb((u8 *)((port)+_IO_BASE), (buf), (ns)) 46*a47a12beSStefan Roese #define insw(port, buf, ns) _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 47*a47a12beSStefan Roese #define outsw(port, buf, ns) _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 48*a47a12beSStefan Roese #define insl(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 49*a47a12beSStefan Roese #define outsl(port, buf, nl) _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 50*a47a12beSStefan Roese 51*a47a12beSStefan Roese #define inb(port) in_8((u8 *)((port)+_IO_BASE)) 52*a47a12beSStefan Roese #define outb(val, port) out_8((u8 *)((port)+_IO_BASE), (val)) 53*a47a12beSStefan Roese #if !defined(__BIG_ENDIAN) 54*a47a12beSStefan Roese #define inw(port) in_be16((u16 *)((port)+_IO_BASE)) 55*a47a12beSStefan Roese #define outw(val, port) out_be16((u16 *)((port)+_IO_BASE), (val)) 56*a47a12beSStefan Roese #define inl(port) in_be32((u32 *)((port)+_IO_BASE)) 57*a47a12beSStefan Roese #define outl(val, port) out_be32((u32 *)((port)+_IO_BASE), (val)) 58*a47a12beSStefan Roese #else 59*a47a12beSStefan Roese #define inw(port) in_le16((u16 *)((port)+_IO_BASE)) 60*a47a12beSStefan Roese #define outw(val, port) out_le16((u16 *)((port)+_IO_BASE), (val)) 61*a47a12beSStefan Roese #define inl(port) in_le32((u32 *)((port)+_IO_BASE)) 62*a47a12beSStefan Roese #define outl(val, port) out_le32((u32 *)((port)+_IO_BASE), (val)) 63*a47a12beSStefan Roese #endif 64*a47a12beSStefan Roese 65*a47a12beSStefan Roese #define inb_p(port) in_8((u8 *)((port)+_IO_BASE)) 66*a47a12beSStefan Roese #define outb_p(val, port) out_8((u8 *)((port)+_IO_BASE), (val)) 67*a47a12beSStefan Roese #define inw_p(port) in_le16((u16 *)((port)+_IO_BASE)) 68*a47a12beSStefan Roese #define outw_p(val, port) out_le16((u16 *)((port)+_IO_BASE), (val)) 69*a47a12beSStefan Roese #define inl_p(port) in_le32((u32 *)((port)+_IO_BASE)) 70*a47a12beSStefan Roese #define outl_p(val, port) out_le32((u32 *)((port)+_IO_BASE), (val)) 71*a47a12beSStefan Roese 72*a47a12beSStefan Roese extern void _insb(volatile u8 *port, void *buf, int ns); 73*a47a12beSStefan Roese extern void _outsb(volatile u8 *port, const void *buf, int ns); 74*a47a12beSStefan Roese extern void _insw(volatile u16 *port, void *buf, int ns); 75*a47a12beSStefan Roese extern void _outsw(volatile u16 *port, const void *buf, int ns); 76*a47a12beSStefan Roese extern void _insl(volatile u32 *port, void *buf, int nl); 77*a47a12beSStefan Roese extern void _outsl(volatile u32 *port, const void *buf, int nl); 78*a47a12beSStefan Roese extern void _insw_ns(volatile u16 *port, void *buf, int ns); 79*a47a12beSStefan Roese extern void _outsw_ns(volatile u16 *port, const void *buf, int ns); 80*a47a12beSStefan Roese extern void _insl_ns(volatile u32 *port, void *buf, int nl); 81*a47a12beSStefan Roese extern void _outsl_ns(volatile u32 *port, const void *buf, int nl); 82*a47a12beSStefan Roese 83*a47a12beSStefan Roese /* 84*a47a12beSStefan Roese * The *_ns versions below don't do byte-swapping. 85*a47a12beSStefan Roese * Neither do the standard versions now, these are just here 86*a47a12beSStefan Roese * for older code. 87*a47a12beSStefan Roese */ 88*a47a12beSStefan Roese #define insw_ns(port, buf, ns) _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 89*a47a12beSStefan Roese #define outsw_ns(port, buf, ns) _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 90*a47a12beSStefan Roese #define insl_ns(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 91*a47a12beSStefan Roese #define outsl_ns(port, buf, nl) _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 92*a47a12beSStefan Roese 93*a47a12beSStefan Roese 94*a47a12beSStefan Roese #define IO_SPACE_LIMIT ~0 95*a47a12beSStefan Roese 96*a47a12beSStefan Roese #define memset_io(a,b,c) memset((void *)(a),(b),(c)) 97*a47a12beSStefan Roese #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) 98*a47a12beSStefan Roese #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) 99*a47a12beSStefan Roese 100*a47a12beSStefan Roese /* 101*a47a12beSStefan Roese * Enforce In-order Execution of I/O: 102*a47a12beSStefan Roese * Acts as a barrier to ensure all previous I/O accesses have 103*a47a12beSStefan Roese * completed before any further ones are issued. 104*a47a12beSStefan Roese */ 105*a47a12beSStefan Roese static inline void eieio(void) 106*a47a12beSStefan Roese { 107*a47a12beSStefan Roese __asm__ __volatile__ ("eieio" : : : "memory"); 108*a47a12beSStefan Roese } 109*a47a12beSStefan Roese 110*a47a12beSStefan Roese static inline void sync(void) 111*a47a12beSStefan Roese { 112*a47a12beSStefan Roese __asm__ __volatile__ ("sync" : : : "memory"); 113*a47a12beSStefan Roese } 114*a47a12beSStefan Roese 115*a47a12beSStefan Roese static inline void isync(void) 116*a47a12beSStefan Roese { 117*a47a12beSStefan Roese __asm__ __volatile__ ("isync" : : : "memory"); 118*a47a12beSStefan Roese } 119*a47a12beSStefan Roese 120*a47a12beSStefan Roese /* Enforce in-order execution of data I/O. 121*a47a12beSStefan Roese * No distinction between read/write on PPC; use eieio for all three. 122*a47a12beSStefan Roese */ 123*a47a12beSStefan Roese #define iobarrier_rw() eieio() 124*a47a12beSStefan Roese #define iobarrier_r() eieio() 125*a47a12beSStefan Roese #define iobarrier_w() eieio() 126*a47a12beSStefan Roese 127*a47a12beSStefan Roese /* 128*a47a12beSStefan Roese * Non ordered and non-swapping "raw" accessors 129*a47a12beSStefan Roese */ 130*a47a12beSStefan Roese #define __iomem 131*a47a12beSStefan Roese #define PCI_FIX_ADDR(addr) (addr) 132*a47a12beSStefan Roese 133*a47a12beSStefan Roese static inline unsigned char __raw_readb(const volatile void __iomem *addr) 134*a47a12beSStefan Roese { 135*a47a12beSStefan Roese return *(volatile unsigned char *)PCI_FIX_ADDR(addr); 136*a47a12beSStefan Roese } 137*a47a12beSStefan Roese static inline unsigned short __raw_readw(const volatile void __iomem *addr) 138*a47a12beSStefan Roese { 139*a47a12beSStefan Roese return *(volatile unsigned short *)PCI_FIX_ADDR(addr); 140*a47a12beSStefan Roese } 141*a47a12beSStefan Roese static inline unsigned int __raw_readl(const volatile void __iomem *addr) 142*a47a12beSStefan Roese { 143*a47a12beSStefan Roese return *(volatile unsigned int *)PCI_FIX_ADDR(addr); 144*a47a12beSStefan Roese } 145*a47a12beSStefan Roese static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) 146*a47a12beSStefan Roese { 147*a47a12beSStefan Roese *(volatile unsigned char *)PCI_FIX_ADDR(addr) = v; 148*a47a12beSStefan Roese } 149*a47a12beSStefan Roese static inline void __raw_writew(unsigned short v, volatile void __iomem *addr) 150*a47a12beSStefan Roese { 151*a47a12beSStefan Roese *(volatile unsigned short *)PCI_FIX_ADDR(addr) = v; 152*a47a12beSStefan Roese } 153*a47a12beSStefan Roese static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) 154*a47a12beSStefan Roese { 155*a47a12beSStefan Roese *(volatile unsigned int *)PCI_FIX_ADDR(addr) = v; 156*a47a12beSStefan Roese } 157*a47a12beSStefan Roese 158*a47a12beSStefan Roese /* 159*a47a12beSStefan Roese * 8, 16 and 32 bit, big and little endian I/O operations, with barrier. 160*a47a12beSStefan Roese * 161*a47a12beSStefan Roese * Read operations have additional twi & isync to make sure the read 162*a47a12beSStefan Roese * is actually performed (i.e. the data has come back) before we start 163*a47a12beSStefan Roese * executing any following instructions. 164*a47a12beSStefan Roese */ 165*a47a12beSStefan Roese extern inline int in_8(const volatile unsigned char __iomem *addr) 166*a47a12beSStefan Roese { 167*a47a12beSStefan Roese int ret; 168*a47a12beSStefan Roese 169*a47a12beSStefan Roese __asm__ __volatile__( 170*a47a12beSStefan Roese "sync; lbz%U1%X1 %0,%1;\n" 171*a47a12beSStefan Roese "twi 0,%0,0;\n" 172*a47a12beSStefan Roese "isync" : "=r" (ret) : "m" (*addr)); 173*a47a12beSStefan Roese return ret; 174*a47a12beSStefan Roese } 175*a47a12beSStefan Roese 176*a47a12beSStefan Roese extern inline void out_8(volatile unsigned char __iomem *addr, int val) 177*a47a12beSStefan Roese { 178*a47a12beSStefan Roese __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val)); 179*a47a12beSStefan Roese } 180*a47a12beSStefan Roese 181*a47a12beSStefan Roese extern inline int in_le16(const volatile unsigned short __iomem *addr) 182*a47a12beSStefan Roese { 183*a47a12beSStefan Roese int ret; 184*a47a12beSStefan Roese 185*a47a12beSStefan Roese __asm__ __volatile__("sync; lhbrx %0,0,%1;\n" 186*a47a12beSStefan Roese "twi 0,%0,0;\n" 187*a47a12beSStefan Roese "isync" : "=r" (ret) : 188*a47a12beSStefan Roese "r" (addr), "m" (*addr)); 189*a47a12beSStefan Roese return ret; 190*a47a12beSStefan Roese } 191*a47a12beSStefan Roese 192*a47a12beSStefan Roese extern inline int in_be16(const volatile unsigned short __iomem *addr) 193*a47a12beSStefan Roese { 194*a47a12beSStefan Roese int ret; 195*a47a12beSStefan Roese 196*a47a12beSStefan Roese __asm__ __volatile__("sync; lhz%U1%X1 %0,%1;\n" 197*a47a12beSStefan Roese "twi 0,%0,0;\n" 198*a47a12beSStefan Roese "isync" : "=r" (ret) : "m" (*addr)); 199*a47a12beSStefan Roese return ret; 200*a47a12beSStefan Roese } 201*a47a12beSStefan Roese 202*a47a12beSStefan Roese extern inline void out_le16(volatile unsigned short __iomem *addr, int val) 203*a47a12beSStefan Roese { 204*a47a12beSStefan Roese __asm__ __volatile__("sync; sthbrx %1,0,%2" : "=m" (*addr) : 205*a47a12beSStefan Roese "r" (val), "r" (addr)); 206*a47a12beSStefan Roese } 207*a47a12beSStefan Roese 208*a47a12beSStefan Roese extern inline void out_be16(volatile unsigned short __iomem *addr, int val) 209*a47a12beSStefan Roese { 210*a47a12beSStefan Roese __asm__ __volatile__("sync; sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); 211*a47a12beSStefan Roese } 212*a47a12beSStefan Roese 213*a47a12beSStefan Roese extern inline unsigned in_le32(const volatile unsigned __iomem *addr) 214*a47a12beSStefan Roese { 215*a47a12beSStefan Roese unsigned ret; 216*a47a12beSStefan Roese 217*a47a12beSStefan Roese __asm__ __volatile__("sync; lwbrx %0,0,%1;\n" 218*a47a12beSStefan Roese "twi 0,%0,0;\n" 219*a47a12beSStefan Roese "isync" : "=r" (ret) : 220*a47a12beSStefan Roese "r" (addr), "m" (*addr)); 221*a47a12beSStefan Roese return ret; 222*a47a12beSStefan Roese } 223*a47a12beSStefan Roese 224*a47a12beSStefan Roese extern inline unsigned in_be32(const volatile unsigned __iomem *addr) 225*a47a12beSStefan Roese { 226*a47a12beSStefan Roese unsigned ret; 227*a47a12beSStefan Roese 228*a47a12beSStefan Roese __asm__ __volatile__("sync; lwz%U1%X1 %0,%1;\n" 229*a47a12beSStefan Roese "twi 0,%0,0;\n" 230*a47a12beSStefan Roese "isync" : "=r" (ret) : "m" (*addr)); 231*a47a12beSStefan Roese return ret; 232*a47a12beSStefan Roese } 233*a47a12beSStefan Roese 234*a47a12beSStefan Roese extern inline void out_le32(volatile unsigned __iomem *addr, int val) 235*a47a12beSStefan Roese { 236*a47a12beSStefan Roese __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) : 237*a47a12beSStefan Roese "r" (val), "r" (addr)); 238*a47a12beSStefan Roese } 239*a47a12beSStefan Roese 240*a47a12beSStefan Roese extern inline void out_be32(volatile unsigned __iomem *addr, int val) 241*a47a12beSStefan Roese { 242*a47a12beSStefan Roese __asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); 243*a47a12beSStefan Roese } 244*a47a12beSStefan Roese 245*a47a12beSStefan Roese /* Clear and set bits in one shot. These macros can be used to clear and 246*a47a12beSStefan Roese * set multiple bits in a register using a single call. These macros can 247*a47a12beSStefan Roese * also be used to set a multiple-bit bit pattern using a mask, by 248*a47a12beSStefan Roese * specifying the mask in the 'clear' parameter and the new bit pattern 249*a47a12beSStefan Roese * in the 'set' parameter. 250*a47a12beSStefan Roese */ 251*a47a12beSStefan Roese 252*a47a12beSStefan Roese #define clrbits(type, addr, clear) \ 253*a47a12beSStefan Roese out_##type((addr), in_##type(addr) & ~(clear)) 254*a47a12beSStefan Roese 255*a47a12beSStefan Roese #define setbits(type, addr, set) \ 256*a47a12beSStefan Roese out_##type((addr), in_##type(addr) | (set)) 257*a47a12beSStefan Roese 258*a47a12beSStefan Roese #define clrsetbits(type, addr, clear, set) \ 259*a47a12beSStefan Roese out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) 260*a47a12beSStefan Roese 261*a47a12beSStefan Roese #define clrbits_be32(addr, clear) clrbits(be32, addr, clear) 262*a47a12beSStefan Roese #define setbits_be32(addr, set) setbits(be32, addr, set) 263*a47a12beSStefan Roese #define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) 264*a47a12beSStefan Roese 265*a47a12beSStefan Roese #define clrbits_le32(addr, clear) clrbits(le32, addr, clear) 266*a47a12beSStefan Roese #define setbits_le32(addr, set) setbits(le32, addr, set) 267*a47a12beSStefan Roese #define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) 268*a47a12beSStefan Roese 269*a47a12beSStefan Roese #define clrbits_be16(addr, clear) clrbits(be16, addr, clear) 270*a47a12beSStefan Roese #define setbits_be16(addr, set) setbits(be16, addr, set) 271*a47a12beSStefan Roese #define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) 272*a47a12beSStefan Roese 273*a47a12beSStefan Roese #define clrbits_le16(addr, clear) clrbits(le16, addr, clear) 274*a47a12beSStefan Roese #define setbits_le16(addr, set) setbits(le16, addr, set) 275*a47a12beSStefan Roese #define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) 276*a47a12beSStefan Roese 277*a47a12beSStefan Roese #define clrbits_8(addr, clear) clrbits(8, addr, clear) 278*a47a12beSStefan Roese #define setbits_8(addr, set) setbits(8, addr, set) 279*a47a12beSStefan Roese #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) 280*a47a12beSStefan Roese 281*a47a12beSStefan Roese /* 282*a47a12beSStefan Roese * Given a physical address and a length, return a virtual address 283*a47a12beSStefan Roese * that can be used to access the memory range with the caching 284*a47a12beSStefan Roese * properties specified by "flags". 285*a47a12beSStefan Roese */ 286*a47a12beSStefan Roese #define MAP_NOCACHE (0) 287*a47a12beSStefan Roese #define MAP_WRCOMBINE (0) 288*a47a12beSStefan Roese #define MAP_WRBACK (0) 289*a47a12beSStefan Roese #define MAP_WRTHROUGH (0) 290*a47a12beSStefan Roese 291*a47a12beSStefan Roese static inline void * 292*a47a12beSStefan Roese map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) 293*a47a12beSStefan Roese { 294*a47a12beSStefan Roese #ifdef CONFIG_ADDR_MAP 295*a47a12beSStefan Roese return (void *)(addrmap_phys_to_virt(paddr)); 296*a47a12beSStefan Roese #else 297*a47a12beSStefan Roese return (void *)((unsigned long)paddr); 298*a47a12beSStefan Roese #endif 299*a47a12beSStefan Roese } 300*a47a12beSStefan Roese 301*a47a12beSStefan Roese /* 302*a47a12beSStefan Roese * Take down a mapping set up by map_physmem(). 303*a47a12beSStefan Roese */ 304*a47a12beSStefan Roese static inline void unmap_physmem(void *vaddr, unsigned long flags) 305*a47a12beSStefan Roese { 306*a47a12beSStefan Roese 307*a47a12beSStefan Roese } 308*a47a12beSStefan Roese 309*a47a12beSStefan Roese static inline phys_addr_t virt_to_phys(void * vaddr) 310*a47a12beSStefan Roese { 311*a47a12beSStefan Roese #ifdef CONFIG_ADDR_MAP 312*a47a12beSStefan Roese return addrmap_virt_to_phys(vaddr); 313*a47a12beSStefan Roese #else 314*a47a12beSStefan Roese return (phys_addr_t)((unsigned long)vaddr); 315*a47a12beSStefan Roese #endif 316*a47a12beSStefan Roese } 317*a47a12beSStefan Roese 318*a47a12beSStefan Roese #endif 319