xref: /rk3399_rockchip-uboot/drivers/fpga/cyclon2.c (revision c8aa7dfc18f7cc90d0aea6c7becbb67dfc5bba4b)
1*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
2*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2006
3*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Heiko Schocher, hs@denx.de
4*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Based on ACE1XK.c
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 #include <common.h>		/* core U-Boot definitions */
27*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <altera.h>
28*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <ACEX1K.h>		/* ACEX device family */
29*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
30*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Define FPGA_DEBUG to get debug printf's */
31*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef	FPGA_DEBUG
32*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...)	printf (fmt ,##args)
33*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #else
34*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...)
35*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
36*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
37*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Note: The assumption is that we cannot possibly run fast enough to
38*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * overrun the device (the Slave Parallel mode can free run at 50MHz).
39*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
40*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * the board config file to slow things down.
41*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
42*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_FPGA_DELAY
43*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_FPGA_DELAY()
44*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
45*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
46*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT
47*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10		/* 100 ms */
48*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
49*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
50*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize );
51*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize );
52*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* static int CYC2_ps_info( Altera_desc *desc ); */
53*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int CYC2_ps_reloc( Altera_desc *desc, ulong reloc_offset );
54*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
55*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
56*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* CYCLON2 Generic Implementation */
57*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int CYC2_load (Altera_desc * desc, void *buf, size_t bsize)
58*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
59*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
60*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
61*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	switch (desc->iface) {
62*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case passive_serial:
63*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__);
64*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = CYC2_ps_load (desc, buf, bsize);
65*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
66*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
67*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Add new interface types here */
68*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
69*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	default:
70*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported interface type, %d\n",
71*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->iface);
72*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
73*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
74*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
75*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
76*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
77*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize)
78*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
79*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
80*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
81*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	switch (desc->iface) {
82*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case passive_serial:
83*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__);
84*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = CYC2_ps_dump (desc, buf, bsize);
85*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
86*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
87*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Add new interface types here */
88*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
89*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	default:
90*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported interface type, %d\n",
91*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->iface);
92*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
93*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
94*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
95*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
96*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
97*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int CYC2_info( Altera_desc *desc )
98*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
99*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return FPGA_SUCCESS;
100*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
101*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
102*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int CYC2_reloc (Altera_desc * desc, ulong reloc_offset)
103*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
104*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;	/* assume a failure */
105*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
106*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (desc->family != Altera_CYC2) {
107*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported family type, %d\n",
108*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->family);
109*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		return FPGA_FAIL;
110*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else
111*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		switch (desc->iface) {
112*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		case passive_serial:
113*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			ret_val = CYC2_ps_reloc (desc, reloc_offset);
114*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			break;
115*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
116*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Add new interface types here */
117*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
118*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		default:
119*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			printf ("%s: Unsupported interface type, %d\n",
120*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					__FUNCTION__, desc->iface);
121*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
122*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
123*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
124*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
125*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
126*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
127*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* CYCLON2 Passive Serial Generic Implementation                                  */
128*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize)
129*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
130*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;	/* assume the worst */
131*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
132*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int	ret = 0;
133*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
134*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	PRINTF ("%s: start with interface functions @ 0x%p\n",
135*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			__FUNCTION__, fn);
136*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
137*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
138*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		int cookie = desc->cookie;	/* make a local copy */
139*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		unsigned long ts;		/* timestamp */
140*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
141*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Function Table:\n"
142*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"ptr:\t0x%p\n"
143*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"struct: 0x%p\n"
144*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"config:\t0x%p\n"
145*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"status:\t0x%p\n"
146*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"write:\t0x%p\n"
147*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"done:\t0x%p\n\n",
148*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, &fn, fn, fn->config, fn->status,
149*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				fn->write, fn->done);
150*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
151*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("Loading FPGA Device %d...", cookie);
152*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
153*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
154*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
155*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Run the pre configuration function if there is one.
156*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
157*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (*fn->pre) {
158*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->pre) (cookie);
159*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
160*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
161*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Establish the initial state */
162*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->config) (TRUE, TRUE, cookie);	/* Assert nCONFIG */
163*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
164*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		udelay(2);		/* T_cfg > 2us	*/
165*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
166*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Wait for nSTATUS to be asserted */
167*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ts = get_timer (0);		/* get current time */
168*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		do {
169*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			CONFIG_FPGA_DELAY ();
170*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
171*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				puts ("** Timeout waiting for STATUS to go high.\n");
172*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
173*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
174*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
175*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} while (!(*fn->status) (cookie));
176*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
177*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Get ready for the burn */
178*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
179*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
180*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret = (*fn->write) (buf, bsize, TRUE, cookie);
181*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (ret) {
182*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			puts ("** Write failed.\n");
183*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->abort) (cookie);
184*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			return FPGA_FAIL;
185*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
186*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
187*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		puts(" OK? ...");
188*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
189*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
190*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
191*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
192*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
193*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		putc (' ');			/* terminate the dotted line */
194*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
195*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
196*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	/*
197*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	 * Checking FPGA's CONF_DONE signal - correctly booted ?
198*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	 */
199*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
200*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if ( ! (*fn->done) (cookie) ) {
201*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		puts ("** Booting failed! CONF_DONE is still deasserted.\n");
202*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->abort) (cookie);
203*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		return (FPGA_FAIL);
204*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
205*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
206*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	puts(" OK\n");
207*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
208*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
209*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	ret_val = FPGA_SUCCESS;
210*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
211*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
212*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (ret_val == FPGA_SUCCESS) {
213*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		puts ("Done.\n");
214*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
215*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	else {
216*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		puts ("Fail.\n");
217*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
218*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
219*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	(*fn->post) (cookie);
220*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
221*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
222*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
223*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
224*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
225*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
226*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
227*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
228*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize)
229*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
230*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	/* Readback is only available through the Slave Parallel and         */
231*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	/* boundary-scan interfaces.                                         */
232*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	printf ("%s: Passive Serial Dumping is unavailable\n",
233*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			__FUNCTION__);
234*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return FPGA_FAIL;
235*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
236*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
237*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int CYC2_ps_reloc (Altera_desc * desc, ulong reloc_offset)
238*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
239*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;	/* assume the worst */
240*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Altera_CYC2_Passive_Serial_fns *fn_r, *fn =
241*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(Altera_CYC2_Passive_Serial_fns *) (desc->iface_fns);
242*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
243*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
244*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ulong addr;
245*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
246*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Get the relocated table address */
247*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		addr = (ulong) fn + reloc_offset;
248*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		fn_r = (Altera_CYC2_Passive_Serial_fns *) addr;
249*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
250*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (!fn_r->relocated) {
251*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
252*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (memcmp (fn_r, fn,
253*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						sizeof (Altera_CYC2_Passive_Serial_fns))
254*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				== 0) {
255*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				/* good copy of the table, fix the descriptor pointer */
256*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				desc->iface_fns = fn_r;
257*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			} else {
258*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				PRINTF ("%s: Invalid function table at 0x%p\n",
259*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						__FUNCTION__, fn_r);
260*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
261*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
262*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
263*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__,
264*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					desc);
265*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
266*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->pre) + reloc_offset;
267*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->pre = (Altera_pre_fn) addr;
268*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
269*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->config) + reloc_offset;
270*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->config = (Altera_config_fn) addr;
271*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
272*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->status) + reloc_offset;
273*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->status = (Altera_status_fn) addr;
274*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
275*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->done) + reloc_offset;
276*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->done = (Altera_done_fn) addr;
277*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
278*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->write) + reloc_offset;
279*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->write = (Altera_write_fn) addr;
280*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
281*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->abort) + reloc_offset;
282*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->abort = (Altera_abort_fn) addr;
283*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
284*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->post) + reloc_offset;
285*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->post = (Altera_post_fn) addr;
286*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
287*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->relocated = TRUE;
288*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
289*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} else {
290*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/* this table has already been moved */
291*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/* XXX - should check to see if the descriptor is correct */
292*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			desc->iface_fns = fn_r;
293*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
294*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
295*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = FPGA_SUCCESS;
296*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
297*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
298*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
299*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
300*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
301*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
302