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