• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
spartan3_load(xilinx_desc * desc,const void * buf,size_t bsize,bitstream_type bstype)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 
spartan3_dump(xilinx_desc * desc,const void * buf,size_t bsize)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 
spartan3_info(xilinx_desc * desc)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 
spartan3_sp_load(xilinx_desc * desc,const void * buf,size_t bsize)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 
spartan3_sp_dump(xilinx_desc * desc,const void * buf,size_t bsize)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 
spartan3_ss_load(xilinx_desc * desc,const void * buf,size_t bsize)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 
spartan3_ss_dump(xilinx_desc * desc,const void * buf,size_t bsize)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 };
474