]> git.sur5r.net Git - u-boot/blob - common/miiphybb.c
Update make target for ARM supported boards.
[u-boot] / common / miiphybb.c
1 /*
2  * (C) Copyright 2001
3  * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * This provides a bit-banged interface to the ethernet MII management
26  * channel.
27  */
28
29 #include <common.h>
30 #include <ioports.h>
31 #include <ppc_asm.tmpl>
32
33 #ifdef CONFIG_BITBANGMII
34
35
36 /*****************************************************************************
37  *
38  * Utility to send the preamble, address, and register (common to read
39  * and write).
40  */
41 static void miiphy_pre (char read, unsigned char addr, unsigned char reg)
42 {
43         int j;                  /* counter */
44 #ifndef CONFIG_EP8248
45         volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
46 #endif
47
48         /*
49          * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
50          * The IEEE spec says this is a PHY optional requirement.  The AMD
51          * 79C874 requires one after power up and one after a MII communications
52          * error.  This means that we are doing more preambles than we need,
53          * but it is safer and will be much more robust.
54          */
55
56         MDIO_ACTIVE;
57         MDIO (1);
58         for (j = 0; j < 32; j++) {
59                 MDC (0);
60                 MIIDELAY;
61                 MDC (1);
62                 MIIDELAY;
63         }
64
65         /* send the start bit (01) and the read opcode (10) or write (10) */
66         MDC (0);
67         MDIO (0);
68         MIIDELAY;
69         MDC (1);
70         MIIDELAY;
71         MDC (0);
72         MDIO (1);
73         MIIDELAY;
74         MDC (1);
75         MIIDELAY;
76         MDC (0);
77         MDIO (read);
78         MIIDELAY;
79         MDC (1);
80         MIIDELAY;
81         MDC (0);
82         MDIO (!read);
83         MIIDELAY;
84         MDC (1);
85         MIIDELAY;
86
87         /* send the PHY address */
88         for (j = 0; j < 5; j++) {
89                 MDC (0);
90                 if ((addr & 0x10) == 0) {
91                         MDIO (0);
92                 } else {
93                         MDIO (1);
94                 }
95                 MIIDELAY;
96                 MDC (1);
97                 MIIDELAY;
98                 addr <<= 1;
99         }
100
101         /* send the register address */
102         for (j = 0; j < 5; j++) {
103                 MDC (0);
104                 if ((reg & 0x10) == 0) {
105                         MDIO (0);
106                 } else {
107                         MDIO (1);
108                 }
109                 MIIDELAY;
110                 MDC (1);
111                 MIIDELAY;
112                 reg <<= 1;
113         }
114 }
115
116
117 /*****************************************************************************
118  *
119  * Read a MII PHY register.
120  *
121  * Returns:
122  *   0 on success
123  */
124 int miiphy_read (unsigned char addr, unsigned char reg, unsigned short *value)
125 {
126         short rdreg;            /* register working value */
127         int j;                  /* counter */
128 #ifndef CONFIG_EP8248
129         volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
130 #endif
131
132         miiphy_pre (1, addr, reg);
133
134         /* tri-state our MDIO I/O pin so we can read */
135         MDC (0);
136         MDIO_TRISTATE;
137         MIIDELAY;
138         MDC (1);
139         MIIDELAY;
140
141         /* check the turnaround bit: the PHY should be driving it to zero */
142         if (MDIO_READ != 0) {
143                 /* puts ("PHY didn't drive TA low\n"); */
144                 for (j = 0; j < 32; j++) {
145                         MDC (0);
146                         MIIDELAY;
147                         MDC (1);
148                         MIIDELAY;
149                 }
150                 return (-1);
151         }
152
153         MDC (0);
154         MIIDELAY;
155
156         /* read 16 bits of register data, MSB first */
157         rdreg = 0;
158         for (j = 0; j < 16; j++) {
159                 MDC (1);
160                 MIIDELAY;
161                 rdreg <<= 1;
162                 rdreg |= MDIO_READ;
163                 MDC (0);
164                 MIIDELAY;
165         }
166
167         MDC (1);
168         MIIDELAY;
169         MDC (0);
170         MIIDELAY;
171         MDC (1);
172         MIIDELAY;
173
174         *value = rdreg;
175
176 #ifdef DEBUG
177         printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
178 #endif
179
180         return 0;
181 }
182
183
184 /*****************************************************************************
185  *
186  * Write a MII PHY register.
187  *
188  * Returns:
189  *   0 on success
190  */
191 int miiphy_write (unsigned char addr, unsigned char reg, unsigned short value)
192 {
193         int j;                  /* counter */
194 #ifndef CONFIG_EP8248
195         volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
196 #endif
197
198         miiphy_pre (0, addr, reg);
199
200         /* send the turnaround (10) */
201         MDC (0);
202         MDIO (1);
203         MIIDELAY;
204         MDC (1);
205         MIIDELAY;
206         MDC (0);
207         MDIO (0);
208         MIIDELAY;
209         MDC (1);
210         MIIDELAY;
211
212         /* write 16 bits of register data, MSB first */
213         for (j = 0; j < 16; j++) {
214                 MDC (0);
215                 if ((value & 0x00008000) == 0) {
216                         MDIO (0);
217                 } else {
218                         MDIO (1);
219                 }
220                 MIIDELAY;
221                 MDC (1);
222                 MIIDELAY;
223                 value <<= 1;
224         }
225
226         /*
227          * Tri-state the MDIO line.
228          */
229         MDIO_TRISTATE;
230         MDC (0);
231         MIIDELAY;
232         MDC (1);
233         MIIDELAY;
234
235         return 0;
236 }
237
238 #endif /* CONFIG_BITBANGMII */