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