]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - examples/standalone/smc91111_eeprom.c
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / examples / standalone / smc91111_eeprom.c
1 /*
2  * (C) Copyright 2004
3  * Robin Getz rgetz@blacfin.uclinux.org
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  * Heavily borrowed from the following peoples GPL'ed software:
24  *  - Wolfgang Denk, DENX Software Engineering, wd@denx.de
25  *       Das U-boot
26  *  - Ladislav Michl ladis@linux-mips.org
27  *       A rejected patch on the U-Boot mailing list
28  */
29
30 #include <common.h>
31 #include <exports.h>
32 #include "../drivers/net/smc91111.h"
33
34 #ifdef CONFIG_DRIVER_SMC91111
35
36 #ifndef SMC91111_EEPROM_INIT
37 # define SMC91111_EEPROM_INIT()
38 #endif
39
40 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
41 #define EEPROM          0x1
42 #define MAC             0x2
43 #define UNKNOWN         0x4
44
45 void dump_reg (void);
46 void dump_eeprom (void);
47 int write_eeprom_reg (int, int);
48 void copy_from_eeprom (void);
49 void print_MAC (void);
50 int read_eeprom_reg (int);
51 void print_macaddr (void);
52
53 int smc91111_eeprom (int argc, char *argv[])
54 {
55         int c, i, j, done, line, reg, value, start, what;
56         char input[50];
57
58         /* Print the ABI version */
59         app_startup (argv);
60         if (XF_VERSION != (int) get_version ()) {
61                 printf ("Expects ABI version %d\n", XF_VERSION);
62                 printf ("Actual U-Boot ABI version %d\n",
63                         (int) get_version ());
64                 printf ("Can't run\n\n");
65                 return (0);
66         }
67
68         SMC91111_EEPROM_INIT();
69
70         if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) {
71                 printf ("Can't find SMSC91111\n");
72                 return (0);
73         }
74
75         done = 0;
76         what = UNKNOWN;
77         printf ("\n");
78         while (!done) {
79                 /* print the prompt */
80                 printf ("SMC91111> ");
81                 line = 0;
82                 i = 0;
83                 start = 1;
84                 while (!line) {
85                         /* Wait for a keystroke */
86                         while (!tstc ());
87
88                         c = getc ();
89                         /* Make Uppercase */
90                         if (c >= 'Z')
91                                 c -= ('a' - 'A');
92                         /* printf(" |%02x| ",c); */
93
94                         switch (c) {
95                         case '\r':      /* Enter                */
96                         case '\n':
97                                 input[i] = 0;
98                                 puts ("\r\n");
99                                 line = 1;
100                                 break;
101                         case '\0':      /* nul                  */
102                                 continue;
103
104                         case 0x03:      /* ^C - break           */
105                                 input[0] = 0;
106                                 i = 0;
107                                 line = 1;
108                                 done = 1;
109                                 break;
110
111                         case 0x5F:
112                         case 0x08:      /* ^H  - backspace      */
113                         case 0x7F:      /* DEL - backspace      */
114                                 if (i > 0) {
115                                         puts ("\b \b");
116                                         i--;
117                                 }
118                                 break;
119                         default:
120                                 if (start) {
121                                         if ((c == 'W') || (c == 'D')
122                                             || (c == 'M') || (c == 'C')
123                                             || (c == 'P')) {
124                                                 putc (c);
125                                                 input[i] = c;
126                                                 if (i <= 45)
127                                                         i++;
128                                                 start = 0;
129                                         }
130                                 } else {
131                                         if ((c >= '0' && c <= '9')
132                                             || (c >= 'A' && c <= 'F')
133                                             || (c == 'E') || (c == 'M')
134                                             || (c == ' ')) {
135                                                 putc (c);
136                                                 input[i] = c;
137                                                 if (i <= 45)
138                                                         i++;
139                                                 break;
140                                         }
141                                 }
142                                 break;
143                         }
144                 }
145
146                 for (; i < 49; i++)
147                         input[i] = 0;
148
149                 switch (input[0]) {
150                 case ('W'):
151                         /* Line should be w reg value */
152                         i = 0;
153                         reg = 0;
154                         value = 0;
155                         /* Skip to the next space or end) */
156                         while ((input[i] != ' ') && (input[i] != 0))
157                                 i++;
158
159                         if (input[i] != 0)
160                                 i++;
161
162                         /* Are we writing to EEPROM or MAC */
163                         switch (input[i]) {
164                         case ('E'):
165                                 what = EEPROM;
166                                 break;
167                         case ('M'):
168                                 what = MAC;
169                                 break;
170                         default:
171                                 what = UNKNOWN;
172                                 break;
173                         }
174
175                         /* skip to the next space or end */
176                         while ((input[i] != ' ') && (input[i] != 0))
177                                 i++;
178                         if (input[i] != 0)
179                                 i++;
180
181                         /* Find register to write into */
182                         j = 0;
183                         while ((input[i] != ' ') && (input[i] != 0)) {
184                                 j = input[i] - 0x30;
185                                 if (j >= 0xA) {
186                                         j -= 0x07;
187                                 }
188                                 reg = (reg * 0x10) + j;
189                                 i++;
190                         }
191
192                         while ((input[i] != ' ') && (input[i] != 0))
193                                 i++;
194
195                         if (input[i] != 0)
196                                 i++;
197                         else
198                                 what = UNKNOWN;
199
200                         /* Get the value to write */
201                         j = 0;
202                         while ((input[i] != ' ') && (input[i] != 0)) {
203                                 j = input[i] - 0x30;
204                                 if (j >= 0xA) {
205                                         j -= 0x07;
206                                 }
207                                 value = (value * 0x10) + j;
208                                 i++;
209                         }
210
211                         switch (what) {
212                         case 1:
213                                 printf ("Writing EEPROM register %02x with %04x\n", reg, value);
214                                 write_eeprom_reg (value, reg);
215                                 break;
216                         case 2:
217                                 printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
218                                 SMC_SELECT_BANK (reg >> 4);
219                                 SMC_outw (value, reg & 0xE);
220                                 break;
221                         default:
222                                 printf ("Wrong\n");
223                                 break;
224                         }
225                         break;
226                 case ('D'):
227                         dump_eeprom ();
228                         break;
229                 case ('M'):
230                         dump_reg ();
231                         break;
232                 case ('C'):
233                         copy_from_eeprom ();
234                         break;
235                 case ('P'):
236                         print_macaddr ();
237                         break;
238                 default:
239                         break;
240                 }
241
242         }
243
244         return (0);
245 }
246
247 void copy_from_eeprom (void)
248 {
249         int i;
250
251         SMC_SELECT_BANK (1);
252         SMC_outw ((SMC_inw (CTL_REG) & !CTL_EEPROM_SELECT) | CTL_RELOAD,
253                   CTL_REG);
254         i = 100;
255         while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --i)
256                 udelay (100);
257         if (i == 0) {
258                 printf ("Timeout Refreshing EEPROM registers\n");
259         } else {
260                 printf ("EEPROM contents copied to MAC\n");
261         }
262
263 }
264
265 void print_macaddr (void)
266 {
267         int i, j, k, mac[6];
268
269         printf ("Current MAC Address in SMSC91111 ");
270         SMC_SELECT_BANK (1);
271         for (i = 0; i < 5; i++) {
272                 printf ("%02x:", SMC_inb (ADDR0_REG + i));
273         }
274
275         printf ("%02x\n", SMC_inb (ADDR0_REG + 5));
276
277         i = 0;
278         for (j = 0x20; j < 0x23; j++) {
279                 k = read_eeprom_reg (j);
280                 mac[i] = k & 0xFF;
281                 i++;
282                 mac[i] = k >> 8;
283                 i++;
284         }
285
286         printf ("Current MAC Address in EEPROM    ");
287         for (i = 0; i < 5; i++)
288                 printf ("%02x:", mac[i]);
289         printf ("%02x\n", mac[5]);
290
291 }
292 void dump_eeprom (void)
293 {
294         int j, k;
295
296         printf ("IOS2-0    ");
297         for (j = 0; j < 8; j++) {
298                 printf ("%03x     ", j);
299         }
300         printf ("\n");
301
302         for (k = 0; k < 4; k++) {
303                 if (k == 0)
304                         printf ("CONFIG ");
305                 if (k == 1)
306                         printf ("BASE   ");
307                 if ((k == 2) || (k == 3))
308                         printf ("       ");
309                 for (j = 0; j < 0x20; j += 4) {
310                         printf ("%02x:%04x ", j + k, read_eeprom_reg (j + k));
311                 }
312                 printf ("\n");
313         }
314
315         for (j = 0x20; j < 0x40; j++) {
316                 if ((j & 0x07) == 0)
317                         printf ("\n");
318                 printf ("%02x:%04x ", j, read_eeprom_reg (j));
319         }
320         printf ("\n");
321
322 }
323
324 int read_eeprom_reg (int reg)
325 {
326         int timeout;
327
328         SMC_SELECT_BANK (2);
329         SMC_outw (reg, PTR_REG);
330
331         SMC_SELECT_BANK (1);
332         SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD,
333                   CTL_REG);
334         timeout = 100;
335         while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --timeout)
336                 udelay (100);
337         if (timeout == 0) {
338                 printf ("Timeout Reading EEPROM register %02x\n", reg);
339                 return 0;
340         }
341
342         return SMC_inw (GP_REG);
343
344 }
345
346 int write_eeprom_reg (int value, int reg)
347 {
348         int timeout;
349
350         SMC_SELECT_BANK (2);
351         SMC_outw (reg, PTR_REG);
352
353         SMC_SELECT_BANK (1);
354         SMC_outw (value, GP_REG);
355         SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE, CTL_REG);
356         timeout = 100;
357         while ((SMC_inw (CTL_REG) & CTL_STORE) && --timeout)
358                 udelay (100);
359         if (timeout == 0) {
360                 printf ("Timeout Writing EEPROM register %02x\n", reg);
361                 return 0;
362         }
363
364         return 1;
365
366 }
367
368 void dump_reg (void)
369 {
370         int i, j;
371
372         printf ("    ");
373         for (j = 0; j < 4; j++) {
374                 printf ("Bank%i ", j);
375         }
376         printf ("\n");
377         for (i = 0; i < 0xF; i += 2) {
378                 printf ("%02x  ", i);
379                 for (j = 0; j < 4; j++) {
380                         SMC_SELECT_BANK (j);
381                         printf ("%04x  ", SMC_inw (i));
382                 }
383                 printf ("\n");
384         }
385 }
386
387 #else
388
389 int smc91111_eeprom (int argc, char *argv[])
390 {
391         printf("Not supported for this board\n");
392         return 1;
393 }
394
395 #endif