mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-01 08:59:33 +00:00
b196ca7550
Rather than sticking Blackfin-specific stuff into the eeprom example, use an indirect macro so that any board can override it with their own magic sauce in their board config file. Also fix some spurious semi-colons in defines while I'm at it ... Signed-off-by: Mike Frysinger <vapier@gentoo.org> CC: Ben Warren <biggerbadderben@gmail.com>
395 lines
7.6 KiB
C
395 lines
7.6 KiB
C
/*
|
|
* (C) Copyright 2004
|
|
* Robin Getz rgetz@blacfin.uclinux.org
|
|
*
|
|
* See file CREDITS for list of people who contributed to this
|
|
* project.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
* Heavily borrowed from the following peoples GPL'ed software:
|
|
* - Wolfgang Denk, DENX Software Engineering, wd@denx.de
|
|
* Das U-boot
|
|
* - Ladislav Michl ladis@linux-mips.org
|
|
* A rejected patch on the U-Boot mailing list
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <exports.h>
|
|
#include "../drivers/net/smc91111.h"
|
|
|
|
#ifdef CONFIG_DRIVER_SMC91111
|
|
|
|
#ifndef SMC91111_EEPROM_INIT
|
|
# define SMC91111_EEPROM_INIT()
|
|
#endif
|
|
|
|
#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
|
|
#define EEPROM 0x1
|
|
#define MAC 0x2
|
|
#define UNKNOWN 0x4
|
|
|
|
void dump_reg (void);
|
|
void dump_eeprom (void);
|
|
int write_eeprom_reg (int, int);
|
|
void copy_from_eeprom (void);
|
|
void print_MAC (void);
|
|
int read_eeprom_reg (int);
|
|
void print_macaddr (void);
|
|
|
|
int smc91111_eeprom (int argc, char *argv[])
|
|
{
|
|
int c, i, j, done, line, reg, value, start, what;
|
|
char input[50];
|
|
|
|
/* Print the ABI version */
|
|
app_startup (argv);
|
|
if (XF_VERSION != (int) get_version ()) {
|
|
printf ("Expects ABI version %d\n", XF_VERSION);
|
|
printf ("Actual U-Boot ABI version %d\n",
|
|
(int) get_version ());
|
|
printf ("Can't run\n\n");
|
|
return (0);
|
|
}
|
|
|
|
SMC91111_EEPROM_INIT();
|
|
|
|
if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) {
|
|
printf ("Can't find SMSC91111\n");
|
|
return (0);
|
|
}
|
|
|
|
done = 0;
|
|
what = UNKNOWN;
|
|
printf ("\n");
|
|
while (!done) {
|
|
/* print the prompt */
|
|
printf ("SMC91111> ");
|
|
line = 0;
|
|
i = 0;
|
|
start = 1;
|
|
while (!line) {
|
|
/* Wait for a keystroke */
|
|
while (!tstc ());
|
|
|
|
c = getc ();
|
|
/* Make Uppercase */
|
|
if (c >= 'Z')
|
|
c -= ('a' - 'A');
|
|
/* printf(" |%02x| ",c); */
|
|
|
|
switch (c) {
|
|
case '\r': /* Enter */
|
|
case '\n':
|
|
input[i] = 0;
|
|
puts ("\r\n");
|
|
line = 1;
|
|
break;
|
|
case '\0': /* nul */
|
|
continue;
|
|
|
|
case 0x03: /* ^C - break */
|
|
input[0] = 0;
|
|
i = 0;
|
|
line = 1;
|
|
done = 1;
|
|
break;
|
|
|
|
case 0x5F:
|
|
case 0x08: /* ^H - backspace */
|
|
case 0x7F: /* DEL - backspace */
|
|
if (i > 0) {
|
|
puts ("\b \b");
|
|
i--;
|
|
}
|
|
break;
|
|
default:
|
|
if (start) {
|
|
if ((c == 'W') || (c == 'D')
|
|
|| (c == 'M') || (c == 'C')
|
|
|| (c == 'P')) {
|
|
putc (c);
|
|
input[i] = c;
|
|
if (i <= 45)
|
|
i++;
|
|
start = 0;
|
|
}
|
|
} else {
|
|
if ((c >= '0' && c <= '9')
|
|
|| (c >= 'A' && c <= 'F')
|
|
|| (c == 'E') || (c == 'M')
|
|
|| (c == ' ')) {
|
|
putc (c);
|
|
input[i] = c;
|
|
if (i <= 45)
|
|
i++;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (; i < 49; i++)
|
|
input[i] = 0;
|
|
|
|
switch (input[0]) {
|
|
case ('W'):
|
|
/* Line should be w reg value */
|
|
i = 0;
|
|
reg = 0;
|
|
value = 0;
|
|
/* Skip to the next space or end) */
|
|
while ((input[i] != ' ') && (input[i] != 0))
|
|
i++;
|
|
|
|
if (input[i] != 0)
|
|
i++;
|
|
|
|
/* Are we writing to EEPROM or MAC */
|
|
switch (input[i]) {
|
|
case ('E'):
|
|
what = EEPROM;
|
|
break;
|
|
case ('M'):
|
|
what = MAC;
|
|
break;
|
|
default:
|
|
what = UNKNOWN;
|
|
break;
|
|
}
|
|
|
|
/* skip to the next space or end */
|
|
while ((input[i] != ' ') && (input[i] != 0))
|
|
i++;
|
|
if (input[i] != 0)
|
|
i++;
|
|
|
|
/* Find register to write into */
|
|
j = 0;
|
|
while ((input[i] != ' ') && (input[i] != 0)) {
|
|
j = input[i] - 0x30;
|
|
if (j >= 0xA) {
|
|
j -= 0x07;
|
|
}
|
|
reg = (reg * 0x10) + j;
|
|
i++;
|
|
}
|
|
|
|
while ((input[i] != ' ') && (input[i] != 0))
|
|
i++;
|
|
|
|
if (input[i] != 0)
|
|
i++;
|
|
else
|
|
what = UNKNOWN;
|
|
|
|
/* Get the value to write */
|
|
j = 0;
|
|
while ((input[i] != ' ') && (input[i] != 0)) {
|
|
j = input[i] - 0x30;
|
|
if (j >= 0xA) {
|
|
j -= 0x07;
|
|
}
|
|
value = (value * 0x10) + j;
|
|
i++;
|
|
}
|
|
|
|
switch (what) {
|
|
case 1:
|
|
printf ("Writing EEPROM register %02x with %04x\n", reg, value);
|
|
write_eeprom_reg (value, reg);
|
|
break;
|
|
case 2:
|
|
printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
|
|
SMC_SELECT_BANK (reg >> 4);
|
|
SMC_outw (value, reg & 0xE);
|
|
break;
|
|
default:
|
|
printf ("Wrong\n");
|
|
break;
|
|
}
|
|
break;
|
|
case ('D'):
|
|
dump_eeprom ();
|
|
break;
|
|
case ('M'):
|
|
dump_reg ();
|
|
break;
|
|
case ('C'):
|
|
copy_from_eeprom ();
|
|
break;
|
|
case ('P'):
|
|
print_macaddr ();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
void copy_from_eeprom (void)
|
|
{
|
|
int i;
|
|
|
|
SMC_SELECT_BANK (1);
|
|
SMC_outw ((SMC_inw (CTL_REG) & !CTL_EEPROM_SELECT) | CTL_RELOAD,
|
|
CTL_REG);
|
|
i = 100;
|
|
while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --i)
|
|
udelay (100);
|
|
if (i == 0) {
|
|
printf ("Timeout Refreshing EEPROM registers\n");
|
|
} else {
|
|
printf ("EEPROM contents copied to MAC\n");
|
|
}
|
|
|
|
}
|
|
|
|
void print_macaddr (void)
|
|
{
|
|
int i, j, k, mac[6];
|
|
|
|
printf ("Current MAC Address in SMSC91111 ");
|
|
SMC_SELECT_BANK (1);
|
|
for (i = 0; i < 5; i++) {
|
|
printf ("%02x:", SMC_inb (ADDR0_REG + i));
|
|
}
|
|
|
|
printf ("%02x\n", SMC_inb (ADDR0_REG + 5));
|
|
|
|
i = 0;
|
|
for (j = 0x20; j < 0x23; j++) {
|
|
k = read_eeprom_reg (j);
|
|
mac[i] = k & 0xFF;
|
|
i++;
|
|
mac[i] = k >> 8;
|
|
i++;
|
|
}
|
|
|
|
printf ("Current MAC Address in EEPROM ");
|
|
for (i = 0; i < 5; i++)
|
|
printf ("%02x:", mac[i]);
|
|
printf ("%02x\n", mac[5]);
|
|
|
|
}
|
|
void dump_eeprom (void)
|
|
{
|
|
int j, k;
|
|
|
|
printf ("IOS2-0 ");
|
|
for (j = 0; j < 8; j++) {
|
|
printf ("%03x ", j);
|
|
}
|
|
printf ("\n");
|
|
|
|
for (k = 0; k < 4; k++) {
|
|
if (k == 0)
|
|
printf ("CONFIG ");
|
|
if (k == 1)
|
|
printf ("BASE ");
|
|
if ((k == 2) || (k == 3))
|
|
printf (" ");
|
|
for (j = 0; j < 0x20; j += 4) {
|
|
printf ("%02x:%04x ", j + k, read_eeprom_reg (j + k));
|
|
}
|
|
printf ("\n");
|
|
}
|
|
|
|
for (j = 0x20; j < 0x40; j++) {
|
|
if ((j & 0x07) == 0)
|
|
printf ("\n");
|
|
printf ("%02x:%04x ", j, read_eeprom_reg (j));
|
|
}
|
|
printf ("\n");
|
|
|
|
}
|
|
|
|
int read_eeprom_reg (int reg)
|
|
{
|
|
int timeout;
|
|
|
|
SMC_SELECT_BANK (2);
|
|
SMC_outw (reg, PTR_REG);
|
|
|
|
SMC_SELECT_BANK (1);
|
|
SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD,
|
|
CTL_REG);
|
|
timeout = 100;
|
|
while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --timeout)
|
|
udelay (100);
|
|
if (timeout == 0) {
|
|
printf ("Timeout Reading EEPROM register %02x\n", reg);
|
|
return 0;
|
|
}
|
|
|
|
return SMC_inw (GP_REG);
|
|
|
|
}
|
|
|
|
int write_eeprom_reg (int value, int reg)
|
|
{
|
|
int timeout;
|
|
|
|
SMC_SELECT_BANK (2);
|
|
SMC_outw (reg, PTR_REG);
|
|
|
|
SMC_SELECT_BANK (1);
|
|
SMC_outw (value, GP_REG);
|
|
SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE, CTL_REG);
|
|
timeout = 100;
|
|
while ((SMC_inw (CTL_REG) & CTL_STORE) && --timeout)
|
|
udelay (100);
|
|
if (timeout == 0) {
|
|
printf ("Timeout Writing EEPROM register %02x\n", reg);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
void dump_reg (void)
|
|
{
|
|
int i, j;
|
|
|
|
printf (" ");
|
|
for (j = 0; j < 4; j++) {
|
|
printf ("Bank%i ", j);
|
|
}
|
|
printf ("\n");
|
|
for (i = 0; i < 0xF; i += 2) {
|
|
printf ("%02x ", i);
|
|
for (j = 0; j < 4; j++) {
|
|
SMC_SELECT_BANK (j);
|
|
printf ("%04x ", SMC_inw (i));
|
|
}
|
|
printf ("\n");
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
int smc91111_eeprom (int argc, char *argv[])
|
|
{
|
|
printf("Not supported for this board\n");
|
|
return 1;
|
|
}
|
|
|
|
#endif
|