ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-m68knommu / mcfsmc.h
1 /****************************************************************************/
2
3 /*
4  *      mcfsmc.h -- SMC ethernet support for ColdFire environments.
5  *
6  *      (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
7  *      (C) Copyright 2000, Lineo Inc. (www.lineo.com) 
8  */
9
10 /****************************************************************************/
11 #ifndef mcfsmc_h
12 #define mcfsmc_h
13 /****************************************************************************/
14
15 /*
16  *      None of the current ColdFire targets that use the SMC91x111
17  *      allow 8 bit accesses. So this code is 16bit access only.
18  */
19
20 #include <linux/config.h>
21
22 #undef  outb
23 #undef  inb
24
25 /*
26  *      Re-defines for ColdFire environment... The SMC part is
27  *      mapped into memory space, so remap the PC-style in/out
28  *      routines to handle that.
29  */
30 #define outb    smc_outb
31 #define inb     smc_inb
32 #define outw    smc_outw
33 #define outwd   smc_outwd
34 #define inw     smc_inw
35 #define outl    smc_outl
36 #define inl     smc_inl
37
38 #define outsb   smc_outsb
39 #define outsw   smc_outsw
40 #define outsl   smc_outsl
41 #define insb    smc_insb
42 #define insw    smc_insw
43 #define insl    smc_insl
44
45
46 static inline int smc_inb(unsigned int addr)
47 {
48         register unsigned short w;
49         w = *((volatile unsigned short *) (addr & ~0x1));
50         return(((addr & 0x1) ? w : (w >> 8)) & 0xff);
51 }
52
53 static inline void smc_outw(unsigned int val, unsigned int addr)
54 {
55         *((volatile unsigned short *) addr) = (val << 8) | (val >> 8);
56 }
57
58 static inline int smc_inw(unsigned int addr)
59 {
60         register unsigned short w;
61         w = *((volatile unsigned short *) addr);
62         return(((w << 8) | (w >> 8)) & 0xffff);
63 }
64
65 static inline void smc_outl(unsigned long val, unsigned int addr)
66 {
67         *((volatile unsigned long *) addr) = 
68                 ((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) |
69                 ((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff);
70 }
71
72 static inline void smc_outwd(unsigned int val, unsigned int addr)
73 {
74         *((volatile unsigned short *) addr) = val;
75 }
76
77
78 /*
79  *      The rep* functions are used to feed the data port with
80  *      raw data. So we do not byte swap them when copying.
81  */
82
83 static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len)
84 {
85         volatile unsigned short *rp;
86         unsigned short          *buf, *ebuf;
87
88         buf = (unsigned short *) vbuf;
89         rp = (volatile unsigned short *) addr;
90
91         /* Copy as words for as long as possible */
92         for (ebuf = buf + (len >> 1); (buf < ebuf); )
93                 *buf++ = *rp;
94
95         /* Lastly, handle left over byte */
96         if (len & 0x1)
97                 *((unsigned char *) buf) = (*rp >> 8) & 0xff;
98 }
99
100 static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len)
101 {
102         volatile unsigned short *rp;
103         unsigned short          *buf, *ebuf;
104
105         buf = (unsigned short *) vbuf;
106         rp = (volatile unsigned short *) addr;
107         for (ebuf = buf + len; (buf < ebuf); )
108                 *buf++ = *rp;
109 }
110
111 static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len)
112 {
113         volatile unsigned long  *rp;
114         unsigned long           *buf, *ebuf;
115
116         buf = (unsigned long *) vbuf;
117         rp = (volatile unsigned long *) addr;
118         for (ebuf = buf + len; (buf < ebuf); )
119                 *buf++ = *rp;
120 }
121
122 static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len)
123 {
124         volatile unsigned short *rp;
125         unsigned short          *buf, *ebuf;
126
127         buf = (unsigned short *) vbuf;
128         rp = (volatile unsigned short *) addr;
129         for (ebuf = buf + len; (buf < ebuf); )
130                 *rp = *buf++;
131 }
132
133 static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len)
134 {
135         volatile unsigned long  *rp;
136         unsigned long           *buf, *ebuf;
137
138         buf = (unsigned long *) vbuf;
139         rp = (volatile unsigned long *) addr;
140         for (ebuf = buf + len; (buf < ebuf); )
141                 *rp = *buf++;
142 }
143
144
145 #ifdef CONFIG_NETtel
146 /*
147  *      Re-map the address space of at least one of the SMC ethernet
148  *      parts. Both parts power up decoding the same address, so we
149  *      need to move one of them first, before doing enything else.
150  *
151  *      We also increase the number of wait states for this part by one.
152  */
153
154 void smc_remap(unsigned int ioaddr)
155 {
156         static int              once = 0;
157         extern unsigned short   ppdata;
158         if (once++ == 0) {
159                 *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec;
160                 ppdata |= 0x0080;
161                 *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
162                 outw(0x0001, ioaddr + BANK_SELECT);
163                 outw(0x0001, ioaddr + BANK_SELECT);
164                 outw(0x0067, ioaddr + BASE);
165
166                 ppdata &= ~0x0080;
167                 *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
168         }
169         
170         *((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
171 }
172
173 #endif
174
175 /****************************************************************************/
176 #endif  /* mcfsmc_h */