uboot/drivers/fpga/spartan3.c
<<
>>
Prefs
   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#include <common.h>             /* core U-Boot definitions */
  13#include <spartan3.h>           /* Spartan-II device family */
  14
  15/* Define FPGA_DEBUG to get debug printf's */
  16#ifdef  FPGA_DEBUG
  17#define PRINTF(fmt,args...)     printf (fmt ,##args)
  18#else
  19#define PRINTF(fmt,args...)
  20#endif
  21
  22#undef CONFIG_SYS_FPGA_CHECK_BUSY
  23
  24/* Note: The assumption is that we cannot possibly run fast enough to
  25 * overrun the device (the Slave Parallel mode can free run at 50MHz).
  26 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
  27 * the board config file to slow things down.
  28 */
  29#ifndef CONFIG_FPGA_DELAY
  30#define CONFIG_FPGA_DELAY()
  31#endif
  32
  33#ifndef CONFIG_SYS_FPGA_WAIT
  34#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100  /* 10 ms */
  35#endif
  36
  37static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
  38static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
  39/* static int spartan3_sp_info(xilinx_desc *desc ); */
  40
  41static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
  42static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
  43/* static int spartan3_ss_info(xilinx_desc *desc); */
  44
  45/* ------------------------------------------------------------------------- */
  46/* Spartan-II Generic Implementation */
  47static int spartan3_load(xilinx_desc *desc, const void *buf, size_t bsize,
  48                         bitstream_type bstype)
  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
  71static 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
  94static int spartan3_info(xilinx_desc *desc)
  95{
  96        return FPGA_SUCCESS;
  97}
  98
  99
 100/* ------------------------------------------------------------------------- */
 101/* Spartan-II Slave Parallel Generic Implementation */
 102
 103static 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
 257static 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
 305static 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
 460static 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
 469struct xilinx_fpga_op spartan3_op = {
 470        .load = spartan3_load,
 471        .dump = spartan3_dump,
 472        .info = spartan3_info,
 473};
 474