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