1/* 2 * linux/include/asm-m68k/io.h 3 * 4 * 4/1/00 RZ: - rewritten to avoid clashes between ISA/PCI and other 5 * IO access 6 * - added Q40 support 7 * - added skeleton for GG-II and Amiga PCMCIA 8 * 2/3/01 RZ: - moved a few more defs into raw_io.h 9 * 10 * inX/outX/readX/writeX should not be used by any driver unless it does 11 * ISA or PCI access. Other drivers should use function defined in raw_io.h 12 * or define its own macros on top of these. 13 * 14 * inX(),outX() are for PCI and ISA I/O 15 * readX(),writeX() are for PCI memory 16 * isa_readX(),isa_writeX() are for ISA memory 17 * 18 * moved mem{cpy,set}_*io inside CONFIG_PCI 19 */ 20 21#ifndef _IO_H 22#define _IO_H 23 24#ifdef __KERNEL__ 25 26#include <linux/config.h> 27#include <asm/raw_io.h> 28#include <asm/virtconvert.h> 29 30 31#ifdef CONFIG_ATARI 32#include <asm/atarihw.h> 33#endif 34 35 36/* 37 * IO/MEM definitions for various ISA bridges 38 */ 39 40 41#ifdef CONFIG_Q40 42 43#define q40_isa_io_base 0xff400000 44#define q40_isa_mem_base 0xff800000 45 46#define Q40_ISA_IO_B(ioaddr) (q40_isa_io_base+1+4*((unsigned long)(ioaddr))) 47#define Q40_ISA_IO_W(ioaddr) (q40_isa_io_base+ 4*((unsigned long)(ioaddr))) 48#define Q40_ISA_MEM_B(madr) (q40_isa_mem_base+1+4*((unsigned long)(madr))) 49#define Q40_ISA_MEM_W(madr) (q40_isa_mem_base+ 4*((unsigned long)(madr))) 50 51#define MULTI_ISA 0 52#endif /* Q40 */ 53 54/* GG-II Zorro to ISA bridge */ 55#ifdef CONFIG_GG2 56 57extern unsigned long gg2_isa_base; 58#define GG2_ISA_IO_B(ioaddr) (gg2_isa_base+1+((unsigned long)(ioaddr)*4)) 59#define GG2_ISA_IO_W(ioaddr) (gg2_isa_base+ ((unsigned long)(ioaddr)*4)) 60#define GG2_ISA_MEM_B(madr) (gg2_isa_base+1+(((unsigned long)(madr)*4) & 0xfffff)) 61#define GG2_ISA_MEM_W(madr) (gg2_isa_base+ (((unsigned long)(madr)*4) & 0xfffff)) 62 63#ifndef MULTI_ISA 64#define MULTI_ISA 0 65#else 66#undef MULTI_ISA 67#define MULTI_ISA 1 68#endif 69#endif /* GG2 */ 70 71#ifdef CONFIG_AMIGA_PCMCIA 72#include <asm/amigayle.h> 73 74#define AG_ISA_IO_B(ioaddr) ( GAYLE_IO+(ioaddr)+(((ioaddr)&1)*GAYLE_ODD) ) 75#define AG_ISA_IO_W(ioaddr) ( GAYLE_IO+(ioaddr) ) 76 77#ifndef MULTI_ISA 78#define MULTI_ISA 0 79#else 80#undef MULTI_ISA 81#define MULTI_ISA 1 82#endif 83#endif /* AMIGA_PCMCIA */ 84 85 86 87#ifdef CONFIG_ISA 88 89#if MULTI_ISA == 0 90#undef MULTI_ISA 91#endif 92 93#define Q40_ISA (1) 94#define GG2_ISA (2) 95#define AG_ISA (3) 96 97#if defined(CONFIG_Q40) && !defined(MULTI_ISA) 98#define ISA_TYPE Q40_ISA 99#define ISA_SEX 0 100#endif 101#if defined(CONFIG_AMIGA_PCMCIA) && !defined(MULTI_ISA) 102#define ISA_TYPE AG_ISA 103#define ISA_SEX 1 104#endif 105#if defined(CONFIG_GG2) && !defined(MULTI_ISA) 106#define ISA_TYPE GG2_ISA 107#define ISA_SEX 0 108#endif 109 110#ifdef MULTI_ISA 111extern int isa_type; 112extern int isa_sex; 113 114#define ISA_TYPE isa_type 115#define ISA_SEX isa_sex 116#endif 117 118/* 119 * define inline addr translation functions. Normally only one variant will 120 * be compiled in so the case statement will be optimised away 121 */ 122 123static inline unsigned long isa_itb(long addr) 124{ 125 switch(ISA_TYPE) 126 { 127#ifdef CONFIG_Q40 128 case Q40_ISA: return Q40_ISA_IO_B(addr); 129#endif 130#ifdef CONFIG_GG2 131 case GG2_ISA: return GG2_ISA_IO_B(addr); 132#endif 133#ifdef CONFIG_AMIGA_PCMCIA 134 case AG_ISA: return AG_ISA_IO_B(addr); 135#endif 136 default: return 0; /* avoid warnings, just in case */ 137 } 138} 139static inline unsigned long isa_itw(long addr) 140{ 141 switch(ISA_TYPE) 142 { 143#ifdef CONFIG_Q40 144 case Q40_ISA: return Q40_ISA_IO_W(addr); 145#endif 146#ifdef CONFIG_GG2 147 case GG2_ISA: return GG2_ISA_IO_W(addr); 148#endif 149#ifdef CONFIG_AMIGA_PCMCIA 150 case AG_ISA: return AG_ISA_IO_W(addr); 151#endif 152 default: return 0; /* avoid warnings, just in case */ 153 } 154} 155static inline unsigned long isa_mtb(long addr) 156{ 157 switch(ISA_TYPE) 158 { 159#ifdef CONFIG_Q40 160 case Q40_ISA: return Q40_ISA_MEM_B(addr); 161#endif 162#ifdef CONFIG_GG2 163 case GG2_ISA: return GG2_ISA_MEM_B(addr); 164#endif 165 default: return 0; /* avoid warnings, just in case */ 166 } 167} 168static inline unsigned long isa_mtw(long addr) 169{ 170 switch(ISA_TYPE) 171 { 172#ifdef CONFIG_Q40 173 case Q40_ISA: return Q40_ISA_MEM_W(addr); 174#endif 175#ifdef CONFIG_GG2 176 case GG2_ISA: return GG2_ISA_MEM_W(addr); 177#endif 178 default: return 0; /* avoid warnings, just in case */ 179 } 180} 181 182 183#define isa_inb(port) in_8(isa_itb(port)) 184#define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) 185#define isa_outb(val,port) out_8(isa_itb(port),(val)) 186#define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) 187 188#define isa_readb(p) in_8(isa_mtb(p)) 189#define isa_readw(p) in_le16(isa_mtw(p)) 190#define isa_writeb(val,p) out_8(isa_mtb(p),(val)) 191#define isa_writew(val,p) out_le16(isa_mtw(p),(val)) 192 193static inline void isa_delay(void) 194{ 195 switch(ISA_TYPE) 196 { 197#ifdef CONFIG_Q40 198 case Q40_ISA: isa_outb(0,0x80); break; 199#endif 200#ifdef CONFIG_GG2 201 case GG2_ISA: break; 202#endif 203#ifdef CONFIG_AMIGA_PCMCIA 204 case AG_ISA: break; 205#endif 206 default: break; /* avoid warnings */ 207 } 208} 209 210#define isa_inb_p(p) ({unsigned char v=isa_inb(p);isa_delay();v;}) 211#define isa_outb_p(v,p) ({isa_outb((v),(p));isa_delay();}) 212 213#define isa_insb(port, buf, nr) raw_insb(isa_itb(port), (buf), (nr)) 214#define isa_outsb(port, buf, nr) raw_outsb(isa_itb(port), (buf), (nr)) 215 216#define isa_insw(port, buf, nr) \ 217 (ISA_SEX ? raw_insw(isa_itw(port), (buf), (nr)) : \ 218 raw_insw_swapw(isa_itw(port), (buf), (nr))) 219 220#define isa_outsw(port, buf, nr) \ 221 (ISA_SEX ? raw_outsw(isa_itw(port), (buf), (nr)) : \ 222 raw_outsw_swapw(isa_itw(port), (buf), (nr))) 223#endif /* CONFIG_ISA */ 224 225 226#if defined(CONFIG_ISA) && !defined(CONFIG_PCI) 227#define inb isa_inb 228#define inb_p isa_inb_p 229#define outb isa_outb 230#define outb_p isa_outb_p 231#define inw isa_inw 232#define outw isa_outw 233#define inl isa_inw 234#define outl isa_outw 235#define insb isa_insb 236#define insw isa_insw 237#define outsb isa_outsb 238#define outsw isa_outsw 239#define readb isa_readb 240#define readw isa_readw 241#define writeb isa_writeb 242#define writew isa_writew 243#endif /* CONFIG_ISA */ 244 245#if defined(CONFIG_PCI) 246 247#define inl(port) in_le32(port) 248#define outl(val,port) out_le32((port),(val)) 249#define readl(addr) in_le32(addr) 250#define writel(val,addr) out_le32((addr),(val)) 251 252/* those can be defined for both ISA and PCI - it wont work though */ 253#define readb(addr) in_8(addr) 254#define readw(addr) in_le16(addr) 255#define writeb(val,addr) out_8((addr),(val)) 256#define writew(val,addr) out_le16((addr),(val)) 257 258#ifndef CONFIG_ISA 259#define inb(port) in_8(port) 260#define outb(val,port) out_8((port),(val)) 261#define inw(port) in_le16(port) 262#define outw(val,port) out_le16((port),(val)) 263 264#else 265/* 266 * kernel with both ISA and PCI compiled in, those have 267 * conflicting defs for in/out. Simply consider port < 1024 268 * ISA and everything else PCI. read,write not defined 269 * in this case 270 */ 271#define inb(port) ((port)<1024 ? isa_inb(port) : in_8(port)) 272#define inb_p(port) ((port)<1024 ? isa_inb_p(port) : in_8(port)) 273#define inw(port) ((port)<1024 ? isa_inw(port) : in_le16(port)) 274 275#define outb(val,port) ((port)<1024 ? isa_outb((val),(port)) : out_8((port),(val))) 276#define outb_p(val,port) ((port)<1024 ? isa_outb_p((val),(port)) : out_8((port),(val))) 277#define outw(val,port) ((port)<1024 ? isa_outw((val),(port)) : out_le16((port),(val))) 278#endif 279#endif /* CONFIG_PCI */ 280 281 282/* Values for nocacheflag and cmode */ 283#define IOMAP_FULL_CACHING 0 284#define IOMAP_NOCACHE_SER 1 285#define IOMAP_NOCACHE_NONSER 2 286#define IOMAP_WRITETHROUGH 3 287 288/* 289 * Change "struct page" to physical address. 290 */ 291#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) 292 293extern void iounmap(void *addr); 294 295extern void *__ioremap(unsigned long physaddr, unsigned long size, 296 int cacheflag); 297extern void __iounmap(void *addr, unsigned long size); 298 299extern inline void *ioremap(unsigned long physaddr, unsigned long size) 300{ 301 return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); 302} 303extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) 304{ 305 return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); 306} 307extern inline void *ioremap_writethrough(unsigned long physaddr, 308 unsigned long size) 309{ 310 return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); 311} 312extern inline void *ioremap_fullcache(unsigned long physaddr, 313 unsigned long size) 314{ 315 return __ioremap(physaddr, size, IOMAP_FULL_CACHING); 316} 317 318 319/* m68k caches aren't DMA coherent */ 320extern void dma_cache_wback_inv(unsigned long start, unsigned long size); 321extern void dma_cache_wback(unsigned long start, unsigned long size); 322extern void dma_cache_inv(unsigned long start, unsigned long size); 323 324 325#ifndef CONFIG_SUN3 326#define IO_SPACE_LIMIT 0xffff 327#else 328#define IO_SPACE_LIMIT 0x0fffffff 329#endif 330 331#endif /* __KERNEL__ */ 332#endif /* _IO_H */ 333