]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/fpga/spartan2.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / fpga / spartan2.c
1 /*
2  * (C) Copyright 2002
3  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  */
24
25 #include <common.h>             /* core U-Boot definitions */
26 #include <spartan2.h>           /* Spartan-II device family */
27
28 /* Define FPGA_DEBUG to get debug printf's */
29 #ifdef  FPGA_DEBUG
30 #define PRINTF(fmt,args...)     printf (fmt ,##args)
31 #else
32 #define PRINTF(fmt,args...)
33 #endif
34
35 #undef CONFIG_SYS_FPGA_CHECK_BUSY
36 #undef CONFIG_SYS_FPGA_PROG_FEEDBACK
37
38 /* Note: The assumption is that we cannot possibly run fast enough to
39  * overrun the device (the Slave Parallel mode can free run at 50MHz).
40  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
41  * the board config file to slow things down.
42  */
43 #ifndef CONFIG_FPGA_DELAY
44 #define CONFIG_FPGA_DELAY()
45 #endif
46
47 #ifndef CONFIG_SYS_FPGA_WAIT
48 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100  /* 10 ms */
49 #endif
50
51 static int Spartan2_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize);
52 static int Spartan2_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
53 /* static int Spartan2_sp_info(Xilinx_desc *desc ); */
54
55 static int Spartan2_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize);
56 static int Spartan2_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
57 /* static int Spartan2_ss_info(Xilinx_desc *desc ); */
58
59 /* ------------------------------------------------------------------------- */
60 /* Spartan-II Generic Implementation */
61 int Spartan2_load(Xilinx_desc *desc, const void *buf, size_t bsize)
62 {
63         int ret_val = FPGA_FAIL;
64
65         switch (desc->iface) {
66         case slave_serial:
67                 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
68                 ret_val = Spartan2_ss_load (desc, buf, bsize);
69                 break;
70
71         case slave_parallel:
72                 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
73                 ret_val = Spartan2_sp_load (desc, buf, bsize);
74                 break;
75
76         default:
77                 printf ("%s: Unsupported interface type, %d\n",
78                                 __FUNCTION__, desc->iface);
79         }
80
81         return ret_val;
82 }
83
84 int Spartan2_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
85 {
86         int ret_val = FPGA_FAIL;
87
88         switch (desc->iface) {
89         case slave_serial:
90                 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
91                 ret_val = Spartan2_ss_dump (desc, buf, bsize);
92                 break;
93
94         case slave_parallel:
95                 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
96                 ret_val = Spartan2_sp_dump (desc, buf, bsize);
97                 break;
98
99         default:
100                 printf ("%s: Unsupported interface type, %d\n",
101                                 __FUNCTION__, desc->iface);
102         }
103
104         return ret_val;
105 }
106
107 int Spartan2_info( Xilinx_desc *desc )
108 {
109         return FPGA_SUCCESS;
110 }
111
112
113 /* ------------------------------------------------------------------------- */
114 /* Spartan-II Slave Parallel Generic Implementation */
115
116 static int Spartan2_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize)
117 {
118         int ret_val = FPGA_FAIL;        /* assume the worst */
119         Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns;
120
121         PRINTF ("%s: start with interface functions @ 0x%p\n",
122                         __FUNCTION__, fn);
123
124         if (fn) {
125                 size_t bytecount = 0;
126                 unsigned char *data = (unsigned char *) buf;
127                 int cookie = desc->cookie;      /* make a local copy */
128                 unsigned long ts;               /* timestamp */
129
130                 PRINTF ("%s: Function Table:\n"
131                                 "ptr:\t0x%p\n"
132                                 "struct: 0x%p\n"
133                                 "pre: 0x%p\n"
134                                 "pgm:\t0x%p\n"
135                                 "init:\t0x%p\n"
136                                 "err:\t0x%p\n"
137                                 "clk:\t0x%p\n"
138                                 "cs:\t0x%p\n"
139                                 "wr:\t0x%p\n"
140                                 "read data:\t0x%p\n"
141                                 "write data:\t0x%p\n"
142                                 "busy:\t0x%p\n"
143                                 "abort:\t0x%p\n",
144                                 "post:\t0x%p\n\n",
145                                 __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
146                                 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
147                                 fn->abort, fn->post);
148
149                 /*
150                  * This code is designed to emulate the "Express Style"
151                  * Continuous Data Loading in Slave Parallel Mode for
152                  * the Spartan-II Family.
153                  */
154 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
155                 printf ("Loading FPGA Device %d...\n", cookie);
156 #endif
157                 /*
158                  * Run the pre configuration function if there is one.
159                  */
160                 if (*fn->pre) {
161                         (*fn->pre) (cookie);
162                 }
163
164                 /* Establish the initial state */
165                 (*fn->pgm) (true, true, cookie);        /* Assert the program, commit */
166
167                 /* Get ready for the burn */
168                 CONFIG_FPGA_DELAY ();
169                 (*fn->pgm) (false, true, cookie);       /* Deassert the program, commit */
170
171                 ts = get_timer (0);             /* get current time */
172                 /* Now wait for INIT and BUSY to go high */
173                 do {
174                         CONFIG_FPGA_DELAY ();
175                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
176                                 puts ("** Timeout waiting for INIT to clear.\n");
177                                 (*fn->abort) (cookie);  /* abort the burn */
178                                 return FPGA_FAIL;
179                         }
180                 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
181
182                 (*fn->wr) (true, true, cookie); /* Assert write, commit */
183                 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
184                 (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
185
186                 /* Load the data */
187                 while (bytecount < bsize) {
188                         /* XXX - do we check for an Ctrl-C press in here ??? */
189                         /* XXX - Check the error bit? */
190
191                         (*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
192                         CONFIG_FPGA_DELAY ();
193                         (*fn->clk) (false, true, cookie);       /* Deassert the clock pin */
194                         CONFIG_FPGA_DELAY ();
195                         (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
196
197 #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
198                         ts = get_timer (0);     /* get current time */
199                         while ((*fn->busy) (cookie)) {
200                                 /* XXX - we should have a check in here somewhere to
201                                  * make sure we aren't busy forever... */
202
203                                 CONFIG_FPGA_DELAY ();
204                                 (*fn->clk) (false, true, cookie);       /* Deassert the clock pin */
205                                 CONFIG_FPGA_DELAY ();
206                                 (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
207
208                                 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
209                                         puts ("** Timeout waiting for BUSY to clear.\n");
210                                         (*fn->abort) (cookie);  /* abort the burn */
211                                         return FPGA_FAIL;
212                                 }
213                         }
214 #endif
215
216 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
217                         if (bytecount % (bsize / 40) == 0)
218                                 putc ('.');             /* let them know we are alive */
219 #endif
220                 }
221
222                 CONFIG_FPGA_DELAY ();
223                 (*fn->cs) (false, true, cookie);        /* Deassert the chip select */
224                 (*fn->wr) (false, true, cookie);        /* Deassert the write pin */
225
226 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
227                 putc ('\n');                    /* terminate the dotted line */
228 #endif
229
230                 /* now check for done signal */
231                 ts = get_timer (0);             /* get current time */
232                 ret_val = FPGA_SUCCESS;
233                 while ((*fn->done) (cookie) == FPGA_FAIL) {
234
235                         CONFIG_FPGA_DELAY ();
236                         (*fn->clk) (false, true, cookie);       /* Deassert the clock pin */
237                         CONFIG_FPGA_DELAY ();
238                         (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
239
240                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
241                                 puts ("** Timeout waiting for DONE to clear.\n");
242                                 (*fn->abort) (cookie);  /* abort the burn */
243                                 ret_val = FPGA_FAIL;
244                                 break;
245                         }
246                 }
247
248                 /*
249                  * Run the post configuration function if there is one.
250                  */
251                 if (*fn->post)
252                         (*fn->post) (cookie);
253
254 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
255                 if (ret_val == FPGA_SUCCESS)
256                         puts ("Done.\n");
257                 else
258                         puts ("Fail.\n");
259 #endif
260
261         } else {
262                 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
263         }
264
265         return ret_val;
266 }
267
268 static int Spartan2_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
269 {
270         int ret_val = FPGA_FAIL;        /* assume the worst */
271         Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns;
272
273         if (fn) {
274                 unsigned char *data = (unsigned char *) buf;
275                 size_t bytecount = 0;
276                 int cookie = desc->cookie;      /* make a local copy */
277
278                 printf ("Starting Dump of FPGA Device %d...\n", cookie);
279
280                 (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
281                 (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
282
283                 /* dump the data */
284                 while (bytecount < bsize) {
285                         /* XXX - do we check for an Ctrl-C press in here ??? */
286
287                         (*fn->clk) (false, true, cookie);       /* Deassert the clock pin */
288                         (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
289                         (*fn->rdata) (&(data[bytecount++]), cookie);    /* read the data */
290 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
291                         if (bytecount % (bsize / 40) == 0)
292                                 putc ('.');             /* let them know we are alive */
293 #endif
294                 }
295
296                 (*fn->cs) (false, false, cookie);       /* Deassert the chip select */
297                 (*fn->clk) (false, true, cookie);       /* Deassert the clock pin */
298                 (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
299
300 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
301                 putc ('\n');                    /* terminate the dotted line */
302 #endif
303                 puts ("Done.\n");
304
305                 /* XXX - checksum the data? */
306         } else {
307                 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
308         }
309
310         return ret_val;
311 }
312
313
314 /* ------------------------------------------------------------------------- */
315
316 static int Spartan2_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize)
317 {
318         int ret_val = FPGA_FAIL;        /* assume the worst */
319         Xilinx_Spartan2_Slave_Serial_fns *fn = desc->iface_fns;
320         int i;
321         unsigned char val;
322
323         PRINTF ("%s: start with interface functions @ 0x%p\n",
324                         __FUNCTION__, fn);
325
326         if (fn) {
327                 size_t bytecount = 0;
328                 unsigned char *data = (unsigned char *) buf;
329                 int cookie = desc->cookie;      /* make a local copy */
330                 unsigned long ts;               /* timestamp */
331
332                 PRINTF ("%s: Function Table:\n"
333                                 "ptr:\t0x%p\n"
334                                 "struct: 0x%p\n"
335                                 "pgm:\t0x%p\n"
336                                 "init:\t0x%p\n"
337                                 "clk:\t0x%p\n"
338                                 "wr:\t0x%p\n"
339                                 "done:\t0x%p\n\n",
340                                 __FUNCTION__, &fn, fn, fn->pgm, fn->init,
341                                 fn->clk, fn->wr, fn->done);
342 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
343                 printf ("Loading FPGA Device %d...\n", cookie);
344 #endif
345
346                 /*
347                  * Run the pre configuration function if there is one.
348                  */
349                 if (*fn->pre) {
350                         (*fn->pre) (cookie);
351                 }
352
353                 /* Establish the initial state */
354                 (*fn->pgm) (true, true, cookie);        /* Assert the program, commit */
355
356                 /* Wait for INIT state (init low)                            */
357                 ts = get_timer (0);             /* get current time */
358                 do {
359                         CONFIG_FPGA_DELAY ();
360                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
361                                 puts ("** Timeout waiting for INIT to start.\n");
362                                 return FPGA_FAIL;
363                         }
364                 } while (!(*fn->init) (cookie));
365
366                 /* Get ready for the burn */
367                 CONFIG_FPGA_DELAY ();
368                 (*fn->pgm) (false, true, cookie);       /* Deassert the program, commit */
369
370                 ts = get_timer (0);             /* get current time */
371                 /* Now wait for INIT to go high */
372                 do {
373                         CONFIG_FPGA_DELAY ();
374                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
375                                 puts ("** Timeout waiting for INIT to clear.\n");
376                                 return FPGA_FAIL;
377                         }
378                 } while ((*fn->init) (cookie));
379
380                 /* Load the data */
381                 while (bytecount < bsize) {
382
383                         /* Xilinx detects an error if INIT goes low (active)
384                            while DONE is low (inactive) */
385                         if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
386                                 puts ("** CRC error during FPGA load.\n");
387                                 return (FPGA_FAIL);
388                         }
389                         val = data [bytecount ++];
390                         i = 8;
391                         do {
392                                 /* Deassert the clock */
393                                 (*fn->clk) (false, true, cookie);
394                                 CONFIG_FPGA_DELAY ();
395                                 /* Write data */
396                                 (*fn->wr) ((val & 0x80), true, cookie);
397                                 CONFIG_FPGA_DELAY ();
398                                 /* Assert the clock */
399                                 (*fn->clk) (true, true, cookie);
400                                 CONFIG_FPGA_DELAY ();
401                                 val <<= 1;
402                                 i --;
403                         } while (i > 0);
404
405 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
406                         if (bytecount % (bsize / 40) == 0)
407                                 putc ('.');             /* let them know we are alive */
408 #endif
409                 }
410
411                 CONFIG_FPGA_DELAY ();
412
413 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
414                 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;
420                 (*fn->wr) (true, true, cookie);
421
422                 while (! (*fn->done) (cookie)) {
423
424                         CONFIG_FPGA_DELAY ();
425                         (*fn->clk) (false, true, cookie);       /* Deassert the clock pin */
426                         CONFIG_FPGA_DELAY ();
427                         (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
428
429                         putc ('*');
430
431                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
432                                 puts ("** Timeout waiting for DONE to clear.\n");
433                                 ret_val = FPGA_FAIL;
434                                 break;
435                         }
436                 }
437                 putc ('\n');                    /* terminate the dotted line */
438
439                 /*
440                  * Run the post configuration function if there is one.
441                  */
442                 if (*fn->post)
443                         (*fn->post) (cookie);
444
445 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
446                 if (ret_val == FPGA_SUCCESS)
447                         puts ("Done.\n");
448                 else
449                         puts ("Fail.\n");
450 #endif
451
452         } else {
453                 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
454         }
455
456         return ret_val;
457 }
458
459 static int Spartan2_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
460 {
461         /* Readback is only available through the Slave Parallel and         */
462         /* boundary-scan interfaces.                                         */
463         printf ("%s: Slave Serial Dumping is unavailable\n",
464                         __FUNCTION__);
465         return FPGA_FAIL;
466 }