1/* 2 * linux/arch/m32r/platforms/mappi/io.c 3 * 4 * Typical I/O routines for Mappi board. 5 * 6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, 7 * Hitoshi Yamamoto 8 */ 9 10#include <asm/m32r.h> 11#include <asm/page.h> 12#include <asm/io.h> 13#include <asm/byteorder.h> 14 15#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 16#include <linux/types.h> 17 18#define M32R_PCC_IOMAP_SIZE 0x1000 19 20#define M32R_PCC_IOSTART0 0x1000 21#define M32R_PCC_IOEND0 (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1) 22#define M32R_PCC_IOSTART1 0x2000 23#define M32R_PCC_IOEND1 (M32R_PCC_IOSTART1 + M32R_PCC_IOMAP_SIZE - 1) 24 25extern void pcc_ioread(int, unsigned long, void *, size_t, size_t, int); 26extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int); 27#endif /* CONFIG_PCMCIA && CONFIG_M32R_PCC */ 28 29#define PORT2ADDR(port) _port2addr(port) 30 31static inline void *_port2addr(unsigned long port) 32{ 33 return (void *)(port | NONCACHE_OFFSET); 34} 35 36static inline void *_port2addr_ne(unsigned long port) 37{ 38 return (void *)((port<<1) + NONCACHE_OFFSET + 0x0C000000); 39} 40 41static inline void delay(void) 42{ 43 __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory"); 44} 45 46/* 47 * NIC I/O function 48 */ 49 50#define PORT2ADDR_NE(port) _port2addr_ne(port) 51 52static inline unsigned char _ne_inb(void *portp) 53{ 54 return (unsigned char) *(volatile unsigned short *)portp; 55} 56 57static inline unsigned short _ne_inw(void *portp) 58{ 59 unsigned short tmp; 60 61 tmp = *(volatile unsigned short *)portp; 62 return le16_to_cpu(tmp); 63} 64 65static inline void _ne_outb(unsigned char b, void *portp) 66{ 67 *(volatile unsigned short *)portp = (unsigned short)b; 68} 69 70static inline void _ne_outw(unsigned short w, void *portp) 71{ 72 *(volatile unsigned short *)portp = cpu_to_le16(w); 73} 74 75unsigned char _inb(unsigned long port) 76{ 77 if (port >= 0x300 && port < 0x320) 78 return _ne_inb(PORT2ADDR_NE(port)); 79 else 80#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 81 if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 82 unsigned char b; 83 pcc_ioread(0, port, &b, sizeof(b), 1, 0); 84 return b; 85 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 86 unsigned char b; 87 pcc_ioread(1, port, &b, sizeof(b), 1, 0); 88 return b; 89 } else 90#endif 91 92 return *(volatile unsigned char *)PORT2ADDR(port); 93} 94 95unsigned short _inw(unsigned long port) 96{ 97 if (port >= 0x300 && port < 0x320) 98 return _ne_inw(PORT2ADDR_NE(port)); 99 else 100#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 101 if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 102 unsigned short w; 103 pcc_ioread(0, port, &w, sizeof(w), 1, 0); 104 return w; 105 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 106 unsigned short w; 107 pcc_ioread(1, port, &w, sizeof(w), 1, 0); 108 return w; 109 } else 110#endif 111 return *(volatile unsigned short *)PORT2ADDR(port); 112} 113 114unsigned long _inl(unsigned long port) 115{ 116#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 117 if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 118 unsigned long l; 119 pcc_ioread(0, port, &l, sizeof(l), 1, 0); 120 return l; 121 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 122 unsigned short l; 123 pcc_ioread(1, port, &l, sizeof(l), 1, 0); 124 return l; 125 } else 126#endif 127 return *(volatile unsigned long *)PORT2ADDR(port); 128} 129 130unsigned char _inb_p(unsigned long port) 131{ 132 unsigned char v = _inb(port); 133 delay(); 134 return (v); 135} 136 137unsigned short _inw_p(unsigned long port) 138{ 139 unsigned short v = _inw(port); 140 delay(); 141 return (v); 142} 143 144unsigned long _inl_p(unsigned long port) 145{ 146 unsigned long v = _inl(port); 147 delay(); 148 return (v); 149} 150 151void _outb(unsigned char b, unsigned long port) 152{ 153 if (port >= 0x300 && port < 0x320) 154 _ne_outb(b, PORT2ADDR_NE(port)); 155 else 156#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 157 if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 158 pcc_iowrite(0, port, &b, sizeof(b), 1, 0); 159 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 160 pcc_iowrite(1, port, &b, sizeof(b), 1, 0); 161 } else 162#endif 163 *(volatile unsigned char *)PORT2ADDR(port) = b; 164} 165 166void _outw(unsigned short w, unsigned long port) 167{ 168 if (port >= 0x300 && port < 0x320) 169 _ne_outw(w, PORT2ADDR_NE(port)); 170 else 171#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 172 if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 173 pcc_iowrite(0, port, &w, sizeof(w), 1, 0); 174 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 175 pcc_iowrite(1, port, &w, sizeof(w), 1, 0); 176 } else 177#endif 178 *(volatile unsigned short *)PORT2ADDR(port) = w; 179} 180 181void _outl(unsigned long l, unsigned long port) 182{ 183#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 184 if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 185 pcc_iowrite(0, port, &l, sizeof(l), 1, 0); 186 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 187 pcc_iowrite(1, port, &l, sizeof(l), 1, 0); 188 } else 189#endif 190 *(volatile unsigned long *)PORT2ADDR(port) = l; 191} 192 193void _outb_p(unsigned char b, unsigned long port) 194{ 195 _outb(b, port); 196 delay(); 197} 198 199void _outw_p(unsigned short w, unsigned long port) 200{ 201 _outw(w, port); 202 delay(); 203} 204 205void _outl_p(unsigned long l, unsigned long port) 206{ 207 _outl(l, port); 208 delay(); 209} 210 211void _insb(unsigned int port, void *addr, unsigned long count) 212{ 213 unsigned short *buf = addr; 214 unsigned short *portp; 215 216 if (port >= 0x300 && port < 0x320){ 217 portp = PORT2ADDR_NE(port); 218 while (count--) 219 *buf++ = *(volatile unsigned char *)portp; 220#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 221 } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 222 pcc_ioread(0, port, (void *)addr, sizeof(unsigned char), 223 count, 1); 224 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 225 pcc_ioread(1, port, (void *)addr, sizeof(unsigned char), 226 count, 1); 227#endif 228 } else { 229 portp = PORT2ADDR(port); 230 while (count--) 231 *buf++ = *(volatile unsigned char *)portp; 232 } 233} 234 235void _insw(unsigned int port, void *addr, unsigned long count) 236{ 237 unsigned short *buf = addr; 238 unsigned short *portp; 239 240 if (port >= 0x300 && port < 0x320) { 241 portp = PORT2ADDR_NE(port); 242 while (count--) 243 *buf++ = _ne_inw(portp); 244#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 245 } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 246 pcc_ioread(0, port, (void *)addr, sizeof(unsigned short), 247 count, 1); 248 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 249 pcc_ioread(1, port, (void *)addr, sizeof(unsigned short), 250 count, 1); 251#endif 252 } else { 253 portp = PORT2ADDR(port); 254 while (count--) 255 *buf++ = *(volatile unsigned short *)portp; 256 } 257} 258 259void _insl(unsigned int port, void *addr, unsigned long count) 260{ 261 unsigned long *buf = addr; 262 unsigned long *portp; 263 264 portp = PORT2ADDR(port); 265 while (count--) 266 *buf++ = *(volatile unsigned long *)portp; 267} 268 269void _outsb(unsigned int port, const void *addr, unsigned long count) 270{ 271 const unsigned char *buf = addr; 272 unsigned char *portp; 273 274 if (port >= 0x300 && port < 0x320) { 275 portp = PORT2ADDR_NE(port); 276 while (count--) 277 _ne_outb(*buf++, portp); 278#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 279 } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 280 pcc_iowrite(0, port, (void *)addr, sizeof(unsigned char), 281 count, 1); 282 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 283 pcc_iowrite(1, port, (void *)addr, sizeof(unsigned char), 284 count, 1); 285#endif 286 } else { 287 portp = PORT2ADDR(port); 288 while (count--) 289 *(volatile unsigned char *)portp = *buf++; 290 } 291} 292 293void _outsw(unsigned int port, const void *addr, unsigned long count) 294{ 295 const unsigned short *buf = addr; 296 unsigned short *portp; 297 298 if (port >= 0x300 && port < 0x320) { 299 portp = PORT2ADDR_NE(port); 300 while (count--) 301 _ne_outw(*buf++, portp); 302#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) 303 } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { 304 pcc_iowrite(0, port, (void *)addr, sizeof(unsigned short), 305 count, 1); 306 } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { 307 pcc_iowrite(1, port, (void *)addr, sizeof(unsigned short), 308 count, 1); 309#endif 310 } else { 311 portp = PORT2ADDR(port); 312 while (count--) 313 *(volatile unsigned short *)portp = *buf++; 314 } 315} 316 317void _outsl(unsigned int port, const void *addr, unsigned long count) 318{ 319 const unsigned long *buf = addr; 320 unsigned char *portp; 321 322 portp = PORT2ADDR(port); 323 while (count--) 324 *(volatile unsigned long *)portp = *buf++; 325} 326