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