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