3 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5 * SPDX-License-Identifier: GPL-2.0+
9 * Configuration support for Xilinx Spartan3 devices. Based
10 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
13 #include <common.h> /* core U-Boot definitions */
14 #include <spartan3.h> /* Spartan-II device family */
16 /* Define FPGA_DEBUG to get debug printf's */
18 #define PRINTF(fmt,args...) printf (fmt ,##args)
20 #define PRINTF(fmt,args...)
23 #undef CONFIG_SYS_FPGA_CHECK_BUSY
25 /* Note: The assumption is that we cannot possibly run fast enough to
26 * overrun the device (the Slave Parallel mode can free run at 50MHz).
27 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
28 * the board config file to slow things down.
30 #ifndef CONFIG_FPGA_DELAY
31 #define CONFIG_FPGA_DELAY()
34 #ifndef CONFIG_SYS_FPGA_WAIT
35 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
38 static int Spartan3_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize);
39 static int Spartan3_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
40 /* static int Spartan3_sp_info(Xilinx_desc *desc ); */
42 static int Spartan3_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize);
43 static int Spartan3_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
44 /* static int Spartan3_ss_info(Xilinx_desc *desc); */
46 /* ------------------------------------------------------------------------- */
47 /* Spartan-II Generic Implementation */
48 int Spartan3_load(Xilinx_desc *desc, const void *buf, size_t bsize)
50 int ret_val = FPGA_FAIL;
52 switch (desc->iface) {
54 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
55 ret_val = Spartan3_ss_load (desc, buf, bsize);
59 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
60 ret_val = Spartan3_sp_load (desc, buf, bsize);
64 printf ("%s: Unsupported interface type, %d\n",
65 __FUNCTION__, desc->iface);
71 int Spartan3_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
73 int ret_val = FPGA_FAIL;
75 switch (desc->iface) {
77 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
78 ret_val = Spartan3_ss_dump (desc, buf, bsize);
82 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
83 ret_val = Spartan3_sp_dump (desc, buf, bsize);
87 printf ("%s: Unsupported interface type, %d\n",
88 __FUNCTION__, desc->iface);
94 int Spartan3_info( Xilinx_desc *desc )
100 /* ------------------------------------------------------------------------- */
101 /* Spartan-II Slave Parallel Generic Implementation */
103 static int Spartan3_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize)
105 int ret_val = FPGA_FAIL; /* assume the worst */
106 Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
108 PRINTF ("%s: start with interface functions @ 0x%p\n",
112 size_t bytecount = 0;
113 unsigned char *data = (unsigned char *) buf;
114 int cookie = desc->cookie; /* make a local copy */
115 unsigned long ts; /* timestamp */
117 PRINTF ("%s: Function Table:\n"
128 "write data:\t0x%p\n"
132 __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
133 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
134 fn->abort, fn->post);
137 * This code is designed to emulate the "Express Style"
138 * Continuous Data Loading in Slave Parallel Mode for
139 * the Spartan-II Family.
141 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
142 printf ("Loading FPGA Device %d...\n", cookie);
145 * Run the pre configuration function if there is one.
151 /* Establish the initial state */
152 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
154 /* Get ready for the burn */
155 CONFIG_FPGA_DELAY ();
156 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
158 ts = get_timer (0); /* get current time */
159 /* Now wait for INIT and BUSY to go high */
161 CONFIG_FPGA_DELAY ();
162 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
163 puts ("** Timeout waiting for INIT to clear.\n");
164 (*fn->abort) (cookie); /* abort the burn */
167 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
169 (*fn->wr) (true, true, cookie); /* Assert write, commit */
170 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
171 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
174 while (bytecount < bsize) {
175 /* XXX - do we check for an Ctrl-C press in here ??? */
176 /* XXX - Check the error bit? */
178 (*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
179 CONFIG_FPGA_DELAY ();
180 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
181 CONFIG_FPGA_DELAY ();
182 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
184 #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
185 ts = get_timer (0); /* get current time */
186 while ((*fn->busy) (cookie)) {
187 /* XXX - we should have a check in here somewhere to
188 * make sure we aren't busy forever... */
190 CONFIG_FPGA_DELAY ();
191 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
192 CONFIG_FPGA_DELAY ();
193 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
195 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
196 puts ("** Timeout waiting for BUSY to clear.\n");
197 (*fn->abort) (cookie); /* abort the burn */
203 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
204 if (bytecount % (bsize / 40) == 0)
205 putc ('.'); /* let them know we are alive */
209 CONFIG_FPGA_DELAY ();
210 (*fn->cs) (false, true, cookie); /* Deassert the chip select */
211 (*fn->wr) (false, true, cookie); /* Deassert the write pin */
213 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
214 putc ('\n'); /* terminate the dotted line */
217 /* now check for done signal */
218 ts = get_timer (0); /* get current time */
219 ret_val = FPGA_SUCCESS;
220 while ((*fn->done) (cookie) == FPGA_FAIL) {
221 /* XXX - we should have a check in here somewhere to
222 * make sure we aren't busy forever... */
224 CONFIG_FPGA_DELAY ();
225 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
226 CONFIG_FPGA_DELAY ();
227 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
229 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
230 puts ("** Timeout waiting for DONE to clear.\n");
231 (*fn->abort) (cookie); /* abort the burn */
238 * Run the post configuration function if there is one.
241 (*fn->post) (cookie);
243 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
244 if (ret_val == FPGA_SUCCESS)
251 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
257 static int Spartan3_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
259 int ret_val = FPGA_FAIL; /* assume the worst */
260 Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
263 unsigned char *data = (unsigned char *) buf;
264 size_t bytecount = 0;
265 int cookie = desc->cookie; /* make a local copy */
267 printf ("Starting Dump of FPGA Device %d...\n", cookie);
269 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
270 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
273 while (bytecount < bsize) {
274 /* XXX - do we check for an Ctrl-C press in here ??? */
276 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
277 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
278 (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
279 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
280 if (bytecount % (bsize / 40) == 0)
281 putc ('.'); /* let them know we are alive */
285 (*fn->cs) (false, false, cookie); /* Deassert the chip select */
286 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
287 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
289 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
290 putc ('\n'); /* terminate the dotted line */
294 /* XXX - checksum the data? */
296 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
303 /* ------------------------------------------------------------------------- */
305 static int Spartan3_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize)
307 int ret_val = FPGA_FAIL; /* assume the worst */
308 Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns;
312 PRINTF ("%s: start with interface functions @ 0x%p\n",
316 size_t bytecount = 0;
317 unsigned char *data = (unsigned char *) buf;
318 int cookie = desc->cookie; /* make a local copy */
319 unsigned long ts; /* timestamp */
321 PRINTF ("%s: Function Table:\n"
329 __FUNCTION__, &fn, fn, fn->pgm, fn->init,
330 fn->clk, fn->wr, fn->done);
331 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
332 printf ("Loading FPGA Device %d...\n", cookie);
336 * Run the pre configuration function if there is one.
342 /* Establish the initial state */
343 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
345 /* Wait for INIT state (init low) */
346 ts = get_timer (0); /* get current time */
348 CONFIG_FPGA_DELAY ();
349 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
350 puts ("** Timeout waiting for INIT to start.\n");
352 (*fn->abort) (cookie);
355 } while (!(*fn->init) (cookie));
357 /* Get ready for the burn */
358 CONFIG_FPGA_DELAY ();
359 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
361 ts = get_timer (0); /* get current time */
362 /* Now wait for INIT to go high */
364 CONFIG_FPGA_DELAY ();
365 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
366 puts ("** Timeout waiting for INIT to clear.\n");
368 (*fn->abort) (cookie);
371 } while ((*fn->init) (cookie));
375 (*fn->bwr) (data, bsize, true, cookie);
377 while (bytecount < bsize) {
379 /* Xilinx detects an error if INIT goes low (active)
380 while DONE is low (inactive) */
381 if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
382 puts ("** CRC error during FPGA load.\n");
384 (*fn->abort) (cookie);
387 val = data [bytecount ++];
390 /* Deassert the clock */
391 (*fn->clk) (false, true, cookie);
392 CONFIG_FPGA_DELAY ();
394 (*fn->wr) ((val & 0x80), true, cookie);
395 CONFIG_FPGA_DELAY ();
396 /* Assert the clock */
397 (*fn->clk) (true, true, cookie);
398 CONFIG_FPGA_DELAY ();
403 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
404 if (bytecount % (bsize / 40) == 0)
405 putc ('.'); /* let them know we are alive */
410 CONFIG_FPGA_DELAY ();
412 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
413 putc ('\n'); /* terminate the dotted line */
416 /* now check for done signal */
417 ts = get_timer (0); /* get current time */
418 ret_val = FPGA_SUCCESS;
419 (*fn->wr) (true, true, cookie);
421 while (! (*fn->done) (cookie)) {
422 /* XXX - we should have a check in here somewhere to
423 * make sure we aren't busy forever... */
425 CONFIG_FPGA_DELAY ();
426 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
427 CONFIG_FPGA_DELAY ();
428 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
432 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
433 puts ("** Timeout waiting for DONE to clear.\n");
438 putc ('\n'); /* terminate the dotted line */
441 * Run the post configuration function if there is one.
444 (*fn->post) (cookie);
446 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
447 if (ret_val == FPGA_SUCCESS)
454 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
460 static int Spartan3_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
462 /* Readback is only available through the Slave Parallel and */
463 /* boundary-scan interfaces. */
464 printf ("%s: Slave Serial Dumping is unavailable\n",