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