xref: /rk3399_rockchip-uboot/drivers/fpga/virtex2.c (revision c8aa7dfc18f7cc90d0aea6c7becbb67dfc5bba4b)
1*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
2*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2002
3*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
4*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Keith Outwater, keith_outwater@mvis.com
5*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
6*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * See file CREDITS for list of people who contributed to this
7*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * project.
8*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
9*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or
10*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * modify it under the terms of the GNU General Public License as
11*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * published by the Free Software Foundation; either version 2 of
12*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * the License, or (at your option) any later version.
13*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
14*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
15*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
18*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
19*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
20*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
21*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * MA 02111-1307 USA
23*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
24*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
25*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
26*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
27*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Configuration support for Xilinx Virtex2 devices.  Based
28*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * on spartan2.c (Rich Ireland, rireland@enterasys.com).
29*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
30*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
31*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <common.h>
32*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <virtex2.h>
33*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
34*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #if 0
35*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define FPGA_DEBUG
36*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
37*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
38*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef	FPGA_DEBUG
39*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define	PRINTF(fmt,args...)	printf (fmt ,##args)
40*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #else
41*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...)
42*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
43*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
44*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
45*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * If the SelectMap interface can be overrun by the processor, define
46*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration
47*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * file and add board-specific support for checking BUSY status. By default,
48*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * assume that the SelectMap interface cannot be overrun.
49*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
50*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_BUSY
51*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_CHECK_BUSY
52*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
53*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
54*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_FPGA_DELAY
55*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_FPGA_DELAY()
56*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
57*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
58*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK
59*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_PROG_FEEDBACK
60*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
61*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
62*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
63*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Don't allow config cycle to be interrupted
64*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
65*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_CTRLC
66*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_CHECK_CTRLC
67*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
68*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
69*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
70*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Check for errors during configuration by default
71*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
72*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_ERROR
73*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_CHECK_ERROR
74*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
75*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
76*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
77*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * The default timeout in mS for INIT_B to deassert after PROG_B has
78*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * been deasserted. Per the latest Virtex II Handbook (page 347), the
79*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
80*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * data frame for the XC2V8000.  The XC2V8000 has 2860 data frames
81*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * which yields 11.44 mS.  So let's make it bigger in order to handle
82*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * an XC2V1000, if anyone can ever get ahold of one.
83*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
84*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_INIT
85*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_INIT	CONFIG_SYS_HZ/2	/* 500 ms */
86*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
87*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
88*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
89*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * The default timeout for waiting for BUSY to deassert during configuration.
90*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * This is normally not necessary since for most reasonable configuration
91*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
92*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
93*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_BUSY
94*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_BUSY	CONFIG_SYS_HZ/200	/* 5 ms*/
95*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
96*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
97*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Default timeout for waiting for FPGA to enter operational mode after
98*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * configuration data has been written.
99*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
100*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef	CONFIG_SYS_FPGA_WAIT_CONFIG
101*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_CONFIG	CONFIG_SYS_HZ/5	/* 200 ms */
102*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
103*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
104*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize);
105*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize);
106*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset);
107*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
108*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize);
109*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize);
110*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset);
111*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
112*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize)
113*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
114*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
115*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
116*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	switch (desc->iface) {
117*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case slave_serial:
118*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
119*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = Virtex2_ss_load (desc, buf, bsize);
120*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
121*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
122*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case slave_selectmap:
123*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
124*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = Virtex2_ssm_load (desc, buf, bsize);
125*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
126*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
127*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	default:
128*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported interface type, %d\n",
129*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->iface);
130*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
131*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
132*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
133*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
134*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize)
135*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
136*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
137*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
138*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	switch (desc->iface) {
139*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case slave_serial:
140*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
141*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = Virtex2_ss_dump (desc, buf, bsize);
142*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
143*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
144*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case slave_parallel:
145*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
146*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = Virtex2_ssm_dump (desc, buf, bsize);
147*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
148*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
149*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	default:
150*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported interface type, %d\n",
151*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->iface);
152*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
153*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
154*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
155*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
156*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_info (Xilinx_desc * desc)
157*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
158*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return FPGA_SUCCESS;
159*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
160*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
161*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset)
162*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
163*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
164*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
165*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (desc->family != Xilinx_Virtex2) {
166*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported family type, %d\n",
167*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->family);
168*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		return FPGA_FAIL;
169*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else
170*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		switch (desc->iface) {
171*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		case slave_serial:
172*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			ret_val = Virtex2_ss_reloc (desc, reloc_offset);
173*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			break;
174*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
175*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		case slave_selectmap:
176*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			ret_val = Virtex2_ssm_reloc (desc, reloc_offset);
177*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			break;
178*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
179*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		default:
180*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			printf ("%s: Unsupported interface type, %d\n",
181*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					__FUNCTION__, desc->iface);
182*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
183*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
184*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
185*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
186*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
187*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Virtex-II Slave SelectMap configuration loader. Configuration via
188*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * SelectMap is as follows:
189*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * 1. Set the FPGA's PROG_B line low.
190*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * 2. Set the FPGA's PROG_B line high.  Wait for INIT_B to go high.
191*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * 3. Write data to the SelectMap port.  If INIT_B goes low at any time
192*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *    this process, a configuration error (most likely CRC failure) has
193*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *    ocurred.  At this point a status word may be read from the
194*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *    SelectMap interface to determine the source of the problem (You
195*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *    could, for instance, put this in your 'abort' function handler).
196*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * 4. After all data has been written, test the state of the FPGA
197*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *    INIT_B and DONE lines.  If both are high, configuration has
198*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *    succeeded. Congratulations!
199*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
200*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize)
201*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
202*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
203*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
204*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
205*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	PRINTF ("%s:%d: Start with interface functions @ 0x%p\n",
206*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			__FUNCTION__, __LINE__, fn);
207*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
208*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
209*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		size_t bytecount = 0;
210*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		unsigned char *data = (unsigned char *) buf;
211*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		int cookie = desc->cookie;
212*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		unsigned long ts;
213*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
214*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Gotta split this one up (so the stack won't blow??) */
215*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s:%d: Function Table:\n"
216*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  base   0x%p\n"
217*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  struct 0x%p\n"
218*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  pre    0x%p\n"
219*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  prog   0x%p\n"
220*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  init   0x%p\n"
221*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  error  0x%p\n",
222*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, __LINE__,
223*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				&fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
224*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("  clock  0x%p\n"
225*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  cs     0x%p\n"
226*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  write  0x%p\n"
227*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  rdata  0x%p\n"
228*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  wdata  0x%p\n"
229*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  busy   0x%p\n"
230*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  abort  0x%p\n"
231*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"  post   0x%p\n\n",
232*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
233*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				fn->busy, fn->abort, fn->post);
234*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
235*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
236*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("Initializing FPGA Device %d...\n", cookie);
237*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
238*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
239*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Run the pre configuration function if there is one.
240*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
241*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (*fn->pre) {
242*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->pre) (cookie);
243*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
244*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
245*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
246*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Assert the program line.  The minimum pulse width for
247*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
248*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * There is no maximum value for the pulse width.  Check to make
249*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * sure that INIT_B goes low after assertion of PROG_B
250*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
251*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->pgm) (TRUE, TRUE, cookie);
252*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		udelay (10);
253*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ts = get_timer (0);
254*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		do {
255*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
256*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
257*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						" to assert.\n", __FUNCTION__, __LINE__,
258*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						CONFIG_SYS_FPGA_WAIT_INIT);
259*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
260*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
261*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
262*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} while (!(*fn->init) (cookie));
263*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
264*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->pgm) (FALSE, TRUE, cookie);
265*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
266*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->clk) (TRUE, TRUE, cookie);
267*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
268*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
269*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Start a timer and wait for INIT_B to go high
270*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
271*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ts = get_timer (0);
272*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		do {
273*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			CONFIG_FPGA_DELAY ();
274*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
275*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				printf ("%s:%d: ** Timeout after %d ticks waiting for INIT"
276*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						" to deassert.\n", __FUNCTION__, __LINE__,
277*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						CONFIG_SYS_FPGA_WAIT_INIT);
278*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
279*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
280*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
281*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} while ((*fn->init) (cookie) && (*fn->busy) (cookie));
282*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
283*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->wr) (TRUE, TRUE, cookie);
284*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->cs) (TRUE, TRUE, cookie);
285*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
286*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		udelay (10000);
287*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
288*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
289*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Load the data byte by byte
290*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
291*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		while (bytecount < bsize) {
292*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
293*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (ctrlc ()) {
294*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
295*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
296*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
297*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
298*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
299*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if ((*fn->done) (cookie) == FPGA_SUCCESS) {
300*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			    PRINTF ("%s:%d:done went active early, bytecount = %d\n",
301*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				    __FUNCTION__, __LINE__, bytecount);
302*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			    break;
303*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
304*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
305*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_ERROR
306*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if ((*fn->init) (cookie)) {
307*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				printf ("\n%s:%d:  ** Error: INIT asserted during"
308*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						" configuration\n", __FUNCTION__, __LINE__);
309*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				printf ("%d = buffer offset, %d = buffer size\n",
310*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					bytecount, bsize);
311*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
312*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
313*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
314*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
315*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
316*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->wdata) (data[bytecount++], TRUE, cookie);
317*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			CONFIG_FPGA_DELAY ();
318*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
319*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/*
320*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			 * Cycle the clock pin
321*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			 */
322*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->clk) (FALSE, TRUE, cookie);
323*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			CONFIG_FPGA_DELAY ();
324*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->clk) (TRUE, TRUE, cookie);
325*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
326*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
327*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			ts = get_timer (0);
328*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			while ((*fn->busy) (cookie)) {
329*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) {
330*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					printf ("%s:%d: ** Timeout after %d ticks waiting for"
331*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 							" BUSY to deassert\n",
332*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 							__FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY);
333*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					(*fn->abort) (cookie);
334*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					return FPGA_FAIL;
335*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				}
336*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
337*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
338*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
339*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
340*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (bytecount % (bsize / 40) == 0)
341*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				putc ('.');
342*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
343*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
344*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
345*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
346*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
347*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
348*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
349*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->cs) (FALSE, TRUE, cookie);
350*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->wr) (FALSE, TRUE, cookie);
351*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
352*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
353*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		putc ('\n');
354*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
355*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
356*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
357*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Check for successful configuration.  FPGA INIT_B and DONE should
358*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * both be high upon successful configuration.
359*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
360*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ts = get_timer (0);
361*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = FPGA_SUCCESS;
362*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) {
363*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
364*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to"
365*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						"assert and INIT to deassert\n",
366*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						__FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
367*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
368*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				ret_val = FPGA_FAIL;
369*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				break;
370*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
371*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
372*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
373*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (ret_val == FPGA_SUCCESS) {
374*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
375*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			printf ("Initialization of FPGA device %d complete\n", cookie);
376*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
377*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/*
378*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			 * Run the post configuration function if there is one.
379*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			 */
380*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (*fn->post) {
381*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->post) (cookie);
382*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
383*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} else {
384*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
385*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			printf ("** Initialization of FPGA device %d FAILED\n",
386*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					cookie);
387*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
388*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
389*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
390*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s:%d: NULL Interface function table!\n",
391*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, __LINE__);
392*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
393*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
394*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
395*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
396*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
397*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Read the FPGA configuration data
398*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
399*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize)
400*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
401*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
402*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
403*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
404*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
405*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		unsigned char *data = (unsigned char *) buf;
406*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		size_t bytecount = 0;
407*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		int cookie = desc->cookie;
408*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
409*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("Starting Dump of FPGA Device %d...\n", cookie);
410*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
411*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->cs) (TRUE, TRUE, cookie);
412*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->clk) (TRUE, TRUE, cookie);
413*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
414*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		while (bytecount < bsize) {
415*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
416*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (ctrlc ()) {
417*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
418*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
419*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
420*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
421*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/*
422*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			 * Cycle the clock and read the data
423*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			 */
424*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->clk) (FALSE, TRUE, cookie);
425*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->clk) (TRUE, TRUE, cookie);
426*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->rdata) (&(data[bytecount++]), cookie);
427*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
428*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (bytecount % (bsize / 40) == 0)
429*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				putc ('.');
430*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
431*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
432*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
433*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
434*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Deassert CS_B and cycle the clock to deselect the device.
435*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
436*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->cs) (FALSE, FALSE, cookie);
437*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->clk) (FALSE, TRUE, cookie);
438*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->clk) (TRUE, TRUE, cookie);
439*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
440*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
441*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		putc ('\n');
442*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
443*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		puts ("Done.\n");
444*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
445*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s:%d: NULL Interface function table!\n",
446*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, __LINE__);
447*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
448*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
449*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
450*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
451*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
452*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Relocate the addresses in the function table from FLASH (or ROM,
453*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * or whatever) to RAM.
454*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
455*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset)
456*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
457*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	ulong addr;
458*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
459*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn =
460*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns);
461*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
462*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
463*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
464*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Get the relocated table address
465*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
466*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		addr = (ulong) fn + reloc_offset;
467*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr;
468*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
469*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
470*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Check to see if the table has already been relocated.  If not, do
471*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * a sanity check to make sure there is a faithful copy of the
472*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * FLASH based function table in RAM, then adjust the table.
473*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
474*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (!fn_r->relocated) {
475*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (memcmp
476*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns))
477*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				== 0) {
478*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				desc->iface_fns = fn_r;
479*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			} else {
480*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				PRINTF ("%s:%d: Invalid function table at 0x%p\n",
481*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						__FUNCTION__, __LINE__, fn_r);
482*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
483*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
484*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
485*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			PRINTF ("%s:%d: Relocating descriptor at 0x%p\n",
486*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					__FUNCTION__, __LINE__, desc);
487*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
488*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->pre) + reloc_offset;
489*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->pre = (Xilinx_pre_fn) addr;
490*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->pgm) + reloc_offset;
491*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->pgm = (Xilinx_pgm_fn) addr;
492*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->init) + reloc_offset;
493*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->init = (Xilinx_init_fn) addr;
494*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->done) + reloc_offset;
495*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->done = (Xilinx_done_fn) addr;
496*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->err) + reloc_offset;
497*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->err = (Xilinx_err_fn) addr;
498*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->clk) + reloc_offset;
499*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->clk = (Xilinx_clk_fn) addr;
500*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->cs) + reloc_offset;
501*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->cs = (Xilinx_cs_fn) addr;
502*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->wr) + reloc_offset;
503*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->wr = (Xilinx_wr_fn) addr;
504*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->rdata) + reloc_offset;
505*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->rdata = (Xilinx_rdata_fn) addr;
506*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->wdata) + reloc_offset;
507*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->wdata = (Xilinx_wdata_fn) addr;
508*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->busy) + reloc_offset;
509*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->busy = (Xilinx_busy_fn) addr;
510*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->abort) + reloc_offset;
511*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->abort = (Xilinx_abort_fn) addr;
512*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->post) + reloc_offset;
513*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->post = (Xilinx_post_fn) addr;
514*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->relocated = TRUE;
515*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} else {
516*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r);
517*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			desc->iface_fns = fn_r;
518*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
519*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = FPGA_SUCCESS;
520*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
521*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
522*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
523*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
524*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
525*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
526*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
527*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
528*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__);
529*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return FPGA_FAIL;
530*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
531*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
532*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
533*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
534*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__);
535*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return FPGA_FAIL;
536*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
537*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
538*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset)
539*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
540*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
541*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Xilinx_Virtex2_Slave_Serial_fns *fn =
542*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns);
543*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
544*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
545*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s:%d: Slave Serial Loading is unsupported\n",
546*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, __LINE__);
547*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
548*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s:%d: NULL Interface function table!\n",
549*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, __LINE__);
550*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
551*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
552*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
553*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
554*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* vim: set ts=4 tw=78: */
555