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