uboot/drivers/fpga/virtex2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2002
   4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
   5 * Keith Outwater, keith_outwater@mvis.com
   6 *
   7 * Copyright (c) 2019 SED Systems, a division of Calian Ltd.
   8 */
   9
  10/*
  11 * Configuration support for Xilinx Virtex2 devices.  Based
  12 * on spartan2.c (Rich Ireland, rireland@enterasys.com).
  13 */
  14
  15#include <common.h>
  16#include <console.h>
  17#include <virtex2.h>
  18#include <linux/delay.h>
  19
  20#if 0
  21#define FPGA_DEBUG
  22#endif
  23
  24#ifdef  FPGA_DEBUG
  25#define PRINTF(fmt, args...)    printf(fmt, ##args)
  26#else
  27#define PRINTF(fmt, args...)
  28#endif
  29
  30/*
  31 * If the SelectMap interface can be overrun by the processor, define
  32 * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board
  33 * configuration file and add board-specific support for checking BUSY status.
  34 * By default, assume that the SelectMap interface cannot be overrun.
  35 */
  36#ifndef CONFIG_SYS_FPGA_CHECK_BUSY
  37#undef CONFIG_SYS_FPGA_CHECK_BUSY
  38#endif
  39
  40#ifndef CONFIG_FPGA_DELAY
  41#define CONFIG_FPGA_DELAY()
  42#endif
  43
  44#ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK
  45#define CONFIG_SYS_FPGA_PROG_FEEDBACK
  46#endif
  47
  48/*
  49 * Don't allow config cycle to be interrupted
  50 */
  51#ifndef CONFIG_SYS_FPGA_CHECK_CTRLC
  52#undef CONFIG_SYS_FPGA_CHECK_CTRLC
  53#endif
  54
  55/*
  56 * Check for errors during configuration by default
  57 */
  58#ifndef CONFIG_SYS_FPGA_CHECK_ERROR
  59#define CONFIG_SYS_FPGA_CHECK_ERROR
  60#endif
  61
  62/*
  63 * The default timeout in mS for INIT_B to deassert after PROG_B has
  64 * been deasserted. Per the latest Virtex II Handbook (page 347), the
  65 * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
  66 * data frame for the XC2V8000.  The XC2V8000 has 2860 data frames
  67 * which yields 11.44 mS.  So let's make it bigger in order to handle
  68 * an XC2V1000, if anyone can ever get ahold of one.
  69 */
  70#ifndef CONFIG_SYS_FPGA_WAIT_INIT
  71#define CONFIG_SYS_FPGA_WAIT_INIT       CONFIG_SYS_HZ / 2       /* 500 ms */
  72#endif
  73
  74/*
  75 * The default timeout for waiting for BUSY to deassert during configuration.
  76 * This is normally not necessary since for most reasonable configuration
  77 * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
  78 */
  79#ifndef CONFIG_SYS_FPGA_WAIT_BUSY
  80#define CONFIG_SYS_FPGA_WAIT_BUSY       CONFIG_SYS_HZ / 200     /* 5 ms*/
  81#endif
  82
  83/* Default timeout for waiting for FPGA to enter operational mode after
  84 * configuration data has been written.
  85 */
  86#ifndef CONFIG_SYS_FPGA_WAIT_CONFIG
  87#define CONFIG_SYS_FPGA_WAIT_CONFIG     CONFIG_SYS_HZ / 5       /* 200 ms */
  88#endif
  89
  90static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize);
  91static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize);
  92
  93static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
  94static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
  95
  96static int virtex2_load(xilinx_desc *desc, const void *buf, size_t bsize,
  97                        bitstream_type bstype)
  98{
  99        int ret_val = FPGA_FAIL;
 100
 101        switch (desc->iface) {
 102        case slave_serial:
 103                PRINTF("%s: Launching Slave Serial Load\n", __func__);
 104                ret_val = virtex2_ss_load(desc, buf, bsize);
 105                break;
 106
 107        case slave_selectmap:
 108                PRINTF("%s: Launching Slave Parallel Load\n", __func__);
 109                ret_val = virtex2_ssm_load(desc, buf, bsize);
 110                break;
 111
 112        default:
 113                printf("%s: Unsupported interface type, %d\n",
 114                       __func__, desc->iface);
 115        }
 116        return ret_val;
 117}
 118
 119static int virtex2_dump(xilinx_desc *desc, const void *buf, size_t bsize)
 120{
 121        int ret_val = FPGA_FAIL;
 122
 123        switch (desc->iface) {
 124        case slave_serial:
 125                PRINTF("%s: Launching Slave Serial Dump\n", __func__);
 126                ret_val = virtex2_ss_dump(desc, buf, bsize);
 127                break;
 128
 129        case slave_parallel:
 130                PRINTF("%s: Launching Slave Parallel Dump\n", __func__);
 131                ret_val = virtex2_ssm_dump(desc, buf, bsize);
 132                break;
 133
 134        default:
 135                printf("%s: Unsupported interface type, %d\n",
 136                       __func__, desc->iface);
 137        }
 138        return ret_val;
 139}
 140
 141static int virtex2_info(xilinx_desc *desc)
 142{
 143        return FPGA_SUCCESS;
 144}
 145
 146/*
 147 * Virtex-II Slave SelectMap or Serial configuration loader. Configuration
 148 * is as follows:
 149 * 1. Set the FPGA's PROG_B line low.
 150 * 2. Set the FPGA's PROG_B line high.  Wait for INIT_B to go high.
 151 * 3. Write data to the SelectMap port.  If INIT_B goes low at any time
 152 *    this process, a configuration error (most likely CRC failure) has
 153 *    ocurred.  At this point a status word may be read from the
 154 *    SelectMap interface to determine the source of the problem (You
 155 *    could, for instance, put this in your 'abort' function handler).
 156 * 4. After all data has been written, test the state of the FPGA
 157 *    INIT_B and DONE lines.  If both are high, configuration has
 158 *    succeeded. Congratulations!
 159 */
 160static int virtex2_slave_pre(xilinx_virtex2_slave_fns *fn, int cookie)
 161{
 162        unsigned long ts;
 163
 164        PRINTF("%s:%d: Start with interface functions @ 0x%p\n",
 165               __func__, __LINE__, fn);
 166
 167        if (!fn) {
 168                printf("%s:%d: NULL Interface function table!\n",
 169                       __func__, __LINE__);
 170                return FPGA_FAIL;
 171        }
 172
 173        /* Gotta split this one up (so the stack won't blow??) */
 174        PRINTF("%s:%d: Function Table:\n"
 175               "  base   0x%p\n"
 176               "  struct 0x%p\n"
 177               "  pre    0x%p\n"
 178               "  prog   0x%p\n"
 179               "  init   0x%p\n"
 180               "  error  0x%p\n",
 181               __func__, __LINE__,
 182               &fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
 183        PRINTF("  clock  0x%p\n"
 184               "  cs     0x%p\n"
 185               "  write  0x%p\n"
 186               "  rdata  0x%p\n"
 187               "  wdata  0x%p\n"
 188               "  busy   0x%p\n"
 189               "  abort  0x%p\n"
 190               "  post   0x%p\n\n",
 191               fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
 192               fn->busy, fn->abort, fn->post);
 193
 194#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 195        printf("Initializing FPGA Device %d...\n", cookie);
 196#endif
 197        /*
 198         * Run the pre configuration function if there is one.
 199         */
 200        if (*fn->pre)
 201                (*fn->pre)(cookie);
 202
 203        /*
 204         * Assert the program line.  The minimum pulse width for
 205         * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
 206         * There is no maximum value for the pulse width. Check to make
 207         * sure that INIT_B goes low after assertion of PROG_B
 208         */
 209        (*fn->pgm)(true, true, cookie);
 210        udelay(10);
 211        ts = get_timer(0);
 212        do {
 213                if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
 214                        printf("%s:%d: ** Timeout after %d ticks waiting for INIT to assert.\n",
 215                               __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT);
 216                        (*fn->abort)(cookie);
 217                        return FPGA_FAIL;
 218                }
 219        } while (!(*fn->init)(cookie));
 220
 221        (*fn->pgm)(false, true, cookie);
 222        CONFIG_FPGA_DELAY();
 223        if (fn->clk)
 224                (*fn->clk)(true, true, cookie);
 225
 226        /*
 227         * Start a timer and wait for INIT_B to go high
 228         */
 229        ts = get_timer(0);
 230        do {
 231                CONFIG_FPGA_DELAY();
 232                if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) {
 233                        printf("%s:%d: ** Timeout after %d ticks waiting for INIT to deassert.\n",
 234                               __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT);
 235                        (*fn->abort)(cookie);
 236                        return FPGA_FAIL;
 237                }
 238        } while ((*fn->init)(cookie) && (*fn->busy)(cookie));
 239
 240        if (fn->wr)
 241                (*fn->wr)(true, true, cookie);
 242        if (fn->cs)
 243                (*fn->cs)(true, true, cookie);
 244
 245        mdelay(10);
 246        return FPGA_SUCCESS;
 247}
 248
 249static int virtex2_slave_post(xilinx_virtex2_slave_fns *fn,
 250                              int cookie)
 251{
 252        int ret_val = FPGA_SUCCESS;
 253        int num_done = 0;
 254        unsigned long ts;
 255
 256        /*
 257         * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
 258         */
 259        CONFIG_FPGA_DELAY();
 260        if (fn->cs)
 261                (*fn->cs)(false, true, cookie);
 262        if (fn->wr)
 263                (*fn->wr)(false, true, cookie);
 264
 265#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 266        putc('\n');
 267#endif
 268
 269        /*
 270         * Check for successful configuration.  FPGA INIT_B and DONE
 271         * should both be high upon successful configuration. Continue pulsing
 272         * clock with data set to all ones until DONE is asserted and for 8
 273         * clock cycles afterwards.
 274         */
 275        ts = get_timer(0);
 276        while (true) {
 277                if ((*fn->done)(cookie) == FPGA_SUCCESS &&
 278                    !((*fn->init)(cookie))) {
 279                        if (num_done++ >= 8)
 280                                break;
 281                }
 282
 283                if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
 284                        printf("%s:%d: ** Timeout after %d ticks waiting for DONE to assert and INIT to deassert\n",
 285                               __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
 286                        (*fn->abort)(cookie);
 287                        ret_val = FPGA_FAIL;
 288                        break;
 289                }
 290                if (fn->wbulkdata) {
 291                        unsigned char dummy = 0xff;
 292                        (*fn->wbulkdata)(&dummy, 1, true, cookie);
 293                } else {
 294                        (*fn->wdata)(0xff, true, cookie);
 295                        CONFIG_FPGA_DELAY();
 296                        (*fn->clk)(false, true, cookie);
 297                        CONFIG_FPGA_DELAY();
 298                        (*fn->clk)(true, true, cookie);
 299                }
 300        }
 301
 302        if (ret_val == FPGA_SUCCESS) {
 303#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 304                printf("Initialization of FPGA device %d complete\n", cookie);
 305#endif
 306                /*
 307                 * Run the post configuration function if there is one.
 308                 */
 309                if (*fn->post)
 310                        (*fn->post)(cookie);
 311        } else {
 312#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 313                printf("** Initialization of FPGA device %d FAILED\n",
 314                       cookie);
 315#endif
 316        }
 317        return ret_val;
 318}
 319
 320static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize)
 321{
 322        int ret_val = FPGA_FAIL;
 323        xilinx_virtex2_slave_fns *fn = desc->iface_fns;
 324        size_t bytecount = 0;
 325        unsigned char *data = (unsigned char *)buf;
 326        int cookie = desc->cookie;
 327
 328        ret_val = virtex2_slave_pre(fn, cookie);
 329        if (ret_val != FPGA_SUCCESS)
 330                return ret_val;
 331
 332        /*
 333         * Load the data byte by byte
 334         */
 335        while (bytecount < bsize) {
 336#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
 337                if (ctrlc()) {
 338                        (*fn->abort)(cookie);
 339                        return FPGA_FAIL;
 340                }
 341#endif
 342
 343                if ((*fn->done)(cookie) == FPGA_SUCCESS) {
 344                        PRINTF("%s:%d:done went active early, bytecount = %d\n",
 345                               __func__, __LINE__, bytecount);
 346                        break;
 347                }
 348
 349#ifdef CONFIG_SYS_FPGA_CHECK_ERROR
 350                if ((*fn->init)(cookie)) {
 351                        printf("\n%s:%d:  ** Error: INIT asserted during configuration\n",
 352                               __func__, __LINE__);
 353                        printf("%zu = buffer offset, %zu = buffer size\n",
 354                               bytecount, bsize);
 355                        (*fn->abort)(cookie);
 356                        return FPGA_FAIL;
 357                }
 358#endif
 359
 360                (*fn->wdata)(data[bytecount++], true, cookie);
 361                CONFIG_FPGA_DELAY();
 362
 363                /*
 364                 * Cycle the clock pin
 365                 */
 366                (*fn->clk)(false, true, cookie);
 367                CONFIG_FPGA_DELAY();
 368                (*fn->clk)(true, true, cookie);
 369
 370#ifdef CONFIG_SYS_FPGA_CHECK_BUSY
 371                ts = get_timer(0);
 372                while ((*fn->busy)(cookie)) {
 373                        if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_BUSY) {
 374                                printf("%s:%d: ** Timeout after %d ticks waiting for BUSY to deassert\n",
 375                                       __func__, __LINE__,
 376                                       CONFIG_SYS_FPGA_WAIT_BUSY);
 377                                (*fn->abort)(cookie);
 378                                return FPGA_FAIL;
 379                        }
 380                }
 381#endif
 382
 383#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 384                if (bytecount % (bsize / 40) == 0)
 385                        putc('.');
 386#endif
 387        }
 388
 389        return virtex2_slave_post(fn, cookie);
 390}
 391
 392/*
 393 * Read the FPGA configuration data
 394 */
 395static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize)
 396{
 397        int ret_val = FPGA_FAIL;
 398        xilinx_virtex2_slave_fns *fn = desc->iface_fns;
 399
 400        if (fn) {
 401                unsigned char *data = (unsigned char *)buf;
 402                size_t bytecount = 0;
 403                int cookie = desc->cookie;
 404
 405                printf("Starting Dump of FPGA Device %d...\n", cookie);
 406
 407                (*fn->cs)(true, true, cookie);
 408                (*fn->clk)(true, true, cookie);
 409
 410                while (bytecount < bsize) {
 411#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
 412                        if (ctrlc()) {
 413                                (*fn->abort)(cookie);
 414                                return FPGA_FAIL;
 415                        }
 416#endif
 417                        /*
 418                         * Cycle the clock and read the data
 419                         */
 420                        (*fn->clk)(false, true, cookie);
 421                        (*fn->clk)(true, true, cookie);
 422                        (*fn->rdata)(&data[bytecount++], cookie);
 423#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 424                        if (bytecount % (bsize / 40) == 0)
 425                                putc('.');
 426#endif
 427                }
 428
 429                /*
 430                 * Deassert CS_B and cycle the clock to deselect the device.
 431                 */
 432                (*fn->cs)(false, false, cookie);
 433                (*fn->clk)(false, true, cookie);
 434                (*fn->clk)(true, true, cookie);
 435
 436#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 437                putc('\n');
 438#endif
 439                puts("Done.\n");
 440        } else {
 441                printf("%s:%d: NULL Interface function table!\n",
 442                       __func__, __LINE__);
 443        }
 444        return ret_val;
 445}
 446
 447static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
 448{
 449        int ret_val = FPGA_FAIL;
 450        xilinx_virtex2_slave_fns *fn = desc->iface_fns;
 451        unsigned char *data = (unsigned char *)buf;
 452        int cookie = desc->cookie;
 453
 454        ret_val = virtex2_slave_pre(fn, cookie);
 455        if (ret_val != FPGA_SUCCESS)
 456                return ret_val;
 457
 458        if (fn->wbulkdata) {
 459                /* Load the data in a single chunk */
 460                (*fn->wbulkdata)(data, bsize, true, cookie);
 461        } else {
 462                size_t bytecount = 0;
 463
 464                /*
 465                 * Load the data bit by bit
 466                 */
 467                while (bytecount < bsize) {
 468                        unsigned char curr_data = data[bytecount++];
 469                        int bit;
 470
 471#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
 472                        if (ctrlc()) {
 473                                (*fn->abort) (cookie);
 474                                return FPGA_FAIL;
 475                        }
 476#endif
 477
 478                        if ((*fn->done)(cookie) == FPGA_SUCCESS) {
 479                                PRINTF("%s:%d:done went active early, bytecount = %d\n",
 480                                       __func__, __LINE__, bytecount);
 481                                break;
 482                        }
 483
 484#ifdef CONFIG_SYS_FPGA_CHECK_ERROR
 485                        if ((*fn->init)(cookie)) {
 486                                printf("\n%s:%d:  ** Error: INIT asserted during configuration\n",
 487                                       __func__, __LINE__);
 488                                printf("%zu = buffer offset, %zu = buffer size\n",
 489                                       bytecount, bsize);
 490                                (*fn->abort)(cookie);
 491                                return FPGA_FAIL;
 492                        }
 493#endif
 494
 495                        for (bit = 7; bit >= 0; --bit) {
 496                                unsigned char curr_bit = (curr_data >> bit) & 1;
 497                                (*fn->wdata)(curr_bit, true, cookie);
 498                                CONFIG_FPGA_DELAY();
 499                                (*fn->clk)(false, true, cookie);
 500                                CONFIG_FPGA_DELAY();
 501                                (*fn->clk)(true, true, cookie);
 502                        }
 503
 504                        /* Slave serial never uses a busy pin */
 505
 506#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 507                        if (bytecount % (bsize / 40) == 0)
 508                                putc('.');
 509#endif
 510                }
 511        }
 512
 513        return virtex2_slave_post(fn, cookie);
 514}
 515
 516static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
 517{
 518        printf("%s: Slave Serial Dumping is unsupported\n", __func__);
 519        return FPGA_FAIL;
 520}
 521
 522/* vim: set ts=4 tw=78: */
 523
 524struct xilinx_fpga_op virtex2_op = {
 525        .load = virtex2_load,
 526        .dump = virtex2_dump,
 527        .info = virtex2_info,
 528};
 529