blob: f7cf02ab5b309cf7666a227cbeb71e89b8af9603 [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 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenk5d3207d2002-08-21 22:08:56 +00007 */
8
9/*
10 * Configuration support for Xilinx Virtex2 devices. Based
11 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
12 */
13
14#include <common.h>
Simon Glassa73bda42015-11-08 23:47:45 -070015#include <console.h>
wdenk5d3207d2002-08-21 22:08:56 +000016#include <virtex2.h>
17
Wolfgang Denkffb77562005-09-24 23:41:00 +020018#if 0
19#define FPGA_DEBUG
Wolfgang Denk0cbaf642005-09-25 00:53:22 +020020#endif
Wolfgang Denkffb77562005-09-24 23:41:00 +020021
wdenk5d3207d2002-08-21 22:08:56 +000022#ifdef FPGA_DEBUG
23#define PRINTF(fmt,args...) printf (fmt ,##args)
24#else
25#define PRINTF(fmt,args...)
26#endif
27
28/*
29 * If the SelectMap interface can be overrun by the processor, define
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020030 * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration
wdenk5d3207d2002-08-21 22:08:56 +000031 * file and add board-specific support for checking BUSY status. By default,
32 * assume that the SelectMap interface cannot be overrun.
33 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020034#ifndef CONFIG_SYS_FPGA_CHECK_BUSY
35#undef CONFIG_SYS_FPGA_CHECK_BUSY
wdenk5d3207d2002-08-21 22:08:56 +000036#endif
37
38#ifndef CONFIG_FPGA_DELAY
39#define CONFIG_FPGA_DELAY()
40#endif
41
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020042#ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK
43#define CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +000044#endif
45
46/*
47 * Don't allow config cycle to be interrupted
48 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020049#ifndef CONFIG_SYS_FPGA_CHECK_CTRLC
50#undef CONFIG_SYS_FPGA_CHECK_CTRLC
wdenk5d3207d2002-08-21 22:08:56 +000051#endif
52
53/*
54 * Check for errors during configuration by default
55 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020056#ifndef CONFIG_SYS_FPGA_CHECK_ERROR
57#define CONFIG_SYS_FPGA_CHECK_ERROR
wdenk5d3207d2002-08-21 22:08:56 +000058#endif
59
60/*
61 * The default timeout in mS for INIT_B to deassert after PROG_B has
62 * been deasserted. Per the latest Virtex II Handbook (page 347), the
63 * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
64 * data frame for the XC2V8000. The XC2V8000 has 2860 data frames
65 * which yields 11.44 mS. So let's make it bigger in order to handle
66 * an XC2V1000, if anyone can ever get ahold of one.
67 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020068#ifndef CONFIG_SYS_FPGA_WAIT_INIT
69#define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ/2 /* 500 ms */
wdenk5d3207d2002-08-21 22:08:56 +000070#endif
71
72/*
73 * The default timeout for waiting for BUSY to deassert during configuration.
74 * This is normally not necessary since for most reasonable configuration
75 * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
76 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020077#ifndef CONFIG_SYS_FPGA_WAIT_BUSY
78#define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ/200 /* 5 ms*/
wdenk5d3207d2002-08-21 22:08:56 +000079#endif
80
81/* Default timeout for waiting for FPGA to enter operational mode after
82 * configuration data has been written.
83 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020084#ifndef CONFIG_SYS_FPGA_WAIT_CONFIG
85#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */
wdenk5d3207d2002-08-21 22:08:56 +000086#endif
87
Michal Simek25e1e2e2014-03-13 12:49:21 +010088static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize);
89static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize);
wdenk5d3207d2002-08-21 22:08:56 +000090
Michal Simek25e1e2e2014-03-13 12:49:21 +010091static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
92static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
wdenk5d3207d2002-08-21 22:08:56 +000093
Michal Simek14663652014-05-02 14:09:30 +020094static int virtex2_load(xilinx_desc *desc, const void *buf, size_t bsize,
95 bitstream_type bstype)
wdenk5d3207d2002-08-21 22:08:56 +000096{
97 int ret_val = FPGA_FAIL;
98
99 switch (desc->iface) {
100 case slave_serial:
101 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
Michal Simek90258882014-03-13 11:33:36 +0100102 ret_val = virtex2_ss_load(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000103 break;
104
105 case slave_selectmap:
106 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
Michal Simek90258882014-03-13 11:33:36 +0100107 ret_val = virtex2_ssm_load(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000108 break;
109
110 default:
111 printf ("%s: Unsupported interface type, %d\n",
112 __FUNCTION__, desc->iface);
113 }
114 return ret_val;
115}
116
Michal Simek75fafac2014-03-13 13:07:57 +0100117static int virtex2_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000118{
119 int ret_val = FPGA_FAIL;
120
121 switch (desc->iface) {
122 case slave_serial:
123 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
Michal Simek90258882014-03-13 11:33:36 +0100124 ret_val = virtex2_ss_dump(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000125 break;
126
127 case slave_parallel:
128 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
Michal Simek90258882014-03-13 11:33:36 +0100129 ret_val = virtex2_ssm_dump(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000130 break;
131
132 default:
133 printf ("%s: Unsupported interface type, %d\n",
134 __FUNCTION__, desc->iface);
135 }
136 return ret_val;
137}
138
Michal Simek75fafac2014-03-13 13:07:57 +0100139static int virtex2_info(xilinx_desc *desc)
wdenk5d3207d2002-08-21 22:08:56 +0000140{
141 return FPGA_SUCCESS;
142}
143
wdenk5d3207d2002-08-21 22:08:56 +0000144/*
145 * Virtex-II Slave SelectMap configuration loader. Configuration via
146 * SelectMap is as follows:
147 * 1. Set the FPGA's PROG_B line low.
148 * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high.
149 * 3. Write data to the SelectMap port. If INIT_B goes low at any time
150 * this process, a configuration error (most likely CRC failure) has
151 * ocurred. At this point a status word may be read from the
152 * SelectMap interface to determine the source of the problem (You
Wolfgang Denkffb77562005-09-24 23:41:00 +0200153 * could, for instance, put this in your 'abort' function handler).
wdenk5d3207d2002-08-21 22:08:56 +0000154 * 4. After all data has been written, test the state of the FPGA
155 * INIT_B and DONE lines. If both are high, configuration has
156 * succeeded. Congratulations!
157 */
Michal Simek25e1e2e2014-03-13 12:49:21 +0100158static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000159{
160 int ret_val = FPGA_FAIL;
Michal Simek90258882014-03-13 11:33:36 +0100161 xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
wdenk5d3207d2002-08-21 22:08:56 +0000162
163 PRINTF ("%s:%d: Start with interface functions @ 0x%p\n",
164 __FUNCTION__, __LINE__, fn);
165
166 if (fn) {
167 size_t bytecount = 0;
168 unsigned char *data = (unsigned char *) buf;
169 int cookie = desc->cookie;
170 unsigned long ts;
171
172 /* Gotta split this one up (so the stack won't blow??) */
173 PRINTF ("%s:%d: Function Table:\n"
174 " base 0x%p\n"
175 " struct 0x%p\n"
176 " pre 0x%p\n"
177 " prog 0x%p\n"
178 " init 0x%p\n"
179 " error 0x%p\n",
180 __FUNCTION__, __LINE__,
181 &fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
182 PRINTF (" clock 0x%p\n"
183 " cs 0x%p\n"
184 " write 0x%p\n"
185 " rdata 0x%p\n"
186 " wdata 0x%p\n"
187 " busy 0x%p\n"
188 " abort 0x%p\n"
189 " post 0x%p\n\n",
190 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
191 fn->busy, fn->abort, fn->post);
192
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200193#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000194 printf ("Initializing FPGA Device %d...\n", cookie);
195#endif
196 /*
197 * Run the pre configuration function if there is one.
198 */
199 if (*fn->pre) {
200 (*fn->pre) (cookie);
201 }
202
203 /*
204 * Assert the program line. The minimum pulse width for
205 * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
206 * There is no maximum value for the pulse width. Check to make
207 * sure that INIT_B goes low after assertion of PROG_B
208 */
York Sun4a598092013-04-01 11:29:11 -0700209 (*fn->pgm) (true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000210 udelay (10);
211 ts = get_timer (0);
212 do {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200213 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200214 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
wdenk5d3207d2002-08-21 22:08:56 +0000215 " to assert.\n", __FUNCTION__, __LINE__,
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200216 CONFIG_SYS_FPGA_WAIT_INIT);
wdenk5d3207d2002-08-21 22:08:56 +0000217 (*fn->abort) (cookie);
218 return FPGA_FAIL;
219 }
220 } while (!(*fn->init) (cookie));
221
York Sun4a598092013-04-01 11:29:11 -0700222 (*fn->pgm) (false, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000223 CONFIG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700224 (*fn->clk) (true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000225
226 /*
227 * Start a timer and wait for INIT_B to go high
228 */
229 ts = get_timer (0);
230 do {
231 CONFIG_FPGA_DELAY ();
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200232 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200233 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
wdenk5d3207d2002-08-21 22:08:56 +0000234 " to deassert.\n", __FUNCTION__, __LINE__,
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200235 CONFIG_SYS_FPGA_WAIT_INIT);
wdenk5d3207d2002-08-21 22:08:56 +0000236 (*fn->abort) (cookie);
237 return FPGA_FAIL;
238 }
239 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
240
York Sun4a598092013-04-01 11:29:11 -0700241 (*fn->wr) (true, true, cookie);
242 (*fn->cs) (true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000243
244 udelay (10000);
245
246 /*
247 * Load the data byte by byte
248 */
249 while (bytecount < bsize) {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200250#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
wdenk5d3207d2002-08-21 22:08:56 +0000251 if (ctrlc ()) {
252 (*fn->abort) (cookie);
253 return FPGA_FAIL;
254 }
255#endif
Wolfgang Denkffb77562005-09-24 23:41:00 +0200256
257 if ((*fn->done) (cookie) == FPGA_SUCCESS) {
258 PRINTF ("%s:%d:done went active early, bytecount = %d\n",
259 __FUNCTION__, __LINE__, bytecount);
260 break;
261 }
262
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200263#ifdef CONFIG_SYS_FPGA_CHECK_ERROR
wdenk5d3207d2002-08-21 22:08:56 +0000264 if ((*fn->init) (cookie)) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200265 printf ("\n%s:%d: ** Error: INIT asserted during"
wdenk5d3207d2002-08-21 22:08:56 +0000266 " configuration\n", __FUNCTION__, __LINE__);
Wolfgang Denkffb77562005-09-24 23:41:00 +0200267 printf ("%d = buffer offset, %d = buffer size\n",
268 bytecount, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000269 (*fn->abort) (cookie);
270 return FPGA_FAIL;
271 }
272#endif
Wolfgang Denkffb77562005-09-24 23:41:00 +0200273
York Sun4a598092013-04-01 11:29:11 -0700274 (*fn->wdata) (data[bytecount++], true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000275 CONFIG_FPGA_DELAY ();
276
277 /*
278 * Cycle the clock pin
279 */
York Sun4a598092013-04-01 11:29:11 -0700280 (*fn->clk) (false, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000281 CONFIG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700282 (*fn->clk) (true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000283
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200284#ifdef CONFIG_SYS_FPGA_CHECK_BUSY
wdenk5d3207d2002-08-21 22:08:56 +0000285 ts = get_timer (0);
286 while ((*fn->busy) (cookie)) {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200287 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200288 printf ("%s:%d: ** Timeout after %d ticks waiting for"
wdenk5d3207d2002-08-21 22:08:56 +0000289 " BUSY to deassert\n",
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200290 __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY);
wdenk5d3207d2002-08-21 22:08:56 +0000291 (*fn->abort) (cookie);
292 return FPGA_FAIL;
293 }
294 }
295#endif
296
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200297#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000298 if (bytecount % (bsize / 40) == 0)
299 putc ('.');
300#endif
301 }
302
303 /*
304 * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
305 */
306 CONFIG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700307 (*fn->cs) (false, true, cookie);
308 (*fn->wr) (false, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000309
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200310#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000311 putc ('\n');
312#endif
313
314 /*
315 * Check for successful configuration. FPGA INIT_B and DONE should
316 * both be high upon successful configuration.
317 */
318 ts = get_timer (0);
319 ret_val = FPGA_SUCCESS;
320 while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200321 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
Wolfgang Denkffb77562005-09-24 23:41:00 +0200322 printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to"
wdenk5d3207d2002-08-21 22:08:56 +0000323 "assert and INIT to deassert\n",
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200324 __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
wdenk5d3207d2002-08-21 22:08:56 +0000325 (*fn->abort) (cookie);
326 ret_val = FPGA_FAIL;
327 break;
328 }
329 }
330
331 if (ret_val == FPGA_SUCCESS) {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200332#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000333 printf ("Initialization of FPGA device %d complete\n", cookie);
334#endif
335 /*
336 * Run the post configuration function if there is one.
337 */
338 if (*fn->post) {
339 (*fn->post) (cookie);
340 }
341 } else {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200342#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000343 printf ("** Initialization of FPGA device %d FAILED\n",
344 cookie);
345#endif
346 }
347 } else {
348 printf ("%s:%d: NULL Interface function table!\n",
349 __FUNCTION__, __LINE__);
350 }
351 return ret_val;
352}
353
354/*
355 * Read the FPGA configuration data
356 */
Michal Simek25e1e2e2014-03-13 12:49:21 +0100357static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000358{
359 int ret_val = FPGA_FAIL;
Michal Simek90258882014-03-13 11:33:36 +0100360 xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
wdenk5d3207d2002-08-21 22:08:56 +0000361
362 if (fn) {
363 unsigned char *data = (unsigned char *) buf;
364 size_t bytecount = 0;
365 int cookie = desc->cookie;
366
367 printf ("Starting Dump of FPGA Device %d...\n", cookie);
368
York Sun4a598092013-04-01 11:29:11 -0700369 (*fn->cs) (true, true, cookie);
370 (*fn->clk) (true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000371
372 while (bytecount < bsize) {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200373#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
wdenk5d3207d2002-08-21 22:08:56 +0000374 if (ctrlc ()) {
375 (*fn->abort) (cookie);
376 return FPGA_FAIL;
377 }
378#endif
379 /*
380 * Cycle the clock and read the data
381 */
York Sun4a598092013-04-01 11:29:11 -0700382 (*fn->clk) (false, true, cookie);
383 (*fn->clk) (true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000384 (*fn->rdata) (&(data[bytecount++]), cookie);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200385#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000386 if (bytecount % (bsize / 40) == 0)
387 putc ('.');
388#endif
389 }
390
391 /*
392 * Deassert CS_B and cycle the clock to deselect the device.
393 */
York Sun4a598092013-04-01 11:29:11 -0700394 (*fn->cs) (false, false, cookie);
395 (*fn->clk) (false, true, cookie);
396 (*fn->clk) (true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000397
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200398#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000399 putc ('\n');
400#endif
401 puts ("Done.\n");
402 } else {
403 printf ("%s:%d: NULL Interface function table!\n",
404 __FUNCTION__, __LINE__);
405 }
406 return ret_val;
407}
408
Michal Simek25e1e2e2014-03-13 12:49:21 +0100409static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000410{
411 printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__);
412 return FPGA_FAIL;
413}
414
Michal Simek25e1e2e2014-03-13 12:49:21 +0100415static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000416{
417 printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__);
418 return FPGA_FAIL;
419}
420
wdenk5d3207d2002-08-21 22:08:56 +0000421/* vim: set ts=4 tw=78: */
Michal Simek75fafac2014-03-13 13:07:57 +0100422
423struct xilinx_fpga_op virtex2_op = {
424 .load = virtex2_load,
425 .dump = virtex2_dump,
426 .info = virtex2_info,
427};