blob: b5dc366aad39c15de8f57e88c8c7699d26c1cc56 [file] [log] [blame]
wdenk5d3207d2002-08-21 22:08:56 +00001/*
2 * (C) Copyright 2002
3 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4 * Keith Outwater, keith_outwater@mvis.com
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 *
24 */
25
26/*
27 * Configuration support for Xilinx Virtex2 devices. Based
28 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
29 */
30
31#include <common.h>
32#include <virtex2.h>
33
34#if (CONFIG_FPGA & (CFG_XILINX | CFG_VIRTEX2))
35
Wolfgang Denkffb77562005-09-24 23:41:00 +020036#if 0
37#define FPGA_DEBUG
Wolfgang Denk0cbaf642005-09-25 00:53:22 +020038#endif
Wolfgang Denkffb77562005-09-24 23:41:00 +020039
wdenk5d3207d2002-08-21 22:08:56 +000040#ifdef FPGA_DEBUG
41#define PRINTF(fmt,args...) printf (fmt ,##args)
42#else
43#define PRINTF(fmt,args...)
44#endif
45
46/*
47 * If the SelectMap interface can be overrun by the processor, define
48 * CFG_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration
49 * file and add board-specific support for checking BUSY status. By default,
50 * assume that the SelectMap interface cannot be overrun.
51 */
52#ifndef CFG_FPGA_CHECK_BUSY
53#undef CFG_FPGA_CHECK_BUSY
54#endif
55
56#ifndef CONFIG_FPGA_DELAY
57#define CONFIG_FPGA_DELAY()
58#endif
59
60#ifndef CFG_FPGA_PROG_FEEDBACK
61#define CFG_FPGA_PROG_FEEDBACK
62#endif
63
64/*
65 * Don't allow config cycle to be interrupted
66 */
67#ifndef CFG_FPGA_CHECK_CTRLC
68#undef CFG_FPGA_CHECK_CTRLC
69#endif
70
71/*
72 * Check for errors during configuration by default
73 */
74#ifndef CFG_FPGA_CHECK_ERROR
75#define CFG_FPGA_CHECK_ERROR
76#endif
77
78/*
79 * The default timeout in mS for INIT_B to deassert after PROG_B has
80 * been deasserted. Per the latest Virtex II Handbook (page 347), the
81 * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
82 * data frame for the XC2V8000. The XC2V8000 has 2860 data frames
83 * which yields 11.44 mS. So let's make it bigger in order to handle
84 * an XC2V1000, if anyone can ever get ahold of one.
85 */
86#ifndef CFG_FPGA_WAIT_INIT
wdenkd729d302004-02-27 00:07:27 +000087#define CFG_FPGA_WAIT_INIT CFG_HZ/2 /* 500 ms */
wdenk5d3207d2002-08-21 22:08:56 +000088#endif
89
90/*
91 * The default timeout for waiting for BUSY to deassert during configuration.
92 * This is normally not necessary since for most reasonable configuration
93 * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
94 */
95#ifndef CFG_FPGA_WAIT_BUSY
wdenkd729d302004-02-27 00:07:27 +000096#define CFG_FPGA_WAIT_BUSY CFG_HZ/200 /* 5 ms*/
wdenk5d3207d2002-08-21 22:08:56 +000097#endif
98
99/* Default timeout for waiting for FPGA to enter operational mode after
100 * configuration data has been written.
101 */
102#ifndef CFG_FPGA_WAIT_CONFIG
wdenkd729d302004-02-27 00:07:27 +0000103#define CFG_FPGA_WAIT_CONFIG CFG_HZ/5 /* 200 ms */
wdenk5d3207d2002-08-21 22:08:56 +0000104#endif
105
106static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize);
107static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize);
108static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset);
109
110static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize);
111static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize);
112static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset);
113
114int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize)
115{
116 int ret_val = FPGA_FAIL;
117
118 switch (desc->iface) {
119 case slave_serial:
120 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
121 ret_val = Virtex2_ss_load (desc, buf, bsize);
122 break;
123
124 case slave_selectmap:
125 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
126 ret_val = Virtex2_ssm_load (desc, buf, bsize);
127 break;
128
129 default:
130 printf ("%s: Unsupported interface type, %d\n",
131 __FUNCTION__, desc->iface);
132 }
133 return ret_val;
134}
135
136int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize)
137{
138 int ret_val = FPGA_FAIL;
139
140 switch (desc->iface) {
141 case slave_serial:
142 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
143 ret_val = Virtex2_ss_dump (desc, buf, bsize);
144 break;
145
146 case slave_parallel:
147 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
148 ret_val = Virtex2_ssm_dump (desc, buf, bsize);
149 break;
150
151 default:
152 printf ("%s: Unsupported interface type, %d\n",
153 __FUNCTION__, desc->iface);
154 }
155 return ret_val;
156}
157
158int Virtex2_info (Xilinx_desc * desc)
159{
160 return FPGA_SUCCESS;
161}
162
163int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset)
164{
165 int ret_val = FPGA_FAIL;
166
167 if (desc->family != Xilinx_Virtex2) {
168 printf ("%s: Unsupported family type, %d\n",
169 __FUNCTION__, desc->family);
170 return FPGA_FAIL;
171 } else
172 switch (desc->iface) {
173 case slave_serial:
174 ret_val = Virtex2_ss_reloc (desc, reloc_offset);
175 break;
176
177 case slave_selectmap:
178 ret_val = Virtex2_ssm_reloc (desc, reloc_offset);
179 break;
180
181 default:
182 printf ("%s: Unsupported interface type, %d\n",
183 __FUNCTION__, desc->iface);
184 }
185 return ret_val;
186}
187
188/*
189 * Virtex-II Slave SelectMap configuration loader. Configuration via
190 * SelectMap is as follows:
191 * 1. Set the FPGA's PROG_B line low.
192 * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high.
193 * 3. Write data to the SelectMap port. If INIT_B goes low at any time
194 * this process, a configuration error (most likely CRC failure) has
195 * ocurred. At this point a status word may be read from the
196 * SelectMap interface to determine the source of the problem (You
Wolfgang Denkffb77562005-09-24 23:41:00 +0200197 * could, for instance, put this in your 'abort' function handler).
wdenk5d3207d2002-08-21 22:08:56 +0000198 * 4. After all data has been written, test the state of the FPGA
199 * INIT_B and DONE lines. If both are high, configuration has
200 * succeeded. Congratulations!
201 */
202static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize)
203{
204 int ret_val = FPGA_FAIL;
205 Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
206
207 PRINTF ("%s:%d: Start with interface functions @ 0x%p\n",
208 __FUNCTION__, __LINE__, fn);
209
210 if (fn) {
211 size_t bytecount = 0;
212 unsigned char *data = (unsigned char *) buf;
213 int cookie = desc->cookie;
214 unsigned long ts;
215
216 /* Gotta split this one up (so the stack won't blow??) */
217 PRINTF ("%s:%d: Function Table:\n"
218 " base 0x%p\n"
219 " struct 0x%p\n"
220 " pre 0x%p\n"
221 " prog 0x%p\n"
222 " init 0x%p\n"
223 " error 0x%p\n",
224 __FUNCTION__, __LINE__,
225 &fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
226 PRINTF (" clock 0x%p\n"
227 " cs 0x%p\n"
228 " write 0x%p\n"
229 " rdata 0x%p\n"
230 " wdata 0x%p\n"
231 " busy 0x%p\n"
232 " abort 0x%p\n"
233 " post 0x%p\n\n",
234 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
235 fn->busy, fn->abort, fn->post);
236
237#ifdef CFG_FPGA_PROG_FEEDBACK
238 printf ("Initializing FPGA Device %d...\n", cookie);
239#endif
240 /*
241 * Run the pre configuration function if there is one.
242 */
243 if (*fn->pre) {
244 (*fn->pre) (cookie);
245 }
246
247 /*
248 * Assert the program line. The minimum pulse width for
249 * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
250 * There is no maximum value for the pulse width. Check to make
251 * sure that INIT_B goes low after assertion of PROG_B
252 */
253 (*fn->pgm) (TRUE, TRUE, cookie);
254 udelay (10);
255 ts = get_timer (0);
256 do {
257 if (get_timer (ts) > CFG_FPGA_WAIT_INIT) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200258 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
wdenk5d3207d2002-08-21 22:08:56 +0000259 " to assert.\n", __FUNCTION__, __LINE__,
260 CFG_FPGA_WAIT_INIT);
261 (*fn->abort) (cookie);
262 return FPGA_FAIL;
263 }
264 } while (!(*fn->init) (cookie));
265
266 (*fn->pgm) (FALSE, TRUE, cookie);
267 CONFIG_FPGA_DELAY ();
268 (*fn->clk) (TRUE, TRUE, cookie);
269
270 /*
271 * Start a timer and wait for INIT_B to go high
272 */
273 ts = get_timer (0);
274 do {
275 CONFIG_FPGA_DELAY ();
276 if (get_timer (ts) > CFG_FPGA_WAIT_INIT) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200277 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
wdenk5d3207d2002-08-21 22:08:56 +0000278 " to deassert.\n", __FUNCTION__, __LINE__,
279 CFG_FPGA_WAIT_INIT);
280 (*fn->abort) (cookie);
281 return FPGA_FAIL;
282 }
283 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
284
285 (*fn->wr) (TRUE, TRUE, cookie);
286 (*fn->cs) (TRUE, TRUE, cookie);
287
288 udelay (10000);
289
290 /*
291 * Load the data byte by byte
292 */
293 while (bytecount < bsize) {
294#ifdef CFG_FPGA_CHECK_CTRLC
295 if (ctrlc ()) {
296 (*fn->abort) (cookie);
297 return FPGA_FAIL;
298 }
299#endif
Wolfgang Denkffb77562005-09-24 23:41:00 +0200300
301 if ((*fn->done) (cookie) == FPGA_SUCCESS) {
302 PRINTF ("%s:%d:done went active early, bytecount = %d\n",
303 __FUNCTION__, __LINE__, bytecount);
304 break;
305 }
306
wdenk5d3207d2002-08-21 22:08:56 +0000307#ifdef CFG_FPGA_CHECK_ERROR
308 if ((*fn->init) (cookie)) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200309 printf ("\n%s:%d: ** Error: INIT asserted during"
wdenk5d3207d2002-08-21 22:08:56 +0000310 " configuration\n", __FUNCTION__, __LINE__);
Wolfgang Denkffb77562005-09-24 23:41:00 +0200311 printf ("%d = buffer offset, %d = buffer size\n",
312 bytecount, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000313 (*fn->abort) (cookie);
314 return FPGA_FAIL;
315 }
316#endif
Wolfgang Denkffb77562005-09-24 23:41:00 +0200317
wdenk5d3207d2002-08-21 22:08:56 +0000318 (*fn->wdata) (data[bytecount++], TRUE, cookie);
319 CONFIG_FPGA_DELAY ();
320
321 /*
322 * Cycle the clock pin
323 */
324 (*fn->clk) (FALSE, TRUE, cookie);
325 CONFIG_FPGA_DELAY ();
326 (*fn->clk) (TRUE, TRUE, cookie);
327
328#ifdef CFG_FPGA_CHECK_BUSY
329 ts = get_timer (0);
330 while ((*fn->busy) (cookie)) {
331 if (get_timer (ts) > CFG_FPGA_WAIT_BUSY) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200332 printf ("%s:%d: ** Timeout after %d ticks waiting for"
wdenk5d3207d2002-08-21 22:08:56 +0000333 " BUSY to deassert\n",
334 __FUNCTION__, __LINE__, CFG_FPGA_WAIT_BUSY);
335 (*fn->abort) (cookie);
336 return FPGA_FAIL;
337 }
338 }
339#endif
340
341#ifdef CFG_FPGA_PROG_FEEDBACK
342 if (bytecount % (bsize / 40) == 0)
343 putc ('.');
344#endif
345 }
346
347 /*
348 * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
349 */
350 CONFIG_FPGA_DELAY ();
351 (*fn->cs) (FALSE, TRUE, cookie);
352 (*fn->wr) (FALSE, TRUE, cookie);
353
354#ifdef CFG_FPGA_PROG_FEEDBACK
355 putc ('\n');
356#endif
357
358 /*
359 * Check for successful configuration. FPGA INIT_B and DONE should
360 * both be high upon successful configuration.
361 */
362 ts = get_timer (0);
363 ret_val = FPGA_SUCCESS;
364 while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) {
365 if (get_timer (ts) > CFG_FPGA_WAIT_CONFIG) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200366 printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to"
wdenk5d3207d2002-08-21 22:08:56 +0000367 "assert and INIT to deassert\n",
368 __FUNCTION__, __LINE__, CFG_FPGA_WAIT_CONFIG);
369 (*fn->abort) (cookie);
370 ret_val = FPGA_FAIL;
371 break;
372 }
373 }
374
375 if (ret_val == FPGA_SUCCESS) {
376#ifdef CFG_FPGA_PROG_FEEDBACK
377 printf ("Initialization of FPGA device %d complete\n", cookie);
378#endif
379 /*
380 * Run the post configuration function if there is one.
381 */
382 if (*fn->post) {
383 (*fn->post) (cookie);
384 }
385 } else {
386#ifdef CFG_FPGA_PROG_FEEDBACK
387 printf ("** Initialization of FPGA device %d FAILED\n",
388 cookie);
389#endif
390 }
391 } else {
392 printf ("%s:%d: NULL Interface function table!\n",
393 __FUNCTION__, __LINE__);
394 }
395 return ret_val;
396}
397
398/*
399 * Read the FPGA configuration data
400 */
401static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize)
402{
403 int ret_val = FPGA_FAIL;
404 Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
405
406 if (fn) {
407 unsigned char *data = (unsigned char *) buf;
408 size_t bytecount = 0;
409 int cookie = desc->cookie;
410
411 printf ("Starting Dump of FPGA Device %d...\n", cookie);
412
413 (*fn->cs) (TRUE, TRUE, cookie);
414 (*fn->clk) (TRUE, TRUE, cookie);
415
416 while (bytecount < bsize) {
417#ifdef CFG_FPGA_CHECK_CTRLC
418 if (ctrlc ()) {
419 (*fn->abort) (cookie);
420 return FPGA_FAIL;
421 }
422#endif
423 /*
424 * Cycle the clock and read the data
425 */
426 (*fn->clk) (FALSE, TRUE, cookie);
427 (*fn->clk) (TRUE, TRUE, cookie);
428 (*fn->rdata) (&(data[bytecount++]), cookie);
429#ifdef CFG_FPGA_PROG_FEEDBACK
430 if (bytecount % (bsize / 40) == 0)
431 putc ('.');
432#endif
433 }
434
435 /*
436 * Deassert CS_B and cycle the clock to deselect the device.
437 */
438 (*fn->cs) (FALSE, FALSE, cookie);
439 (*fn->clk) (FALSE, TRUE, cookie);
440 (*fn->clk) (TRUE, TRUE, cookie);
441
442#ifdef CFG_FPGA_PROG_FEEDBACK
443 putc ('\n');
444#endif
445 puts ("Done.\n");
446 } else {
447 printf ("%s:%d: NULL Interface function table!\n",
448 __FUNCTION__, __LINE__);
449 }
450 return ret_val;
451}
452
453/*
454 * Relocate the addresses in the function table from FLASH (or ROM,
455 * or whatever) to RAM.
456 */
457static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset)
458{
459 ulong addr;
460 int ret_val = FPGA_FAIL;
461 Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn =
462 (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns);
463
464 if (fn) {
465 /*
466 * Get the relocated table address
467 */
468 addr = (ulong) fn + reloc_offset;
469 fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr;
470
471 /*
472 * Check to see if the table has already been relocated. If not, do
473 * a sanity check to make sure there is a faithful copy of the
474 * FLASH based function table in RAM, then adjust the table.
475 */
476 if (!fn_r->relocated) {
477 if (memcmp
478 (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns))
479 == 0) {
480 desc->iface_fns = fn_r;
481 } else {
482 PRINTF ("%s:%d: Invalid function table at 0x%p\n",
483 __FUNCTION__, __LINE__, fn_r);
484 return FPGA_FAIL;
485 }
486
487 PRINTF ("%s:%d: Relocating descriptor at 0x%p\n",
488 __FUNCTION__, __LINE__, desc);
489
490 addr = (ulong) (fn->pre) + reloc_offset;
491 fn_r->pre = (Xilinx_pre_fn) addr;
492 addr = (ulong) (fn->pgm) + reloc_offset;
493 fn_r->pgm = (Xilinx_pgm_fn) addr;
494 addr = (ulong) (fn->init) + reloc_offset;
495 fn_r->init = (Xilinx_init_fn) addr;
496 addr = (ulong) (fn->done) + reloc_offset;
497 fn_r->done = (Xilinx_done_fn) addr;
498 addr = (ulong) (fn->err) + reloc_offset;
499 fn_r->err = (Xilinx_err_fn) addr;
500 addr = (ulong) (fn->clk) + reloc_offset;
501 fn_r->clk = (Xilinx_clk_fn) addr;
502 addr = (ulong) (fn->cs) + reloc_offset;
503 fn_r->cs = (Xilinx_cs_fn) addr;
504 addr = (ulong) (fn->wr) + reloc_offset;
505 fn_r->wr = (Xilinx_wr_fn) addr;
506 addr = (ulong) (fn->rdata) + reloc_offset;
507 fn_r->rdata = (Xilinx_rdata_fn) addr;
508 addr = (ulong) (fn->wdata) + reloc_offset;
509 fn_r->wdata = (Xilinx_wdata_fn) addr;
510 addr = (ulong) (fn->busy) + reloc_offset;
511 fn_r->busy = (Xilinx_busy_fn) addr;
512 addr = (ulong) (fn->abort) + reloc_offset;
513 fn_r->abort = (Xilinx_abort_fn) addr;
514 addr = (ulong) (fn->post) + reloc_offset;
515 fn_r->post = (Xilinx_post_fn) addr;
516 fn_r->relocated = TRUE;
517 } else {
518 printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r);
519 desc->iface_fns = fn_r;
520 }
521 ret_val = FPGA_SUCCESS;
522 } else {
523 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
524 }
525 return ret_val;
526}
527
528static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
529{
530 printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__);
531 return FPGA_FAIL;
532}
533
534static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
535{
536 printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__);
537 return FPGA_FAIL;
538}
539
540static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset)
541{
542 int ret_val = FPGA_FAIL;
543 Xilinx_Virtex2_Slave_Serial_fns *fn =
544 (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns);
545
546 if (fn) {
547 printf ("%s:%d: Slave Serial Loading is unsupported\n",
548 __FUNCTION__, __LINE__);
549 } else {
550 printf ("%s:%d: NULL Interface function table!\n",
551 __FUNCTION__, __LINE__);
552 }
553 return ret_val;
554}
555#endif
556
557/* vim: set ts=4 tw=78: */