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