blob: 502824424cd7327552966c46ff9643538e139ff1 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenk5d3207d2002-08-21 22:08:56 +00002/*
3 * (C) Copyright 2002
4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5 * Keith Outwater, keith_outwater@mvis.com
wdenk5d3207d2002-08-21 22:08:56 +00006 */
7
8/*
9 * Configuration support for Xilinx Virtex2 devices. Based
10 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
11 */
12
13#include <common.h>
Simon Glass24b852a2015-11-08 23:47:45 -070014#include <console.h>
wdenk5d3207d2002-08-21 22:08:56 +000015#include <virtex2.h>
16
Wolfgang Denk9a9200b2005-09-24 23:41:00 +020017#if 0
18#define FPGA_DEBUG
Wolfgang Denk265817c2005-09-25 00:53:22 +020019#endif
Wolfgang Denk9a9200b2005-09-24 23:41:00 +020020
wdenk5d3207d2002-08-21 22:08:56 +000021#ifdef FPGA_DEBUG
Robert Hancockfa57af02019-06-18 09:47:12 -060022#define PRINTF(fmt, args...) printf(fmt, ##args)
wdenk5d3207d2002-08-21 22:08:56 +000023#else
Robert Hancockfa57af02019-06-18 09:47:12 -060024#define PRINTF(fmt, args...)
wdenk5d3207d2002-08-21 22:08:56 +000025#endif
26
27/*
28 * If the SelectMap interface can be overrun by the processor, define
Robert Hancockfa57af02019-06-18 09:47:12 -060029 * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board
30 * configuration file and add board-specific support for checking BUSY status.
31 * By default, assume that the SelectMap interface cannot be overrun.
wdenk5d3207d2002-08-21 22:08:56 +000032 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020033#ifndef CONFIG_SYS_FPGA_CHECK_BUSY
34#undef CONFIG_SYS_FPGA_CHECK_BUSY
wdenk5d3207d2002-08-21 22:08:56 +000035#endif
36
37#ifndef CONFIG_FPGA_DELAY
38#define CONFIG_FPGA_DELAY()
39#endif
40
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020041#ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK
42#define CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +000043#endif
44
45/*
46 * Don't allow config cycle to be interrupted
47 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020048#ifndef CONFIG_SYS_FPGA_CHECK_CTRLC
49#undef CONFIG_SYS_FPGA_CHECK_CTRLC
wdenk5d3207d2002-08-21 22:08:56 +000050#endif
51
52/*
53 * Check for errors during configuration by default
54 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020055#ifndef CONFIG_SYS_FPGA_CHECK_ERROR
56#define CONFIG_SYS_FPGA_CHECK_ERROR
wdenk5d3207d2002-08-21 22:08:56 +000057#endif
58
59/*
60 * The default timeout in mS for INIT_B to deassert after PROG_B has
61 * been deasserted. Per the latest Virtex II Handbook (page 347), the
62 * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
63 * data frame for the XC2V8000. The XC2V8000 has 2860 data frames
64 * which yields 11.44 mS. So let's make it bigger in order to handle
65 * an XC2V1000, if anyone can ever get ahold of one.
66 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020067#ifndef CONFIG_SYS_FPGA_WAIT_INIT
Robert Hancockfa57af02019-06-18 09:47:12 -060068#define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ / 2 /* 500 ms */
wdenk5d3207d2002-08-21 22:08:56 +000069#endif
70
71/*
72 * The default timeout for waiting for BUSY to deassert during configuration.
73 * This is normally not necessary since for most reasonable configuration
74 * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
75 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020076#ifndef CONFIG_SYS_FPGA_WAIT_BUSY
Robert Hancockfa57af02019-06-18 09:47:12 -060077#define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ / 200 /* 5 ms*/
wdenk5d3207d2002-08-21 22:08:56 +000078#endif
79
80/* Default timeout for waiting for FPGA to enter operational mode after
81 * configuration data has been written.
82 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020083#ifndef CONFIG_SYS_FPGA_WAIT_CONFIG
Robert Hancockfa57af02019-06-18 09:47:12 -060084#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ / 5 /* 200 ms */
wdenk5d3207d2002-08-21 22:08:56 +000085#endif
86
Michal Simekf8c1be92014-03-13 12:49:21 +010087static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize);
88static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize);
wdenk5d3207d2002-08-21 22:08:56 +000089
Michal Simekf8c1be92014-03-13 12:49:21 +010090static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
91static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
wdenk5d3207d2002-08-21 22:08:56 +000092
Michal Simek7a78bd22014-05-02 14:09:30 +020093static int virtex2_load(xilinx_desc *desc, const void *buf, size_t bsize,
94 bitstream_type bstype)
wdenk5d3207d2002-08-21 22:08:56 +000095{
96 int ret_val = FPGA_FAIL;
97
98 switch (desc->iface) {
99 case slave_serial:
Robert Hancockfa57af02019-06-18 09:47:12 -0600100 PRINTF("%s: Launching Slave Serial Load\n", __func__);
Michal Simekd9071ce2014-03-13 11:33:36 +0100101 ret_val = virtex2_ss_load(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000102 break;
103
104 case slave_selectmap:
Robert Hancockfa57af02019-06-18 09:47:12 -0600105 PRINTF("%s: Launching Slave Parallel Load\n", __func__);
Michal Simekd9071ce2014-03-13 11:33:36 +0100106 ret_val = virtex2_ssm_load(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000107 break;
108
109 default:
Robert Hancockfa57af02019-06-18 09:47:12 -0600110 printf("%s: Unsupported interface type, %d\n",
111 __func__, desc->iface);
wdenk5d3207d2002-08-21 22:08:56 +0000112 }
113 return ret_val;
114}
115
Michal Simek14cfc4f2014-03-13 13:07:57 +0100116static int virtex2_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000117{
118 int ret_val = FPGA_FAIL;
119
120 switch (desc->iface) {
121 case slave_serial:
Robert Hancockfa57af02019-06-18 09:47:12 -0600122 PRINTF("%s: Launching Slave Serial Dump\n", __func__);
Michal Simekd9071ce2014-03-13 11:33:36 +0100123 ret_val = virtex2_ss_dump(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000124 break;
125
126 case slave_parallel:
Robert Hancockfa57af02019-06-18 09:47:12 -0600127 PRINTF("%s: Launching Slave Parallel Dump\n", __func__);
Michal Simekd9071ce2014-03-13 11:33:36 +0100128 ret_val = virtex2_ssm_dump(desc, buf, bsize);
wdenk5d3207d2002-08-21 22:08:56 +0000129 break;
130
131 default:
Robert Hancockfa57af02019-06-18 09:47:12 -0600132 printf("%s: Unsupported interface type, %d\n",
133 __func__, desc->iface);
wdenk5d3207d2002-08-21 22:08:56 +0000134 }
135 return ret_val;
136}
137
Michal Simek14cfc4f2014-03-13 13:07:57 +0100138static int virtex2_info(xilinx_desc *desc)
wdenk5d3207d2002-08-21 22:08:56 +0000139{
140 return FPGA_SUCCESS;
141}
142
wdenk5d3207d2002-08-21 22:08:56 +0000143/*
144 * Virtex-II Slave SelectMap configuration loader. Configuration via
145 * SelectMap is as follows:
146 * 1. Set the FPGA's PROG_B line low.
147 * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high.
148 * 3. Write data to the SelectMap port. If INIT_B goes low at any time
149 * this process, a configuration error (most likely CRC failure) has
150 * ocurred. At this point a status word may be read from the
151 * SelectMap interface to determine the source of the problem (You
Wolfgang Denk9a9200b2005-09-24 23:41:00 +0200152 * could, for instance, put this in your 'abort' function handler).
wdenk5d3207d2002-08-21 22:08:56 +0000153 * 4. After all data has been written, test the state of the FPGA
154 * INIT_B and DONE lines. If both are high, configuration has
155 * succeeded. Congratulations!
156 */
Robert Hancock33720812019-06-18 09:47:14 -0600157static int virtex2_slave_pre(xilinx_virtex2_slave_selectmap_fns *fn, int cookie)
wdenk5d3207d2002-08-21 22:08:56 +0000158{
Robert Hancock33720812019-06-18 09:47:14 -0600159 unsigned long ts;
wdenk5d3207d2002-08-21 22:08:56 +0000160
Robert Hancockfa57af02019-06-18 09:47:12 -0600161 PRINTF("%s:%d: Start with interface functions @ 0x%p\n",
162 __func__, __LINE__, fn);
wdenk5d3207d2002-08-21 22:08:56 +0000163
Robert Hancock33720812019-06-18 09:47:14 -0600164 if (!fn) {
165 printf("%s:%d: NULL Interface function table!\n",
166 __func__, __LINE__);
167 return FPGA_FAIL;
168 }
wdenk5d3207d2002-08-21 22:08:56 +0000169
Robert Hancock33720812019-06-18 09:47:14 -0600170 /* Gotta split this one up (so the stack won't blow??) */
171 PRINTF("%s:%d: Function Table:\n"
172 " base 0x%p\n"
173 " struct 0x%p\n"
174 " pre 0x%p\n"
175 " prog 0x%p\n"
176 " init 0x%p\n"
177 " error 0x%p\n",
178 __func__, __LINE__,
179 &fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
180 PRINTF(" clock 0x%p\n"
181 " cs 0x%p\n"
182 " write 0x%p\n"
183 " rdata 0x%p\n"
184 " wdata 0x%p\n"
185 " busy 0x%p\n"
186 " abort 0x%p\n"
187 " post 0x%p\n\n",
188 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
189 fn->busy, fn->abort, fn->post);
wdenk5d3207d2002-08-21 22:08:56 +0000190
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200191#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Robert Hancock33720812019-06-18 09:47:14 -0600192 printf("Initializing FPGA Device %d...\n", cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000193#endif
Robert Hancock33720812019-06-18 09:47:14 -0600194 /*
195 * Run the pre configuration function if there is one.
196 */
197 if (*fn->pre)
198 (*fn->pre)(cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000199
Robert Hancock33720812019-06-18 09:47:14 -0600200 /*
201 * Assert the program line. The minimum pulse width for
202 * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
203 * There is no maximum value for the pulse width. Check to make
204 * sure that INIT_B goes low after assertion of PROG_B
205 */
206 (*fn->pgm)(true, true, cookie);
207 udelay(10);
208 ts = get_timer(0);
209 do {
210 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
211 printf("%s:%d: ** Timeout after %d ticks waiting for INIT to assert.\n",
212 __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT);
213 (*fn->abort)(cookie);
214 return FPGA_FAIL;
215 }
216 } while (!(*fn->init)(cookie));
wdenk5d3207d2002-08-21 22:08:56 +0000217
Robert Hancock33720812019-06-18 09:47:14 -0600218 (*fn->pgm)(false, true, cookie);
219 CONFIG_FPGA_DELAY();
220 if (fn->clk)
Robert Hancockfa57af02019-06-18 09:47:12 -0600221 (*fn->clk)(true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000222
Robert Hancock33720812019-06-18 09:47:14 -0600223 /*
224 * Start a timer and wait for INIT_B to go high
225 */
226 ts = get_timer(0);
227 do {
228 CONFIG_FPGA_DELAY();
229 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
230 printf("%s:%d: ** Timeout after %d ticks waiting for INIT to deassert.\n",
231 __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT);
232 (*fn->abort)(cookie);
233 return FPGA_FAIL;
234 }
235 } while ((*fn->init)(cookie) && (*fn->busy)(cookie));
wdenk5d3207d2002-08-21 22:08:56 +0000236
Robert Hancock33720812019-06-18 09:47:14 -0600237 if (fn->wr)
Robert Hancockfa57af02019-06-18 09:47:12 -0600238 (*fn->wr)(true, true, cookie);
Robert Hancock33720812019-06-18 09:47:14 -0600239 if (fn->cs)
Robert Hancockfa57af02019-06-18 09:47:12 -0600240 (*fn->cs)(true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000241
Robert Hancock33720812019-06-18 09:47:14 -0600242 mdelay(10);
243 return FPGA_SUCCESS;
244}
wdenk5d3207d2002-08-21 22:08:56 +0000245
Robert Hancock33720812019-06-18 09:47:14 -0600246static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
247 int cookie)
248{
249 int ret_val = FPGA_SUCCESS;
Robert Hancocka0549f72019-06-18 09:47:15 -0600250 int num_done = 0;
Robert Hancock33720812019-06-18 09:47:14 -0600251 unsigned long ts;
Wolfgang Denk9a9200b2005-09-24 23:41:00 +0200252
Robert Hancock33720812019-06-18 09:47:14 -0600253 /*
254 * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
255 */
256 CONFIG_FPGA_DELAY();
257 if (fn->cs)
Robert Hancockfa57af02019-06-18 09:47:12 -0600258 (*fn->cs)(false, true, cookie);
Robert Hancock33720812019-06-18 09:47:14 -0600259 if (fn->wr)
Robert Hancockfa57af02019-06-18 09:47:12 -0600260 (*fn->wr)(false, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000261
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200262#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Robert Hancock33720812019-06-18 09:47:14 -0600263 putc('\n');
wdenk5d3207d2002-08-21 22:08:56 +0000264#endif
265
Robert Hancock33720812019-06-18 09:47:14 -0600266 /*
267 * Check for successful configuration. FPGA INIT_B and DONE
Robert Hancocka0549f72019-06-18 09:47:15 -0600268 * should both be high upon successful configuration. Continue pulsing
269 * clock with data set to all ones until DONE is asserted and for 8
270 * clock cycles afterwards.
Robert Hancock33720812019-06-18 09:47:14 -0600271 */
272 ts = get_timer(0);
Robert Hancocka0549f72019-06-18 09:47:15 -0600273 while (true) {
274 if ((*fn->done)(cookie) == FPGA_SUCCESS &&
275 !((*fn->init)(cookie))) {
276 if (num_done++ >= 8)
277 break;
278 }
279
Robert Hancock33720812019-06-18 09:47:14 -0600280 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
281 printf("%s:%d: ** Timeout after %d ticks waiting for DONE to assert and INIT to deassert\n",
282 __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
283 (*fn->abort)(cookie);
284 ret_val = FPGA_FAIL;
285 break;
286 }
Robert Hancocka0549f72019-06-18 09:47:15 -0600287 (*fn->wdata) (0xff, true, cookie);
288 CONFIG_FPGA_DELAY();
289 (*fn->clk) (false, true, cookie);
290 CONFIG_FPGA_DELAY();
291 (*fn->clk) (true, true, cookie);
Robert Hancock33720812019-06-18 09:47:14 -0600292 }
293
294 if (ret_val == FPGA_SUCCESS) {
295#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
296 printf("Initialization of FPGA device %d complete\n", cookie);
297#endif
wdenk5d3207d2002-08-21 22:08:56 +0000298 /*
Robert Hancock33720812019-06-18 09:47:14 -0600299 * Run the post configuration function if there is one.
wdenk5d3207d2002-08-21 22:08:56 +0000300 */
Robert Hancock33720812019-06-18 09:47:14 -0600301 if (*fn->post)
302 (*fn->post)(cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000303 } else {
Robert Hancock33720812019-06-18 09:47:14 -0600304#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
305 printf("** Initialization of FPGA device %d FAILED\n",
306 cookie);
307#endif
wdenk5d3207d2002-08-21 22:08:56 +0000308 }
309 return ret_val;
310}
311
Robert Hancock33720812019-06-18 09:47:14 -0600312static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize)
313{
314 int ret_val = FPGA_FAIL;
315 xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
316 size_t bytecount = 0;
317 unsigned char *data = (unsigned char *)buf;
318 int cookie = desc->cookie;
319
320 ret_val = virtex2_slave_pre(fn, cookie);
321 if (ret_val != FPGA_SUCCESS)
322 return ret_val;
323
324 /*
325 * Load the data byte by byte
326 */
327 while (bytecount < bsize) {
328#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
329 if (ctrlc()) {
330 (*fn->abort)(cookie);
331 return FPGA_FAIL;
332 }
333#endif
334
335 if ((*fn->done)(cookie) == FPGA_SUCCESS) {
336 PRINTF("%s:%d:done went active early, bytecount = %d\n",
337 __func__, __LINE__, bytecount);
338 break;
339 }
340
341#ifdef CONFIG_SYS_FPGA_CHECK_ERROR
342 if ((*fn->init)(cookie)) {
343 printf("\n%s:%d: ** Error: INIT asserted during configuration\n",
344 __func__, __LINE__);
345 printf("%zu = buffer offset, %zu = buffer size\n",
346 bytecount, bsize);
347 (*fn->abort)(cookie);
348 return FPGA_FAIL;
349 }
350#endif
351
352 (*fn->wdata)(data[bytecount++], true, cookie);
353 CONFIG_FPGA_DELAY();
354
355 /*
356 * Cycle the clock pin
357 */
358 (*fn->clk)(false, true, cookie);
359 CONFIG_FPGA_DELAY();
360 (*fn->clk)(true, true, cookie);
361
362#ifdef CONFIG_SYS_FPGA_CHECK_BUSY
363 ts = get_timer(0);
364 while ((*fn->busy)(cookie)) {
365 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_BUSY) {
366 printf("%s:%d: ** Timeout after %d ticks waiting for BUSY to deassert\n",
367 __func__, __LINE__,
368 CONFIG_SYS_FPGA_WAIT_BUSY);
369 (*fn->abort)(cookie);
370 return FPGA_FAIL;
371 }
372 }
373#endif
374
375#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
376 if (bytecount % (bsize / 40) == 0)
377 putc('.');
378#endif
379 }
380
381 return virtex2_slave_post(fn, cookie);
382}
383
wdenk5d3207d2002-08-21 22:08:56 +0000384/*
385 * Read the FPGA configuration data
386 */
Michal Simekf8c1be92014-03-13 12:49:21 +0100387static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000388{
389 int ret_val = FPGA_FAIL;
Michal Simekd9071ce2014-03-13 11:33:36 +0100390 xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
wdenk5d3207d2002-08-21 22:08:56 +0000391
392 if (fn) {
Robert Hancockfa57af02019-06-18 09:47:12 -0600393 unsigned char *data = (unsigned char *)buf;
wdenk5d3207d2002-08-21 22:08:56 +0000394 size_t bytecount = 0;
395 int cookie = desc->cookie;
396
Robert Hancockfa57af02019-06-18 09:47:12 -0600397 printf("Starting Dump of FPGA Device %d...\n", cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000398
Robert Hancockfa57af02019-06-18 09:47:12 -0600399 (*fn->cs)(true, true, cookie);
400 (*fn->clk)(true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000401
402 while (bytecount < bsize) {
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200403#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
Robert Hancockfa57af02019-06-18 09:47:12 -0600404 if (ctrlc()) {
405 (*fn->abort)(cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000406 return FPGA_FAIL;
407 }
408#endif
409 /*
410 * Cycle the clock and read the data
411 */
Robert Hancockfa57af02019-06-18 09:47:12 -0600412 (*fn->clk)(false, true, cookie);
413 (*fn->clk)(true, true, cookie);
414 (*fn->rdata)(&data[bytecount++], cookie);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200415#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk5d3207d2002-08-21 22:08:56 +0000416 if (bytecount % (bsize / 40) == 0)
Robert Hancockfa57af02019-06-18 09:47:12 -0600417 putc('.');
wdenk5d3207d2002-08-21 22:08:56 +0000418#endif
419 }
420
421 /*
422 * Deassert CS_B and cycle the clock to deselect the device.
423 */
Robert Hancockfa57af02019-06-18 09:47:12 -0600424 (*fn->cs)(false, false, cookie);
425 (*fn->clk)(false, true, cookie);
426 (*fn->clk)(true, true, cookie);
wdenk5d3207d2002-08-21 22:08:56 +0000427
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200428#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Robert Hancockfa57af02019-06-18 09:47:12 -0600429 putc('\n');
wdenk5d3207d2002-08-21 22:08:56 +0000430#endif
Robert Hancockfa57af02019-06-18 09:47:12 -0600431 puts("Done.\n");
wdenk5d3207d2002-08-21 22:08:56 +0000432 } else {
Robert Hancockfa57af02019-06-18 09:47:12 -0600433 printf("%s:%d: NULL Interface function table!\n",
434 __func__, __LINE__);
wdenk5d3207d2002-08-21 22:08:56 +0000435 }
436 return ret_val;
437}
438
Michal Simekf8c1be92014-03-13 12:49:21 +0100439static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000440{
Robert Hancockfa57af02019-06-18 09:47:12 -0600441 printf("%s: Slave Serial Loading is unsupported\n", __func__);
wdenk5d3207d2002-08-21 22:08:56 +0000442 return FPGA_FAIL;
443}
444
Michal Simekf8c1be92014-03-13 12:49:21 +0100445static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenk5d3207d2002-08-21 22:08:56 +0000446{
Robert Hancockfa57af02019-06-18 09:47:12 -0600447 printf("%s: Slave Serial Dumping is unsupported\n", __func__);
wdenk5d3207d2002-08-21 22:08:56 +0000448 return FPGA_FAIL;
449}
450
wdenk5d3207d2002-08-21 22:08:56 +0000451/* vim: set ts=4 tw=78: */
Michal Simek14cfc4f2014-03-13 13:07:57 +0100452
453struct xilinx_fpga_op virtex2_op = {
454 .load = virtex2_load,
455 .dump = virtex2_dump,
456 .info = virtex2_info,
457};