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