1
2
3
4
5
6
7
8
9#include <config.h>
10#include <common.h>
11#include "w7o.h"
12#include <asm/processor.h>
13#include <linux/compiler.h>
14#include "errors.h"
15
16static void
17fpga_img_write(unsigned long *src, unsigned long len, unsigned short *daddr)
18{
19 unsigned long i;
20 volatile unsigned long val;
21 volatile unsigned short *dest = daddr;
22
23 for (i = 0; i < len; i++, src++) {
24 val = *src;
25 *dest = (unsigned short) ((val & 0xff000000L) >> 16);
26 *dest = (unsigned short) ((val & 0x00ff0000L) >> 8);
27 *dest = (unsigned short) (val & 0x0000ff00L);
28 *dest = (unsigned short) ((val & 0x000000ffL) << 8);
29 }
30
31
32 dest = daddr;
33 val = *(unsigned short *) dest;
34 val = *(unsigned short *) dest;
35 val = *(unsigned short *) dest;
36 val = *(unsigned short *) dest;
37
38}
39
40
41int
42fpgaDownload(unsigned char *saddr, unsigned long size, unsigned short *daddr)
43{
44 int i;
45 int start;
46 unsigned long greg, grego;
47 unsigned long length;
48 unsigned long *source;
49 unsigned short *dest;
50 volatile unsigned short *ndest;
51 unsigned long cnfg = GPIO_XCV_CNFG;
52 unsigned long eirq = GPIO_XCV_IRQ;
53 int retval = -1;
54 __maybe_unused volatile unsigned short val;
55
56
57 length = (size / 4) + 1;
58
59 source = (unsigned long *) saddr;
60 dest = (unsigned short *) daddr;
61
62
63 grego = in32(PPC405GP_GPIO0_OR);
64
65
66 grego &= ~GPIO_XCV_PROG;
67 out32(PPC405GP_GPIO0_OR, grego);
68
69
70 start = get_timer(0);
71
72
73 while (in32(PPC405GP_GPIO0_IR) & GPIO_XCV_INIT) {
74
75 if (get_timer(start) > 3) {
76 printf(" failed to start init.\n");
77 log_warn(ERR_XINIT0);
78
79
80 goto done;
81 }
82 }
83
84
85 grego |= GPIO_XCV_PROG;
86 out32(PPC405GP_GPIO0_OR, grego);
87
88
89 while (!(in32(PPC405GP_GPIO0_IR) & GPIO_XCV_INIT)) {
90
91
92 if (get_timer(start) > 3) {
93 printf(" failed to exit init.\n");
94 log_warn(ERR_XINIT1);
95
96
97 grego &= ~GPIO_XCV_PROG;
98 out32(PPC405GP_GPIO0_OR, grego);
99
100 goto done;
101 }
102 }
103
104
105 ndest = dest;
106 for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
107
108 greg = mfdcr(CPC0_CR0);
109 greg |= eirq;
110 mtdcr(CPC0_CR0, greg);
111
112
113 greg = in32(PPC405GP_GPIO0_ODR);
114 greg |= cnfg;
115 out32(PPC405GP_GPIO0_ODR, greg);
116
117
118 greg = in32(PPC405GP_GPIO0_TCR);
119 greg |= cnfg;
120 out32(PPC405GP_GPIO0_TCR, greg);
121
122
123 grego &= ~cnfg;
124 out32(PPC405GP_GPIO0_OR, grego);
125
126
127
128
129 printf("\n destination: 0x%lx ", (unsigned long) ndest);
130
131 fpga_img_write(source, length, (unsigned short *) ndest);
132
133
134 grego |= cnfg;
135 out32(PPC405GP_GPIO0_OR, grego);
136
137
138 greg = in32(PPC405GP_GPIO0_TCR);
139 greg &= ~cnfg;
140 out32(PPC405GP_GPIO0_TCR, greg);
141
142
143 greg = mfdcr(CPC0_CR0);
144 greg &= ~eirq;
145 mtdcr(CPC0_CR0, greg);
146
147
148 ndest = (unsigned short *) ((char *) ndest + 0x00100000L);
149 cnfg >>= 1;
150 eirq >>= 1;
151 }
152
153
154 ndest = dest;
155 for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
156 val = *ndest;
157 val = *ndest;
158 val = *ndest;
159 val = *ndest;
160 ndest = (unsigned short *) ((char *) ndest + 0x00100000L);
161 }
162
163
164 start = get_timer(0);
165
166
167 while (!(in32(PPC405GP_GPIO0_IR) & GPIO_XCV_DONE)) {
168
169
170 if (get_timer(start) > 3) {
171 printf(" done failed to come high.\n");
172 log_warn(ERR_XDONE1);
173
174
175 grego &= ~GPIO_XCV_PROG;
176 out32(PPC405GP_GPIO0_OR, grego);
177
178 goto done;
179 }
180 }
181
182 printf("\n FPGA load succeeded\n");
183 retval = 0;
184
185done:
186 return retval;
187}
188
189
190extern flash_info_t flash_info[];
191
192int init_fpga(void)
193{
194 unsigned int i, j, ptr;
195 unsigned char bufchar;
196 unsigned char *buf;
197 unsigned long len;
198 unsigned char *fn_buf;
199 unsigned int fn_len;
200 unsigned char *xcv_buf;
201 unsigned long xcv_len;
202 unsigned long crc;
203 unsigned long calc_crc;
204 int retval = -1;
205
206
207 printf("FPGA: ");
208
209
210
211
212
213 buf = (unsigned char *) flash_info[1].start[0];
214
215
216
217
218 crc = *(unsigned long *) (buf + 4);
219 len = *(unsigned long *) (buf + 8);
220
221
222 if ((len < 0x133A4) || (len > 0x80000))
223 goto bad_image;
224
225
226
227
228
229 fn_len = (*(unsigned short *) (buf + 12) & 0xff);
230 fn_buf = buf + 14;
231
232
233
234
235 xcv_buf = fn_buf + fn_len;
236 xcv_len = len - 14 - fn_len;
237
238
239 if ((strncmp((char *) buf, "w7o", 3) != 0) || (len > 0x0007ffffL)
240 || (len == 0))
241 goto bad_image;
242
243
244
245
246 calc_crc = crc32(0, xcv_buf, xcv_len);
247 if (crc != calc_crc) {
248 printf("\nfailed - bad CRC\n");
249 goto done;
250 }
251
252
253 printf("file name : ");
254 for (i = 0; i < fn_len; i++) {
255 bufchar = fn_buf[+i];
256 if (bufchar < ' ' || bufchar > '~')
257 bufchar = '.';
258 putc(bufchar);
259 }
260
261
262
263
264 ptr = 15;
265
266 j = xcv_buf[ptr];
267 if (j > 32)
268 goto bad_image;
269 ptr = ptr + j + 3;
270
271
272
273
274
275 j = xcv_buf[ptr++] - 1;
276 if (j > 32)
277 goto bad_image;
278 printf("\n target : ");
279 for (i = 0; i < j; i++) {
280 bufchar = (xcv_buf[ptr++]);
281 if (bufchar < ' ' || bufchar > '~')
282 bufchar = '.';
283 putc(bufchar);
284 }
285
286
287
288
289 ptr += 3;
290 printf("\n synth time : ");
291 j = (xcv_buf[ptr++] - 1);
292 if (j > 32)
293 goto bad_image;
294 for (i = 0; i < j; i++) {
295 bufchar = (xcv_buf[ptr++]);
296 if (bufchar < ' ' || bufchar > '~')
297 bufchar = '.';
298 putc(bufchar);
299 }
300
301 ptr += 3;
302 printf(" - ");
303 j = (xcv_buf[ptr++] - 1);
304 if (j > 32)
305 goto bad_image;
306 for (i = 0; i < j; i++) {
307 bufchar = (xcv_buf[ptr++]);
308 if (bufchar < ' ' || bufchar > '~')
309 bufchar = '.';
310 putc(bufchar);
311 }
312
313
314
315
316 printf("\n len & crc : 0x%lx 0x%lx", len, crc);
317
318
319
320
321 retval = fpgaDownload((unsigned char *) xcv_buf, xcv_len,
322 (unsigned short *) 0xfd000000L);
323 return retval;
324
325bad_image:
326 printf("\n BAD FPGA image format @ %lx\n",
327 flash_info[1].start[0]);
328 log_warn(ERR_XIMAGE);
329done:
330 return retval;
331}
332
333void test_fpga(unsigned short *daddr)
334{
335 int i;
336 volatile unsigned short *ndest = daddr;
337
338 for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
339#if defined(CONFIG_W7OLMG)
340 ndest[0x7e] = 0x55aa;
341 if (ndest[0x7e] != 0x55aa)
342 log_warn(ERR_XRW1 + i);
343 ndest[0x7e] = 0xaa55;
344 if (ndest[0x7e] != 0xaa55)
345 log_warn(ERR_XRW1 + i);
346 ndest[0x7e] = 0xc318;
347 if (ndest[0x7e] != 0xc318)
348 log_warn(ERR_XRW1 + i);
349
350#elif defined(CONFIG_W7OLMC)
351 ndest[0x800] = 0x55aa;
352 ndest[0x801] = 0xaa55;
353 ndest[0x802] = 0xc318;
354 ndest[0x4800] = 0x55aa;
355 ndest[0x4801] = 0xaa55;
356 ndest[0x4802] = 0xc318;
357 if ((ndest[0x800] != 0x55aa) ||
358 (ndest[0x801] != 0xaa55) || (ndest[0x802] != 0xc318))
359 log_warn(ERR_XRW1 + (2 * i));
360 if ((ndest[0x4800] != 0x55aa) ||
361 (ndest[0x4801] != 0xaa55) || (ndest[0x4802] != 0xc318))
362 log_warn(ERR_XRW2 + (2 * i));
363
364#else
365#error "Unknown W7O board configuration"
366#endif
367 }
368
369 printf(" FPGA ready\n");
370 return;
371}
372