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