3 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 * Configuration support for Xilinx Spartan3 devices. Based
27 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
30 #include <common.h> /* core U-Boot definitions */
31 #include <spartan3.h> /* Spartan-II device family */
33 /* Define FPGA_DEBUG to get debug printf's */
35 #define PRINTF(fmt,args...) printf (fmt ,##args)
37 #define PRINTF(fmt,args...)
40 #undef CONFIG_SYS_FPGA_CHECK_BUSY
41 #undef CONFIG_SYS_FPGA_PROG_FEEDBACK
43 /* Note: The assumption is that we cannot possibly run fast enough to
44 * overrun the device (the Slave Parallel mode can free run at 50MHz).
45 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
46 * the board config file to slow things down.
48 #ifndef CONFIG_FPGA_DELAY
49 #define CONFIG_FPGA_DELAY()
52 #ifndef CONFIG_SYS_FPGA_WAIT
53 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
56 static int Spartan3_sp_load( Xilinx_desc
*desc
, void *buf
, size_t bsize
);
57 static int Spartan3_sp_dump( Xilinx_desc
*desc
, void *buf
, size_t bsize
);
58 /* static int Spartan3_sp_info( Xilinx_desc *desc ); */
60 static int Spartan3_ss_load( Xilinx_desc
*desc
, void *buf
, size_t bsize
);
61 static int Spartan3_ss_dump( Xilinx_desc
*desc
, void *buf
, size_t bsize
);
62 /* static int Spartan3_ss_info( Xilinx_desc *desc ); */
64 /* ------------------------------------------------------------------------- */
65 /* Spartan-II Generic Implementation */
66 int Spartan3_load (Xilinx_desc
* desc
, void *buf
, size_t bsize
)
68 int ret_val
= FPGA_FAIL
;
70 switch (desc
->iface
) {
72 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__
);
73 ret_val
= Spartan3_ss_load (desc
, buf
, bsize
);
77 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__
);
78 ret_val
= Spartan3_sp_load (desc
, buf
, bsize
);
82 printf ("%s: Unsupported interface type, %d\n",
83 __FUNCTION__
, desc
->iface
);
89 int Spartan3_dump (Xilinx_desc
* desc
, void *buf
, size_t bsize
)
91 int ret_val
= FPGA_FAIL
;
93 switch (desc
->iface
) {
95 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__
);
96 ret_val
= Spartan3_ss_dump (desc
, buf
, bsize
);
100 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__
);
101 ret_val
= Spartan3_sp_dump (desc
, buf
, bsize
);
105 printf ("%s: Unsupported interface type, %d\n",
106 __FUNCTION__
, desc
->iface
);
112 int Spartan3_info( Xilinx_desc
*desc
)
118 /* ------------------------------------------------------------------------- */
119 /* Spartan-II Slave Parallel Generic Implementation */
121 static int Spartan3_sp_load (Xilinx_desc
* desc
, void *buf
, size_t bsize
)
123 int ret_val
= FPGA_FAIL
; /* assume the worst */
124 Xilinx_Spartan3_Slave_Parallel_fns
*fn
= desc
->iface_fns
;
126 PRINTF ("%s: start with interface functions @ 0x%p\n",
130 size_t bytecount
= 0;
131 unsigned char *data
= (unsigned char *) buf
;
132 int cookie
= desc
->cookie
; /* make a local copy */
133 unsigned long ts
; /* timestamp */
135 PRINTF ("%s: Function Table:\n"
146 "write data:\t0x%p\n"
150 __FUNCTION__
, &fn
, fn
, fn
->pre
, fn
->pgm
, fn
->init
, fn
->err
,
151 fn
->clk
, fn
->cs
, fn
->wr
, fn
->rdata
, fn
->wdata
, fn
->busy
,
152 fn
->abort
, fn
->post
);
155 * This code is designed to emulate the "Express Style"
156 * Continuous Data Loading in Slave Parallel Mode for
157 * the Spartan-II Family.
159 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
160 printf ("Loading FPGA Device %d...\n", cookie
);
163 * Run the pre configuration function if there is one.
169 /* Establish the initial state */
170 (*fn
->pgm
) (TRUE
, TRUE
, cookie
); /* Assert the program, commit */
172 /* Get ready for the burn */
173 CONFIG_FPGA_DELAY ();
174 (*fn
->pgm
) (FALSE
, TRUE
, cookie
); /* Deassert the program, commit */
176 ts
= get_timer (0); /* get current time */
177 /* Now wait for INIT and BUSY to go high */
179 CONFIG_FPGA_DELAY ();
180 if (get_timer (ts
) > CONFIG_SYS_FPGA_WAIT
) { /* check the time */
181 puts ("** Timeout waiting for INIT to clear.\n");
182 (*fn
->abort
) (cookie
); /* abort the burn */
185 } while ((*fn
->init
) (cookie
) && (*fn
->busy
) (cookie
));
187 (*fn
->wr
) (TRUE
, TRUE
, cookie
); /* Assert write, commit */
188 (*fn
->cs
) (TRUE
, TRUE
, cookie
); /* Assert chip select, commit */
189 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
192 while (bytecount
< bsize
) {
193 /* XXX - do we check for an Ctrl-C press in here ??? */
194 /* XXX - Check the error bit? */
196 (*fn
->wdata
) (data
[bytecount
++], TRUE
, cookie
); /* write the data */
197 CONFIG_FPGA_DELAY ();
198 (*fn
->clk
) (FALSE
, TRUE
, cookie
); /* Deassert the clock pin */
199 CONFIG_FPGA_DELAY ();
200 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
202 #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
203 ts
= get_timer (0); /* get current time */
204 while ((*fn
->busy
) (cookie
)) {
205 /* XXX - we should have a check in here somewhere to
206 * make sure we aren't busy forever... */
208 CONFIG_FPGA_DELAY ();
209 (*fn
->clk
) (FALSE
, TRUE
, cookie
); /* Deassert the clock pin */
210 CONFIG_FPGA_DELAY ();
211 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
213 if (get_timer (ts
) > CONFIG_SYS_FPGA_WAIT
) { /* check the time */
214 puts ("** Timeout waiting for BUSY to clear.\n");
215 (*fn
->abort
) (cookie
); /* abort the burn */
221 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
222 if (bytecount
% (bsize
/ 40) == 0)
223 putc ('.'); /* let them know we are alive */
227 CONFIG_FPGA_DELAY ();
228 (*fn
->cs
) (FALSE
, TRUE
, cookie
); /* Deassert the chip select */
229 (*fn
->wr
) (FALSE
, TRUE
, cookie
); /* Deassert the write pin */
231 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
232 putc ('\n'); /* terminate the dotted line */
235 /* now check for done signal */
236 ts
= get_timer (0); /* get current time */
237 ret_val
= FPGA_SUCCESS
;
238 while ((*fn
->done
) (cookie
) == FPGA_FAIL
) {
239 /* XXX - we should have a check in here somewhere to
240 * make sure we aren't busy forever... */
242 CONFIG_FPGA_DELAY ();
243 (*fn
->clk
) (FALSE
, TRUE
, cookie
); /* Deassert the clock pin */
244 CONFIG_FPGA_DELAY ();
245 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
247 if (get_timer (ts
) > CONFIG_SYS_FPGA_WAIT
) { /* check the time */
248 puts ("** Timeout waiting for DONE to clear.\n");
249 (*fn
->abort
) (cookie
); /* abort the burn */
256 * Run the post configuration function if there is one.
259 (*fn
->post
) (cookie
);
261 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
262 if (ret_val
== FPGA_SUCCESS
)
269 printf ("%s: NULL Interface function table!\n", __FUNCTION__
);
275 static int Spartan3_sp_dump (Xilinx_desc
* desc
, void *buf
, size_t bsize
)
277 int ret_val
= FPGA_FAIL
; /* assume the worst */
278 Xilinx_Spartan3_Slave_Parallel_fns
*fn
= desc
->iface_fns
;
281 unsigned char *data
= (unsigned char *) buf
;
282 size_t bytecount
= 0;
283 int cookie
= desc
->cookie
; /* make a local copy */
285 printf ("Starting Dump of FPGA Device %d...\n", cookie
);
287 (*fn
->cs
) (TRUE
, TRUE
, cookie
); /* Assert chip select, commit */
288 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
291 while (bytecount
< bsize
) {
292 /* XXX - do we check for an Ctrl-C press in here ??? */
294 (*fn
->clk
) (FALSE
, TRUE
, cookie
); /* Deassert the clock pin */
295 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
296 (*fn
->rdata
) (&(data
[bytecount
++]), cookie
); /* read the data */
297 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
298 if (bytecount
% (bsize
/ 40) == 0)
299 putc ('.'); /* let them know we are alive */
303 (*fn
->cs
) (FALSE
, FALSE
, cookie
); /* Deassert the chip select */
304 (*fn
->clk
) (FALSE
, TRUE
, cookie
); /* Deassert the clock pin */
305 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
307 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
308 putc ('\n'); /* terminate the dotted line */
312 /* XXX - checksum the data? */
314 printf ("%s: NULL Interface function table!\n", __FUNCTION__
);
321 /* ------------------------------------------------------------------------- */
323 static int Spartan3_ss_load (Xilinx_desc
* desc
, void *buf
, size_t bsize
)
325 int ret_val
= FPGA_FAIL
; /* assume the worst */
326 Xilinx_Spartan3_Slave_Serial_fns
*fn
= desc
->iface_fns
;
330 PRINTF ("%s: start with interface functions @ 0x%p\n",
334 size_t bytecount
= 0;
335 unsigned char *data
= (unsigned char *) buf
;
336 int cookie
= desc
->cookie
; /* make a local copy */
337 unsigned long ts
; /* timestamp */
339 PRINTF ("%s: Function Table:\n"
347 __FUNCTION__
, &fn
, fn
, fn
->pgm
, fn
->init
,
348 fn
->clk
, fn
->wr
, fn
->done
);
349 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
350 printf ("Loading FPGA Device %d...\n", cookie
);
354 * Run the pre configuration function if there is one.
360 /* Establish the initial state */
361 (*fn
->pgm
) (TRUE
, TRUE
, cookie
); /* Assert the program, commit */
363 /* Wait for INIT state (init low) */
364 ts
= get_timer (0); /* get current time */
366 CONFIG_FPGA_DELAY ();
367 if (get_timer (ts
) > CONFIG_SYS_FPGA_WAIT
) { /* check the time */
368 puts ("** Timeout waiting for INIT to start.\n");
371 } while (!(*fn
->init
) (cookie
));
373 /* Get ready for the burn */
374 CONFIG_FPGA_DELAY ();
375 (*fn
->pgm
) (FALSE
, TRUE
, cookie
); /* Deassert the program, commit */
377 ts
= get_timer (0); /* get current time */
378 /* Now wait for INIT to go high */
380 CONFIG_FPGA_DELAY ();
381 if (get_timer (ts
) > CONFIG_SYS_FPGA_WAIT
) { /* check the time */
382 puts ("** Timeout waiting for INIT to clear.\n");
385 } while ((*fn
->init
) (cookie
));
389 (*fn
->bwr
) (data
, bsize
, TRUE
, cookie
);
391 while (bytecount
< bsize
) {
393 /* Xilinx detects an error if INIT goes low (active)
394 while DONE is low (inactive) */
395 if ((*fn
->done
) (cookie
) == 0 && (*fn
->init
) (cookie
)) {
396 puts ("** CRC error during FPGA load.\n");
399 val
= data
[bytecount
++];
402 /* Deassert the clock */
403 (*fn
->clk
) (FALSE
, TRUE
, cookie
);
404 CONFIG_FPGA_DELAY ();
406 (*fn
->wr
) ((val
& 0x80), TRUE
, cookie
);
407 CONFIG_FPGA_DELAY ();
408 /* Assert the clock */
409 (*fn
->clk
) (TRUE
, TRUE
, cookie
);
410 CONFIG_FPGA_DELAY ();
415 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
416 if (bytecount
% (bsize
/ 40) == 0)
417 putc ('.'); /* let them know we are alive */
422 CONFIG_FPGA_DELAY ();
424 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
425 putc ('\n'); /* terminate the dotted line */
428 /* now check for done signal */
429 ts
= get_timer (0); /* get current time */
430 ret_val
= FPGA_SUCCESS
;
431 (*fn
->wr
) (TRUE
, TRUE
, cookie
);
433 while (! (*fn
->done
) (cookie
)) {
434 /* XXX - we should have a check in here somewhere to
435 * make sure we aren't busy forever... */
437 CONFIG_FPGA_DELAY ();
438 (*fn
->clk
) (FALSE
, TRUE
, cookie
); /* Deassert the clock pin */
439 CONFIG_FPGA_DELAY ();
440 (*fn
->clk
) (TRUE
, TRUE
, cookie
); /* Assert the clock pin */
444 if (get_timer (ts
) > CONFIG_SYS_FPGA_WAIT
) { /* check the time */
445 puts ("** Timeout waiting for DONE to clear.\n");
450 putc ('\n'); /* terminate the dotted line */
453 * Run the post configuration function if there is one.
456 (*fn
->post
) (cookie
);
458 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
459 if (ret_val
== FPGA_SUCCESS
)
466 printf ("%s: NULL Interface function table!\n", __FUNCTION__
);
472 static int Spartan3_ss_dump (Xilinx_desc
* desc
, void *buf
, size_t bsize
)
474 /* Readback is only available through the Slave Parallel and */
475 /* boundary-scan interfaces. */
476 printf ("%s: Slave Serial Dumping is unavailable\n",