mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-10-31 16:31:25 +01:00 
			
		
		
		
	Signed-off-by: Wolfgang Denk <wd@denx.de> [trini: Fixup common/cmd_io.c] Signed-off-by: Tom Rini <trini@ti.com>
		
			
				
	
	
		
			332 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			332 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
 | |
|  *
 | |
|  * SPDX-License-Identifier:	GPL-2.0+
 | |
|  */
 | |
| 
 | |
| #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"
 | |
| );
 |