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