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