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