blob: 4850c99352ddf330eb37a798be1a26a54bc3fd4c [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Wolfgang Denk875c7892005-09-25 16:44:21 +02002/*
3 * (C) Copyright 2002
4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
Wolfgang Denk875c7892005-09-25 16:44:21 +02005 */
6
7/*
8 * Configuration support for Xilinx Spartan3 devices. Based
9 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
10 */
Wolfgang Denk716c1dc2005-09-25 18:49:35 +020011
Wolfgang Denk875c7892005-09-25 16:44:21 +020012#include <common.h> /* core U-Boot definitions */
13#include <spartan3.h> /* Spartan-II device family */
14
Wolfgang Denk875c7892005-09-25 16:44:21 +020015/* Define FPGA_DEBUG to get debug printf's */
16#ifdef FPGA_DEBUG
17#define PRINTF(fmt,args...) printf (fmt ,##args)
18#else
19#define PRINTF(fmt,args...)
20#endif
21
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020022#undef CONFIG_SYS_FPGA_CHECK_BUSY
Wolfgang Denk875c7892005-09-25 16:44:21 +020023
24/* Note: The assumption is that we cannot possibly run fast enough to
25 * overrun the device (the Slave Parallel mode can free run at 50MHz).
26 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
27 * the board config file to slow things down.
28 */
29#ifndef CONFIG_FPGA_DELAY
30#define CONFIG_FPGA_DELAY()
31#endif
32
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020033#ifndef CONFIG_SYS_FPGA_WAIT
34#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
Wolfgang Denk875c7892005-09-25 16:44:21 +020035#endif
36
Michal Simekf8c1be92014-03-13 12:49:21 +010037static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
38static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
39/* static int spartan3_sp_info(xilinx_desc *desc ); */
Wolfgang Denk875c7892005-09-25 16:44:21 +020040
Michal Simekf8c1be92014-03-13 12:49:21 +010041static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
42static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
43/* static int spartan3_ss_info(xilinx_desc *desc); */
Wolfgang Denk875c7892005-09-25 16:44:21 +020044
45/* ------------------------------------------------------------------------- */
46/* Spartan-II Generic Implementation */
Michal Simek7a78bd22014-05-02 14:09:30 +020047static int spartan3_load(xilinx_desc *desc, const void *buf, size_t bsize,
48 bitstream_type bstype)
Wolfgang Denk875c7892005-09-25 16:44:21 +020049{
50 int ret_val = FPGA_FAIL;
51
52 switch (desc->iface) {
53 case slave_serial:
54 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010055 ret_val = spartan3_ss_load(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020056 break;
57
58 case slave_parallel:
59 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010060 ret_val = spartan3_sp_load(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020061 break;
62
63 default:
64 printf ("%s: Unsupported interface type, %d\n",
65 __FUNCTION__, desc->iface);
66 }
67
68 return ret_val;
69}
70
Michal Simek14cfc4f2014-03-13 13:07:57 +010071static int spartan3_dump(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +020072{
73 int ret_val = FPGA_FAIL;
74
75 switch (desc->iface) {
76 case slave_serial:
77 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010078 ret_val = spartan3_ss_dump(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020079 break;
80
81 case slave_parallel:
82 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
Michal Simek2a6e3862014-03-13 11:28:42 +010083 ret_val = spartan3_sp_dump(desc, buf, bsize);
Wolfgang Denk875c7892005-09-25 16:44:21 +020084 break;
85
86 default:
87 printf ("%s: Unsupported interface type, %d\n",
88 __FUNCTION__, desc->iface);
89 }
90
91 return ret_val;
92}
93
Michal Simek14cfc4f2014-03-13 13:07:57 +010094static int spartan3_info(xilinx_desc *desc)
Wolfgang Denk875c7892005-09-25 16:44:21 +020095{
96 return FPGA_SUCCESS;
97}
98
99
Wolfgang Denk875c7892005-09-25 16:44:21 +0200100/* ------------------------------------------------------------------------- */
101/* Spartan-II Slave Parallel Generic Implementation */
102
Michal Simekf8c1be92014-03-13 12:49:21 +0100103static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200104{
105 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek2a6e3862014-03-13 11:28:42 +0100106 xilinx_spartan3_slave_parallel_fns *fn = desc->iface_fns;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200107
108 PRINTF ("%s: start with interface functions @ 0x%p\n",
109 __FUNCTION__, fn);
110
111 if (fn) {
112 size_t bytecount = 0;
113 unsigned char *data = (unsigned char *) buf;
114 int cookie = desc->cookie; /* make a local copy */
115 unsigned long ts; /* timestamp */
116
117 PRINTF ("%s: Function Table:\n"
118 "ptr:\t0x%p\n"
119 "struct: 0x%p\n"
120 "pre: 0x%p\n"
121 "pgm:\t0x%p\n"
122 "init:\t0x%p\n"
123 "err:\t0x%p\n"
124 "clk:\t0x%p\n"
125 "cs:\t0x%p\n"
126 "wr:\t0x%p\n"
127 "read data:\t0x%p\n"
128 "write data:\t0x%p\n"
129 "busy:\t0x%p\n"
130 "abort:\t0x%p\n",
131 "post:\t0x%p\n\n",
132 __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
133 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
134 fn->abort, fn->post);
135
136 /*
137 * This code is designed to emulate the "Express Style"
138 * Continuous Data Loading in Slave Parallel Mode for
139 * the Spartan-II Family.
140 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200141#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200142 printf ("Loading FPGA Device %d...\n", cookie);
143#endif
144 /*
145 * Run the pre configuration function if there is one.
146 */
147 if (*fn->pre) {
148 (*fn->pre) (cookie);
149 }
150
151 /* Establish the initial state */
York Sun472d5462013-04-01 11:29:11 -0700152 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200153
154 /* Get ready for the burn */
155 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700156 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200157
158 ts = get_timer (0); /* get current time */
159 /* Now wait for INIT and BUSY to go high */
160 do {
161 CONFIG_FPGA_DELAY ();
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200162 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200163 puts ("** Timeout waiting for INIT to clear.\n");
164 (*fn->abort) (cookie); /* abort the burn */
165 return FPGA_FAIL;
166 }
167 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
168
York Sun472d5462013-04-01 11:29:11 -0700169 (*fn->wr) (true, true, cookie); /* Assert write, commit */
170 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
171 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200172
173 /* Load the data */
174 while (bytecount < bsize) {
175 /* XXX - do we check for an Ctrl-C press in here ??? */
176 /* XXX - Check the error bit? */
177
York Sun472d5462013-04-01 11:29:11 -0700178 (*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200179 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700180 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200181 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700182 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200183
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200184#ifdef CONFIG_SYS_FPGA_CHECK_BUSY
Wolfgang Denk875c7892005-09-25 16:44:21 +0200185 ts = get_timer (0); /* get current time */
186 while ((*fn->busy) (cookie)) {
187 /* XXX - we should have a check in here somewhere to
188 * make sure we aren't busy forever... */
189
190 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700191 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200192 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700193 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200194
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200195 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200196 puts ("** Timeout waiting for BUSY to clear.\n");
197 (*fn->abort) (cookie); /* abort the burn */
198 return FPGA_FAIL;
199 }
200 }
201#endif
202
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200203#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200204 if (bytecount % (bsize / 40) == 0)
205 putc ('.'); /* let them know we are alive */
206#endif
207 }
208
209 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700210 (*fn->cs) (false, true, cookie); /* Deassert the chip select */
211 (*fn->wr) (false, true, cookie); /* Deassert the write pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200212
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200213#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200214 putc ('\n'); /* terminate the dotted line */
215#endif
216
217 /* now check for done signal */
218 ts = get_timer (0); /* get current time */
219 ret_val = FPGA_SUCCESS;
220 while ((*fn->done) (cookie) == FPGA_FAIL) {
221 /* XXX - we should have a check in here somewhere to
222 * make sure we aren't busy forever... */
223
224 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700225 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200226 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700227 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200228
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200229 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200230 puts ("** Timeout waiting for DONE to clear.\n");
231 (*fn->abort) (cookie); /* abort the burn */
232 ret_val = FPGA_FAIL;
233 break;
234 }
235 }
236
Wolfgang Denk875c7892005-09-25 16:44:21 +0200237 /*
238 * Run the post configuration function if there is one.
239 */
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100240 if (*fn->post)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200241 (*fn->post) (cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200242
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200243#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100244 if (ret_val == FPGA_SUCCESS)
245 puts ("Done.\n");
246 else
Wolfgang Denk875c7892005-09-25 16:44:21 +0200247 puts ("Fail.\n");
248#endif
Wolfgang Denk875c7892005-09-25 16:44:21 +0200249
250 } else {
251 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
252 }
253
254 return ret_val;
255}
256
Michal Simekf8c1be92014-03-13 12:49:21 +0100257static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200258{
259 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek2a6e3862014-03-13 11:28:42 +0100260 xilinx_spartan3_slave_parallel_fns *fn = desc->iface_fns;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200261
262 if (fn) {
263 unsigned char *data = (unsigned char *) buf;
264 size_t bytecount = 0;
265 int cookie = desc->cookie; /* make a local copy */
266
267 printf ("Starting Dump of FPGA Device %d...\n", cookie);
268
York Sun472d5462013-04-01 11:29:11 -0700269 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
270 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200271
272 /* dump the data */
273 while (bytecount < bsize) {
274 /* XXX - do we check for an Ctrl-C press in here ??? */
275
York Sun472d5462013-04-01 11:29:11 -0700276 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
277 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200278 (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200279#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200280 if (bytecount % (bsize / 40) == 0)
281 putc ('.'); /* let them know we are alive */
282#endif
283 }
284
York Sun472d5462013-04-01 11:29:11 -0700285 (*fn->cs) (false, false, cookie); /* Deassert the chip select */
286 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
287 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200288
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200289#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200290 putc ('\n'); /* terminate the dotted line */
291#endif
292 puts ("Done.\n");
293
294 /* XXX - checksum the data? */
295 } else {
296 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
297 }
298
299 return ret_val;
300}
301
302
Wolfgang Denk875c7892005-09-25 16:44:21 +0200303/* ------------------------------------------------------------------------- */
304
Michal Simekf8c1be92014-03-13 12:49:21 +0100305static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200306{
307 int ret_val = FPGA_FAIL; /* assume the worst */
Michal Simek2a6e3862014-03-13 11:28:42 +0100308 xilinx_spartan3_slave_serial_fns *fn = desc->iface_fns;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200309 int i;
Matthias Fuchs437fc732007-12-27 17:13:05 +0100310 unsigned char val;
Wolfgang Denk875c7892005-09-25 16:44:21 +0200311
312 PRINTF ("%s: start with interface functions @ 0x%p\n",
313 __FUNCTION__, fn);
314
315 if (fn) {
316 size_t bytecount = 0;
317 unsigned char *data = (unsigned char *) buf;
318 int cookie = desc->cookie; /* make a local copy */
319 unsigned long ts; /* timestamp */
320
321 PRINTF ("%s: Function Table:\n"
322 "ptr:\t0x%p\n"
323 "struct: 0x%p\n"
324 "pgm:\t0x%p\n"
325 "init:\t0x%p\n"
326 "clk:\t0x%p\n"
327 "wr:\t0x%p\n"
328 "done:\t0x%p\n\n",
329 __FUNCTION__, &fn, fn, fn->pgm, fn->init,
330 fn->clk, fn->wr, fn->done);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200331#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200332 printf ("Loading FPGA Device %d...\n", cookie);
333#endif
334
335 /*
336 * Run the pre configuration function if there is one.
337 */
338 if (*fn->pre) {
339 (*fn->pre) (cookie);
340 }
341
342 /* Establish the initial state */
York Sun472d5462013-04-01 11:29:11 -0700343 (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200344
345 /* Wait for INIT state (init low) */
346 ts = get_timer (0); /* get current time */
347 do {
348 CONFIG_FPGA_DELAY ();
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200349 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200350 puts ("** Timeout waiting for INIT to start.\n");
Wolfgang Wegnerb0bc8b72010-04-23 11:08:05 +0200351 if (*fn->abort)
352 (*fn->abort) (cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200353 return FPGA_FAIL;
354 }
355 } while (!(*fn->init) (cookie));
356
357 /* Get ready for the burn */
358 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700359 (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200360
361 ts = get_timer (0); /* get current time */
362 /* Now wait for INIT to go high */
363 do {
364 CONFIG_FPGA_DELAY ();
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200365 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200366 puts ("** Timeout waiting for INIT to clear.\n");
Wolfgang Wegnerb0bc8b72010-04-23 11:08:05 +0200367 if (*fn->abort)
368 (*fn->abort) (cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200369 return FPGA_FAIL;
370 }
371 } while ((*fn->init) (cookie));
372
373 /* Load the data */
Wolfgang Wegner89083342009-10-30 16:55:02 +0100374 if(*fn->bwr)
York Sun472d5462013-04-01 11:29:11 -0700375 (*fn->bwr) (data, bsize, true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100376 else {
377 while (bytecount < bsize) {
Wolfgang Denk875c7892005-09-25 16:44:21 +0200378
Wolfgang Wegner89083342009-10-30 16:55:02 +0100379 /* Xilinx detects an error if INIT goes low (active)
380 while DONE is low (inactive) */
381 if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
382 puts ("** CRC error during FPGA load.\n");
Wolfgang Wegnerb0bc8b72010-04-23 11:08:05 +0200383 if (*fn->abort)
384 (*fn->abort) (cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100385 return (FPGA_FAIL);
386 }
387 val = data [bytecount ++];
388 i = 8;
389 do {
390 /* Deassert the clock */
York Sun472d5462013-04-01 11:29:11 -0700391 (*fn->clk) (false, true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100392 CONFIG_FPGA_DELAY ();
393 /* Write data */
York Sun472d5462013-04-01 11:29:11 -0700394 (*fn->wr) ((val & 0x80), true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100395 CONFIG_FPGA_DELAY ();
396 /* Assert the clock */
York Sun472d5462013-04-01 11:29:11 -0700397 (*fn->clk) (true, true, cookie);
Wolfgang Wegner89083342009-10-30 16:55:02 +0100398 CONFIG_FPGA_DELAY ();
399 val <<= 1;
400 i --;
401 } while (i > 0);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200402
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200403#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Wegner89083342009-10-30 16:55:02 +0100404 if (bytecount % (bsize / 40) == 0)
405 putc ('.'); /* let them know we are alive */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200406#endif
Wolfgang Wegner89083342009-10-30 16:55:02 +0100407 }
Wolfgang Denk875c7892005-09-25 16:44:21 +0200408 }
409
410 CONFIG_FPGA_DELAY ();
411
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200412#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Wolfgang Denk875c7892005-09-25 16:44:21 +0200413 putc ('\n'); /* terminate the dotted line */
414#endif
415
416 /* now check for done signal */
417 ts = get_timer (0); /* get current time */
418 ret_val = FPGA_SUCCESS;
York Sun472d5462013-04-01 11:29:11 -0700419 (*fn->wr) (true, true, cookie);
Wolfgang Denk875c7892005-09-25 16:44:21 +0200420
421 while (! (*fn->done) (cookie)) {
422 /* XXX - we should have a check in here somewhere to
423 * make sure we aren't busy forever... */
424
425 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700426 (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200427 CONFIG_FPGA_DELAY ();
York Sun472d5462013-04-01 11:29:11 -0700428 (*fn->clk) (true, true, cookie); /* Assert the clock pin */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200429
430 putc ('*');
431
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200432 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
Wolfgang Denk875c7892005-09-25 16:44:21 +0200433 puts ("** Timeout waiting for DONE to clear.\n");
434 ret_val = FPGA_FAIL;
435 break;
436 }
437 }
438 putc ('\n'); /* terminate the dotted line */
439
Matthias Fuchs21d39d52007-12-27 17:12:43 +0100440 /*
441 * Run the post configuration function if there is one.
442 */
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100443 if (*fn->post)
Matthias Fuchs21d39d52007-12-27 17:12:43 +0100444 (*fn->post) (cookie);
Matthias Fuchs21d39d52007-12-27 17:12:43 +0100445
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200446#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100447 if (ret_val == FPGA_SUCCESS)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200448 puts ("Done.\n");
Matthias Fuchs670cbde2009-02-15 22:29:15 +0100449 else
Wolfgang Denk875c7892005-09-25 16:44:21 +0200450 puts ("Fail.\n");
Wolfgang Denk875c7892005-09-25 16:44:21 +0200451#endif
452
453 } else {
454 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
455 }
456
457 return ret_val;
458}
459
Michal Simekf8c1be92014-03-13 12:49:21 +0100460static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
Wolfgang Denk875c7892005-09-25 16:44:21 +0200461{
462 /* Readback is only available through the Slave Parallel and */
463 /* boundary-scan interfaces. */
464 printf ("%s: Slave Serial Dumping is unavailable\n",
465 __FUNCTION__);
466 return FPGA_FAIL;
467}
Michal Simek14cfc4f2014-03-13 13:07:57 +0100468
469struct xilinx_fpga_op spartan3_op = {
470 .load = spartan3_load,
471 .dump = spartan3_dump,
472 .info = spartan3_info,
473};