Merge https://gitlab.denx.de/u-boot/custodians/u-boot-x86
[platform/kernel/u-boot.git] / drivers / fpga / spartan3.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2002
4  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5  */
6
7 /*
8  * Configuration support for Xilinx Spartan3 devices.  Based
9  * on spartan2.c (Rich Ireland, rireland@enterasys.com).
10  */
11
12 #include <common.h>             /* core U-Boot definitions */
13 #include <spartan3.h>           /* Spartan-II device family */
14
15 /* Define FPGA_DEBUG to get debug printf's */
16 #ifdef  FPGA_DEBUG
17 #define PRINTF(fmt,args...)     printf (fmt ,##args)
18 #else
19 #define PRINTF(fmt,args...)
20 #endif
21
22 #undef CONFIG_SYS_FPGA_CHECK_BUSY
23
24 /* Note: The assumption is that we cannot possibly run fast enough to
25  * overrun the device (the Slave Parallel mode can free run at 50MHz).
26  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
27  * the board config file to slow things down.
28  */
29 #ifndef CONFIG_FPGA_DELAY
30 #define CONFIG_FPGA_DELAY()
31 #endif
32
33 #ifndef CONFIG_SYS_FPGA_WAIT
34 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100  /* 10 ms */
35 #endif
36
37 static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
38 static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
39 /* static int spartan3_sp_info(xilinx_desc *desc ); */
40
41 static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
42 static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
43 /* static int spartan3_ss_info(xilinx_desc *desc); */
44
45 /* ------------------------------------------------------------------------- */
46 /* Spartan-II Generic Implementation */
47 static int spartan3_load(xilinx_desc *desc, const void *buf, size_t bsize,
48                          bitstream_type bstype)
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 static 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 static 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 }
468
469 struct xilinx_fpga_op spartan3_op = {
470         .load = spartan3_load,
471         .dump = spartan3_dump,
472         .info = spartan3_info,
473 };