uboot/drivers/fpga/spartan2.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#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
  33static int spartan2_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
  34static int spartan2_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
  35/* static int spartan2_sp_info(xilinx_desc *desc ); */
  36
  37static int spartan2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
  38static 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 */
  43static 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
  67static 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
  90static int spartan2_info(xilinx_desc *desc)
  91{
  92        return FPGA_SUCCESS;
  93}
  94
  95
  96/* ------------------------------------------------------------------------- */
  97/* Spartan-II Slave Parallel Generic Implementation */
  98
  99static 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
 251static 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
 299static 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
 442static 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
 451struct xilinx_fpga_op spartan2_op = {
 452        .load = spartan2_load,
 453        .dump = spartan2_dump,
 454        .info = spartan2_info,
 455};
 456