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