mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-19 03:08:31 +00:00
83d290c56f
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
330 lines
6 KiB
C
330 lines
6 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include "rtl8169.h"
|
|
|
|
static unsigned char *PCI_MEMR;
|
|
|
|
static void mac_delay(unsigned int cnt)
|
|
{
|
|
udelay(cnt);
|
|
}
|
|
|
|
static void mac_pci_setup(void)
|
|
{
|
|
unsigned long pci_data;
|
|
|
|
PCI_PAR = 0x00000010;
|
|
PCI_PDR = 0x00001000;
|
|
PCI_PAR = 0x00000004;
|
|
pci_data = PCI_PDR;
|
|
PCI_PDR = pci_data | 0x00000007;
|
|
PCI_PAR = 0x00000010;
|
|
|
|
PCI_MEMR = (unsigned char *)((PCI_PDR | 0xFE240050) & 0xFFFFFFF0);
|
|
}
|
|
|
|
static void EECS(int level)
|
|
{
|
|
unsigned char data = *PCI_MEMR;
|
|
|
|
if (level)
|
|
*PCI_MEMR = data | 0x08;
|
|
else
|
|
*PCI_MEMR = data & 0xf7;
|
|
}
|
|
|
|
static void EECLK(int level)
|
|
{
|
|
unsigned char data = *PCI_MEMR;
|
|
|
|
if (level)
|
|
*PCI_MEMR = data | 0x04;
|
|
else
|
|
*PCI_MEMR = data & 0xfb;
|
|
}
|
|
|
|
static void EEDI(int level)
|
|
{
|
|
unsigned char data = *PCI_MEMR;
|
|
|
|
if (level)
|
|
*PCI_MEMR = data | 0x02;
|
|
else
|
|
*PCI_MEMR = data & 0xfd;
|
|
}
|
|
|
|
static inline void sh7785lcr_bitset(unsigned short bit)
|
|
{
|
|
if (bit)
|
|
EEDI(HIGH);
|
|
else
|
|
EEDI(LOW);
|
|
|
|
EECLK(LOW);
|
|
mac_delay(TIME1);
|
|
EECLK(HIGH);
|
|
mac_delay(TIME1);
|
|
EEDI(LOW);
|
|
}
|
|
|
|
static inline unsigned char sh7785lcr_bitget(void)
|
|
{
|
|
unsigned char bit;
|
|
|
|
EECLK(LOW);
|
|
mac_delay(TIME1);
|
|
bit = *PCI_MEMR & 0x01;
|
|
EECLK(HIGH);
|
|
mac_delay(TIME1);
|
|
|
|
return bit;
|
|
}
|
|
|
|
static inline void sh7785lcr_setcmd(unsigned char command)
|
|
{
|
|
sh7785lcr_bitset(BIT_DUMMY);
|
|
switch (command) {
|
|
case MAC_EEP_READ:
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(0);
|
|
break;
|
|
case MAC_EEP_WRITE:
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(0);
|
|
sh7785lcr_bitset(1);
|
|
break;
|
|
case MAC_EEP_ERACE:
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(1);
|
|
break;
|
|
case MAC_EEP_EWEN:
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(0);
|
|
sh7785lcr_bitset(0);
|
|
break;
|
|
case MAC_EEP_EWDS:
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(0);
|
|
sh7785lcr_bitset(0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline unsigned short sh7785lcr_getdt(void)
|
|
{
|
|
unsigned short data = 0;
|
|
int i;
|
|
|
|
sh7785lcr_bitget(); /* DUMMY */
|
|
for (i = 0 ; i < 16 ; i++) {
|
|
data <<= 1;
|
|
data |= sh7785lcr_bitget();
|
|
}
|
|
return data;
|
|
}
|
|
|
|
static inline void sh7785lcr_setadd(unsigned short address)
|
|
{
|
|
sh7785lcr_bitset(address & 0x0020); /* A5 */
|
|
sh7785lcr_bitset(address & 0x0010); /* A4 */
|
|
sh7785lcr_bitset(address & 0x0008); /* A3 */
|
|
sh7785lcr_bitset(address & 0x0004); /* A2 */
|
|
sh7785lcr_bitset(address & 0x0002); /* A1 */
|
|
sh7785lcr_bitset(address & 0x0001); /* A0 */
|
|
}
|
|
|
|
static inline void sh7785lcr_setdata(unsigned short data)
|
|
{
|
|
sh7785lcr_bitset(data & 0x8000);
|
|
sh7785lcr_bitset(data & 0x4000);
|
|
sh7785lcr_bitset(data & 0x2000);
|
|
sh7785lcr_bitset(data & 0x1000);
|
|
sh7785lcr_bitset(data & 0x0800);
|
|
sh7785lcr_bitset(data & 0x0400);
|
|
sh7785lcr_bitset(data & 0x0200);
|
|
sh7785lcr_bitset(data & 0x0100);
|
|
sh7785lcr_bitset(data & 0x0080);
|
|
sh7785lcr_bitset(data & 0x0040);
|
|
sh7785lcr_bitset(data & 0x0020);
|
|
sh7785lcr_bitset(data & 0x0010);
|
|
sh7785lcr_bitset(data & 0x0008);
|
|
sh7785lcr_bitset(data & 0x0004);
|
|
sh7785lcr_bitset(data & 0x0002);
|
|
sh7785lcr_bitset(data & 0x0001);
|
|
}
|
|
|
|
static void sh7785lcr_datawrite(const unsigned short *data, unsigned short address,
|
|
unsigned int count)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
EECS(HIGH);
|
|
EEDI(LOW);
|
|
mac_delay(TIME1);
|
|
|
|
sh7785lcr_setcmd(MAC_EEP_WRITE);
|
|
sh7785lcr_setadd(address++);
|
|
sh7785lcr_setdata(*(data + i));
|
|
|
|
EECLK(LOW);
|
|
EEDI(LOW);
|
|
EECS(LOW);
|
|
mac_delay(TIME2);
|
|
}
|
|
}
|
|
|
|
static void sh7785lcr_macerase(void)
|
|
{
|
|
unsigned int i;
|
|
unsigned short pci_address = 7;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
EECS(HIGH);
|
|
EEDI(LOW);
|
|
mac_delay(TIME1);
|
|
sh7785lcr_setcmd(MAC_EEP_ERACE);
|
|
sh7785lcr_setadd(pci_address++);
|
|
mac_delay(TIME1);
|
|
EECLK(LOW);
|
|
EEDI(LOW);
|
|
EECS(LOW);
|
|
}
|
|
|
|
mac_delay(TIME2);
|
|
|
|
printf("\n\nErace End\n");
|
|
for (i = 0; i < 10; i++)
|
|
mac_delay(TIME2);
|
|
}
|
|
|
|
static void sh7785lcr_macwrite(unsigned short *data)
|
|
{
|
|
sh7785lcr_macerase();
|
|
|
|
sh7785lcr_datawrite(EEPROM_W_Data_8169_A, 0x0000, 7);
|
|
sh7785lcr_datawrite(data, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
|
|
sh7785lcr_datawrite(EEPROM_W_Data_8169_B, 0x000a, 54);
|
|
}
|
|
|
|
void sh7785lcr_macdtrd(unsigned char *buf, unsigned short address, unsigned int count)
|
|
{
|
|
unsigned int i;
|
|
unsigned short wk;
|
|
|
|
for (i = 0 ; i < count; i++) {
|
|
EECS(HIGH);
|
|
EEDI(LOW);
|
|
mac_delay(TIME1);
|
|
sh7785lcr_setcmd(MAC_EEP_READ);
|
|
sh7785lcr_setadd(address++);
|
|
wk = sh7785lcr_getdt();
|
|
|
|
*buf++ = (unsigned char)(wk & 0xff);
|
|
*buf++ = (unsigned char)((wk >> 8) & 0xff);
|
|
EECLK(LOW);
|
|
EEDI(LOW);
|
|
EECS(LOW);
|
|
}
|
|
}
|
|
|
|
static void sh7785lcr_macadrd(unsigned char *buf)
|
|
{
|
|
*PCI_MEMR = PCI_PROG;
|
|
|
|
sh7785lcr_macdtrd(buf, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
|
|
}
|
|
|
|
static void sh7785lcr_eepewen(void)
|
|
{
|
|
*PCI_MEMR = PCI_PROG;
|
|
mac_delay(TIME1);
|
|
EECS(LOW);
|
|
EECLK(LOW);
|
|
EEDI(LOW);
|
|
EECS(HIGH);
|
|
mac_delay(TIME1);
|
|
|
|
sh7785lcr_setcmd(MAC_EEP_EWEN);
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(1);
|
|
sh7785lcr_bitset(BIT_DUMMY);
|
|
sh7785lcr_bitset(BIT_DUMMY);
|
|
sh7785lcr_bitset(BIT_DUMMY);
|
|
sh7785lcr_bitset(BIT_DUMMY);
|
|
|
|
EECLK(LOW);
|
|
EEDI(LOW);
|
|
EECS(LOW);
|
|
mac_delay(TIME1);
|
|
}
|
|
|
|
void mac_write(unsigned short *data)
|
|
{
|
|
mac_pci_setup();
|
|
sh7785lcr_eepewen();
|
|
sh7785lcr_macwrite(data);
|
|
}
|
|
|
|
void mac_read(void)
|
|
{
|
|
unsigned char data[6];
|
|
|
|
mac_pci_setup();
|
|
sh7785lcr_macadrd(data);
|
|
printf("Mac = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
data[0], data[1], data[2], data[3], data[4], data[5]);
|
|
}
|
|
|
|
int do_set_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
{
|
|
int i;
|
|
unsigned char mac[6];
|
|
char *s, *e;
|
|
|
|
if (argc != 2)
|
|
return cmd_usage(cmdtp);
|
|
|
|
s = argv[1];
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
mac[i] = s ? simple_strtoul(s, &e, 16) : 0;
|
|
if (s)
|
|
s = (*e) ? e + 1 : e;
|
|
}
|
|
mac_write((unsigned short *)mac);
|
|
|
|
return 0;
|
|
}
|
|
|
|
U_BOOT_CMD(
|
|
setmac, 2, 1, do_set_mac,
|
|
"write MAC address for RTL8110SCL",
|
|
"\n"
|
|
"setmac <mac address> - write MAC address for RTL8110SCL"
|
|
);
|
|
|
|
int do_print_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
{
|
|
if (argc != 1)
|
|
return cmd_usage(cmdtp);
|
|
|
|
mac_read();
|
|
|
|
return 0;
|
|
}
|
|
|
|
U_BOOT_CMD(
|
|
printmac, 1, 1, do_print_mac,
|
|
"print MAC address for RTL8110",
|
|
"\n"
|
|
" - print MAC address for RTL8110"
|
|
);
|