Import 2.3.18pre1
[davej-history.git] / arch / mips / sni / io.c
blob1b57e9bc4e4d9ff95cd0c90f3b85cb65196c5812
1 /* $Id: io.c,v 1.3 1999/01/04 16:03:58 ralf Exp $
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
7 * Low level I/O functions for SNI.
8 */
9 #include <linux/string.h>
10 #include <linux/spinlock.h>
11 #include <asm/mipsconfig.h>
12 #include <asm/addrspace.h>
13 #include <asm/system.h>
14 #include <asm/sni.h>
17 * Urgs... We only can see a 16mb window of the 4gb EISA address space
18 * at PCIMT_EISA_BASE. Maladia segmentitis ...
20 * To avoid locking and all the related headacke we implement this such
21 * that accessing the bus address space nests, so we're treating this
22 * correctly even for interrupts. This is going to suck seriously for
23 * the SMP members of the RM family.
25 * Making things worse the PCIMT_CSMAPISA register resides on the X bus with
26 * it's unbeatable 1.4 mb/s transfer rate.
29 static inline void eisa_map(unsigned long address)
31 unsigned char upper;
33 upper = address >> 24;
34 *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper;
37 #define save_eisa_map() \
38 (*(volatile unsigned char *)PCIMT_CSMAPISA)
39 #define restore_eisa_map(val) \
40 do { (*(volatile unsigned char *)PCIMT_CSMAPISA) = val; } while(0)
42 static unsigned char sni_readb(unsigned long addr)
44 unsigned char res;
45 unsigned int save_map;
47 save_map = save_eisa_map();
48 eisa_map(addr);
49 addr &= 0xffffff;
50 res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
51 restore_eisa_map(save_map);
53 return res;
56 static unsigned short sni_readw(unsigned long addr)
58 unsigned short res;
59 unsigned int save_map;
61 save_map = save_eisa_map();
62 eisa_map(addr);
63 addr &= 0xffffff;
64 res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
65 restore_eisa_map(save_map);
67 return res;
70 static unsigned int sni_readl(unsigned long addr)
72 unsigned int res;
73 unsigned int save_map;
75 save_map = save_eisa_map();
76 eisa_map(addr);
77 addr &= 0xffffff;
78 res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
79 restore_eisa_map(save_map);
81 return res;
84 static void sni_writeb(unsigned char val, unsigned long addr)
86 unsigned int save_map;
88 save_map = save_eisa_map();
89 eisa_map(addr);
90 addr &= 0xffffff;
91 *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
92 restore_eisa_map(save_map);
95 static void sni_writew(unsigned short val, unsigned long addr)
97 unsigned int save_map;
99 save_map = save_eisa_map();
100 eisa_map(addr);
101 addr &= 0xffffff;
102 *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
103 restore_eisa_map(save_map);
106 static void sni_writel(unsigned int val, unsigned long addr)
108 unsigned int save_map;
110 save_map = save_eisa_map();
111 eisa_map(addr);
112 addr &= 0xffffff;
113 *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
114 restore_eisa_map(save_map);
117 static void sni_memset_io(unsigned long addr, int val, unsigned long len)
119 unsigned long waddr;
120 unsigned int save_map;
122 save_map = save_eisa_map();
123 waddr = PCIMT_EISA_BASE | (addr & 0xffffff);
124 while(len) {
125 unsigned long fraglen;
127 fraglen = (~addr + 1) & 0xffffff;
128 fraglen = (fraglen < len) ? fraglen : len;
129 eisa_map(addr);
130 memset((char *)waddr, val, fraglen);
131 addr += fraglen;
132 waddr = waddr + fraglen - 0x1000000;
133 len -= fraglen;
135 restore_eisa_map(save_map);
138 static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
140 unsigned long waddr;
141 unsigned int save_map;
143 save_map = save_eisa_map();
144 waddr = PCIMT_EISA_BASE | (from & 0xffffff);
145 while(len) {
146 unsigned long fraglen;
148 fraglen = (~from + 1) & 0xffffff;
149 fraglen = (fraglen < len) ? fraglen : len;
150 eisa_map(from);
151 memcpy((void *)to, (void *)waddr, fraglen);
152 to += fraglen;
153 from += fraglen;
154 waddr = waddr + fraglen - 0x1000000;
155 len -= fraglen;
157 restore_eisa_map(save_map);
160 static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
162 unsigned long waddr;
163 unsigned int save_map;
165 save_map = save_eisa_map();
166 waddr = PCIMT_EISA_BASE | (to & 0xffffff);
167 while(len) {
168 unsigned long fraglen;
170 fraglen = (~to + 1) & 0xffffff;
171 fraglen = (fraglen < len) ? fraglen : len;
172 eisa_map(to);
173 memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen);
174 to += fraglen;
175 from += fraglen;
176 waddr = waddr + fraglen - 0x1000000;
177 len -= fraglen;
179 restore_eisa_map(save_map);