xref: /rk3399_rockchip-uboot/drivers/fpga/ACEX1K.c (revision c8aa7dfc18f7cc90d0aea6c7becbb67dfc5bba4b)
1*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
2*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2003
3*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de
4*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
5*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2002
6*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
7*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
8*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * See file CREDITS for list of people who contributed to this
9*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * project.
10*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
11*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or
12*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * modify it under the terms of the GNU General Public License as
13*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * published by the Free Software Foundation; either version 2 of
14*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * the License, or (at your option) any later version.
15*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
16*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
17*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
19*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
20*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
21*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
22*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
23*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * MA 02111-1307 USA
25*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  *
26*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
27*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
28*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <common.h>		/* core U-Boot definitions */
29*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <ACEX1K.h>		/* ACEX device family */
30*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
31*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Define FPGA_DEBUG to get debug printf's */
32*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef	FPGA_DEBUG
33*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...)	printf (fmt ,##args)
34*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #else
35*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...)
36*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
37*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
38*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Note: The assumption is that we cannot possibly run fast enough to
39*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * overrun the device (the Slave Parallel mode can free run at 50MHz).
40*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
41*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  * the board config file to slow things down.
42*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD  */
43*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_FPGA_DELAY
44*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_FPGA_DELAY()
45*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
46*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
47*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT
48*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10		/* 100 ms */
49*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
50*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
51*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int ACEX1K_ps_load( Altera_desc *desc, void *buf, size_t bsize );
52*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int ACEX1K_ps_dump( Altera_desc *desc, void *buf, size_t bsize );
53*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* static int ACEX1K_ps_info( Altera_desc *desc ); */
54*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int ACEX1K_ps_reloc( Altera_desc *desc, ulong reloc_offset );
55*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
56*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
57*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ACEX1K Generic Implementation */
58*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ACEX1K_load (Altera_desc * desc, void *buf, size_t bsize)
59*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
60*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
61*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
62*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	switch (desc->iface) {
63*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case passive_serial:
64*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__);
65*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = ACEX1K_ps_load (desc, buf, bsize);
66*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
67*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
68*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Add new interface types here */
69*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
70*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	default:
71*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported interface type, %d\n",
72*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->iface);
73*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
74*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
75*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
76*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
77*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
78*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ACEX1K_dump (Altera_desc * desc, void *buf, size_t bsize)
79*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
80*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;
81*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
82*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	switch (desc->iface) {
83*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	case passive_serial:
84*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__);
85*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = ACEX1K_ps_dump (desc, buf, bsize);
86*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		break;
87*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
88*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Add new interface types here */
89*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
90*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	default:
91*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported interface type, %d\n",
92*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->iface);
93*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
94*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
95*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
96*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
97*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
98*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ACEX1K_info( Altera_desc *desc )
99*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
100*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return FPGA_SUCCESS;
101*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
102*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
103*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
104*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ACEX1K_reloc (Altera_desc * desc, ulong reloc_offset)
105*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
106*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;	/* assume a failure */
107*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
108*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (desc->family != Altera_ACEX1K) {
109*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: Unsupported family type, %d\n",
110*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, desc->family);
111*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		return FPGA_FAIL;
112*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else
113*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		switch (desc->iface) {
114*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		case passive_serial:
115*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			ret_val = ACEX1K_ps_reloc (desc, reloc_offset);
116*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			break;
117*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
118*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Add new interface types here */
119*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
120*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		default:
121*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			printf ("%s: Unsupported interface type, %d\n",
122*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					__FUNCTION__, desc->iface);
123*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
124*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
125*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
126*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
127*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
128*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
129*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
130*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ACEX1K Passive Serial Generic Implementation                                  */
131*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
132*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int ACEX1K_ps_load (Altera_desc * desc, void *buf, size_t bsize)
133*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
134*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;	/* assume the worst */
135*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Altera_ACEX1K_Passive_Serial_fns *fn = desc->iface_fns;
136*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int i;
137*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
138*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	PRINTF ("%s: start with interface functions @ 0x%p\n",
139*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			__FUNCTION__, fn);
140*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
141*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
142*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		size_t bytecount = 0;
143*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		unsigned char *data = (unsigned char *) buf;
144*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		int cookie = desc->cookie;	/* make a local copy */
145*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		unsigned long ts;		/* timestamp */
146*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
147*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		PRINTF ("%s: Function Table:\n"
148*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"ptr:\t0x%p\n"
149*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"struct: 0x%p\n"
150*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"config:\t0x%p\n"
151*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"status:\t0x%p\n"
152*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"clk:\t0x%p\n"
153*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"data:\t0x%p\n"
154*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				"done:\t0x%p\n\n",
155*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				__FUNCTION__, &fn, fn, fn->config, fn->status,
156*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				fn->clk, fn->data, fn->done);
157*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
158*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("Loading FPGA Device %d...", cookie);
159*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
160*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
161*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/*
162*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 * Run the pre configuration function if there is one.
163*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		 */
164*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (*fn->pre) {
165*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->pre) (cookie);
166*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
167*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
168*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Establish the initial state */
169*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->config) (TRUE, TRUE, cookie);	/* Assert nCONFIG */
170*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
171*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		udelay(2);		/* T_cfg > 2us	*/
172*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
173*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* nSTATUS should be asserted now */
174*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->done) (cookie);
175*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if ( !(*fn->status) (cookie) ) {
176*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			puts ("** nSTATUS is not asserted.\n");
177*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->abort) (cookie);
178*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			return FPGA_FAIL;
179*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
180*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
181*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->config) (FALSE, TRUE, cookie);	/* Deassert nCONFIG */
182*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		udelay(2);		/* T_cf2st1 < 4us	*/
183*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
184*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Wait for nSTATUS to be released (i.e. deasserted) */
185*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ts = get_timer (0);		/* get current time */
186*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		do {
187*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			CONFIG_FPGA_DELAY ();
188*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {	/* check the time */
189*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				puts ("** Timeout waiting for STATUS to go high.\n");
190*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
191*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
192*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
193*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(*fn->done) (cookie);
194*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} while ((*fn->status) (cookie));
195*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
196*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Get ready for the burn */
197*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
198*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
199*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Load the data */
200*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		while (bytecount < bsize) {
201*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			unsigned char val=0;
202*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
203*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (ctrlc ()) {
204*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
205*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
206*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
207*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
208*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/* Altera detects an error if INIT goes low (active)
209*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			   while DONE is low (inactive) */
210*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #if 0 /* not yet implemented */
211*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
212*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				puts ("** CRC error during FPGA load.\n");
213*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->abort) (cookie);
214*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return (FPGA_FAIL);
215*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
216*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
217*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			val = data [bytecount ++ ];
218*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			i = 8;
219*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			do {
220*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				/* Deassert the clock */
221*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->clk) (FALSE, TRUE, cookie);
222*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				CONFIG_FPGA_DELAY ();
223*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				/* Write data */
224*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->data) ( (val & 0x01), TRUE, cookie);
225*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				CONFIG_FPGA_DELAY ();
226*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				/* Assert the clock */
227*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				(*fn->clk) (TRUE, TRUE, cookie);
228*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				CONFIG_FPGA_DELAY ();
229*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				val >>= 1;
230*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				i --;
231*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			} while (i > 0);
232*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
233*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
234*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (bytecount % (bsize / 40) == 0)
235*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				putc ('.');		/* let them know we are alive */
236*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
237*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
238*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
239*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
240*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
241*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
242*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		putc (' ');			/* terminate the dotted line */
243*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
244*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
245*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	/*
246*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	 * Checking FPGA's CONF_DONE signal - correctly booted ?
247*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	 */
248*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
249*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if ( ! (*fn->done) (cookie) ) {
250*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		puts ("** Booting failed! CONF_DONE is still deasserted.\n");
251*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->abort) (cookie);
252*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		return (FPGA_FAIL);
253*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
254*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
255*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	/*
256*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	 * "DCLK must be clocked an additional 10 times fpr ACEX 1K..."
257*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	 */
258*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
259*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < 12; i++) {
260*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
261*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->clk) (TRUE, TRUE, cookie);	/* Assert the clock pin */
262*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		CONFIG_FPGA_DELAY ();
263*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		(*fn->clk) (FALSE, TRUE, cookie);	/* Deassert the clock pin */
264*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
265*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
266*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	ret_val = FPGA_SUCCESS;
267*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
268*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
269*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (ret_val == FPGA_SUCCESS) {
270*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			puts ("Done.\n");
271*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
272*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		else {
273*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			puts ("Fail.\n");
274*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
275*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
276*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	(*fn->post) (cookie);
277*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
278*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
279*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
280*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
281*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
282*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
283*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
284*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
285*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int ACEX1K_ps_dump (Altera_desc * desc, void *buf, size_t bsize)
286*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
287*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	/* Readback is only available through the Slave Parallel and         */
288*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	/* boundary-scan interfaces.                                         */
289*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	printf ("%s: Passive Serial Dumping is unavailable\n",
290*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			__FUNCTION__);
291*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return FPGA_FAIL;
292*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
293*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
294*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int ACEX1K_ps_reloc (Altera_desc * desc, ulong reloc_offset)
295*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
296*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	int ret_val = FPGA_FAIL;	/* assume the worst */
297*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	Altera_ACEX1K_Passive_Serial_fns *fn_r, *fn =
298*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			(Altera_ACEX1K_Passive_Serial_fns *) (desc->iface_fns);
299*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
300*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	if (fn) {
301*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ulong addr;
302*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
303*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		/* Get the relocated table address */
304*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		addr = (ulong) fn + reloc_offset;
305*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		fn_r = (Altera_ACEX1K_Passive_Serial_fns *) addr;
306*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
307*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		if (!fn_r->relocated) {
308*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
309*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			if (memcmp (fn_r, fn,
310*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						sizeof (Altera_ACEX1K_Passive_Serial_fns))
311*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				== 0) {
312*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				/* good copy of the table, fix the descriptor pointer */
313*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				desc->iface_fns = fn_r;
314*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			} else {
315*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				PRINTF ("%s: Invalid function table at 0x%p\n",
316*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 						__FUNCTION__, fn_r);
317*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 				return FPGA_FAIL;
318*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			}
319*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
320*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__,
321*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 					desc);
322*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
323*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->pre) + reloc_offset;
324*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->pre = (Altera_pre_fn) addr;
325*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
326*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->config) + reloc_offset;
327*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->config = (Altera_config_fn) addr;
328*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
329*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->status) + reloc_offset;
330*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->status = (Altera_status_fn) addr;
331*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
332*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->done) + reloc_offset;
333*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->done = (Altera_done_fn) addr;
334*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
335*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->clk) + reloc_offset;
336*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->clk = (Altera_clk_fn) addr;
337*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
338*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->data) + reloc_offset;
339*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->data = (Altera_data_fn) addr;
340*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
341*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->abort) + reloc_offset;
342*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->abort = (Altera_abort_fn) addr;
343*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
344*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			addr = (ulong) (fn->post) + reloc_offset;
345*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->post = (Altera_post_fn) addr;
346*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
347*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			fn_r->relocated = TRUE;
348*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
349*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		} else {
350*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/* this table has already been moved */
351*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			/* XXX - should check to see if the descriptor is correct */
352*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 			desc->iface_fns = fn_r;
353*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		}
354*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
355*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		ret_val = FPGA_SUCCESS;
356*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	} else {
357*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
358*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	}
359*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
360*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 	return ret_val;
361*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 
362*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
363