1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2002
4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5 */
6
7 /*
8 * Configuration support for Xilinx Spartan3 devices. Based
9 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
10 */
11
12 #define LOG_CATEGORY UCLASS_FPGA
13
14 #include <common.h> /* core U-Boot definitions */
15 #include <log.h>
16 #include <spartan3.h> /* Spartan-II device family */
17
18 /* Note: The assumption is that we cannot possibly run fast enough to
19 * overrun the device (the Slave Parallel mode can free run at 50MHz).
20 * If there is a need to operate slower, define CFG_FPGA_DELAY in
21 * the board config file to slow things down.
22 */
23 #ifndef CFG_FPGA_DELAY
24 #define CFG_FPGA_DELAY()
25 #endif
26
27 #ifndef CFG_SYS_FPGA_WAIT
28 #define CFG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
29 #endif
30
31 static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
32 static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
33 /* static int spartan3_sp_info(xilinx_desc *desc ); */
34
35 static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
36 static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
37 /* static int spartan3_ss_info(xilinx_desc *desc); */
38
39 /* ------------------------------------------------------------------------- */
40 /* Spartan-II Generic Implementation */
spartan3_load(xilinx_desc * desc,const void * buf,size_t bsize,bitstream_type bstype,int flags)41 static int spartan3_load(xilinx_desc *desc, const void *buf, size_t bsize,
42 bitstream_type bstype, int flags)
43 {
44 int ret_val = FPGA_FAIL;
45
46 switch (desc->iface) {
47 case slave_serial:
48 log_debug("Launching Slave Serial Load\n");
49 ret_val = spartan3_ss_load(desc, buf, bsize);
50 break;
51
52 case slave_parallel:
53 log_debug("Launching Slave Parallel Load\n");
54 ret_val = spartan3_sp_load(desc, buf, bsize);
55 break;
56
57 default:
58 printf ("%s: Unsupported interface type, %d\n",
59 __FUNCTION__, desc->iface);
60 }
61
62 return ret_val;
63 }
64
spartan3_dump(xilinx_desc * desc,const void * buf,size_t bsize)65 static int spartan3_dump(xilinx_desc *desc, const void *buf, size_t bsize)
66 {
67 int ret_val = FPGA_FAIL;
68
69 switch (desc->iface) {
70 case slave_serial:
71 log_debug("Launching Slave Serial Dump\n");
72 ret_val = spartan3_ss_dump(desc, buf, bsize);
73 break;
74
75 case slave_parallel:
76 log_debug("Launching Slave Parallel Dump\n");
77 ret_val = spartan3_sp_dump(desc, buf, bsize);
78 break;
79
80 default:
81 printf ("%s: Unsupported interface type, %d\n",
82 __FUNCTION__, desc->iface);
83 }
84
85 return ret_val;
86 }
87
spartan3_info(xilinx_desc * desc)88 static int spartan3_info(xilinx_desc *desc)
89 {
90 return FPGA_SUCCESS;
91 }
92
93
94 /* ------------------------------------------------------------------------- */
95 /* Spartan-II Slave Parallel Generic Implementation */
96
spartan3_sp_load(xilinx_desc * desc,const void * buf,size_t bsize)97 static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize)
98 {
99 int ret_val = FPGA_FAIL; /* assume the worst */
100 xilinx_spartan3_slave_parallel_fns *fn = desc->iface_fns;
101
102 log_debug("start with interface functions @ 0x%p\n", fn);
103
104 if (fn) {
105 size_t bytecount = 0;
106 unsigned char *data = (unsigned char *) buf;
107 int cookie = desc->cookie; /* make a local copy */
108 unsigned long ts; /* timestamp */
109
110 log_debug("Function Table:\n"
111 "ptr:\t0x%p\n"
112 "struct: 0x%p\n"
113 "pre: 0x%p\n"
114 "pgm:\t0x%p\n"
115 "init:\t0x%p\n"
116 "err:\t0x%p\n"
117 "clk:\t0x%p\n"
118 "cs:\t0x%p\n"
119 "wr:\t0x%p\n"
120 "read data:\t0x%p\n"
121 "write data:\t0x%p\n"
122 "busy:\t0x%p\n"
123 "abort:\t0x%p\n"
124 "post:\t0x%p\n\n",
125 &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
126 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
127 fn->abort, fn->post);
128
129 /*
130 * This code is designed to emulate the "Express Style"
131 * Continuous Data Loading in Slave Parallel Mode for
132 * the Spartan-II Family.
133 */
134 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
135 printf ("Loading FPGA Device %d...\n", cookie);
136 #endif
137 /*
138 * Run the pre configuration function if there is one.
139 */
140 if (*fn->pre) {
141 (*fn->pre) (cookie);
142 }
143
144 /* Establish the initial state */
145 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
146
147 /* Get ready for the burn */
148 CFG_FPGA_DELAY ();
149 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
150
151 ts = get_timer (0); /* get current time */
152 /* Now wait for INIT and BUSY to go high */
153 do {
154 CFG_FPGA_DELAY ();
155 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
156 puts ("** Timeout waiting for INIT to clear.\n");
157 (*fn->abort) (cookie); /* abort the burn */
158 return FPGA_FAIL;
159 }
160 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
161
162 (*fn->wr) (true, true, cookie); /* Assert write, commit */
163 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
164 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
165
166 /* Load the data */
167 while (bytecount < bsize) {
168 /* XXX - do we check for an Ctrl-C press in here ??? */
169 /* XXX - Check the error bit? */
170
171 (*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
172 CFG_FPGA_DELAY ();
173 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
174 CFG_FPGA_DELAY ();
175 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
176
177 #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
178 ts = get_timer (0); /* get current time */
179 while ((*fn->busy) (cookie)) {
180 /* XXX - we should have a check in here somewhere to
181 * make sure we aren't busy forever... */
182
183 CFG_FPGA_DELAY ();
184 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
185 CFG_FPGA_DELAY ();
186 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
187
188 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
189 puts ("** Timeout waiting for BUSY to clear.\n");
190 (*fn->abort) (cookie); /* abort the burn */
191 return FPGA_FAIL;
192 }
193 }
194 #endif
195
196 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
197 if (bytecount % (bsize / 40) == 0)
198 putc ('.'); /* let them know we are alive */
199 #endif
200 }
201
202 CFG_FPGA_DELAY ();
203 (*fn->cs) (false, true, cookie); /* Deassert the chip select */
204 (*fn->wr) (false, true, cookie); /* Deassert the write pin */
205
206 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
207 putc ('\n'); /* terminate the dotted line */
208 #endif
209
210 /* now check for done signal */
211 ts = get_timer (0); /* get current time */
212 ret_val = FPGA_SUCCESS;
213 while ((*fn->done) (cookie) == FPGA_FAIL) {
214 /* XXX - we should have a check in here somewhere to
215 * make sure we aren't busy forever... */
216
217 CFG_FPGA_DELAY ();
218 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
219 CFG_FPGA_DELAY ();
220 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
221
222 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
223 puts ("** Timeout waiting for DONE to clear.\n");
224 (*fn->abort) (cookie); /* abort the burn */
225 ret_val = FPGA_FAIL;
226 break;
227 }
228 }
229
230 /*
231 * Run the post configuration function if there is one.
232 */
233 if (*fn->post)
234 (*fn->post) (cookie);
235
236 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
237 if (ret_val == FPGA_SUCCESS)
238 puts ("Done.\n");
239 else
240 puts ("Fail.\n");
241 #endif
242
243 } else {
244 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
245 }
246
247 return ret_val;
248 }
249
spartan3_sp_dump(xilinx_desc * desc,const void * buf,size_t bsize)250 static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize)
251 {
252 int ret_val = FPGA_FAIL; /* assume the worst */
253 xilinx_spartan3_slave_parallel_fns *fn = desc->iface_fns;
254
255 if (fn) {
256 unsigned char *data = (unsigned char *) buf;
257 size_t bytecount = 0;
258 int cookie = desc->cookie; /* make a local copy */
259
260 printf ("Starting Dump of FPGA Device %d...\n", cookie);
261
262 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
263 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
264
265 /* dump the data */
266 while (bytecount < bsize) {
267 /* XXX - do we check for an Ctrl-C press in here ??? */
268
269 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
270 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
271 (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
272 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
273 if (bytecount % (bsize / 40) == 0)
274 putc ('.'); /* let them know we are alive */
275 #endif
276 }
277
278 (*fn->cs) (false, false, cookie); /* Deassert the chip select */
279 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
280 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
281
282 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
283 putc ('\n'); /* terminate the dotted line */
284 #endif
285 puts ("Done.\n");
286
287 /* XXX - checksum the data? */
288 } else {
289 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
290 }
291
292 return ret_val;
293 }
294
295
296 /* ------------------------------------------------------------------------- */
297
spartan3_ss_load(xilinx_desc * desc,const void * buf,size_t bsize)298 static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
299 {
300 int ret_val = FPGA_FAIL; /* assume the worst */
301 xilinx_spartan3_slave_serial_fns *fn = desc->iface_fns;
302 int i;
303 unsigned char val;
304
305 log_debug("start with interface functions @ 0x%p\n", fn);
306
307 if (fn) {
308 size_t bytecount = 0;
309 unsigned char *data = (unsigned char *) buf;
310 int cookie = desc->cookie; /* make a local copy */
311 unsigned long ts; /* timestamp */
312
313 log_debug("Function Table:\n"
314 "ptr:\t0x%p\n"
315 "struct: 0x%p\n"
316 "pgm:\t0x%p\n"
317 "init:\t0x%p\n"
318 "clk:\t0x%p\n"
319 "wr:\t0x%p\n"
320 "done:\t0x%p\n\n",
321 &fn, fn, fn->pgm, fn->init,
322 fn->clk, fn->wr, fn->done);
323 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
324 printf ("Loading FPGA Device %d...\n", cookie);
325 #endif
326
327 /*
328 * Run the pre configuration function if there is one.
329 */
330 if (*fn->pre) {
331 (*fn->pre) (cookie);
332 }
333
334 /* Establish the initial state */
335 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
336
337 /* Wait for INIT state (init low) */
338 ts = get_timer (0); /* get current time */
339 do {
340 CFG_FPGA_DELAY ();
341 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
342 puts ("** Timeout waiting for INIT to start.\n");
343 if (*fn->abort)
344 (*fn->abort) (cookie);
345 return FPGA_FAIL;
346 }
347 } while (!(*fn->init) (cookie));
348
349 /* Get ready for the burn */
350 CFG_FPGA_DELAY ();
351 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
352
353 ts = get_timer (0); /* get current time */
354 /* Now wait for INIT to go high */
355 do {
356 CFG_FPGA_DELAY ();
357 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
358 puts ("** Timeout waiting for INIT to clear.\n");
359 if (*fn->abort)
360 (*fn->abort) (cookie);
361 return FPGA_FAIL;
362 }
363 } while ((*fn->init) (cookie));
364
365 /* Load the data */
366 if(*fn->bwr)
367 (*fn->bwr) (data, bsize, true, cookie);
368 else {
369 while (bytecount < bsize) {
370
371 /* Xilinx detects an error if INIT goes low (active)
372 while DONE is low (inactive) */
373 if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
374 puts ("** CRC error during FPGA load.\n");
375 if (*fn->abort)
376 (*fn->abort) (cookie);
377 return (FPGA_FAIL);
378 }
379 val = data [bytecount ++];
380 i = 8;
381 do {
382 /* Deassert the clock */
383 (*fn->clk) (false, true, cookie);
384 CFG_FPGA_DELAY ();
385 /* Write data */
386 (*fn->wr) ((val & 0x80), true, cookie);
387 CFG_FPGA_DELAY ();
388 /* Assert the clock */
389 (*fn->clk) (true, true, cookie);
390 CFG_FPGA_DELAY ();
391 val <<= 1;
392 i --;
393 } while (i > 0);
394
395 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
396 if (bytecount % (bsize / 40) == 0)
397 putc ('.'); /* let them know we are alive */
398 #endif
399 }
400 }
401
402 CFG_FPGA_DELAY ();
403
404 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
405 putc ('\n'); /* terminate the dotted line */
406 #endif
407
408 /* now check for done signal */
409 ts = get_timer (0); /* get current time */
410 ret_val = FPGA_SUCCESS;
411 (*fn->wr) (true, true, cookie);
412
413 while (! (*fn->done) (cookie)) {
414 /* XXX - we should have a check in here somewhere to
415 * make sure we aren't busy forever... */
416
417 CFG_FPGA_DELAY ();
418 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
419 CFG_FPGA_DELAY ();
420 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
421
422 putc ('*');
423
424 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
425 puts ("** Timeout waiting for DONE to clear.\n");
426 ret_val = FPGA_FAIL;
427 break;
428 }
429 }
430 putc ('\n'); /* terminate the dotted line */
431
432 /*
433 * Run the post configuration function if there is one.
434 */
435 if (*fn->post)
436 (*fn->post) (cookie);
437
438 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
439 if (ret_val == FPGA_SUCCESS)
440 puts ("Done.\n");
441 else
442 puts ("Fail.\n");
443 #endif
444
445 } else {
446 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
447 }
448
449 return ret_val;
450 }
451
spartan3_ss_dump(xilinx_desc * desc,const void * buf,size_t bsize)452 static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
453 {
454 /* Readback is only available through the Slave Parallel and */
455 /* boundary-scan interfaces. */
456 printf ("%s: Slave Serial Dumping is unavailable\n",
457 __FUNCTION__);
458 return FPGA_FAIL;
459 }
460
461 struct xilinx_fpga_op spartan3_op = {
462 .load = spartan3_load,
463 .dump = spartan3_dump,
464 .info = spartan3_info,
465 };
466