blob: 906649ea18139ddba8f79608cfd3974832a31e6e [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenke2211742002-11-02 23:30:20 +00002/*
3 * (C) Copyright 2002
4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
wdenke2211742002-11-02 23:30:20 +00005 */
6
Alexander Dahlcb9c1f92022-10-07 14:20:01 +02007#define LOG_CATEGORY UCLASS_FPGA
8
Tom Rinidec7ea02024-05-20 13:35:03 -06009#include <config.h> /* core U-Boot definitions */
Alexander Dahlcb9c1f92022-10-07 14:20:01 +020010#include <log.h>
wdenke2211742002-11-02 23:30:20 +000011#include <spartan2.h> /* Spartan-II device family */
12
wdenke2211742002-11-02 23:30:20 +000013/* Note: The assumption is that we cannot possibly run fast enough to
14 * overrun the device (the Slave Parallel mode can free run at 50MHz).
Tom Rini88d86ec2022-12-04 10:03:57 -050015 * If there is a need to operate slower, define CFG_FPGA_DELAY in
wdenke2211742002-11-02 23:30:20 +000016 * the board config file to slow things down.
17 */
Tom Rini88d86ec2022-12-04 10:03:57 -050018#ifndef CFG_FPGA_DELAY
19#define CFG_FPGA_DELAY()
wdenke2211742002-11-02 23:30:20 +000020#endif
21
Tom Rini6a5dccc2022-11-16 13:10:41 -050022#ifndef CFG_SYS_FPGA_WAIT
23#define CFG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
wdenke2211742002-11-02 23:30:20 +000024#endif
25
Michal Simek25e1e2e2014-03-13 12:49:21 +010026static int spartan2_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
27static int spartan2_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
28/* static int spartan2_sp_info(xilinx_desc *desc ); */
wdenke2211742002-11-02 23:30:20 +000029
Michal Simek25e1e2e2014-03-13 12:49:21 +010030static int spartan2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
31static int spartan2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
32/* static int spartan2_ss_info(xilinx_desc *desc ); */
wdenke2211742002-11-02 23:30:20 +000033
34/* ------------------------------------------------------------------------- */
35/* Spartan-II Generic Implementation */
Michal Simek14663652014-05-02 14:09:30 +020036static int spartan2_load(xilinx_desc *desc, const void *buf, size_t bsize,
Oleksandr Suvorovc0806cc2022-07-22 17:16:10 +030037 bitstream_type bstype, int flags)
wdenke2211742002-11-02 23:30:20 +000038{
39 int ret_val = FPGA_FAIL;
40
41 switch (desc->iface) {
42 case slave_serial:
Alexander Dahlcb9c1f92022-10-07 14:20:01 +020043 log_debug("Launching Slave Serial Load\n");
Michal Simek5206cca2014-03-13 11:23:43 +010044 ret_val = spartan2_ss_load(desc, buf, bsize);
wdenke2211742002-11-02 23:30:20 +000045 break;
46
47 case slave_parallel:
Alexander Dahlcb9c1f92022-10-07 14:20:01 +020048 log_debug("Launching Slave Parallel Load\n");
Michal Simek5206cca2014-03-13 11:23:43 +010049 ret_val = spartan2_sp_load(desc, buf, bsize);
wdenke2211742002-11-02 23:30:20 +000050 break;
51
52 default:
53 printf ("%s: Unsupported interface type, %d\n",
54 __FUNCTION__, desc->iface);
55 }
56
57 return ret_val;
58}
59
Michal Simek75fafac2014-03-13 13:07:57 +010060static int spartan2_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenke2211742002-11-02 23:30:20 +000061{
62 int ret_val = FPGA_FAIL;
63
64 switch (desc->iface) {
65 case slave_serial:
Alexander Dahlcb9c1f92022-10-07 14:20:01 +020066 log_debug("Launching Slave Serial Dump\n");
Michal Simek5206cca2014-03-13 11:23:43 +010067 ret_val = spartan2_ss_dump(desc, buf, bsize);
wdenke2211742002-11-02 23:30:20 +000068 break;
69
70 case slave_parallel:
Alexander Dahlcb9c1f92022-10-07 14:20:01 +020071 log_debug("Launching Slave Parallel Dump\n");
Michal Simek5206cca2014-03-13 11:23:43 +010072 ret_val = spartan2_sp_dump(desc, buf, bsize);
wdenke2211742002-11-02 23:30:20 +000073 break;
74
75 default:
76 printf ("%s: Unsupported interface type, %d\n",
77 __FUNCTION__, desc->iface);
78 }
79
80 return ret_val;
81}
82
Michal Simek75fafac2014-03-13 13:07:57 +010083static int spartan2_info(xilinx_desc *desc)
wdenke2211742002-11-02 23:30:20 +000084{
85 return FPGA_SUCCESS;
86}
87
wdenke2211742002-11-02 23:30:20 +000088/* ------------------------------------------------------------------------- */
89/* Spartan-II Slave Parallel Generic Implementation */
90
Michal Simek25e1e2e2014-03-13 12:49:21 +010091static int spartan2_sp_load(xilinx_desc *desc, const void *buf, size_t bsize)
wdenke2211742002-11-02 23:30:20 +000092{
93 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek5206cca2014-03-13 11:23:43 +010094 xilinx_spartan2_slave_parallel_fns *fn = desc->iface_fns;
wdenke2211742002-11-02 23:30:20 +000095
Alexander Dahlcb9c1f92022-10-07 14:20:01 +020096 log_debug("start with interface functions @ 0x%p\n", fn);
wdenke2211742002-11-02 23:30:20 +000097
98 if (fn) {
99 size_t bytecount = 0;
100 unsigned char *data = (unsigned char *) buf;
101 int cookie = desc->cookie; /* make a local copy */
102 unsigned long ts; /* timestamp */
103
Alexander Dahlcb9c1f92022-10-07 14:20:01 +0200104 log_debug("Function Table:\n"
105 "ptr:\t0x%p\n"
106 "struct: 0x%p\n"
107 "pre: 0x%p\n"
108 "pgm:\t0x%p\n"
109 "init:\t0x%p\n"
110 "err:\t0x%p\n"
111 "clk:\t0x%p\n"
112 "cs:\t0x%p\n"
113 "wr:\t0x%p\n"
114 "read data:\t0x%p\n"
115 "write data:\t0x%p\n"
116 "busy:\t0x%p\n"
117 "abort:\t0x%p\n"
118 "post:\t0x%p\n\n",
119 &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
120 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
121 fn->abort, fn->post);
wdenke2211742002-11-02 23:30:20 +0000122
123 /*
124 * This code is designed to emulate the "Express Style"
125 * Continuous Data Loading in Slave Parallel Mode for
126 * the Spartan-II Family.
127 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200128#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenke2211742002-11-02 23:30:20 +0000129 printf ("Loading FPGA Device %d...\n", cookie);
130#endif
131 /*
132 * Run the pre configuration function if there is one.
133 */
134 if (*fn->pre) {
135 (*fn->pre) (cookie);
136 }
137
138 /* Establish the initial state */
York Sun4a598092013-04-01 11:29:11 -0700139 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
wdenke2211742002-11-02 23:30:20 +0000140
141 /* Get ready for the burn */
Tom Rini88d86ec2022-12-04 10:03:57 -0500142 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700143 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
wdenke2211742002-11-02 23:30:20 +0000144
145 ts = get_timer (0); /* get current time */
146 /* Now wait for INIT and BUSY to go high */
147 do {
Tom Rini88d86ec2022-12-04 10:03:57 -0500148 CFG_FPGA_DELAY ();
Tom Rini6a5dccc2022-11-16 13:10:41 -0500149 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
wdenke2211742002-11-02 23:30:20 +0000150 puts ("** Timeout waiting for INIT to clear.\n");
151 (*fn->abort) (cookie); /* abort the burn */
152 return FPGA_FAIL;
153 }
154 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
155
York Sun4a598092013-04-01 11:29:11 -0700156 (*fn->wr) (true, true, cookie); /* Assert write, commit */
157 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
158 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenke2211742002-11-02 23:30:20 +0000159
160 /* Load the data */
161 while (bytecount < bsize) {
162 /* XXX - do we check for an Ctrl-C press in here ??? */
163 /* XXX - Check the error bit? */
164
York Sun4a598092013-04-01 11:29:11 -0700165 (*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
Tom Rini88d86ec2022-12-04 10:03:57 -0500166 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700167 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Tom Rini88d86ec2022-12-04 10:03:57 -0500168 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700169 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenke2211742002-11-02 23:30:20 +0000170
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200171#ifdef CONFIG_SYS_FPGA_CHECK_BUSY
wdenke2211742002-11-02 23:30:20 +0000172 ts = get_timer (0); /* get current time */
173 while ((*fn->busy) (cookie)) {
174 /* XXX - we should have a check in here somewhere to
175 * make sure we aren't busy forever... */
176
Tom Rini88d86ec2022-12-04 10:03:57 -0500177 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700178 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Tom Rini88d86ec2022-12-04 10:03:57 -0500179 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700180 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenke2211742002-11-02 23:30:20 +0000181
Tom Rini6a5dccc2022-11-16 13:10:41 -0500182 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
wdenke2211742002-11-02 23:30:20 +0000183 puts ("** Timeout waiting for BUSY to clear.\n");
184 (*fn->abort) (cookie); /* abort the burn */
185 return FPGA_FAIL;
186 }
187 }
188#endif
189
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200190#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenke2211742002-11-02 23:30:20 +0000191 if (bytecount % (bsize / 40) == 0)
192 putc ('.'); /* let them know we are alive */
193#endif
194 }
195
Tom Rini88d86ec2022-12-04 10:03:57 -0500196 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700197 (*fn->cs) (false, true, cookie); /* Deassert the chip select */
198 (*fn->wr) (false, true, cookie); /* Deassert the write pin */
wdenke2211742002-11-02 23:30:20 +0000199
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200200#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenke2211742002-11-02 23:30:20 +0000201 putc ('\n'); /* terminate the dotted line */
202#endif
203
204 /* now check for done signal */
205 ts = get_timer (0); /* get current time */
206 ret_val = FPGA_SUCCESS;
207 while ((*fn->done) (cookie) == FPGA_FAIL) {
wdenke2211742002-11-02 23:30:20 +0000208
Tom Rini88d86ec2022-12-04 10:03:57 -0500209 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700210 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Tom Rini88d86ec2022-12-04 10:03:57 -0500211 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700212 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenke2211742002-11-02 23:30:20 +0000213
Tom Rini6a5dccc2022-11-16 13:10:41 -0500214 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
wdenke2211742002-11-02 23:30:20 +0000215 puts ("** Timeout waiting for DONE to clear.\n");
216 (*fn->abort) (cookie); /* abort the burn */
217 ret_val = FPGA_FAIL;
218 break;
219 }
220 }
221
wdenke2211742002-11-02 23:30:20 +0000222 /*
223 * Run the post configuration function if there is one.
224 */
Matthias Fuchsf73e0ed2009-02-15 22:28:36 +0100225 if (*fn->post)
wdenke2211742002-11-02 23:30:20 +0000226 (*fn->post) (cookie);
wdenke2211742002-11-02 23:30:20 +0000227
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200228#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Matthias Fuchsf73e0ed2009-02-15 22:28:36 +0100229 if (ret_val == FPGA_SUCCESS)
230 puts ("Done.\n");
231 else
wdenke2211742002-11-02 23:30:20 +0000232 puts ("Fail.\n");
233#endif
wdenke2211742002-11-02 23:30:20 +0000234
235 } else {
236 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
237 }
238
239 return ret_val;
240}
241
Michal Simek25e1e2e2014-03-13 12:49:21 +0100242static int spartan2_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenke2211742002-11-02 23:30:20 +0000243{
244 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek5206cca2014-03-13 11:23:43 +0100245 xilinx_spartan2_slave_parallel_fns *fn = desc->iface_fns;
wdenke2211742002-11-02 23:30:20 +0000246
247 if (fn) {
248 unsigned char *data = (unsigned char *) buf;
249 size_t bytecount = 0;
250 int cookie = desc->cookie; /* make a local copy */
251
252 printf ("Starting Dump of FPGA Device %d...\n", cookie);
253
York Sun4a598092013-04-01 11:29:11 -0700254 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
255 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenke2211742002-11-02 23:30:20 +0000256
257 /* dump the data */
258 while (bytecount < bsize) {
259 /* XXX - do we check for an Ctrl-C press in here ??? */
260
York Sun4a598092013-04-01 11:29:11 -0700261 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
262 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenke2211742002-11-02 23:30:20 +0000263 (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200264#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenke2211742002-11-02 23:30:20 +0000265 if (bytecount % (bsize / 40) == 0)
266 putc ('.'); /* let them know we are alive */
267#endif
268 }
269
York Sun4a598092013-04-01 11:29:11 -0700270 (*fn->cs) (false, false, cookie); /* Deassert the chip select */
271 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
272 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenke2211742002-11-02 23:30:20 +0000273
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200274#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenke2211742002-11-02 23:30:20 +0000275 putc ('\n'); /* terminate the dotted line */
276#endif
277 puts ("Done.\n");
278
279 /* XXX - checksum the data? */
280 } else {
281 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
282 }
283
284 return ret_val;
285}
286
wdenke2211742002-11-02 23:30:20 +0000287/* ------------------------------------------------------------------------- */
288
Michal Simek25e1e2e2014-03-13 12:49:21 +0100289static int spartan2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
wdenke2211742002-11-02 23:30:20 +0000290{
wdenk57b2d802003-06-27 21:31:46 +0000291 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek5206cca2014-03-13 11:23:43 +0100292 xilinx_spartan2_slave_serial_fns *fn = desc->iface_fns;
wdenk57b2d802003-06-27 21:31:46 +0000293 int i;
Matthias Fuchsb845b1e2007-12-27 17:13:05 +0100294 unsigned char val;
wdenk57b2d802003-06-27 21:31:46 +0000295
Alexander Dahlcb9c1f92022-10-07 14:20:01 +0200296 log_debug("start with interface functions @ 0x%p\n", fn);
wdenk1272e232002-11-10 22:06:23 +0000297
298 if (fn) {
299 size_t bytecount = 0;
300 unsigned char *data = (unsigned char *) buf;
301 int cookie = desc->cookie; /* make a local copy */
302 unsigned long ts; /* timestamp */
303
Alexander Dahlcb9c1f92022-10-07 14:20:01 +0200304 log_debug("Function Table:\n"
305 "ptr:\t0x%p\n"
306 "struct: 0x%p\n"
307 "pgm:\t0x%p\n"
308 "init:\t0x%p\n"
309 "clk:\t0x%p\n"
310 "wr:\t0x%p\n"
311 "done:\t0x%p\n\n",
312 &fn, fn, fn->pgm, fn->init,
313 fn->clk, fn->wr, fn->done);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200314#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk1272e232002-11-10 22:06:23 +0000315 printf ("Loading FPGA Device %d...\n", cookie);
316#endif
317
318 /*
319 * Run the pre configuration function if there is one.
320 */
321 if (*fn->pre) {
322 (*fn->pre) (cookie);
323 }
324
325 /* Establish the initial state */
York Sun4a598092013-04-01 11:29:11 -0700326 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
wdenk1272e232002-11-10 22:06:23 +0000327
wdenk57b2d802003-06-27 21:31:46 +0000328 /* Wait for INIT state (init low) */
wdenk1272e232002-11-10 22:06:23 +0000329 ts = get_timer (0); /* get current time */
330 do {
Tom Rini88d86ec2022-12-04 10:03:57 -0500331 CFG_FPGA_DELAY ();
Tom Rini6a5dccc2022-11-16 13:10:41 -0500332 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
wdenk1272e232002-11-10 22:06:23 +0000333 puts ("** Timeout waiting for INIT to start.\n");
334 return FPGA_FAIL;
335 }
336 } while (!(*fn->init) (cookie));
wdenk57b2d802003-06-27 21:31:46 +0000337
wdenk1272e232002-11-10 22:06:23 +0000338 /* Get ready for the burn */
Tom Rini88d86ec2022-12-04 10:03:57 -0500339 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700340 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
wdenk1272e232002-11-10 22:06:23 +0000341
342 ts = get_timer (0); /* get current time */
343 /* Now wait for INIT to go high */
344 do {
Tom Rini88d86ec2022-12-04 10:03:57 -0500345 CFG_FPGA_DELAY ();
Tom Rini6a5dccc2022-11-16 13:10:41 -0500346 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
wdenk1272e232002-11-10 22:06:23 +0000347 puts ("** Timeout waiting for INIT to clear.\n");
348 return FPGA_FAIL;
349 }
350 } while ((*fn->init) (cookie));
351
352 /* Load the data */
353 while (bytecount < bsize) {
wdenk57b2d802003-06-27 21:31:46 +0000354
355 /* Xilinx detects an error if INIT goes low (active)
356 while DONE is low (inactive) */
357 if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
358 puts ("** CRC error during FPGA load.\n");
359 return (FPGA_FAIL);
360 }
361 val = data [bytecount ++];
362 i = 8;
363 do {
364 /* Deassert the clock */
York Sun4a598092013-04-01 11:29:11 -0700365 (*fn->clk) (false, true, cookie);
Tom Rini88d86ec2022-12-04 10:03:57 -0500366 CFG_FPGA_DELAY ();
wdenk57b2d802003-06-27 21:31:46 +0000367 /* Write data */
York Sun4a598092013-04-01 11:29:11 -0700368 (*fn->wr) ((val & 0x80), true, cookie);
Tom Rini88d86ec2022-12-04 10:03:57 -0500369 CFG_FPGA_DELAY ();
wdenk57b2d802003-06-27 21:31:46 +0000370 /* Assert the clock */
York Sun4a598092013-04-01 11:29:11 -0700371 (*fn->clk) (true, true, cookie);
Tom Rini88d86ec2022-12-04 10:03:57 -0500372 CFG_FPGA_DELAY ();
wdenk57b2d802003-06-27 21:31:46 +0000373 val <<= 1;
374 i --;
375 } while (i > 0);
376
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200377#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk1272e232002-11-10 22:06:23 +0000378 if (bytecount % (bsize / 40) == 0)
379 putc ('.'); /* let them know we are alive */
380#endif
381 }
382
Tom Rini88d86ec2022-12-04 10:03:57 -0500383 CFG_FPGA_DELAY ();
wdenk1272e232002-11-10 22:06:23 +0000384
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200385#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
wdenk1272e232002-11-10 22:06:23 +0000386 putc ('\n'); /* terminate the dotted line */
387#endif
388
389 /* now check for done signal */
390 ts = get_timer (0); /* get current time */
391 ret_val = FPGA_SUCCESS;
York Sun4a598092013-04-01 11:29:11 -0700392 (*fn->wr) (true, true, cookie);
wdenk1272e232002-11-10 22:06:23 +0000393
394 while (! (*fn->done) (cookie)) {
wdenk1272e232002-11-10 22:06:23 +0000395
Tom Rini88d86ec2022-12-04 10:03:57 -0500396 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700397 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Tom Rini88d86ec2022-12-04 10:03:57 -0500398 CFG_FPGA_DELAY ();
York Sun4a598092013-04-01 11:29:11 -0700399 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
wdenk1272e232002-11-10 22:06:23 +0000400
wdenk57b2d802003-06-27 21:31:46 +0000401 putc ('*');
402
Tom Rini6a5dccc2022-11-16 13:10:41 -0500403 if (get_timer (ts) > CFG_SYS_FPGA_WAIT) { /* check the time */
wdenk1272e232002-11-10 22:06:23 +0000404 puts ("** Timeout waiting for DONE to clear.\n");
405 ret_val = FPGA_FAIL;
406 break;
407 }
408 }
409 putc ('\n'); /* terminate the dotted line */
410
Matthias Fuchs518e2e142007-12-27 17:12:43 +0100411 /*
412 * Run the post configuration function if there is one.
413 */
Matthias Fuchsf73e0ed2009-02-15 22:28:36 +0100414 if (*fn->post)
Matthias Fuchs518e2e142007-12-27 17:12:43 +0100415 (*fn->post) (cookie);
Matthias Fuchs518e2e142007-12-27 17:12:43 +0100416
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200417#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Matthias Fuchsf73e0ed2009-02-15 22:28:36 +0100418 if (ret_val == FPGA_SUCCESS)
wdenk1272e232002-11-10 22:06:23 +0000419 puts ("Done.\n");
Matthias Fuchsf73e0ed2009-02-15 22:28:36 +0100420 else
wdenk1272e232002-11-10 22:06:23 +0000421 puts ("Fail.\n");
wdenk1272e232002-11-10 22:06:23 +0000422#endif
423
424 } else {
425 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
426 }
427
428 return ret_val;
wdenke2211742002-11-02 23:30:20 +0000429}
430
Michal Simek25e1e2e2014-03-13 12:49:21 +0100431static int spartan2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
wdenke2211742002-11-02 23:30:20 +0000432{
wdenk57b2d802003-06-27 21:31:46 +0000433 /* Readback is only available through the Slave Parallel and */
434 /* boundary-scan interfaces. */
wdenk1272e232002-11-10 22:06:23 +0000435 printf ("%s: Slave Serial Dumping is unavailable\n",
wdenke2211742002-11-02 23:30:20 +0000436 __FUNCTION__);
437 return FPGA_FAIL;
438}
Michal Simek75fafac2014-03-13 13:07:57 +0100439
440struct xilinx_fpga_op spartan2_op = {
441 .load = spartan2_load,
442 .dump = spartan2_dump,
443 .info = spartan2_info,
444};