blob: 6a2480741110ad2a9562967c21c2290316d70907 [file] [log] [blame]
wdenke69b4b82002-09-17 21:26:59 +00001/*
2 * (C) Copyright 2002 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
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/* includes */
25#include <common.h>
26#include <linux/ctype.h>
27#include <pci.h>
28#include <net.h>
29#include <mpc106.h>
30#include <w83c553f.h>
31#include "srom.h"
32
33/* imports */
34extern char console_buffer[CFG_CBSIZE];
35extern int l2_cache_enable (int l2control);
36extern void *nvram_read (void *dest, const short src, size_t count);
37extern void nvram_write (short dest, const void *src, size_t count);
38
39/* globals */
40unsigned int ata_reset_time = 60;
41unsigned int scsi_reset_time = 10;
42unsigned int eltec_board;
43
44/* BAB750 uses SYM53C875(default) and BAB740 uses SYM53C860
45 * values fixed after board identification
46 */
47unsigned short scsi_dev_id = PCI_DEVICE_ID_NCR_53C875;
48unsigned int scsi_max_scsi_id = 15;
49unsigned char scsi_sym53c8xx_ccf = 0x13;
50
51/*----------------------------------------------------------------------------*/
52/*
53 * handle sroms on BAB740/750
54 * fix ether address
55 * L2 cache initialization
56 * ide dma control
57 */
58int misc_init_r (void)
59{
60 revinfo eerev;
Wolfgang Denk77ddac92005-10-13 16:45:02 +020061 char *ptr;
wdenke69b4b82002-09-17 21:26:59 +000062 u_int i, l, initSrom, copyNv;
63 char buf[256];
64 char hex[23] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0,
wdenk8bde7f72003-06-27 21:31:46 +000065 0, 0, 0, 0, 10, 11, 12, 13, 14, 15 };
wdenke69b4b82002-09-17 21:26:59 +000066 pci_dev_t bdf;
67
68 char sromSYM[] = {
69#ifdef TULIP_BUG
70 /* 10BaseT, 100BaseTx no full duplex modes */
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x08,
75 0x02, 0x86, 0x02, 0x00, 0xaf, 0x08, 0xa5, 0x00,
76 0x88, 0x04, 0x03, 0x27, 0x08, 0x25, 0x00, 0x61,
77 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe8
87#endif
88 /* 10BaseT, 10BaseT-FD, 100BaseTx, 100BaseTx-FD */
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x08,
93 0x04, 0x86, 0x02, 0x00, 0xaf, 0x08, 0xa5, 0x00,
94 0x86, 0x02, 0x04, 0xaf, 0x08, 0xa5, 0x00, 0x88,
95 0x04, 0x03, 0x27, 0x08, 0x25, 0x00, 0x61, 0x80,
96 0x88, 0x04, 0x05, 0x27, 0x08, 0x25, 0x00, 0x61,
97 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x77
105 };
106
107 char sromMII[] = {
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x5b, 0x00,
111 0x2e, 0x4d, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x08,
112 0x01, 0x95, 0x03, 0x00, 0x00, 0x04, 0x01, 0x08,
113 0x00, 0x00, 0x02, 0x08, 0x02, 0x00, 0x00, 0x78,
114 0xe0, 0x01, 0x00, 0x50, 0x00, 0x18, 0x80, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x41
124 };
125
126 /*
127 * Check/Remake revision info
128 */
129 initSrom = 0;
130 copyNv = 0;
131
132 /* read out current revision srom contens */
133 el_srom_load (0x0000, (u_char*)&eerev, sizeof(revinfo),
wdenk8bde7f72003-06-27 21:31:46 +0000134 SECOND_DEVICE, FIRST_BLOCK);
wdenke69b4b82002-09-17 21:26:59 +0000135
136 /* read out current nvram shadow image */
137 nvram_read (buf, CFG_NV_SROM_COPY_ADDR, CFG_SROM_SIZE);
138
139 if (strcmp (eerev.magic, "ELTEC") != 0)
140 {
wdenk8bde7f72003-06-27 21:31:46 +0000141 /* srom is not initialized -> create a default revision info */
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200142 for (i = 0, ptr = (char *)&eerev; i < sizeof(revinfo); i++)
wdenk8bde7f72003-06-27 21:31:46 +0000143 *ptr++ = 0x00;
144 strcpy(eerev.magic, "ELTEC");
145 eerev.revrev[0] = 1;
146 eerev.revrev[1] = 0;
147 eerev.size = 0x00E0;
148 eerev.category[0] = 0x01;
wdenke69b4b82002-09-17 21:26:59 +0000149
wdenk8bde7f72003-06-27 21:31:46 +0000150 /* node id from dead e128 as default */
151 eerev.etheraddr[0] = 0x00;
152 eerev.etheraddr[1] = 0x00;
153 eerev.etheraddr[2] = 0x5B;
154 eerev.etheraddr[3] = 0x00;
155 eerev.etheraddr[4] = 0x2E;
156 eerev.etheraddr[5] = 0x4D;
wdenke69b4b82002-09-17 21:26:59 +0000157
wdenk8bde7f72003-06-27 21:31:46 +0000158 /* cache config word for bab750 */
159 *(int*)&eerev.res[0] = CLK2P0TO1_1MB_PB_0P5DH;
wdenke69b4b82002-09-17 21:26:59 +0000160
wdenk8bde7f72003-06-27 21:31:46 +0000161 initSrom = 1; /* force dialog */
162 copyNv = 1; /* copy to nvram */
wdenke69b4b82002-09-17 21:26:59 +0000163 }
164
165 if ((copyNv == 0) && (el_srom_checksum((u_char*)&eerev, CFG_SROM_SIZE) !=
wdenk8bde7f72003-06-27 21:31:46 +0000166 el_srom_checksum((u_char*)buf, CFG_SROM_SIZE)))
wdenke69b4b82002-09-17 21:26:59 +0000167 {
wdenk8bde7f72003-06-27 21:31:46 +0000168 printf ("Invalid revision info copy in nvram !\n");
169 printf ("Press key:\n <c> to copy current revision info to nvram.\n");
170 printf (" <r> to reenter revision info.\n");
171 printf ("=> ");
172 if (0 != readline (NULL))
173 {
174 switch ((char)toupper(console_buffer[0]))
175 {
176 case 'C':
177 copyNv = 1;
178 break;
179 case 'R':
180 copyNv = 1;
181 initSrom = 1;
182 break;
183 }
184 }
wdenke69b4b82002-09-17 21:26:59 +0000185 }
186
187 if (initSrom)
188 {
wdenk8bde7f72003-06-27 21:31:46 +0000189 memcpy (buf, &eerev.revision[0][0], 14); /* save all revision info */
190 printf ("Enter revision number (0-9): %c ", eerev.revision[0][0]);
191 if (0 != readline (NULL))
192 {
193 eerev.revision[0][0] = (char)toupper(console_buffer[0]);
194 memcpy (&eerev.revision[1][0], buf, 12); /* shift rest of rev info */
195 }
wdenke69b4b82002-09-17 21:26:59 +0000196
wdenk8bde7f72003-06-27 21:31:46 +0000197 printf ("Enter revision character (A-Z): %c ", eerev.revision[0][1]);
198 if (1 == readline (NULL))
199 {
200 eerev.revision[0][1] = (char)toupper(console_buffer[0]);
201 }
wdenke69b4b82002-09-17 21:26:59 +0000202
wdenk8bde7f72003-06-27 21:31:46 +0000203 printf ("Enter board name (V-XXXX-XXXX): %s ", (char *)&eerev.board);
204 if (11 == readline (NULL))
205 {
206 for (i=0; i<11; i++)
207 eerev.board[i] = (char)toupper(console_buffer[i]);
208 eerev.board[11] = '\0';
209 }
wdenke69b4b82002-09-17 21:26:59 +0000210
wdenk8bde7f72003-06-27 21:31:46 +0000211 printf ("Enter serial number: %s ", (char *)&eerev.serial );
212 if (6 == readline (NULL))
213 {
214 for (i=0; i<6; i++)
215 eerev.serial[i] = console_buffer[i];
216 eerev.serial[6] = '\0';
217 }
wdenke69b4b82002-09-17 21:26:59 +0000218
wdenk8bde7f72003-06-27 21:31:46 +0000219 printf ("Enter ether node ID with leading zero (HEX): %02x%02x%02x%02x%02x%02x ",
220 eerev.etheraddr[0], eerev.etheraddr[1],
221 eerev.etheraddr[2], eerev.etheraddr[3],
222 eerev.etheraddr[4], eerev.etheraddr[5]);
223 if (12 == readline (NULL))
224 {
225 for (i=0; i<12; i+=2)
226 eerev.etheraddr[i>>1] = (char)(16*hex[toupper(console_buffer[i])-'0'] +
227 hex[toupper(console_buffer[i+1])-'0']);
228 }
wdenke69b4b82002-09-17 21:26:59 +0000229
wdenk8bde7f72003-06-27 21:31:46 +0000230 l = strlen ((char *)&eerev.text);
231 printf("Add to text section (max 64 chr): %s ", (char *)&eerev.text );
232 if (0 != readline (NULL))
233 {
234 for (i = l; i<63; i++)
235 eerev.text[i] = console_buffer[i-l];
236 eerev.text[63] = '\0';
237 }
wdenke69b4b82002-09-17 21:26:59 +0000238
wdenk8bde7f72003-06-27 21:31:46 +0000239 if (strstr ((char *)&eerev.board, "75") != NULL)
240 eltec_board = 750;
241 else
242 eltec_board = 740;
wdenke69b4b82002-09-17 21:26:59 +0000243
wdenk8bde7f72003-06-27 21:31:46 +0000244 if (eltec_board == 750)
245 {
246 if (CPU_TYPE == CPU_TYPE_750)
247 *(int*)&eerev.res[0] = CLK2P0TO1_1MB_PB_0P5DH;
248 else
249 *(int*)&eerev.res[0] = CLK2P5TO1_1MB_PB_0P5DH;
wdenke69b4b82002-09-17 21:26:59 +0000250
wdenk8bde7f72003-06-27 21:31:46 +0000251 printf("Enter L2Cache config word with leading zero (HEX): %08X ",
252 *(int*)&eerev.res[0] );
253 if (0 != readline (NULL))
254 {
255 for (i=0; i<7; i+=2)
256 {
257 eerev.res[i>>1] =
258 (char)(16*hex[toupper(console_buffer[i])-'0'] +
259 hex[toupper(console_buffer[i+1])-'0']);
260 }
261 }
wdenke69b4b82002-09-17 21:26:59 +0000262
wdenk8bde7f72003-06-27 21:31:46 +0000263 /* prepare network eeprom */
264 sromMII[20] = eerev.etheraddr[0];
265 sromMII[21] = eerev.etheraddr[1];
266 sromMII[22] = eerev.etheraddr[2];
267 sromMII[23] = eerev.etheraddr[3];
268 sromMII[24] = eerev.etheraddr[4];
269 sromMII[25] = eerev.etheraddr[5];
270 printf("\nSRom: Writing DEC21143 MII info .. ");
wdenke69b4b82002-09-17 21:26:59 +0000271
wdenk8bde7f72003-06-27 21:31:46 +0000272 if (dc_srom_store ((u_short *)sromMII) == -1)
273 printf("FAILED\n");
274 else
275 printf("OK\n");
276 }
wdenke69b4b82002-09-17 21:26:59 +0000277
wdenk8bde7f72003-06-27 21:31:46 +0000278 if (eltec_board == 740)
279 {
280 *(int *)&eerev.res[0] = 0;
281 sromSYM[20] = eerev.etheraddr[0];
282 sromSYM[21] = eerev.etheraddr[1];
283 sromSYM[22] = eerev.etheraddr[2];
284 sromSYM[23] = eerev.etheraddr[3];
285 sromSYM[24] = eerev.etheraddr[4];
286 sromSYM[25] = eerev.etheraddr[5];
287 printf("\nSRom: Writing DEC21143 SYM info .. ");
wdenke69b4b82002-09-17 21:26:59 +0000288
wdenk8bde7f72003-06-27 21:31:46 +0000289 if (dc_srom_store ((u_short *)sromSYM) == -1)
290 printf("FAILED\n");
291 else
292 printf("OK\n");
293 }
wdenke69b4b82002-09-17 21:26:59 +0000294
wdenk8bde7f72003-06-27 21:31:46 +0000295 /* update CRC */
296 eerev.crc = el_srom_checksum((u_char *)eerev.board, eerev.size);
wdenke69b4b82002-09-17 21:26:59 +0000297
wdenk8bde7f72003-06-27 21:31:46 +0000298 /* write new values */
299 printf("\nSRom: Writing revision info ...... ");
300 if (el_srom_store((BLOCK_SIZE-sizeof(revinfo)), (u_char *)&eerev,
301 sizeof(revinfo), SECOND_DEVICE, FIRST_BLOCK) == -1)
302 printf("FAILED\n\n");
303 else
304 printf("OK\n\n");
wdenke69b4b82002-09-17 21:26:59 +0000305
wdenk8bde7f72003-06-27 21:31:46 +0000306 /* write new values as shadow image to nvram */
307 nvram_write (CFG_NV_SROM_COPY_ADDR, (void *)&eerev, CFG_SROM_SIZE);
wdenke69b4b82002-09-17 21:26:59 +0000308
309 } /*if (initSrom) */
310
311 /* copy current values as shadow image to nvram */
312 if (initSrom == 0 && copyNv == 1)
wdenk8bde7f72003-06-27 21:31:46 +0000313 nvram_write (CFG_NV_SROM_COPY_ADDR, (void *)&eerev, CFG_SROM_SIZE);
wdenke69b4b82002-09-17 21:26:59 +0000314
315 /* update environment */
316 sprintf (buf, "%02x:%02x:%02x:%02x:%02x:%02x",
wdenk8bde7f72003-06-27 21:31:46 +0000317 eerev.etheraddr[0], eerev.etheraddr[1],
318 eerev.etheraddr[2], eerev.etheraddr[3],
319 eerev.etheraddr[4], eerev.etheraddr[5]);
wdenke69b4b82002-09-17 21:26:59 +0000320 setenv ("ethaddr", buf);
321
322 /* print actual board identification */
323 printf("Ident: %s Ser %s Rev %c%c\n",
wdenk8bde7f72003-06-27 21:31:46 +0000324 eerev.board, (char *)&eerev.serial,
325 eerev.revision[0][0], eerev.revision[0][1]);
wdenke69b4b82002-09-17 21:26:59 +0000326
327 /* global board ident */
328 if (strstr ((char *)&eerev.board, "75") != NULL)
wdenk8bde7f72003-06-27 21:31:46 +0000329 eltec_board = 750;
wdenke69b4b82002-09-17 21:26:59 +0000330 else
wdenk8bde7f72003-06-27 21:31:46 +0000331 eltec_board = 740;
wdenke69b4b82002-09-17 21:26:59 +0000332
333 /*
334 * L2 cache configuration
335 */
336#if defined(CFG_L2_BAB7xx)
337 ptr = getenv("l2cache");
338 if (*ptr == '0')
339 {
wdenk8bde7f72003-06-27 21:31:46 +0000340 printf ("Cache: L2 NOT activated on BAB%d\n", eltec_board);
wdenke69b4b82002-09-17 21:26:59 +0000341 }
342 else
343 {
wdenk8bde7f72003-06-27 21:31:46 +0000344 printf ("Cache: L2 activated on BAB%d\n", eltec_board);
345 l2_cache_enable(*(int*)&eerev.res[0]);
wdenke69b4b82002-09-17 21:26:59 +0000346 }
347#endif
348
349 /*
350 * Reconfig ata reset timeout from environment
351 */
352 if ((ptr = getenv ("ata_reset_time")) != NULL)
353 {
wdenk8bde7f72003-06-27 21:31:46 +0000354 ata_reset_time = (int)simple_strtoul (ptr, NULL, 10);
wdenke69b4b82002-09-17 21:26:59 +0000355 }
356 else
357 {
wdenk8bde7f72003-06-27 21:31:46 +0000358 sprintf (buf, "%d", ata_reset_time);
359 setenv ("ata_reset_time", buf);
wdenke69b4b82002-09-17 21:26:59 +0000360 }
361
362 /*
363 * Reconfig scsi reset timeout from environment
364 */
365 if ((ptr = getenv ("scsi_reset_time")) != NULL)
366 {
wdenk8bde7f72003-06-27 21:31:46 +0000367 scsi_reset_time = (int)simple_strtoul (ptr, NULL, 10);
wdenke69b4b82002-09-17 21:26:59 +0000368 }
369 else
370 {
wdenk8bde7f72003-06-27 21:31:46 +0000371 sprintf (buf, "%d", scsi_reset_time);
372 setenv ("scsi_reset_time", buf);
wdenke69b4b82002-09-17 21:26:59 +0000373 }
374
375
376 if ((bdf = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, 0)) > 0)
377 {
wdenk8bde7f72003-06-27 21:31:46 +0000378 if (pci_find_device(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C860, 0) > 0)
379 {
380 /* BAB740 with SCSI=IRQ 11; SCC=IRQ 9; no IDE; NCR860 at 80 Mhz */
381 scsi_dev_id = PCI_DEVICE_ID_NCR_53C860;
382 scsi_max_scsi_id = 7;
383 scsi_sym53c8xx_ccf = 0x15;
384 pci_write_config_byte (bdf, WINBOND_IDEIRCR, 0xb0);
385 }
wdenke69b4b82002-09-17 21:26:59 +0000386
wdenk8bde7f72003-06-27 21:31:46 +0000387 if ((ptr = getenv ("ide_dma_off")) != NULL)
388 {
389 u_long dma_off = simple_strtoul (ptr, NULL, 10);
390 /*
391 * setup user defined registers
392 * s.a. linux/drivers/ide/sl82c105.c
393 */
394 bdf |= PCI_BDF(0,0,1); /* ide user reg at bdf function 1 */
395 if (dma_off & 1)
396 {
397 pci_write_config_byte (bdf, 0x46, 1);
398 printf("IDE: DMA off flag set: Bus 0 : Dev 0\n");
399 }
400 if (dma_off & 2)
401 {
402 pci_write_config_byte (bdf, 0x4a, 1);
403 printf("IDE: DMA off flag set: Bus 0 : Dev 1\n");
404 }
405 if (dma_off & 4)
406 {
407 pci_write_config_byte (bdf, 0x4e, 1);
408 printf("IDE: DMA off flag set: Bus 1 : Dev 0\n");
409 }
410 if (dma_off & 8)
411 {
412 pci_write_config_byte (bdf, 0x52, 1);
413 printf("IDE: DMA off flag set: Bus 1 : Dev 1\n");
414 }
415 }
wdenke69b4b82002-09-17 21:26:59 +0000416 }
417 return (0);
418}
419
420/*----------------------------------------------------------------------------*/
421/*
422 * BAB740 uses KENDIN KS8761 modem chip with not common setup values
423 */
424#ifdef CONFIG_TULIP_SELECT_MEDIA
425
426/* Register bits.
427 */
428#define BMR_SWR 0x00000001 /* Software Reset */
429#define STS_TS 0x00700000 /* Transmit Process State */
430#define STS_RS 0x000e0000 /* Receive Process State */
431#define OMR_ST 0x00002000 /* Start/Stop Transmission Command */
432#define OMR_SR 0x00000002 /* Start/Stop Receive */
433#define OMR_PS 0x00040000 /* Port Select */
434#define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */
435#define OMR_PM 0x00000080 /* Pass All Multicast */
436#define OMR_PR 0x00000040 /* Promiscuous Mode */
437#define OMR_PCS 0x00800000 /* PCS Function */
438#define OMR_TTM 0x00400000 /* Transmit Threshold Mode */
439
440/* Ethernet chip registers.
441 */
442#define DE4X5_BMR 0x000 /* Bus Mode Register */
443#define DE4X5_TPD 0x008 /* Transmit Poll Demand Reg */
444#define DE4X5_RRBA 0x018 /* RX Ring Base Address Reg */
445#define DE4X5_TRBA 0x020 /* TX Ring Base Address Reg */
446#define DE4X5_STS 0x028 /* Status Register */
447#define DE4X5_OMR 0x030 /* Operation Mode Register */
448#define DE4X5_SISR 0x060 /* SIA Status Register */
449#define DE4X5_SICR 0x068 /* SIA Connectivity Register */
450#define DE4X5_TXRX 0x070 /* SIA Transmit and Receive Register */
451#define DE4X5_GPPR 0x078 /* General Purpose Port register */
452#define DE4X5_APROM 0x048 /* Ethernet Address PROM */
453
454/*----------------------------------------------------------------------------*/
455
456static int INL(struct eth_device* dev, u_long addr)
457{
458 return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
459}
460
461/*----------------------------------------------------------------------------*/
462
463static void OUTL(struct eth_device* dev, int command, u_long addr)
464{
465 *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
466}
467
468/*----------------------------------------------------------------------------*/
469
470static void media_reg_init (
471 struct eth_device* dev,
472 u32 csr14,
473 u32 csr15_dir,
474 u32 csr15_v0,
475 u32 csr15_v1,
476 u32 csr6 )
477{
478 OUTL(dev, 0, DE4X5_OMR); /* CSR6 */
479 udelay(10 * 1000);
480 OUTL(dev, 0, DE4X5_SICR); /* CSR13 */
481 OUTL(dev, 1, DE4X5_SICR); /* CSR13 */
482 udelay(10 * 1000);
483 OUTL(dev, csr14, DE4X5_TXRX); /* CSR14 */
484 OUTL(dev, csr15_dir, DE4X5_GPPR); /* CSR15 */
485 OUTL(dev, csr15_v0, DE4X5_GPPR); /* CSR15 */
486 udelay(10 * 1000);
487 OUTL(dev, csr15_v1, DE4X5_GPPR); /* CSR15 */
488 OUTL(dev, 0x00000301, DE4X5_SISR); /* CSR12 */
489 OUTL(dev, csr6, DE4X5_OMR); /* CSR6 */
490}
491
492/*----------------------------------------------------------------------------*/
493
494void dc21x4x_select_media(struct eth_device* dev)
495{
496 int i, status, ext;
497 extern unsigned int eltec_board;
498
499 if (eltec_board == 740)
500 {
wdenk8bde7f72003-06-27 21:31:46 +0000501 printf("SYM media select "); /* BAB740 */
502 /* start autoneg. with 10 mbit */
503 media_reg_init (dev, 0x3ffff, 0x08af0008, 0x00a10008, 0x00a50008, 0x02400080);
504 ext = status = 0;
505 for (i=0; i<2000+ext; i++)
506 {
507 status = INL(dev, DE4X5_SISR);
508 udelay(1000);
509 if (status & 0x2000) ext = 2000;
510 if ((status & 0x7000) == 0x5000) break;
511 }
wdenke69b4b82002-09-17 21:26:59 +0000512
wdenk8bde7f72003-06-27 21:31:46 +0000513 /* autoneg. ok -> 100MB FD */
514 if ((status & 0x0100f000) == 0x0100d000)
515 {
516 media_reg_init (dev, 0x37f7f, 0x08270008, 0x00210008, 0x00250008, 0x03c40280);
517 printf("100baseTx-FD\n");
518 }
519 /* autoneg. ok -> 100MB HD */
520 else if ((status & 0x0080f000) == 0x0080d000)
521 {
522 media_reg_init (dev, 0x17f7f, 0x08270008, 0x00210008, 0x00250008, 0x03c40080);
523 printf("100baseTx\n");
524 }
525 /* autoneg. ok -> 10MB FD */
526 else if ((status & 0x0040f000) == 0x0040d000)
527 {
528 media_reg_init (dev, 0x07f7f, 0x08af0008, 0x00a10008, 0x00a50008, 0x02400280);
529 printf("10baseT-FD\n");
530 }
531 /* autoneg. fail -> 10MB HD */
532 else
533 {
534 media_reg_init (dev, 0x7f7f, 0x08af0008, 0x00a10008, 0x00a50008,
535 (OMR_SDP | OMR_TTM | OMR_PM));
536 printf("10baseT\n");
537 }
wdenke69b4b82002-09-17 21:26:59 +0000538 }
539 else
540 {
wdenk8bde7f72003-06-27 21:31:46 +0000541 printf("MII media selected\n"); /* BAB750 */
542 OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); /* CSR6 */
wdenke69b4b82002-09-17 21:26:59 +0000543 }
544}
545#endif /* CONFIG_TULIP_SELECT_MEDIA */
546
547/*---------------------------------------------------------------------------*/