]> git.sur5r.net Git - u-boot/blob - board/renesas/sh7785lcr/rtl8169_mac.c
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / board / renesas / sh7785lcr / rtl8169_mac.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@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 );