blob: b0213e69992b5772f4e1984bf0a697cd34331832 [file] [log] [blame]
Wolfgang Denk875c7892005-09-25 16:44:21 +02001/*
2 * (C) Copyright 2002
3 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Wolfgang Denk875c7892005-09-25 16:44:21 +02006 */
7
8/*
9 * Configuration support for Xilinx Spartan3 devices. Based
10 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
11 */
Wolfgang Denk716c1dc2005-09-25 18:49:35 +020012
Wolfgang Denk875c7892005-09-25 16:44:21 +020013#include <common.h> /* core U-Boot definitions */
14#include <spartan3.h> /* Spartan-II device family */
15
Wolfgang Denk875c7892005-09-25 16:44:21 +020016/* Define FPGA_DEBUG to get debug printf's */
17#ifdef FPGA_DEBUG
18#define PRINTF(fmt,args...) printf (fmt ,##args)
19#else
20#define PRINTF(fmt,args...)
21#endif
22
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020023#undef CONFIG_SYS_FPGA_CHECK_BUSY
Wolfgang Denk875c7892005-09-25 16:44:21 +020024
25/* Note: The assumption is that we cannot possibly run fast enough to
26 * overrun the device (the Slave Parallel mode can free run at 50MHz).
27 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
28 * the board config file to slow things down.
29 */
30#ifndef CONFIG_FPGA_DELAY
31#define CONFIG_FPGA_DELAY()
32#endif
33
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020034#ifndef CONFIG_SYS_FPGA_WAIT
35#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
Wolfgang Denk875c7892005-09-25 16:44:21 +020036#endif
37
Michal Simekf8c1be92014-03-13 12:49:21 +010038static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
39static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
40/* static int spartan3_sp_info(xilinx_desc *desc ); */
Wolfgang Denk875c7892005-09-25 16:44:21 +020041
Michal Simekf8c1be92014-03-13 12:49:21 +010042static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
43static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
44/* static int spartan3_ss_info(xilinx_desc *desc); */
Wolfgang Denk875c7892005-09-25 16:44:21 +020045
46/* ------------------------------------------------------------------------- */
47/* Spartan-II Generic Implementation */
Michal Simek7a78bd22014-05-02 14:09:30 +020048static int spartan3_load(xilinx_desc *desc, const void *buf, size_t bsize,
49 bitstream_type bstype)
Wolfgang Denk875c7892005-09-25 16:44:21 +020050{
51 int ret_val = FPGA_FAIL;
52
53 switch (desc->iface) {
54 case slave_serial:
55 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010056 ret_val = spartan3_ss_load(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020057 break;
58
59 case slave_parallel:
60 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010061 ret_val = spartan3_sp_load(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020062 break;
63
64 default:
65 printf ("%s: Unsupported interface type, %d\n",
66 __FUNCTION__, desc->iface);
67 }
68
69 return ret_val;
70}
71
Michal Simek14cfc4f2014-03-13 13:07:57 +010072static int spartan3_dump(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +020073{
74 int ret_val = FPGA_FAIL;
75
76 switch (desc->iface) {
77 case slave_serial:
78 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010079 ret_val = spartan3_ss_dump(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020080 break;
81
82 case slave_parallel:
83 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010084 ret_val = spartan3_sp_dump(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020085 break;
86
87 default:
88 printf ("%s: Unsupported interface type, %d\n",
89 __FUNCTION__, desc->iface);
90 }
91
92 return ret_val;
93}
94
Michal Simek14cfc4f2014-03-13 13:07:57 +010095static int spartan3_info(xilinx_desc *desc)
Wolfgang Denk875c7892005-09-25 16:44:21 +020096{
97 return FPGA_SUCCESS;
98}
99
100
Wolfgang Denk875c7892005-09-25 16:44:21 +0200101/* ------------------------------------------------------------------------- */
102/* Spartan-II Slave Parallel Generic Implementation */
103
Michal Simekf8c1be92014-03-13 12:49:21 +0100104static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200105{
106 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek2a6e3862014-03-13 11:28:42 +0100107 xilinx_spartan3_slave_parallel_fns *fn = desc->iface_fns;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200108
109 PRINTF ("%s: start with interface functions @ 0x%p\n",
110 __FUNCTION__, fn);
111
112 if (fn) {
113 size_t bytecount = 0;
114 unsigned char *data = (unsigned char *) buf;
115 int cookie = desc->cookie; /* make a local copy */
116 unsigned long ts; /* timestamp */
117
118 PRINTF ("%s: Function Table:\n"
119 "ptr:\t0x%p\n"
120 "struct: 0x%p\n"
121 "pre: 0x%p\n"
122 "pgm:\t0x%p\n"
123 "init:\t0x%p\n"
124 "err:\t0x%p\n"
125 "clk:\t0x%p\n"
126 "cs:\t0x%p\n"
127 "wr:\t0x%p\n"
128 "read data:\t0x%p\n"
129 "write data:\t0x%p\n"
130 "busy:\t0x%p\n"
131 "abort:\t0x%p\n",
132 "post:\t0x%p\n\n",
133 __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
134 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
135 fn->abort, fn->post);
136
137 /*
138 * This code is designed to emulate the "Express Style"
139 * Continuous Data Loading in Slave Parallel Mode for
140 * the Spartan-II Family.
141 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200142#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200143 printf ("Loading FPGA Device %d...\n", cookie);
144#endif
145 /*
146 * Run the pre configuration function if there is one.
147 */
148 if (*fn->pre) {
149 (*fn->pre) (cookie);
150 }
151
152 /* Establish the initial state */
York Sun472d5462013-04-01 11:29:11 -0700153 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200154
155 /* Get ready for the burn */
156 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700157 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200158
159 ts = get_timer (0); /* get current time */
160 /* Now wait for INIT and BUSY to go high */
161 do {
162 CONFIG_FPGA_DELAY ();
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200163 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200164 puts ("** Timeout waiting for INIT to clear.\n");
165 (*fn->abort) (cookie); /* abort the burn */
166 return FPGA_FAIL;
167 }
168 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
169
York Sun472d5462013-04-01 11:29:11 -0700170 (*fn->wr) (true, true, cookie); /* Assert write, commit */
171 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
172 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200173
174 /* Load the data */
175 while (bytecount < bsize) {
176 /* XXX - do we check for an Ctrl-C press in here ??? */
177 /* XXX - Check the error bit? */
178
York Sun472d5462013-04-01 11:29:11 -0700179 (*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200180 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700181 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200182 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700183 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200184
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200185#ifdef CONFIG_SYS_FPGA_CHECK_BUSY
Wolfgang Denk875c7892005-09-25 16:44:21 +0200186 ts = get_timer (0); /* get current time */
187 while ((*fn->busy) (cookie)) {
188 /* XXX - we should have a check in here somewhere to
189 * make sure we aren't busy forever... */
190
191 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700192 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200193 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700194 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200195
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200196 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200197 puts ("** Timeout waiting for BUSY to clear.\n");
198 (*fn->abort) (cookie); /* abort the burn */
199 return FPGA_FAIL;
200 }
201 }
202#endif
203
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200204#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200205 if (bytecount % (bsize / 40) == 0)
206 putc ('.'); /* let them know we are alive */
207#endif
208 }
209
210 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700211 (*fn->cs) (false, true, cookie); /* Deassert the chip select */
212 (*fn->wr) (false, true, cookie); /* Deassert the write pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200213
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200214#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200215 putc ('\n'); /* terminate the dotted line */
216#endif
217
218 /* now check for done signal */
219 ts = get_timer (0); /* get current time */
220 ret_val = FPGA_SUCCESS;
221 while ((*fn->done) (cookie) == FPGA_FAIL) {
222 /* XXX - we should have a check in here somewhere to
223 * make sure we aren't busy forever... */
224
225 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700226 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200227 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700228 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200229
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200230 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200231 puts ("** Timeout waiting for DONE to clear.\n");
232 (*fn->abort) (cookie); /* abort the burn */
233 ret_val = FPGA_FAIL;
234 break;
235 }
236 }
237
Wolfgang Denk875c7892005-09-25 16:44:21 +0200238 /*
239 * Run the post configuration function if there is one.
240 */
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100241 if (*fn->post)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200242 (*fn->post) (cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200243
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200244#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100245 if (ret_val == FPGA_SUCCESS)
246 puts ("Done.\n");
247 else
Wolfgang Denk875c7892005-09-25 16:44:21 +0200248 puts ("Fail.\n");
249#endif
Wolfgang Denk875c7892005-09-25 16:44:21 +0200250
251 } else {
252 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
253 }
254
255 return ret_val;
256}
257
Michal Simekf8c1be92014-03-13 12:49:21 +0100258static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200259{
260 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek2a6e3862014-03-13 11:28:42 +0100261 xilinx_spartan3_slave_parallel_fns *fn = desc->iface_fns;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200262
263 if (fn) {
264 unsigned char *data = (unsigned char *) buf;
265 size_t bytecount = 0;
266 int cookie = desc->cookie; /* make a local copy */
267
268 printf ("Starting Dump of FPGA Device %d...\n", cookie);
269
York Sun472d5462013-04-01 11:29:11 -0700270 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
271 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200272
273 /* dump the data */
274 while (bytecount < bsize) {
275 /* XXX - do we check for an Ctrl-C press in here ??? */
276
York Sun472d5462013-04-01 11:29:11 -0700277 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
278 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200279 (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200280#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200281 if (bytecount % (bsize / 40) == 0)
282 putc ('.'); /* let them know we are alive */
283#endif
284 }
285
York Sun472d5462013-04-01 11:29:11 -0700286 (*fn->cs) (false, false, cookie); /* Deassert the chip select */
287 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
288 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200289
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200290#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200291 putc ('\n'); /* terminate the dotted line */
292#endif
293 puts ("Done.\n");
294
295 /* XXX - checksum the data? */
296 } else {
297 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
298 }
299
300 return ret_val;
301}
302
303
Wolfgang Denk875c7892005-09-25 16:44:21 +0200304/* ------------------------------------------------------------------------- */
305
Michal Simekf8c1be92014-03-13 12:49:21 +0100306static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200307{
308 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek2a6e3862014-03-13 11:28:42 +0100309 xilinx_spartan3_slave_serial_fns *fn = desc->iface_fns;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200310 int i;
Matthias Fuchs437fc732007-12-27 17:13:05 +0100311 unsigned char val;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200312
313 PRINTF ("%s: start with interface functions @ 0x%p\n",
314 __FUNCTION__, fn);
315
316 if (fn) {
317 size_t bytecount = 0;
318 unsigned char *data = (unsigned char *) buf;
319 int cookie = desc->cookie; /* make a local copy */
320 unsigned long ts; /* timestamp */
321
322 PRINTF ("%s: Function Table:\n"
323 "ptr:\t0x%p\n"
324 "struct: 0x%p\n"
325 "pgm:\t0x%p\n"
326 "init:\t0x%p\n"
327 "clk:\t0x%p\n"
328 "wr:\t0x%p\n"
329 "done:\t0x%p\n\n",
330 __FUNCTION__, &fn, fn, fn->pgm, fn->init,
331 fn->clk, fn->wr, fn->done);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200332#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200333 printf ("Loading FPGA Device %d...\n", cookie);
334#endif
335
336 /*
337 * Run the pre configuration function if there is one.
338 */
339 if (*fn->pre) {
340 (*fn->pre) (cookie);
341 }
342
343 /* Establish the initial state */
York Sun472d5462013-04-01 11:29:11 -0700344 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200345
346 /* Wait for INIT state (init low) */
347 ts = get_timer (0); /* get current time */
348 do {
349 CONFIG_FPGA_DELAY ();
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200350 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200351 puts ("** Timeout waiting for INIT to start.\n");
Wolfgang Wegnerb0bc8b72010-04-23 11:08:05 +0200352 if (*fn->abort)
353 (*fn->abort) (cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200354 return FPGA_FAIL;
355 }
356 } while (!(*fn->init) (cookie));
357
358 /* Get ready for the burn */
359 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700360 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200361
362 ts = get_timer (0); /* get current time */
363 /* Now wait for INIT to go high */
364 do {
365 CONFIG_FPGA_DELAY ();
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200366 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200367 puts ("** Timeout waiting for INIT to clear.\n");
Wolfgang Wegnerb0bc8b72010-04-23 11:08:05 +0200368 if (*fn->abort)
369 (*fn->abort) (cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200370 return FPGA_FAIL;
371 }
372 } while ((*fn->init) (cookie));
373
374 /* Load the data */
Wolfgang Wegner89083342009-10-30 16:55:02 +0100375 if(*fn->bwr)
York Sun472d5462013-04-01 11:29:11 -0700376 (*fn->bwr) (data, bsize, true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100377 else {
378 while (bytecount < bsize) {
Wolfgang Denk875c7892005-09-25 16:44:21 +0200379
Wolfgang Wegner89083342009-10-30 16:55:02 +0100380 /* Xilinx detects an error if INIT goes low (active)
381 while DONE is low (inactive) */
382 if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
383 puts ("** CRC error during FPGA load.\n");
Wolfgang Wegnerb0bc8b72010-04-23 11:08:05 +0200384 if (*fn->abort)
385 (*fn->abort) (cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100386 return (FPGA_FAIL);
387 }
388 val = data [bytecount ++];
389 i = 8;
390 do {
391 /* Deassert the clock */
York Sun472d5462013-04-01 11:29:11 -0700392 (*fn->clk) (false, true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100393 CONFIG_FPGA_DELAY ();
394 /* Write data */
York Sun472d5462013-04-01 11:29:11 -0700395 (*fn->wr) ((val & 0x80), true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100396 CONFIG_FPGA_DELAY ();
397 /* Assert the clock */
York Sun472d5462013-04-01 11:29:11 -0700398 (*fn->clk) (true, true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100399 CONFIG_FPGA_DELAY ();
400 val <<= 1;
401 i --;
402 } while (i > 0);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200403
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200404#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Wegner89083342009-10-30 16:55:02 +0100405 if (bytecount % (bsize / 40) == 0)
406 putc ('.'); /* let them know we are alive */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200407#endif
Wolfgang Wegner89083342009-10-30 16:55:02 +0100408 }
Wolfgang Denk875c7892005-09-25 16:44:21 +0200409 }
410
411 CONFIG_FPGA_DELAY ();
412
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200413#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200414 putc ('\n'); /* terminate the dotted line */
415#endif
416
417 /* now check for done signal */
418 ts = get_timer (0); /* get current time */
419 ret_val = FPGA_SUCCESS;
York Sun472d5462013-04-01 11:29:11 -0700420 (*fn->wr) (true, true, cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200421
422 while (! (*fn->done) (cookie)) {
423 /* XXX - we should have a check in here somewhere to
424 * make sure we aren't busy forever... */
425
426 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700427 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200428 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700429 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200430
431 putc ('*');
432
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200433 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200434 puts ("** Timeout waiting for DONE to clear.\n");
435 ret_val = FPGA_FAIL;
436 break;
437 }
438 }
439 putc ('\n'); /* terminate the dotted line */
440
Matthias Fuchs21d39d52007-12-27 17:12:43 +0100441 /*
442 * Run the post configuration function if there is one.
443 */
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100444 if (*fn->post)
Matthias Fuchs21d39d52007-12-27 17:12:43 +0100445 (*fn->post) (cookie);
Matthias Fuchs21d39d52007-12-27 17:12:43 +0100446
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200447#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100448 if (ret_val == FPGA_SUCCESS)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200449 puts ("Done.\n");
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100450 else
Wolfgang Denk875c7892005-09-25 16:44:21 +0200451 puts ("Fail.\n");
Wolfgang Denk875c7892005-09-25 16:44:21 +0200452#endif
453
454 } else {
455 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
456 }
457
458 return ret_val;
459}
460
Michal Simekf8c1be92014-03-13 12:49:21 +0100461static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200462{
463 /* Readback is only available through the Slave Parallel and */
464 /* boundary-scan interfaces. */
465 printf ("%s: Slave Serial Dumping is unavailable\n",
466 __FUNCTION__);
467 return FPGA_FAIL;
468}
Michal Simek14cfc4f2014-03-13 13:07:57 +0100469
470struct xilinx_fpga_op spartan3_op = {
471 .load = spartan3_load,
472 .dump = spartan3_dump,
473 .info = spartan3_info,
474};