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