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