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