1 /*
2  * (C) Copyright 2002
3  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  */
24 
25 /*
26  * Configuration support for Xilinx Spartan3 devices.  Based
27  * on spartan2.c (Rich Ireland, rireland@enterasys.com).
28  */
29 
30 #include <common.h>		/* core U-Boot definitions */
31 #include <spartan3.h>		/* Spartan-II device family */
32 
33 /* Define FPGA_DEBUG to get debug printf's */
34 #ifdef	FPGA_DEBUG
35 #define PRINTF(fmt,args...)	printf (fmt ,##args)
36 #else
37 #define PRINTF(fmt,args...)
38 #endif
39 
40 #undef CONFIG_SYS_FPGA_CHECK_BUSY
41 #undef CONFIG_SYS_FPGA_PROG_FEEDBACK
42 
43 /* Note: The assumption is that we cannot possibly run fast enough to
44  * overrun the device (the Slave Parallel mode can free run at 50MHz).
45  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
46  * the board config file to slow things down.
47  */
48 #ifndef CONFIG_FPGA_DELAY
49 #define CONFIG_FPGA_DELAY()
50 #endif
51 
52 #ifndef CONFIG_SYS_FPGA_WAIT
53 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100	/* 10 ms */
54 #endif
55 
56 static int Spartan3_sp_load( Xilinx_desc *desc, void *buf, size_t bsize );
57 static int Spartan3_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize );
58 /* static int Spartan3_sp_info( Xilinx_desc *desc ); */
59 
60 static int Spartan3_ss_load( Xilinx_desc *desc, void *buf, size_t bsize );
61 static int Spartan3_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize );
62 /* static int Spartan3_ss_info( Xilinx_desc *desc ); */
63 
64 /* ------------------------------------------------------------------------- */
65 /* Spartan-II Generic Implementation */
Spartan3_load(Xilinx_desc * desc,void * buf,size_t bsize)66 int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize)
67 {
68 	int ret_val = FPGA_FAIL;
69 
70 	switch (desc->iface) {
71 	case slave_serial:
72 		PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
73 		ret_val = Spartan3_ss_load (desc, buf, bsize);
74 		break;
75 
76 	case slave_parallel:
77 		PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
78 		ret_val = Spartan3_sp_load (desc, buf, bsize);
79 		break;
80 
81 	default:
82 		printf ("%s: Unsupported interface type, %d\n",
83 				__FUNCTION__, desc->iface);
84 	}
85 
86 	return ret_val;
87 }
88 
Spartan3_dump(Xilinx_desc * desc,void * buf,size_t bsize)89 int Spartan3_dump (Xilinx_desc * desc, void *buf, size_t bsize)
90 {
91 	int ret_val = FPGA_FAIL;
92 
93 	switch (desc->iface) {
94 	case slave_serial:
95 		PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
96 		ret_val = Spartan3_ss_dump (desc, buf, bsize);
97 		break;
98 
99 	case slave_parallel:
100 		PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
101 		ret_val = Spartan3_sp_dump (desc, buf, bsize);
102 		break;
103 
104 	default:
105 		printf ("%s: Unsupported interface type, %d\n",
106 				__FUNCTION__, desc->iface);
107 	}
108 
109 	return ret_val;
110 }
111 
Spartan3_info(Xilinx_desc * desc)112 int Spartan3_info( Xilinx_desc *desc )
113 {
114 	return FPGA_SUCCESS;
115 }
116 
117 
118 /* ------------------------------------------------------------------------- */
119 /* Spartan-II Slave Parallel Generic Implementation */
120 
Spartan3_sp_load(Xilinx_desc * desc,void * buf,size_t bsize)121 static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
122 {
123 	int ret_val = FPGA_FAIL;	/* assume the worst */
124 	Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
125 
126 	PRINTF ("%s: start with interface functions @ 0x%p\n",
127 			__FUNCTION__, fn);
128 
129 	if (fn) {
130 		size_t bytecount = 0;
131 		unsigned char *data = (unsigned char *) buf;
132 		int cookie = desc->cookie;	/* make a local copy */
133 		unsigned long ts;		/* timestamp */
134 
135 		PRINTF ("%s: Function Table:\n"
136 				"ptr:\t0x%p\n"
137 				"struct: 0x%p\n"
138 				"pre: 0x%p\n"
139 				"pgm:\t0x%p\n"
140 				"init:\t0x%p\n"
141 				"err:\t0x%p\n"
142 				"clk:\t0x%p\n"
143 				"cs:\t0x%p\n"
144 				"wr:\t0x%p\n"
145 				"read data:\t0x%p\n"
146 				"write data:\t0x%p\n"
147 				"busy:\t0x%p\n"
148 				"abort:\t0x%p\n",
149 				"post:\t0x%p\n\n",
150 				__FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
151 				fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
152 				fn->abort, fn->post);
153 
154 		/*
155 		 * This code is designed to emulate the "Express Style"
156 		 * Continuous Data Loading in Slave Parallel Mode for
157 		 * the Spartan-II Family.
158 		 */
159 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
160 		printf ("Loading FPGA Device %d...\n", cookie);
161 #endif
162 		/*
163 		 * Run the pre configuration function if there is one.
164 		 */
165 		if (*fn->pre) {
166 			(*fn->pre) (cookie);
167 		}
168 
169 		/* Establish the initial state */
170 		(*fn->pgm) (TRUE, TRUE, cookie);	/* Assert the program, commit */
171 
172 		/* Get ready for the burn */
173 		CONFIG_FPGA_DELAY ();
174 		(*fn->pgm) (FALSE, TRUE, cookie);	/* Deassert the program, commit */
175 
176 		ts = get_timer (0);		/* get current time */
177 		/* Now wait for INIT and BUSY to go high */
178 		do {
179 			CONFIG_FPGA_DELAY ();
180 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
181 				puts ("** Timeout waiting for INIT to clear.\n");
182 				(*fn->abort) (cookie);	/* abort the burn */
183 				return FPGA_FAIL;
184 			}
185 		} while ((*fn->init) (cookie) && (*fn->busy) (cookie));
186 
187 		(*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */
188 		(*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */
189 		(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
190 
191 		/* Load the data */
192 		while (bytecount < bsize) {
193 			/* XXX - do we check for an Ctrl-C press in here ??? */
194 			/* XXX - Check the error bit? */
195 
196 			(*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */
197 			CONFIG_FPGA_DELAY ();
198 			(*fn->clk) (FALSE, TRUE, cookie);	/* Deassert the clock pin */
199 			CONFIG_FPGA_DELAY ();
200 			(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
201 
202 #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
203 			ts = get_timer (0);	/* get current time */
204 			while ((*fn->busy) (cookie)) {
205 				/* XXX - we should have a check in here somewhere to
206 				 * make sure we aren't busy forever... */
207 
208 				CONFIG_FPGA_DELAY ();
209 				(*fn->clk) (FALSE, TRUE, cookie);	/* Deassert the clock pin */
210 				CONFIG_FPGA_DELAY ();
211 				(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
212 
213 				if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
214 					puts ("** Timeout waiting for BUSY to clear.\n");
215 					(*fn->abort) (cookie);	/* abort the burn */
216 					return FPGA_FAIL;
217 				}
218 			}
219 #endif
220 
221 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
222 			if (bytecount % (bsize / 40) == 0)
223 				putc ('.');		/* let them know we are alive */
224 #endif
225 		}
226 
227 		CONFIG_FPGA_DELAY ();
228 		(*fn->cs) (FALSE, TRUE, cookie);	/* Deassert the chip select */
229 		(*fn->wr) (FALSE, TRUE, cookie);	/* Deassert the write pin */
230 
231 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
232 		putc ('\n');			/* terminate the dotted line */
233 #endif
234 
235 		/* now check for done signal */
236 		ts = get_timer (0);		/* get current time */
237 		ret_val = FPGA_SUCCESS;
238 		while ((*fn->done) (cookie) == FPGA_FAIL) {
239 			/* XXX - we should have a check in here somewhere to
240 			 * make sure we aren't busy forever... */
241 
242 			CONFIG_FPGA_DELAY ();
243 			(*fn->clk) (FALSE, TRUE, cookie);	/* Deassert the clock pin */
244 			CONFIG_FPGA_DELAY ();
245 			(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
246 
247 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
248 				puts ("** Timeout waiting for DONE to clear.\n");
249 				(*fn->abort) (cookie);	/* abort the burn */
250 				ret_val = FPGA_FAIL;
251 				break;
252 			}
253 		}
254 
255 		/*
256 		 * Run the post configuration function if there is one.
257 		 */
258 		if (*fn->post)
259 			(*fn->post) (cookie);
260 
261 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
262 		if (ret_val == FPGA_SUCCESS)
263 			puts ("Done.\n");
264 		else
265 			puts ("Fail.\n");
266 #endif
267 
268 	} else {
269 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
270 	}
271 
272 	return ret_val;
273 }
274 
Spartan3_sp_dump(Xilinx_desc * desc,void * buf,size_t bsize)275 static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize)
276 {
277 	int ret_val = FPGA_FAIL;	/* assume the worst */
278 	Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
279 
280 	if (fn) {
281 		unsigned char *data = (unsigned char *) buf;
282 		size_t bytecount = 0;
283 		int cookie = desc->cookie;	/* make a local copy */
284 
285 		printf ("Starting Dump of FPGA Device %d...\n", cookie);
286 
287 		(*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */
288 		(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
289 
290 		/* dump the data */
291 		while (bytecount < bsize) {
292 			/* XXX - do we check for an Ctrl-C press in here ??? */
293 
294 			(*fn->clk) (FALSE, TRUE, cookie);	/* Deassert the clock pin */
295 			(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
296 			(*fn->rdata) (&(data[bytecount++]), cookie);	/* read the data */
297 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
298 			if (bytecount % (bsize / 40) == 0)
299 				putc ('.');		/* let them know we are alive */
300 #endif
301 		}
302 
303 		(*fn->cs) (FALSE, FALSE, cookie);	/* Deassert the chip select */
304 		(*fn->clk) (FALSE, TRUE, cookie);	/* Deassert the clock pin */
305 		(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
306 
307 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
308 		putc ('\n');			/* terminate the dotted line */
309 #endif
310 		puts ("Done.\n");
311 
312 		/* XXX - checksum the data? */
313 	} else {
314 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
315 	}
316 
317 	return ret_val;
318 }
319 
320 
321 /* ------------------------------------------------------------------------- */
322 
Spartan3_ss_load(Xilinx_desc * desc,void * buf,size_t bsize)323 static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
324 {
325 	int ret_val = FPGA_FAIL;	/* assume the worst */
326 	Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns;
327 	int i;
328 	unsigned char val;
329 
330 	PRINTF ("%s: start with interface functions @ 0x%p\n",
331 			__FUNCTION__, fn);
332 
333 	if (fn) {
334 		size_t bytecount = 0;
335 		unsigned char *data = (unsigned char *) buf;
336 		int cookie = desc->cookie;	/* make a local copy */
337 		unsigned long ts;		/* timestamp */
338 
339 		PRINTF ("%s: Function Table:\n"
340 				"ptr:\t0x%p\n"
341 				"struct: 0x%p\n"
342 				"pgm:\t0x%p\n"
343 				"init:\t0x%p\n"
344 				"clk:\t0x%p\n"
345 				"wr:\t0x%p\n"
346 				"done:\t0x%p\n\n",
347 				__FUNCTION__, &fn, fn, fn->pgm, fn->init,
348 				fn->clk, fn->wr, fn->done);
349 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
350 		printf ("Loading FPGA Device %d...\n", cookie);
351 #endif
352 
353 		/*
354 		 * Run the pre configuration function if there is one.
355 		 */
356 		if (*fn->pre) {
357 			(*fn->pre) (cookie);
358 		}
359 
360 		/* Establish the initial state */
361 		(*fn->pgm) (TRUE, TRUE, cookie);	/* Assert the program, commit */
362 
363 		/* Wait for INIT state (init low)                            */
364 		ts = get_timer (0);		/* get current time */
365 		do {
366 			CONFIG_FPGA_DELAY ();
367 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
368 				puts ("** Timeout waiting for INIT to start.\n");
369 				return FPGA_FAIL;
370 			}
371 		} while (!(*fn->init) (cookie));
372 
373 		/* Get ready for the burn */
374 		CONFIG_FPGA_DELAY ();
375 		(*fn->pgm) (FALSE, TRUE, cookie);	/* Deassert the program, commit */
376 
377 		ts = get_timer (0);		/* get current time */
378 		/* Now wait for INIT to go high */
379 		do {
380 			CONFIG_FPGA_DELAY ();
381 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
382 				puts ("** Timeout waiting for INIT to clear.\n");
383 				return FPGA_FAIL;
384 			}
385 		} while ((*fn->init) (cookie));
386 
387 		/* Load the data */
388 		if(*fn->bwr)
389 			(*fn->bwr) (data, bsize, TRUE, cookie);
390 		else {
391 			while (bytecount < bsize) {
392 
393 				/* Xilinx detects an error if INIT goes low (active)
394 				   while DONE is low (inactive) */
395 				if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
396 					puts ("** CRC error during FPGA load.\n");
397 					return (FPGA_FAIL);
398 				}
399 				val = data [bytecount ++];
400 				i = 8;
401 				do {
402 					/* Deassert the clock */
403 					(*fn->clk) (FALSE, TRUE, cookie);
404 					CONFIG_FPGA_DELAY ();
405 					/* Write data */
406 					(*fn->wr) ((val & 0x80), TRUE, cookie);
407 					CONFIG_FPGA_DELAY ();
408 					/* Assert the clock */
409 					(*fn->clk) (TRUE, TRUE, cookie);
410 					CONFIG_FPGA_DELAY ();
411 					val <<= 1;
412 					i --;
413 				} while (i > 0);
414 
415 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
416 				if (bytecount % (bsize / 40) == 0)
417 					putc ('.');		/* let them know we are alive */
418 #endif
419 			}
420 		}
421 
422 		CONFIG_FPGA_DELAY ();
423 
424 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
425 		putc ('\n');			/* terminate the dotted line */
426 #endif
427 
428 		/* now check for done signal */
429 		ts = get_timer (0);		/* get current time */
430 		ret_val = FPGA_SUCCESS;
431 		(*fn->wr) (TRUE, TRUE, cookie);
432 
433 		while (! (*fn->done) (cookie)) {
434 			/* XXX - we should have a check in here somewhere to
435 			 * make sure we aren't busy forever... */
436 
437 			CONFIG_FPGA_DELAY ();
438 			(*fn->clk) (FALSE, TRUE, cookie);	/* Deassert the clock pin */
439 			CONFIG_FPGA_DELAY ();
440 			(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
441 
442 			putc ('*');
443 
444 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
445 				puts ("** Timeout waiting for DONE to clear.\n");
446 				ret_val = FPGA_FAIL;
447 				break;
448 			}
449 		}
450 		putc ('\n');			/* terminate the dotted line */
451 
452 		/*
453 		 * Run the post configuration function if there is one.
454 		 */
455 		if (*fn->post)
456 			(*fn->post) (cookie);
457 
458 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
459 		if (ret_val == FPGA_SUCCESS)
460 			puts ("Done.\n");
461 		else
462 			puts ("Fail.\n");
463 #endif
464 
465 	} else {
466 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
467 	}
468 
469 	return ret_val;
470 }
471 
Spartan3_ss_dump(Xilinx_desc * desc,void * buf,size_t bsize)472 static int Spartan3_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
473 {
474 	/* Readback is only available through the Slave Parallel and         */
475 	/* boundary-scan interfaces.                                         */
476 	printf ("%s: Slave Serial Dumping is unavailable\n",
477 			__FUNCTION__);
478 	return FPGA_FAIL;
479 }
480