]> git.ipfire.org Git - people/ms/u-boot.git/blame - drivers/fpga/virtex2.c
fpga: Fix typo in function comment
[people/ms/u-boot.git] / drivers / fpga / virtex2.c
CommitLineData
5d3207da
WD
1/*
2 * (C) Copyright 2002
3 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4 * Keith Outwater, keith_outwater@mvis.com
5 *
1a459660 6 * SPDX-License-Identifier: GPL-2.0+
5d3207da
WD
7 */
8
9/*
10 * Configuration support for Xilinx Virtex2 devices. Based
11 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
12 */
13
14#include <common.h>
24b852a7 15#include <console.h>
5d3207da
WD
16#include <virtex2.h>
17
9a9200b4
WD
18#if 0
19#define FPGA_DEBUG
265817c7 20#endif
9a9200b4 21
5d3207da
WD
22#ifdef FPGA_DEBUG
23#define PRINTF(fmt,args...) printf (fmt ,##args)
24#else
25#define PRINTF(fmt,args...)
26#endif
27
28/*
29 * If the SelectMap interface can be overrun by the processor, define
6d0f6bcf 30 * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration
5d3207da
WD
31 * file and add board-specific support for checking BUSY status. By default,
32 * assume that the SelectMap interface cannot be overrun.
33 */
6d0f6bcf
JCPV
34#ifndef CONFIG_SYS_FPGA_CHECK_BUSY
35#undef CONFIG_SYS_FPGA_CHECK_BUSY
5d3207da
WD
36#endif
37
38#ifndef CONFIG_FPGA_DELAY
39#define CONFIG_FPGA_DELAY()
40#endif
41
6d0f6bcf
JCPV
42#ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK
43#define CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
44#endif
45
46/*
47 * Don't allow config cycle to be interrupted
48 */
6d0f6bcf
JCPV
49#ifndef CONFIG_SYS_FPGA_CHECK_CTRLC
50#undef CONFIG_SYS_FPGA_CHECK_CTRLC
5d3207da
WD
51#endif
52
53/*
54 * Check for errors during configuration by default
55 */
6d0f6bcf
JCPV
56#ifndef CONFIG_SYS_FPGA_CHECK_ERROR
57#define CONFIG_SYS_FPGA_CHECK_ERROR
5d3207da
WD
58#endif
59
60/*
61 * The default timeout in mS for INIT_B to deassert after PROG_B has
62 * been deasserted. Per the latest Virtex II Handbook (page 347), the
63 * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
64 * data frame for the XC2V8000. The XC2V8000 has 2860 data frames
65 * which yields 11.44 mS. So let's make it bigger in order to handle
66 * an XC2V1000, if anyone can ever get ahold of one.
67 */
6d0f6bcf
JCPV
68#ifndef CONFIG_SYS_FPGA_WAIT_INIT
69#define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ/2 /* 500 ms */
5d3207da
WD
70#endif
71
72/*
73 * The default timeout for waiting for BUSY to deassert during configuration.
74 * This is normally not necessary since for most reasonable configuration
75 * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
76 */
6d0f6bcf
JCPV
77#ifndef CONFIG_SYS_FPGA_WAIT_BUSY
78#define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ/200 /* 5 ms*/
5d3207da
WD
79#endif
80
81/* Default timeout for waiting for FPGA to enter operational mode after
82 * configuration data has been written.
83 */
6d0f6bcf
JCPV
84#ifndef CONFIG_SYS_FPGA_WAIT_CONFIG
85#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */
5d3207da
WD
86#endif
87
f8c1be98
MS
88static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize);
89static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize);
5d3207da 90
f8c1be98
MS
91static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
92static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
5d3207da 93
7a78bd26
MS
94static int virtex2_load(xilinx_desc *desc, const void *buf, size_t bsize,
95 bitstream_type bstype)
5d3207da
WD
96{
97 int ret_val = FPGA_FAIL;
98
99 switch (desc->iface) {
100 case slave_serial:
101 PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
d9071ce0 102 ret_val = virtex2_ss_load(desc, buf, bsize);
5d3207da
WD
103 break;
104
105 case slave_selectmap:
106 PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
d9071ce0 107 ret_val = virtex2_ssm_load(desc, buf, bsize);
5d3207da
WD
108 break;
109
110 default:
111 printf ("%s: Unsupported interface type, %d\n",
112 __FUNCTION__, desc->iface);
113 }
114 return ret_val;
115}
116
14cfc4f3 117static int virtex2_dump(xilinx_desc *desc, const void *buf, size_t bsize)
5d3207da
WD
118{
119 int ret_val = FPGA_FAIL;
120
121 switch (desc->iface) {
122 case slave_serial:
123 PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
d9071ce0 124 ret_val = virtex2_ss_dump(desc, buf, bsize);
5d3207da
WD
125 break;
126
127 case slave_parallel:
128 PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
d9071ce0 129 ret_val = virtex2_ssm_dump(desc, buf, bsize);
5d3207da
WD
130 break;
131
132 default:
133 printf ("%s: Unsupported interface type, %d\n",
134 __FUNCTION__, desc->iface);
135 }
136 return ret_val;
137}
138
14cfc4f3 139static int virtex2_info(xilinx_desc *desc)
5d3207da
WD
140{
141 return FPGA_SUCCESS;
142}
143
5d3207da
WD
144/*
145 * Virtex-II Slave SelectMap configuration loader. Configuration via
146 * SelectMap is as follows:
147 * 1. Set the FPGA's PROG_B line low.
148 * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high.
149 * 3. Write data to the SelectMap port. If INIT_B goes low at any time
150 * this process, a configuration error (most likely CRC failure) has
151 * ocurred. At this point a status word may be read from the
152 * SelectMap interface to determine the source of the problem (You
9a9200b4 153 * could, for instance, put this in your 'abort' function handler).
5d3207da
WD
154 * 4. After all data has been written, test the state of the FPGA
155 * INIT_B and DONE lines. If both are high, configuration has
156 * succeeded. Congratulations!
157 */
f8c1be98 158static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize)
5d3207da
WD
159{
160 int ret_val = FPGA_FAIL;
d9071ce0 161 xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
5d3207da
WD
162
163 PRINTF ("%s:%d: Start with interface functions @ 0x%p\n",
164 __FUNCTION__, __LINE__, fn);
165
166 if (fn) {
167 size_t bytecount = 0;
168 unsigned char *data = (unsigned char *) buf;
169 int cookie = desc->cookie;
170 unsigned long ts;
171
172 /* Gotta split this one up (so the stack won't blow??) */
173 PRINTF ("%s:%d: Function Table:\n"
174 " base 0x%p\n"
175 " struct 0x%p\n"
176 " pre 0x%p\n"
177 " prog 0x%p\n"
178 " init 0x%p\n"
179 " error 0x%p\n",
180 __FUNCTION__, __LINE__,
181 &fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
182 PRINTF (" clock 0x%p\n"
183 " cs 0x%p\n"
184 " write 0x%p\n"
185 " rdata 0x%p\n"
186 " wdata 0x%p\n"
187 " busy 0x%p\n"
188 " abort 0x%p\n"
189 " post 0x%p\n\n",
190 fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
191 fn->busy, fn->abort, fn->post);
192
6d0f6bcf 193#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
194 printf ("Initializing FPGA Device %d...\n", cookie);
195#endif
196 /*
197 * Run the pre configuration function if there is one.
198 */
199 if (*fn->pre) {
200 (*fn->pre) (cookie);
201 }
202
203 /*
204 * Assert the program line. The minimum pulse width for
205 * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
206 * There is no maximum value for the pulse width. Check to make
207 * sure that INIT_B goes low after assertion of PROG_B
208 */
472d5460 209 (*fn->pgm) (true, true, cookie);
5d3207da
WD
210 udelay (10);
211 ts = get_timer (0);
212 do {
6d0f6bcf 213 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
9a9200b4 214 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
5d3207da 215 " to assert.\n", __FUNCTION__, __LINE__,
6d0f6bcf 216 CONFIG_SYS_FPGA_WAIT_INIT);
5d3207da
WD
217 (*fn->abort) (cookie);
218 return FPGA_FAIL;
219 }
220 } while (!(*fn->init) (cookie));
221
472d5460 222 (*fn->pgm) (false, true, cookie);
5d3207da 223 CONFIG_FPGA_DELAY ();
472d5460 224 (*fn->clk) (true, true, cookie);
5d3207da
WD
225
226 /*
227 * Start a timer and wait for INIT_B to go high
228 */
229 ts = get_timer (0);
230 do {
231 CONFIG_FPGA_DELAY ();
6d0f6bcf 232 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
9a9200b4 233 printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
5d3207da 234 " to deassert.\n", __FUNCTION__, __LINE__,
6d0f6bcf 235 CONFIG_SYS_FPGA_WAIT_INIT);
5d3207da
WD
236 (*fn->abort) (cookie);
237 return FPGA_FAIL;
238 }
239 } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
240
472d5460
YS
241 (*fn->wr) (true, true, cookie);
242 (*fn->cs) (true, true, cookie);
5d3207da
WD
243
244 udelay (10000);
245
246 /*
247 * Load the data byte by byte
248 */
249 while (bytecount < bsize) {
6d0f6bcf 250#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
5d3207da
WD
251 if (ctrlc ()) {
252 (*fn->abort) (cookie);
253 return FPGA_FAIL;
254 }
255#endif
9a9200b4
WD
256
257 if ((*fn->done) (cookie) == FPGA_SUCCESS) {
258 PRINTF ("%s:%d:done went active early, bytecount = %d\n",
259 __FUNCTION__, __LINE__, bytecount);
260 break;
261 }
262
6d0f6bcf 263#ifdef CONFIG_SYS_FPGA_CHECK_ERROR
5d3207da 264 if ((*fn->init) (cookie)) {
9a9200b4 265 printf ("\n%s:%d: ** Error: INIT asserted during"
5d3207da 266 " configuration\n", __FUNCTION__, __LINE__);
9a9200b4
WD
267 printf ("%d = buffer offset, %d = buffer size\n",
268 bytecount, bsize);
5d3207da
WD
269 (*fn->abort) (cookie);
270 return FPGA_FAIL;
271 }
272#endif
9a9200b4 273
472d5460 274 (*fn->wdata) (data[bytecount++], true, cookie);
5d3207da
WD
275 CONFIG_FPGA_DELAY ();
276
277 /*
278 * Cycle the clock pin
279 */
472d5460 280 (*fn->clk) (false, true, cookie);
5d3207da 281 CONFIG_FPGA_DELAY ();
472d5460 282 (*fn->clk) (true, true, cookie);
5d3207da 283
6d0f6bcf 284#ifdef CONFIG_SYS_FPGA_CHECK_BUSY
5d3207da
WD
285 ts = get_timer (0);
286 while ((*fn->busy) (cookie)) {
6d0f6bcf 287 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) {
9a9200b4 288 printf ("%s:%d: ** Timeout after %d ticks waiting for"
5d3207da 289 " BUSY to deassert\n",
6d0f6bcf 290 __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY);
5d3207da
WD
291 (*fn->abort) (cookie);
292 return FPGA_FAIL;
293 }
294 }
295#endif
296
6d0f6bcf 297#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
298 if (bytecount % (bsize / 40) == 0)
299 putc ('.');
300#endif
301 }
302
303 /*
304 * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
305 */
306 CONFIG_FPGA_DELAY ();
472d5460
YS
307 (*fn->cs) (false, true, cookie);
308 (*fn->wr) (false, true, cookie);
5d3207da 309
6d0f6bcf 310#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
311 putc ('\n');
312#endif
313
314 /*
315 * Check for successful configuration. FPGA INIT_B and DONE should
316 * both be high upon successful configuration.
317 */
318 ts = get_timer (0);
319 ret_val = FPGA_SUCCESS;
320 while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) {
6d0f6bcf 321 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
9a9200b4 322 printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to"
5d3207da 323 "assert and INIT to deassert\n",
6d0f6bcf 324 __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
5d3207da
WD
325 (*fn->abort) (cookie);
326 ret_val = FPGA_FAIL;
327 break;
328 }
329 }
330
331 if (ret_val == FPGA_SUCCESS) {
6d0f6bcf 332#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
333 printf ("Initialization of FPGA device %d complete\n", cookie);
334#endif
335 /*
336 * Run the post configuration function if there is one.
337 */
338 if (*fn->post) {
339 (*fn->post) (cookie);
340 }
341 } else {
6d0f6bcf 342#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
343 printf ("** Initialization of FPGA device %d FAILED\n",
344 cookie);
345#endif
346 }
347 } else {
348 printf ("%s:%d: NULL Interface function table!\n",
349 __FUNCTION__, __LINE__);
350 }
351 return ret_val;
352}
353
354/*
355 * Read the FPGA configuration data
356 */
f8c1be98 357static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize)
5d3207da
WD
358{
359 int ret_val = FPGA_FAIL;
d9071ce0 360 xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
5d3207da
WD
361
362 if (fn) {
363 unsigned char *data = (unsigned char *) buf;
364 size_t bytecount = 0;
365 int cookie = desc->cookie;
366
367 printf ("Starting Dump of FPGA Device %d...\n", cookie);
368
472d5460
YS
369 (*fn->cs) (true, true, cookie);
370 (*fn->clk) (true, true, cookie);
5d3207da
WD
371
372 while (bytecount < bsize) {
6d0f6bcf 373#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
5d3207da
WD
374 if (ctrlc ()) {
375 (*fn->abort) (cookie);
376 return FPGA_FAIL;
377 }
378#endif
379 /*
380 * Cycle the clock and read the data
381 */
472d5460
YS
382 (*fn->clk) (false, true, cookie);
383 (*fn->clk) (true, true, cookie);
5d3207da 384 (*fn->rdata) (&(data[bytecount++]), cookie);
6d0f6bcf 385#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
386 if (bytecount % (bsize / 40) == 0)
387 putc ('.');
388#endif
389 }
390
391 /*
392 * Deassert CS_B and cycle the clock to deselect the device.
393 */
472d5460
YS
394 (*fn->cs) (false, false, cookie);
395 (*fn->clk) (false, true, cookie);
396 (*fn->clk) (true, true, cookie);
5d3207da 397
6d0f6bcf 398#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
5d3207da
WD
399 putc ('\n');
400#endif
401 puts ("Done.\n");
402 } else {
403 printf ("%s:%d: NULL Interface function table!\n",
404 __FUNCTION__, __LINE__);
405 }
406 return ret_val;
407}
408
f8c1be98 409static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
5d3207da
WD
410{
411 printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__);
412 return FPGA_FAIL;
413}
414
f8c1be98 415static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
5d3207da
WD
416{
417 printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__);
418 return FPGA_FAIL;
419}
420
5d3207da 421/* vim: set ts=4 tw=78: */
14cfc4f3
MS
422
423struct xilinx_fpga_op virtex2_op = {
424 .load = virtex2_load,
425 .dump = virtex2_dump,
426 .info = virtex2_info,
427};