1 /* 2 * (C) Copyright 2002 3 * Rich Ireland, Enterasys Networks, rireland@enterasys.com. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * Configuration support for Xilinx Spartan3 devices. Based 10 * on spartan2.c (Rich Ireland, rireland@enterasys.com). 11 */ 12 13 #include <common.h> /* core U-Boot definitions */ 14 #include <spartan3.h> /* Spartan-II device family */ 15 16 /* Define FPGA_DEBUG to get debug printf's */ 17 #ifdef FPGA_DEBUG 18 #define PRINTF(fmt,args...) printf (fmt ,##args) 19 #else 20 #define PRINTF(fmt,args...) 21 #endif 22 23 #undef CONFIG_SYS_FPGA_CHECK_BUSY 24 25 /* Note: The assumption is that we cannot possibly run fast enough to 26 * overrun the device (the Slave Parallel mode can free run at 50MHz). 27 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in 28 * the board config file to slow things down. 29 */ 30 #ifndef CONFIG_FPGA_DELAY 31 #define CONFIG_FPGA_DELAY() 32 #endif 33 34 #ifndef CONFIG_SYS_FPGA_WAIT 35 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ 36 #endif 37 38 static int Spartan3_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize); 39 static int Spartan3_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize); 40 /* static int Spartan3_sp_info(Xilinx_desc *desc ); */ 41 42 static int Spartan3_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize); 43 static int Spartan3_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize); 44 /* static int Spartan3_ss_info(Xilinx_desc *desc); */ 45 46 /* ------------------------------------------------------------------------- */ 47 /* Spartan-II Generic Implementation */ 48 int Spartan3_load(Xilinx_desc *desc, const void *buf, size_t bsize) 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 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 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