1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#define _PPC_STRING_H_
22
23#include <common.h>
24#include <exports.h>
25
26static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr);
27
28int eepro100_eeprom(int argc, char * const argv[])
29{
30 int ret = 0;
31
32 unsigned char hwaddr1[6] = { 0x00, 0x00, 0x02, 0x03, 0x04, 0x05 };
33 unsigned char hwaddr2[6] = { 0x00, 0x00, 0x02, 0x03, 0x04, 0x06 };
34
35 app_startup(argv);
36
37#if defined(CONFIG_OXC)
38 ret |= reset_eeprom(0x80000000, hwaddr1);
39 ret |= reset_eeprom(0x81000000, hwaddr2);
40#endif
41
42 return ret;
43}
44
45
46static unsigned short default_eeprom[64] = {
47 0x0100, 0x0302, 0x0504, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
48 0xffff, 0xffff, 0x40c0, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
49 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
50 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
51 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
52 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
53 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
54 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
55};
56
57static unsigned short eeprom[256];
58
59static int eeprom_size = 64;
60static int eeprom_addr_size = 6;
61
62static int debug = 0;
63
64static inline unsigned short swap16(unsigned short x)
65{
66 return (((x & 0xff) << 8) | ((x & 0xff00) >> 8));
67}
68
69static inline void outw(short data, long addr)
70{
71 *(volatile short *)(addr) = swap16(data);
72}
73
74static inline short inw(long addr)
75{
76 return swap16(*(volatile short *)(addr));
77}
78
79void *memcpy(void *dst, const void *src, unsigned int len)
80{
81 char *ret = dst;
82 while (len-- > 0) {
83 *ret++ = *((char *)src);
84 src++;
85 }
86 return (void *)ret;
87}
88
89
90#define EE_WRITE_CMD (5)
91#define EE_READ_CMD (6)
92#define EE_ERASE_CMD (7)
93
94
95#define EE_SHIFT_CLK 0x01
96#define EE_CS 0x02
97#define EE_DATA_WRITE 0x04
98#define EE_DATA_READ 0x08
99#define EE_ENB (0x4800 | EE_CS)
100#define EE_WRITE_0 0x4802
101#define EE_WRITE_1 0x4806
102#define EE_OFFSET 14
103
104
105#define eeprom_delay(ee_addr) inw(ee_addr)
106
107
108static int eeprom_busy_poll(long ee_ioaddr)
109{
110 int i;
111 outw(EE_ENB, ee_ioaddr);
112 for (i = 0; i < 10000; i++)
113 if (inw(ee_ioaddr) & EE_DATA_READ)
114 break;
115 return i;
116}
117
118
119
120
121static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
122{
123 unsigned retval = 0;
124 long ee_addr = ioaddr + EE_OFFSET;
125
126 if (debug > 1)
127 printf(" EEPROM op 0x%x: ", cmd);
128
129 outw(EE_ENB | EE_SHIFT_CLK, ee_addr);
130
131
132 do {
133 short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
134 outw(dataval, ee_addr);
135 eeprom_delay(ee_addr);
136 if (debug > 2)
137 printf("%X", inw(ee_addr) & 15);
138 outw(dataval | EE_SHIFT_CLK, ee_addr);
139 eeprom_delay(ee_addr);
140 retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
141 } while (--cmd_len >= 0);
142#if 0
143 outw(EE_ENB, ee_addr);
144#endif
145
146 outw(EE_ENB & ~EE_CS, ee_addr);
147 if (debug > 1)
148 printf(" EEPROM result is 0x%5.5x.\n", retval);
149 return retval;
150}
151
152static int read_eeprom(long ioaddr, int location, int addr_len)
153{
154 return do_eeprom_cmd(ioaddr, ((EE_READ_CMD << addr_len) | location)
155 << 16 , 3 + addr_len + 16) & 0xffff;
156}
157
158static void write_eeprom(long ioaddr, int index, int value, int addr_len)
159{
160 long ee_ioaddr = ioaddr + EE_OFFSET;
161 int i;
162
163
164 eeprom_busy_poll(ee_ioaddr);
165
166 do_eeprom_cmd(ioaddr, (0x4f << (addr_len-4)), 3 + addr_len);
167
168 do_eeprom_cmd(ioaddr,
169 (((EE_WRITE_CMD<<addr_len) | index)<<16) | (value & 0xffff),
170 3 + addr_len + 16);
171
172 i = eeprom_busy_poll(ee_ioaddr);
173 if (debug)
174 printf(" Write finished after %d ticks.\n", i);
175
176
177 do_eeprom_cmd(ioaddr, (0x40 << (addr_len-4)), 3 + addr_len);
178 eeprom_busy_poll(ee_ioaddr);
179}
180
181static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr)
182{
183 unsigned short checksum = 0;
184 int size_test;
185 int i;
186
187 printf("Resetting i82559 EEPROM @ 0x%08lX ... ", ioaddr);
188
189 size_test = do_eeprom_cmd(ioaddr, (EE_READ_CMD << 8) << 16, 27);
190 eeprom_addr_size = (size_test & 0xffe0000) == 0xffe0000 ? 8 : 6;
191 eeprom_size = 1 << eeprom_addr_size;
192
193 memcpy(eeprom, default_eeprom, sizeof default_eeprom);
194
195 for (i = 0; i < 3; i++)
196 eeprom[i] = (hwaddr[i*2+1]<<8) + hwaddr[i*2];
197
198
199 for (i = 0; i < eeprom_size - 1; i++)
200 checksum += eeprom[i];
201 eeprom[i] = 0xBABA - checksum;
202
203 for (i = 0; i < eeprom_size; i++)
204 write_eeprom(ioaddr, i, eeprom[i], eeprom_addr_size);
205
206 for (i = 0; i < eeprom_size; i++)
207 if (read_eeprom(ioaddr, i, eeprom_addr_size) != eeprom[i]) {
208 printf("failed\n");
209 return 1;
210 }
211
212 printf("done\n");
213 return 0;
214}
215