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