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