1#ifndef _PPC64_IO_H 2#define _PPC64_IO_H 3 4/* 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. 9 */ 10 11#include <linux/config.h> 12#include <asm/page.h> 13#include <asm/byteorder.h> 14#ifdef CONFIG_PPC_ISERIES 15#include <asm/iSeries/iSeries_io.h> 16#endif 17#include <asm/memory.h> 18#include <asm/delay.h> 19 20#define SIO_CONFIG_RA 0x398 21#define SIO_CONFIG_RD 0x399 22 23#define SLOW_DOWN_IO 24/* Define this if you want to see virt_to_* messages */ 25#undef __IO_DEBUG 26 27extern unsigned long isa_io_base; 28extern unsigned long isa_mem_base; 29extern unsigned long pci_io_base; 30extern unsigned long pci_dram_offset; 31extern int have_print; 32#define _IO_BASE isa_io_base 33#define _ISA_MEM_BASE isa_mem_base 34#define PCI_DRAM_OFFSET pci_dram_offset 35 36#ifdef CONFIG_PPC_ISERIES 37#define readb(addr) iSeries_Read_Byte((void*)(addr)) 38#define readw(addr) iSeries_Read_Word((void*)(addr)) 39#define readl(addr) iSeries_Read_Long((void*)(addr)) 40#define writeb(data, addr) iSeries_Write_Byte(data,((void*)(addr))) 41#define writew(data, addr) iSeries_Write_Word(data,((void*)(addr))) 42#define writel(data, addr) iSeries_Write_Long(data,((void*)(addr))) 43#define memset_io(a,b,c) iSeries_memset_io((void *)(a),(b),(c)) 44#define memcpy_fromio(a,b,c) iSeries_memcpy_fromio((void *)(a), (void *)(b), (c)) 45#define memcpy_toio(a,b,c) iSeries_memcpy_toio((void *)(a), (void *)(b), (c)) 46#define inb(addr) readb(((unsigned long)(addr))) 47#define inw(addr) readw(((unsigned long)(addr))) 48#define inl(addr) readl(((unsigned long)(addr))) 49#define outb(data,addr) writeb(data,((unsigned long)(addr))) 50#define outw(data,addr) writew(data,((unsigned long)(addr))) 51#define outl(data,addr) writel(data,((unsigned long)(addr))) 52#else 53#define IS_MAPPED_VADDR(port) ((unsigned long)(port) >> 60UL) 54#define readb(addr) eeh_readb((void*)(addr)) 55#define readw(addr) eeh_readw((void*)(addr)) 56#define readl(addr) eeh_readl((void*)(addr)) 57#define writeb(data, addr) eeh_writeb((data), ((void*)(addr))) 58#define writew(data, addr) eeh_writew((data), ((void*)(addr))) 59#define writel(data, addr) eeh_writel((data), ((void*)(addr))) 60#define memset_io(a,b,c) eeh_memset_io((void *)(a),(b),(c)) 61#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(void *)(b),(c)) 62#define memcpy_toio(a,b,c) eeh_memcpy_toio((void *)(a),(b),(c)) 63#define inb(port) _inb((unsigned long)port) 64#define outb(val, port) _outb(val, (unsigned long)port) 65#define inw(port) _inw((unsigned long)port) 66#define outw(val, port) _outw(val, (unsigned long)port) 67#define inl(port) _inl((unsigned long)port) 68#define outl(val, port) _outl(val, (unsigned long)port) 69 70/* 71 * The insw/outsw/insl/outsl macros don't do byte-swapping. 72 * They are only used in practice for transferring buffers which 73 * are arrays of bytes, and byte-swapping is not appropriate in 74 * that case. - paulus */ 75#define insb(port, buf, ns) eeh_insb((u8 *)(port), (buf), (ns)) 76#define outsb(port, buf, ns) eeh_outsb((u8 *)(port), (buf), (ns)) 77#define insw(port, buf, ns) eeh_insw_ns((u16 *)(port), (buf), (ns)) 78#define outsw(port, buf, ns) eeh_outsw_ns((u16 *)(port), (buf), (ns)) 79#define insl(port, buf, nl) eeh_insl_ns((u32 *)(port), (buf), (nl)) 80#define outsl(port, buf, nl) eeh_outsl_ns((u32 *)(port), (buf), (nl)) 81#endif 82 83 84/* 85 * output pause versions need a delay at least for the 86 * w83c105 ide controller in a p610. 87 */ 88#define inb_p(port) inb(port) 89#define outb_p(val, port) (udelay(1), outb((val), (port))) 90#define inw_p(port) inw(port) 91#define outw_p(val, port) (udelay(1), outw((val), (port))) 92#define inl_p(port) inl(port) 93#define outl_p(val, port) (udelay(1), outl((val, (port))) 94 95 96extern void _insb(volatile u8 *port, void *buf, int ns); 97extern void _outsb(volatile u8 *port, const void *buf, int ns); 98extern void _insw(volatile u16 *port, void *buf, int ns); 99extern void _outsw(volatile u16 *port, const void *buf, int ns); 100extern void _insl(volatile u32 *port, void *buf, int nl); 101extern void _outsl(volatile u32 *port, const void *buf, int nl); 102extern void _insw_ns(volatile u16 *port, void *buf, int ns); 103extern void _outsw_ns(volatile u16 *port, const void *buf, int ns); 104extern void _insl_ns(volatile u32 *port, void *buf, int nl); 105extern void _outsl_ns(volatile u32 *port, const void *buf, int nl); 106 107/* 108 * The *_ns versions below don't do byte-swapping. 109 * Neither do the standard versions now, these are just here 110 * for older code. 111 */ 112#define insw_ns(port, buf, ns) insw(port, buf, ns) 113#define outsw_ns(port, buf, ns) outsw(port, buf, ns) 114#define insl_ns(port, buf, nl) insl(port, buf, nl) 115#define outsl_ns(port, buf, nl) outsl(port, buf, nl) 116 117 118#define IO_SPACE_LIMIT ~(0UL) 119#define MEM_SPACE_LIMIT ~(0UL) 120 121 122#ifdef __KERNEL__ 123/* 124 * Map in an area of physical address space, for accessing 125 * I/O devices etc. 126 */ 127extern void *__ioremap(unsigned long address, unsigned long size, 128 unsigned long flags); 129extern void *ioremap(unsigned long address, unsigned long size); 130#define ioremap_nocache(addr, size) ioremap((addr), (size)) 131extern void iounmap(void *addr); 132 133/* 134 * Change virtual addresses to physical addresses and vv, for 135 * addresses in the area where the kernel has the RAM mapped. 136 */ 137static inline unsigned long virt_to_phys(volatile void * address) 138{ 139#ifdef __IO_DEBUG 140 printk("virt_to_phys: 0x%08lx -> 0x%08lx\n", 141 (unsigned long) address, 142 __pa((unsigned long)address)); 143#endif 144 return __pa((unsigned long)address); 145} 146 147static inline void * phys_to_virt(unsigned long address) 148{ 149#ifdef __IO_DEBUG 150 printk("phys_to_virt: 0x%08lx -> 0x%08lx\n", address, __va(address)); 151#endif 152 return (void *) __va(address); 153} 154 155/* 156 * Change "struct page" to physical address. 157 */ 158#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) 159 160#endif /* __KERNEL__ */ 161 162static inline void iosync(void) 163{ 164 __asm__ __volatile__ ("sync" : : : "memory"); 165} 166 167/* Enforce in-order execution of data I/O. 168 * No distinction between read/write on PPC; use eieio for all three. 169 */ 170#define iobarrier_rw() eieio() 171#define iobarrier_r() eieio() 172#define iobarrier_w() eieio() 173 174/* 175 * 8, 16 and 32 bit, big and little endian I/O operations, with barrier. 176 * Until we can validate all required device drivers are weakc safe, an 177 * excess of syncs before the MMIO operations will make things work. On 178 * sstar, sync time is << than mmio time, so this should not be a big impact. 179 */ 180static inline int in_8(volatile unsigned char *addr) 181{ 182 int ret; 183 184 __asm__ __volatile__("sync; lbz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr)); 185 return ret; 186} 187 188static inline void out_8(volatile unsigned char *addr, int val) 189{ 190 __asm__ __volatile__("sync; stb%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val)); 191} 192 193static inline int in_le16(volatile unsigned short *addr) 194{ 195 int ret; 196 197 __asm__ __volatile__("sync; lhbrx %0,0,%1; sync" : "=r" (ret) : 198 "r" (addr), "m" (*addr)); 199 return ret; 200} 201 202static inline int in_be16(volatile unsigned short *addr) 203{ 204 int ret; 205 206 __asm__ __volatile__("sync; lhz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr)); 207 return ret; 208} 209 210static inline void out_le16(volatile unsigned short *addr, int val) 211{ 212 __asm__ __volatile__("sync; sthbrx %1,0,%2; sync" : "=m" (*addr) : 213 "r" (val), "r" (addr)); 214} 215 216static inline void out_be16(volatile unsigned short *addr, int val) 217{ 218 __asm__ __volatile__("sync; sth%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val)); 219} 220 221static inline unsigned in_le32(volatile unsigned *addr) 222{ 223 unsigned ret; 224 225 __asm__ __volatile__("sync; lwbrx %0,0,%1; sync" : "=r" (ret) : 226 "r" (addr), "m" (*addr)); 227 return ret; 228} 229 230static inline unsigned in_be32(volatile unsigned *addr) 231{ 232 unsigned ret; 233 234 __asm__ __volatile__("sync; lwz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr)); 235 return ret; 236} 237 238static inline void out_le32(volatile unsigned *addr, int val) 239{ 240 __asm__ __volatile__("sync; stwbrx %1,0,%2; sync" : "=m" (*addr) : 241 "r" (val), "r" (addr)); 242} 243 244static inline void out_be32(volatile unsigned *addr, int val) 245{ 246 __asm__ __volatile__("sync; stw%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val)); 247} 248 249#ifndef CONFIG_PPC_ISERIES 250#include <asm/eeh.h> 251 252static inline u8 _inb(unsigned long port) { 253 if (IS_MAPPED_VADDR(port)) 254 return readb((void *)port); 255 else if (_IO_BASE) 256 return in_8((u8 *)((port)+_IO_BASE)); 257 else 258 return 0xff; 259} 260static inline void _outb(u8 val, unsigned long port) { 261 if (IS_MAPPED_VADDR(port)) 262 return writeb(val, (void *)port); 263 else if (_IO_BASE) 264 out_8((u8 *)((port)+_IO_BASE), val); 265} 266static inline u16 _inw(unsigned long port) { 267 if (IS_MAPPED_VADDR(port)) 268 return readw((void *)port); 269 else if (_IO_BASE) 270 return in_le16((u16 *)((port)+_IO_BASE)); 271 else 272 return 0xffff; 273} 274static inline void _outw(u16 val, unsigned long port) { 275 if (IS_MAPPED_VADDR(port)) 276 return writew(val, (void *)port); 277 else if (_IO_BASE) 278 out_le16((u16 *)((port)+_IO_BASE), val); 279} 280static inline u32 _inl(unsigned long port) { 281 if (IS_MAPPED_VADDR(port)) 282 return readl((void *)port); 283 else if (_IO_BASE) 284 return in_le32((u32 *)((port)+_IO_BASE)); 285 else 286 return 0xffffffff; 287} 288static inline void _outl(u32 val, unsigned long port) { 289 if (IS_MAPPED_VADDR(port)) 290 return writel(val, (void *)port); 291 else if (_IO_BASE) 292 out_le32((u32 *)((port)+_IO_BASE), val); 293} 294#endif 295 296#ifdef __KERNEL__ 297static inline int check_signature(unsigned long io_addr, 298 const unsigned char *signature, int length) 299{ 300 int retval = 0; 301#ifndef CONFIG_PPC_ISERIES 302 do { 303 if (readb(io_addr) != *signature) 304 goto out; 305 io_addr++; 306 signature++; 307 length--; 308 } while (length); 309 retval = 1; 310out: 311#endif 312 return retval; 313} 314 315/* Nothing to do */ 316 317#define dma_cache_inv(_start,_size) do { } while (0) 318#define dma_cache_wback(_start,_size) do { } while (0) 319#define dma_cache_wback_inv(_start,_size) do { } while (0) 320 321#endif /* __KERNEL__ */ 322 323#endif /* _PPC64_IO_H */ 324