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