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