]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/virtex2.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / common / virtex2.c
1 /*
2  * (C) Copyright 2002
3  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4  * Keith Outwater, keith_outwater@mvis.com
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  *
24  */
25
26 /*
27  * Configuration support for Xilinx Virtex2 devices.  Based
28  * on spartan2.c (Rich Ireland, rireland@enterasys.com).
29  */
30
31 #include <common.h>
32 #include <virtex2.h>
33
34 #if 0
35 #define FPGA_DEBUG
36 #endif
37
38 #ifdef  FPGA_DEBUG
39 #define PRINTF(fmt,args...)     printf (fmt ,##args)
40 #else
41 #define PRINTF(fmt,args...)
42 #endif
43
44 /*
45  * If the SelectMap interface can be overrun by the processor, define
46  * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration
47  * file and add board-specific support for checking BUSY status. By default,
48  * assume that the SelectMap interface cannot be overrun.
49  */
50 #ifndef CONFIG_SYS_FPGA_CHECK_BUSY
51 #undef CONFIG_SYS_FPGA_CHECK_BUSY
52 #endif
53
54 #ifndef CONFIG_FPGA_DELAY
55 #define CONFIG_FPGA_DELAY()
56 #endif
57
58 #ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK
59 #define CONFIG_SYS_FPGA_PROG_FEEDBACK
60 #endif
61
62 /*
63  * Don't allow config cycle to be interrupted
64  */
65 #ifndef CONFIG_SYS_FPGA_CHECK_CTRLC
66 #undef CONFIG_SYS_FPGA_CHECK_CTRLC
67 #endif
68
69 /*
70  * Check for errors during configuration by default
71  */
72 #ifndef CONFIG_SYS_FPGA_CHECK_ERROR
73 #define CONFIG_SYS_FPGA_CHECK_ERROR
74 #endif
75
76 /*
77  * The default timeout in mS for INIT_B to deassert after PROG_B has
78  * been deasserted. Per the latest Virtex II Handbook (page 347), the
79  * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
80  * data frame for the XC2V8000.  The XC2V8000 has 2860 data frames
81  * which yields 11.44 mS.  So let's make it bigger in order to handle
82  * an XC2V1000, if anyone can ever get ahold of one.
83  */
84 #ifndef CONFIG_SYS_FPGA_WAIT_INIT
85 #define CONFIG_SYS_FPGA_WAIT_INIT       CONFIG_SYS_HZ/2 /* 500 ms */
86 #endif
87
88 /*
89  * The default timeout for waiting for BUSY to deassert during configuration.
90  * This is normally not necessary since for most reasonable configuration
91  * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
92  */
93 #ifndef CONFIG_SYS_FPGA_WAIT_BUSY
94 #define CONFIG_SYS_FPGA_WAIT_BUSY       CONFIG_SYS_HZ/200       /* 5 ms*/
95 #endif
96
97 /* Default timeout for waiting for FPGA to enter operational mode after
98  * configuration data has been written.
99  */
100 #ifndef CONFIG_SYS_FPGA_WAIT_CONFIG
101 #define CONFIG_SYS_FPGA_WAIT_CONFIG     CONFIG_SYS_HZ/5 /* 200 ms */
102 #endif
103
104 static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize);
105 static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize);
106 static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset);
107
108 static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize);
109 static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize);
110 static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset);
111
112 int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize)
113 {
114         int ret_val = FPGA_FAIL;
115
116         switch (desc->iface) {
117         case slave_serial:
118                 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
119                 ret_val = Virtex2_ss_load (desc, buf, bsize);
120                 break;
121
122         case slave_selectmap:
123                 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
124                 ret_val = Virtex2_ssm_load (desc, buf, bsize);
125                 break;
126
127         default:
128                 printf ("%s: Unsupported interface type, %d\n",
129                                 __FUNCTION__, desc->iface);
130         }
131         return ret_val;
132 }
133
134 int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize)
135 {
136         int ret_val = FPGA_FAIL;
137
138         switch (desc->iface) {
139         case slave_serial:
140                 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
141                 ret_val = Virtex2_ss_dump (desc, buf, bsize);
142                 break;
143
144         case slave_parallel:
145                 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
146                 ret_val = Virtex2_ssm_dump (desc, buf, bsize);
147                 break;
148
149         default:
150                 printf ("%s: Unsupported interface type, %d\n",
151                                 __FUNCTION__, desc->iface);
152         }
153         return ret_val;
154 }
155
156 int Virtex2_info (Xilinx_desc * desc)
157 {
158         return FPGA_SUCCESS;
159 }
160
161 int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset)
162 {
163         int ret_val = FPGA_FAIL;
164
165         if (desc->family != Xilinx_Virtex2) {
166                 printf ("%s: Unsupported family type, %d\n",
167                                 __FUNCTION__, desc->family);
168                 return FPGA_FAIL;
169         } else
170                 switch (desc->iface) {
171                 case slave_serial:
172                         ret_val = Virtex2_ss_reloc (desc, reloc_offset);
173                         break;
174
175                 case slave_selectmap:
176                         ret_val = Virtex2_ssm_reloc (desc, reloc_offset);
177                         break;
178
179                 default:
180                         printf ("%s: Unsupported interface type, %d\n",
181                                         __FUNCTION__, desc->iface);
182                 }
183         return ret_val;
184 }
185
186 /*
187  * Virtex-II Slave SelectMap configuration loader. Configuration via
188  * SelectMap is as follows:
189  * 1. Set the FPGA's PROG_B line low.
190  * 2. Set the FPGA's PROG_B line high.  Wait for INIT_B to go high.
191  * 3. Write data to the SelectMap port.  If INIT_B goes low at any time
192  *    this process, a configuration error (most likely CRC failure) has
193  *    ocurred.  At this point a status word may be read from the
194  *    SelectMap interface to determine the source of the problem (You
195  *    could, for instance, put this in your 'abort' function handler).
196  * 4. After all data has been written, test the state of the FPGA
197  *    INIT_B and DONE lines.  If both are high, configuration has
198  *    succeeded. Congratulations!
199  */
200 static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize)
201 {
202         int ret_val = FPGA_FAIL;
203         Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
204
205         PRINTF ("%s:%d: Start with interface functions @ 0x%p\n",
206                         __FUNCTION__, __LINE__, fn);
207
208         if (fn) {
209                 size_t bytecount = 0;
210                 unsigned char *data = (unsigned char *) buf;
211                 int cookie = desc->cookie;
212                 unsigned long ts;
213
214                 /* Gotta split this one up (so the stack won't blow??) */
215                 PRINTF ("%s:%d: Function Table:\n"
216                                 "  base   0x%p\n"
217                                 "  struct 0x%p\n"
218                                 "  pre    0x%p\n"
219                                 "  prog   0x%p\n"
220                                 "  init   0x%p\n"
221                                 "  error  0x%p\n",
222                                 __FUNCTION__, __LINE__,
223                                 &fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
224                 PRINTF ("  clock  0x%p\n"
225                                 "  cs     0x%p\n"
226                                 "  write  0x%p\n"
227                                 "  rdata  0x%p\n"
228                                 "  wdata  0x%p\n"
229                                 "  busy   0x%p\n"
230                                 "  abort  0x%p\n"
231                                 "  post   0x%p\n\n",
232                                 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
233                                 fn->busy, fn->abort, fn->post);
234
235 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
236                 printf ("Initializing FPGA Device %d...\n", cookie);
237 #endif
238                 /*
239                  * Run the pre configuration function if there is one.
240                  */
241                 if (*fn->pre) {
242                         (*fn->pre) (cookie);
243                 }
244
245                 /*
246                  * Assert the program line.  The minimum pulse width for
247                  * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
248                  * There is no maximum value for the pulse width.  Check to make
249                  * sure that INIT_B goes low after assertion of PROG_B
250                  */
251                 (*fn->pgm) (TRUE, TRUE, cookie);
252                 udelay (10);
253                 ts = get_timer (0);
254                 do {
255                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
256                                 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
257                                                 " to assert.\n", __FUNCTION__, __LINE__,
258                                                 CONFIG_SYS_FPGA_WAIT_INIT);
259                                 (*fn->abort) (cookie);
260                                 return FPGA_FAIL;
261                         }
262                 } while (!(*fn->init) (cookie));
263
264                 (*fn->pgm) (FALSE, TRUE, cookie);
265                 CONFIG_FPGA_DELAY ();
266                 (*fn->clk) (TRUE, TRUE, cookie);
267
268                 /*
269                  * Start a timer and wait for INIT_B to go high
270                  */
271                 ts = get_timer (0);
272                 do {
273                         CONFIG_FPGA_DELAY ();
274                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
275                                 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
276                                                 " to deassert.\n", __FUNCTION__, __LINE__,
277                                                 CONFIG_SYS_FPGA_WAIT_INIT);
278                                 (*fn->abort) (cookie);
279                                 return FPGA_FAIL;
280                         }
281                 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
282
283                 (*fn->wr) (TRUE, TRUE, cookie);
284                 (*fn->cs) (TRUE, TRUE, cookie);
285
286                 udelay (10000);
287
288                 /*
289                  * Load the data byte by byte
290                  */
291                 while (bytecount < bsize) {
292 #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
293                         if (ctrlc ()) {
294                                 (*fn->abort) (cookie);
295                                 return FPGA_FAIL;
296                         }
297 #endif
298
299                         if ((*fn->done) (cookie) == FPGA_SUCCESS) {
300                             PRINTF ("%s:%d:done went active early, bytecount = %d\n",
301                                     __FUNCTION__, __LINE__, bytecount);
302                             break;
303                         }
304
305 #ifdef CONFIG_SYS_FPGA_CHECK_ERROR
306                         if ((*fn->init) (cookie)) {
307                                 printf ("\n%s:%d:  ** Error: INIT asserted during"
308                                                 " configuration\n", __FUNCTION__, __LINE__);
309                                 printf ("%d = buffer offset, %d = buffer size\n",
310                                         bytecount, bsize);
311                                 (*fn->abort) (cookie);
312                                 return FPGA_FAIL;
313                         }
314 #endif
315
316                         (*fn->wdata) (data[bytecount++], TRUE, cookie);
317                         CONFIG_FPGA_DELAY ();
318
319                         /*
320                          * Cycle the clock pin
321                          */
322                         (*fn->clk) (FALSE, TRUE, cookie);
323                         CONFIG_FPGA_DELAY ();
324                         (*fn->clk) (TRUE, TRUE, cookie);
325
326 #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
327                         ts = get_timer (0);
328                         while ((*fn->busy) (cookie)) {
329                                 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) {
330                                         printf ("%s:%d: ** Timeout after %d ticks waiting for"
331                                                         " BUSY to deassert\n",
332                                                         __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY);
333                                         (*fn->abort) (cookie);
334                                         return FPGA_FAIL;
335                                 }
336                         }
337 #endif
338
339 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
340                         if (bytecount % (bsize / 40) == 0)
341                                 putc ('.');
342 #endif
343                 }
344
345                 /*
346                  * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
347                  */
348                 CONFIG_FPGA_DELAY ();
349                 (*fn->cs) (FALSE, TRUE, cookie);
350                 (*fn->wr) (FALSE, TRUE, cookie);
351
352 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
353                 putc ('\n');
354 #endif
355
356                 /*
357                  * Check for successful configuration.  FPGA INIT_B and DONE should
358                  * both be high upon successful configuration.
359                  */
360                 ts = get_timer (0);
361                 ret_val = FPGA_SUCCESS;
362                 while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) {
363                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
364                                 printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to"
365                                                 "assert and INIT to deassert\n",
366                                                 __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
367                                 (*fn->abort) (cookie);
368                                 ret_val = FPGA_FAIL;
369                                 break;
370                         }
371                 }
372
373                 if (ret_val == FPGA_SUCCESS) {
374 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
375                         printf ("Initialization of FPGA device %d complete\n", cookie);
376 #endif
377                         /*
378                          * Run the post configuration function if there is one.
379                          */
380                         if (*fn->post) {
381                                 (*fn->post) (cookie);
382                         }
383                 } else {
384 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
385                         printf ("** Initialization of FPGA device %d FAILED\n",
386                                         cookie);
387 #endif
388                 }
389         } else {
390                 printf ("%s:%d: NULL Interface function table!\n",
391                                 __FUNCTION__, __LINE__);
392         }
393         return ret_val;
394 }
395
396 /*
397  * Read the FPGA configuration data
398  */
399 static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize)
400 {
401         int ret_val = FPGA_FAIL;
402         Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
403
404         if (fn) {
405                 unsigned char *data = (unsigned char *) buf;
406                 size_t bytecount = 0;
407                 int cookie = desc->cookie;
408
409                 printf ("Starting Dump of FPGA Device %d...\n", cookie);
410
411                 (*fn->cs) (TRUE, TRUE, cookie);
412                 (*fn->clk) (TRUE, TRUE, cookie);
413
414                 while (bytecount < bsize) {
415 #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
416                         if (ctrlc ()) {
417                                 (*fn->abort) (cookie);
418                                 return FPGA_FAIL;
419                         }
420 #endif
421                         /*
422                          * Cycle the clock and read the data
423                          */
424                         (*fn->clk) (FALSE, TRUE, cookie);
425                         (*fn->clk) (TRUE, TRUE, cookie);
426                         (*fn->rdata) (&(data[bytecount++]), cookie);
427 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
428                         if (bytecount % (bsize / 40) == 0)
429                                 putc ('.');
430 #endif
431                 }
432
433                 /*
434                  * Deassert CS_B and cycle the clock to deselect the device.
435                  */
436                 (*fn->cs) (FALSE, FALSE, cookie);
437                 (*fn->clk) (FALSE, TRUE, cookie);
438                 (*fn->clk) (TRUE, TRUE, cookie);
439
440 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
441                 putc ('\n');
442 #endif
443                 puts ("Done.\n");
444         } else {
445                 printf ("%s:%d: NULL Interface function table!\n",
446                                 __FUNCTION__, __LINE__);
447         }
448         return ret_val;
449 }
450
451 /*
452  * Relocate the addresses in the function table from FLASH (or ROM,
453  * or whatever) to RAM.
454  */
455 static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset)
456 {
457         ulong addr;
458         int ret_val = FPGA_FAIL;
459         Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn =
460                         (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns);
461
462         if (fn) {
463                 /*
464                  * Get the relocated table address
465                  */
466                 addr = (ulong) fn + reloc_offset;
467                 fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr;
468
469                 /*
470                  * Check to see if the table has already been relocated.  If not, do
471                  * a sanity check to make sure there is a faithful copy of the
472                  * FLASH based function table in RAM, then adjust the table.
473                  */
474                 if (!fn_r->relocated) {
475                         if (memcmp
476                                 (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns))
477                                 == 0) {
478                                 desc->iface_fns = fn_r;
479                         } else {
480                                 PRINTF ("%s:%d: Invalid function table at 0x%p\n",
481                                                 __FUNCTION__, __LINE__, fn_r);
482                                 return FPGA_FAIL;
483                         }
484
485                         PRINTF ("%s:%d: Relocating descriptor at 0x%p\n",
486                                         __FUNCTION__, __LINE__, desc);
487
488                         addr = (ulong) (fn->pre) + reloc_offset;
489                         fn_r->pre = (Xilinx_pre_fn) addr;
490                         addr = (ulong) (fn->pgm) + reloc_offset;
491                         fn_r->pgm = (Xilinx_pgm_fn) addr;
492                         addr = (ulong) (fn->init) + reloc_offset;
493                         fn_r->init = (Xilinx_init_fn) addr;
494                         addr = (ulong) (fn->done) + reloc_offset;
495                         fn_r->done = (Xilinx_done_fn) addr;
496                         addr = (ulong) (fn->err) + reloc_offset;
497                         fn_r->err = (Xilinx_err_fn) addr;
498                         addr = (ulong) (fn->clk) + reloc_offset;
499                         fn_r->clk = (Xilinx_clk_fn) addr;
500                         addr = (ulong) (fn->cs) + reloc_offset;
501                         fn_r->cs = (Xilinx_cs_fn) addr;
502                         addr = (ulong) (fn->wr) + reloc_offset;
503                         fn_r->wr = (Xilinx_wr_fn) addr;
504                         addr = (ulong) (fn->rdata) + reloc_offset;
505                         fn_r->rdata = (Xilinx_rdata_fn) addr;
506                         addr = (ulong) (fn->wdata) + reloc_offset;
507                         fn_r->wdata = (Xilinx_wdata_fn) addr;
508                         addr = (ulong) (fn->busy) + reloc_offset;
509                         fn_r->busy = (Xilinx_busy_fn) addr;
510                         addr = (ulong) (fn->abort) + reloc_offset;
511                         fn_r->abort = (Xilinx_abort_fn) addr;
512                         addr = (ulong) (fn->post) + reloc_offset;
513                         fn_r->post = (Xilinx_post_fn) addr;
514                         fn_r->relocated = TRUE;
515                 } else {
516                         printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r);
517                         desc->iface_fns = fn_r;
518                 }
519                 ret_val = FPGA_SUCCESS;
520         } else {
521                 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
522         }
523         return ret_val;
524 }
525
526 static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
527 {
528         printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__);
529         return FPGA_FAIL;
530 }
531
532 static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
533 {
534         printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__);
535         return FPGA_FAIL;
536 }
537
538 static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset)
539 {
540         int ret_val = FPGA_FAIL;
541         Xilinx_Virtex2_Slave_Serial_fns *fn =
542                         (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns);
543
544         if (fn) {
545                 printf ("%s:%d: Slave Serial Loading is unsupported\n",
546                                 __FUNCTION__, __LINE__);
547         } else {
548                 printf ("%s:%d: NULL Interface function table!\n",
549                                 __FUNCTION__, __LINE__);
550         }
551         return ret_val;
552 }
553
554 /* vim: set ts=4 tw=78: */