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