Home | History | Annotate | Download | only in sh7785lcr
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro (at) renesas.com>
      4  */
      5 
      6 #include <common.h>
      7 #include "rtl8169.h"
      8 
      9 static unsigned char *PCI_MEMR;
     10 
     11 static void mac_delay(unsigned int cnt)
     12 {
     13 	udelay(cnt);
     14 }
     15 
     16 static void mac_pci_setup(void)
     17 {
     18 	unsigned long pci_data;
     19 
     20 	PCI_PAR = 0x00000010;
     21 	PCI_PDR = 0x00001000;
     22 	PCI_PAR = 0x00000004;
     23 	pci_data = PCI_PDR;
     24 	PCI_PDR = pci_data | 0x00000007;
     25 	PCI_PAR = 0x00000010;
     26 
     27 	PCI_MEMR = (unsigned char *)((PCI_PDR | 0xFE240050) & 0xFFFFFFF0);
     28 }
     29 
     30 static void EECS(int level)
     31 {
     32 	unsigned char data = *PCI_MEMR;
     33 
     34 	if (level)
     35 		*PCI_MEMR = data | 0x08;
     36 	else
     37 		*PCI_MEMR = data & 0xf7;
     38 }
     39 
     40 static void EECLK(int level)
     41 {
     42 	unsigned char data = *PCI_MEMR;
     43 
     44 	if (level)
     45 		*PCI_MEMR = data | 0x04;
     46 	else
     47 		*PCI_MEMR = data & 0xfb;
     48 }
     49 
     50 static void EEDI(int level)
     51 {
     52 	unsigned char data = *PCI_MEMR;
     53 
     54 	if (level)
     55 		*PCI_MEMR = data | 0x02;
     56 	else
     57 		*PCI_MEMR = data & 0xfd;
     58 }
     59 
     60 static inline void sh7785lcr_bitset(unsigned short bit)
     61 {
     62 	if (bit)
     63 		EEDI(HIGH);
     64 	else
     65 		EEDI(LOW);
     66 
     67 	EECLK(LOW);
     68 	mac_delay(TIME1);
     69 	EECLK(HIGH);
     70 	mac_delay(TIME1);
     71 	EEDI(LOW);
     72 }
     73 
     74 static inline unsigned char sh7785lcr_bitget(void)
     75 {
     76 	unsigned char bit;
     77 
     78 	EECLK(LOW);
     79 	mac_delay(TIME1);
     80 	bit = *PCI_MEMR & 0x01;
     81 	EECLK(HIGH);
     82 	mac_delay(TIME1);
     83 
     84 	return bit;
     85 }
     86 
     87 static inline void sh7785lcr_setcmd(unsigned char command)
     88 {
     89 	sh7785lcr_bitset(BIT_DUMMY);
     90 	switch (command) {
     91 	case MAC_EEP_READ:
     92 		sh7785lcr_bitset(1);
     93 		sh7785lcr_bitset(1);
     94 		sh7785lcr_bitset(0);
     95 		break;
     96 	case MAC_EEP_WRITE:
     97 		sh7785lcr_bitset(1);
     98 		sh7785lcr_bitset(0);
     99 		sh7785lcr_bitset(1);
    100 		break;
    101 	case MAC_EEP_ERACE:
    102 		sh7785lcr_bitset(1);
    103 		sh7785lcr_bitset(1);
    104 		sh7785lcr_bitset(1);
    105 		break;
    106 	case MAC_EEP_EWEN:
    107 		sh7785lcr_bitset(1);
    108 		sh7785lcr_bitset(0);
    109 		sh7785lcr_bitset(0);
    110 		break;
    111 	case MAC_EEP_EWDS:
    112 		sh7785lcr_bitset(1);
    113 		sh7785lcr_bitset(0);
    114 		sh7785lcr_bitset(0);
    115 		break;
    116 	default:
    117 		break;
    118 	}
    119 }
    120 
    121 static inline unsigned short sh7785lcr_getdt(void)
    122 {
    123 	unsigned short data = 0;
    124 	int i;
    125 
    126 	sh7785lcr_bitget();			/* DUMMY */
    127 	for (i = 0 ; i < 16 ; i++) {
    128 		data <<= 1;
    129 		data |= sh7785lcr_bitget();
    130 	}
    131 	return data;
    132 }
    133 
    134 static inline void sh7785lcr_setadd(unsigned short address)
    135 {
    136 	sh7785lcr_bitset(address & 0x0020);	/* A5 */
    137 	sh7785lcr_bitset(address & 0x0010);	/* A4 */
    138 	sh7785lcr_bitset(address & 0x0008);	/* A3 */
    139 	sh7785lcr_bitset(address & 0x0004);	/* A2 */
    140 	sh7785lcr_bitset(address & 0x0002);	/* A1 */
    141 	sh7785lcr_bitset(address & 0x0001);	/* A0 */
    142 }
    143 
    144 static inline void sh7785lcr_setdata(unsigned short data)
    145 {
    146 	sh7785lcr_bitset(data & 0x8000);
    147 	sh7785lcr_bitset(data & 0x4000);
    148 	sh7785lcr_bitset(data & 0x2000);
    149 	sh7785lcr_bitset(data & 0x1000);
    150 	sh7785lcr_bitset(data & 0x0800);
    151 	sh7785lcr_bitset(data & 0x0400);
    152 	sh7785lcr_bitset(data & 0x0200);
    153 	sh7785lcr_bitset(data & 0x0100);
    154 	sh7785lcr_bitset(data & 0x0080);
    155 	sh7785lcr_bitset(data & 0x0040);
    156 	sh7785lcr_bitset(data & 0x0020);
    157 	sh7785lcr_bitset(data & 0x0010);
    158 	sh7785lcr_bitset(data & 0x0008);
    159 	sh7785lcr_bitset(data & 0x0004);
    160 	sh7785lcr_bitset(data & 0x0002);
    161 	sh7785lcr_bitset(data & 0x0001);
    162 }
    163 
    164 static void sh7785lcr_datawrite(const unsigned short *data, unsigned short address,
    165 			 unsigned int count)
    166 {
    167 	unsigned int i;
    168 
    169 	for (i = 0; i < count; i++) {
    170 		EECS(HIGH);
    171 		EEDI(LOW);
    172 		mac_delay(TIME1);
    173 
    174 		sh7785lcr_setcmd(MAC_EEP_WRITE);
    175 		sh7785lcr_setadd(address++);
    176 		sh7785lcr_setdata(*(data + i));
    177 
    178 		EECLK(LOW);
    179 		EEDI(LOW);
    180 		EECS(LOW);
    181 		mac_delay(TIME2);
    182 	}
    183 }
    184 
    185 static void sh7785lcr_macerase(void)
    186 {
    187 	unsigned int i;
    188 	unsigned short pci_address = 7;
    189 
    190 	for (i = 0; i < 3; i++) {
    191 		EECS(HIGH);
    192 		EEDI(LOW);
    193 		mac_delay(TIME1);
    194 		sh7785lcr_setcmd(MAC_EEP_ERACE);
    195 		sh7785lcr_setadd(pci_address++);
    196 		mac_delay(TIME1);
    197 		EECLK(LOW);
    198 		EEDI(LOW);
    199 		EECS(LOW);
    200 	}
    201 
    202 	mac_delay(TIME2);
    203 
    204 	printf("\n\nErace End\n");
    205 	for (i = 0; i < 10; i++)
    206 		mac_delay(TIME2);
    207 }
    208 
    209 static void sh7785lcr_macwrite(unsigned short *data)
    210 {
    211 	sh7785lcr_macerase();
    212 
    213 	sh7785lcr_datawrite(EEPROM_W_Data_8169_A, 0x0000, 7);
    214 	sh7785lcr_datawrite(data, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
    215 	sh7785lcr_datawrite(EEPROM_W_Data_8169_B, 0x000a, 54);
    216 }
    217 
    218 void sh7785lcr_macdtrd(unsigned char *buf, unsigned short address, unsigned int count)
    219 {
    220 	unsigned int i;
    221 	unsigned short wk;
    222 
    223 	for (i = 0 ; i < count; i++) {
    224 		EECS(HIGH);
    225 		EEDI(LOW);
    226 		mac_delay(TIME1);
    227 		sh7785lcr_setcmd(MAC_EEP_READ);
    228 		sh7785lcr_setadd(address++);
    229 		wk = sh7785lcr_getdt();
    230 
    231 		*buf++ = (unsigned char)(wk & 0xff);
    232 		*buf++ = (unsigned char)((wk >> 8) & 0xff);
    233 		EECLK(LOW);
    234 		EEDI(LOW);
    235 		EECS(LOW);
    236 	}
    237 }
    238 
    239 static void sh7785lcr_macadrd(unsigned char *buf)
    240 {
    241 	*PCI_MEMR = PCI_PROG;
    242 
    243 	sh7785lcr_macdtrd(buf, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
    244 }
    245 
    246 static void sh7785lcr_eepewen(void)
    247 {
    248 	*PCI_MEMR = PCI_PROG;
    249 	mac_delay(TIME1);
    250 	EECS(LOW);
    251 	EECLK(LOW);
    252 	EEDI(LOW);
    253 	EECS(HIGH);
    254 	mac_delay(TIME1);
    255 
    256 	sh7785lcr_setcmd(MAC_EEP_EWEN);
    257 	sh7785lcr_bitset(1);
    258 	sh7785lcr_bitset(1);
    259 	sh7785lcr_bitset(BIT_DUMMY);
    260 	sh7785lcr_bitset(BIT_DUMMY);
    261 	sh7785lcr_bitset(BIT_DUMMY);
    262 	sh7785lcr_bitset(BIT_DUMMY);
    263 
    264 	EECLK(LOW);
    265 	EEDI(LOW);
    266 	EECS(LOW);
    267 	mac_delay(TIME1);
    268 }
    269 
    270 void mac_write(unsigned short *data)
    271 {
    272 	mac_pci_setup();
    273 	sh7785lcr_eepewen();
    274 	sh7785lcr_macwrite(data);
    275 }
    276 
    277 void mac_read(void)
    278 {
    279 	unsigned char data[6];
    280 
    281 	mac_pci_setup();
    282 	sh7785lcr_macadrd(data);
    283 	printf("Mac = %02x:%02x:%02x:%02x:%02x:%02x\n",
    284 		data[0], data[1], data[2], data[3], data[4], data[5]);
    285 }
    286 
    287 int do_set_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    288 {
    289 	int i;
    290 	unsigned char mac[6];
    291 	char *s, *e;
    292 
    293 	if (argc != 2)
    294 		return cmd_usage(cmdtp);
    295 
    296 	s = argv[1];
    297 
    298 	for (i = 0; i < 6; i++) {
    299 		mac[i] = s ? simple_strtoul(s, &e, 16) : 0;
    300 		if (s)
    301 			s = (*e) ? e + 1 : e;
    302 	}
    303 	mac_write((unsigned short *)mac);
    304 
    305 	return 0;
    306 }
    307 
    308 U_BOOT_CMD(
    309 	setmac,	2,	1,	do_set_mac,
    310 	"write MAC address for RTL8110SCL",
    311 	"\n"
    312 	"setmac <mac address> - write MAC address for RTL8110SCL"
    313 );
    314 
    315 int do_print_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    316 {
    317 	if (argc != 1)
    318 		return cmd_usage(cmdtp);
    319 
    320 	mac_read();
    321 
    322 	return 0;
    323 }
    324 
    325 U_BOOT_CMD(
    326 	printmac,	1,	1,	do_print_mac,
    327 	"print MAC address for RTL8110",
    328 	"\n"
    329 	"    - print MAC address for RTL8110"
    330 );
    331