uboot/board/hymod/bsp.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 *
  23 * hacked for Hymod FPGA support by Murray.Jensen@csiro.au, 29-Jan-01
  24 */
  25
  26#include <common.h>
  27#include <command.h>
  28#include <net.h>
  29#include <asm/iopin_8260.h>
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33/*-----------------------------------------------------------------------
  34 * Board Special Commands: FPGA load/store, EEPROM erase
  35 */
  36
  37#if defined(CONFIG_CMD_BSP)
  38
  39#define LOAD_SUCCESS            0
  40#define LOAD_FAIL_NOCONF        1
  41#define LOAD_FAIL_NOINIT        2
  42#define LOAD_FAIL_NODONE        3
  43
  44#define STORE_SUCCESS           0
  45
  46/*
  47 * Programming the Hymod FPGAs
  48 *
  49 * The 8260 io port config table is set up so that the INIT pin is
  50 * held Low (Open Drain output 0) - this will delay the automatic
  51 * Power-On config until INIT is released (by making it an input).
  52 *
  53 * If the FPGA has been programmed before, then the assertion of PROGRAM
  54 * will initiate configuration (i.e. it begins clearing the RAM).
  55 *
  56 * When the FPGA is ready to receive configuration data (either after
  57 * releasing INIT after Power-On, or after asserting PROGRAM), it will
  58 * pull INIT high.
  59 *
  60 * Notes from Paul Dunn:
  61 *
  62 *  1. program pin should be forced low for >= 300ns
  63 *     (about 20 bus clock cycles minimum).
  64 *
  65 *  2. then wait for init to go high, which signals
  66 *     that the FPGA has cleared its internal memory
  67 *     and is ready to load
  68 *
  69 *  3. perform load writes of entire config file
  70 *
  71 *  4. wait for done to go high, which should be
  72 *     within a few bus clock cycles. If done has not
  73 *     gone high after reasonable period, then load
  74 *     has not worked (wait several ms?)
  75 */
  76
  77int
  78fpga_load (int mezz, uchar *addr, ulong size)
  79{
  80        hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
  81        xlx_info_t *fp;
  82        xlx_iopins_t *fpgaio;
  83        volatile uchar *fpgabase;
  84        volatile uint cnt;
  85        uchar *eaddr = addr + size;
  86        int result;
  87
  88        if (mezz)
  89                fp = &cp->mezz.xlx[0];
  90        else
  91                fp = &cp->main.xlx[0];
  92
  93        if (!fp->mmap.prog.exists)
  94                return (LOAD_FAIL_NOCONF);
  95
  96        fpgabase = (uchar *)fp->mmap.prog.base;
  97        fpgaio = &fp->iopins;
  98
  99        /* set enable HIGH if required */
 100        if (fpgaio->enable_pin.flag)
 101                iopin_set_high (&fpgaio->enable_pin);
 102
 103        /* ensure INIT is released (set it to be an input) */
 104        iopin_set_in (&fpgaio->init_pin);
 105
 106        /* toggle PROG Low then High (will already be Low after Power-On) */
 107        iopin_set_low (&fpgaio->prog_pin);
 108        udelay (1);     /* minimum 300ns - 1usec should do it */
 109        iopin_set_high (&fpgaio->prog_pin);
 110
 111        /* wait for INIT High */
 112        cnt = 0;
 113        while (!iopin_is_high (&fpgaio->init_pin))
 114                if (++cnt == 10000000) {
 115                        result = LOAD_FAIL_NOINIT;
 116                        goto done;
 117                }
 118
 119        /* write configuration data */
 120        while (addr < eaddr)
 121                *fpgabase = *addr++;
 122
 123        /* wait for DONE High */
 124        cnt = 0;
 125        while (!iopin_is_high (&fpgaio->done_pin))
 126                if (++cnt == 100000000) {
 127                        result = LOAD_FAIL_NODONE;
 128                        goto done;
 129                }
 130
 131        /* success */
 132        result = LOAD_SUCCESS;
 133
 134  done:
 135
 136        if (fpgaio->enable_pin.flag)
 137                iopin_set_low (&fpgaio->enable_pin);
 138
 139        return (result);
 140}
 141
 142/* ------------------------------------------------------------------------- */
 143int
 144do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 145{
 146        uchar *addr, *save_addr;
 147        ulong size;
 148        int mezz, arg, result;
 149
 150        switch (argc) {
 151
 152        case 0:
 153        case 1:
 154                break;
 155
 156        case 2:
 157                if (strcmp (argv[1], "info") == 0) {
 158                        printf ("\nHymod FPGA Info...\n");
 159                        printf ("\t\t\t\tAddress\t\tSize\n");
 160                        printf ("\tMain Configuration:\t0x%08x\t%d\n",
 161                                FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE);
 162                        printf ("\tMain Register:\t\t0x%08x\t%d\n",
 163                                FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE);
 164                        printf ("\tMain Port:\t\t0x%08x\t%d\n",
 165                                FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE);
 166                        printf ("\tMezz Configuration:\t0x%08x\t%d\n",
 167                                FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE);
 168                        return 0;
 169                }
 170                break;
 171
 172        case 3:
 173                if (strcmp (argv[1], "store") == 0) {
 174                        addr = (uchar *) simple_strtoul (argv[2], NULL, 16);
 175
 176                        save_addr = addr;
 177#if 0
 178                        /* fpga readback unimplemented */
 179                        while (more readback data)
 180                                *addr++ = *fpga;
 181                        result = error ? STORE_FAIL_XXX : STORE_SUCCESS;
 182#else
 183                        result = STORE_SUCCESS;
 184#endif
 185
 186                        if (result == STORE_SUCCESS) {
 187                                printf ("SUCCEEDED (%d bytes)\n",
 188                                        addr - save_addr);
 189                                return 0;
 190                        } else
 191                                printf ("FAILED (%d bytes)\n",
 192                                        addr - save_addr);
 193                        return 1;
 194                }
 195                break;
 196
 197        case 4:
 198                if (strcmp (argv[1], "tftp") == 0) {
 199                        copy_filename (BootFile, argv[2], sizeof (BootFile));
 200                        load_addr = simple_strtoul (argv[3], NULL, 16);
 201                        NetBootFileXferSize = 0;
 202
 203                        if (NetLoop (TFTP) <= 0) {
 204                                printf ("tftp transfer failed - aborting "
 205                                        "fgpa load\n");
 206                                return 1;
 207                        }
 208
 209                        if (NetBootFileXferSize == 0) {
 210                                printf ("can't determine file size - "
 211                                        "aborting fpga load\n");
 212                                return 1;
 213                        }
 214
 215                        printf ("File transfer succeeded - "
 216                                "beginning fpga load...");
 217
 218                        result = fpga_load (0, (uchar *) load_addr,
 219                                NetBootFileXferSize);
 220
 221                        if (result == LOAD_SUCCESS) {
 222                                printf ("SUCCEEDED\n");
 223                                return 0;
 224                        } else if (result == LOAD_FAIL_NOCONF)
 225                                printf ("FAILED (no CONF)\n");
 226                        else if (result == LOAD_FAIL_NOINIT)
 227                                printf ("FAILED (no INIT)\n");
 228                        else
 229                                printf ("FAILED (no DONE)\n");
 230                        return 1;
 231
 232                }
 233                /* fall through ... */
 234
 235        case 5:
 236                if (strcmp (argv[1], "load") == 0) {
 237                        if (argc == 5) {
 238                                if (strcmp (argv[2], "main") == 0)
 239                                        mezz = 0;
 240                                else if (strcmp (argv[2], "mezz") == 0)
 241                                        mezz = 1;
 242                                else {
 243                                        printf ("FPGA type must be either "
 244                                                "`main' or `mezz'\n");
 245                                        return 1;
 246                                }
 247                                arg = 3;
 248                        } else {
 249                                mezz = 0;
 250                                arg = 2;
 251                        }
 252
 253                        addr = (uchar *) simple_strtoul (argv[arg++], NULL, 16);
 254                        size = (ulong) simple_strtoul (argv[arg], NULL, 16);
 255
 256                        result = fpga_load (mezz, addr, size);
 257
 258                        if (result == LOAD_SUCCESS) {
 259                                printf ("SUCCEEDED\n");
 260                                return 0;
 261                        } else if (result == LOAD_FAIL_NOCONF)
 262                                printf ("FAILED (no CONF)\n");
 263                        else if (result == LOAD_FAIL_NOINIT)
 264                                printf ("FAILED (no INIT)\n");
 265                        else
 266                                printf ("FAILED (no DONE)\n");
 267                        return 1;
 268                }
 269                break;
 270
 271        default:
 272                break;
 273        }
 274
 275        return cmd_usage(cmdtp);
 276}
 277U_BOOT_CMD(
 278        fpga,   6,      1,      do_fpga,
 279        "FPGA sub-system",
 280        "load [type] addr size\n"
 281        "  - write the configuration data at memory address `addr',\n"
 282        "    size `size' bytes, into the FPGA of type `type' (either\n"
 283        "    `main' or `mezz', default `main'). e.g.\n"
 284        "        `fpga load 100000 7d8f'\n"
 285        "    loads the main FPGA with config data at address 100000\n"
 286        "    HEX, size 7d8f HEX (32143 DEC) bytes\n"
 287        "fpga tftp file addr\n"
 288        "  - transfers `file' from the tftp server into memory at\n"
 289        "    address `addr', then writes the entire file contents\n"
 290        "    into the main FPGA\n"
 291        "fpga store addr\n"
 292        "  - read configuration data from the main FPGA (the mezz\n"
 293        "    FPGA is write-only), into address `addr'. There must be\n"
 294        "    enough memory available at `addr' to hold all the config\n"
 295        "    data - the size of which is determined by VC:???\n"
 296        "fpga info\n"
 297        "  - print information about the Hymod FPGA, namely the\n"
 298        "    memory addresses at which the four FPGA local bus\n"
 299        "    address spaces appear in the physical address space"
 300);
 301/* ------------------------------------------------------------------------- */
 302int
 303do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 304{
 305        uchar data[HYMOD_EEPROM_SIZE];
 306        uint addr = CONFIG_SYS_I2C_EEPROM_ADDR;
 307
 308        switch (argc) {
 309
 310        case 1:
 311                addr |= HYMOD_EEOFF_MAIN;
 312                break;
 313
 314        case 2:
 315                if (strcmp (argv[1], "main") == 0) {
 316                        addr |= HYMOD_EEOFF_MAIN;
 317                        break;
 318                }
 319                if (strcmp (argv[1], "mezz") == 0) {
 320                        addr |= HYMOD_EEOFF_MEZZ;
 321                        break;
 322                }
 323                /* fall through ... */
 324
 325        default:
 326                return cmd_usage(cmdtp);
 327        }
 328
 329        memset (data, 0, HYMOD_EEPROM_SIZE);
 330
 331        eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE);
 332
 333        return 0;
 334}
 335U_BOOT_CMD(
 336        eeclear,        1,      0,      do_eecl,
 337        "Clear the eeprom on a Hymod board",
 338        "[type]\n"
 339        "  - write zeroes into the EEPROM on the board of type `type'\n"
 340        "    (`type' is either `main' or `mezz' - default `main')\n"
 341        "    Note: the EEPROM write enable jumper must be installed"
 342);
 343
 344/* ------------------------------------------------------------------------- */
 345
 346int
 347do_htest (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 348{
 349#if 0
 350        int rc;
 351#endif
 352#ifdef CONFIG_ETHER_LOOPBACK_TEST
 353        extern void eth_loopback_test (void);
 354#endif /* CONFIG_ETHER_LOOPBACK_TEST */
 355
 356        printf ("HYMOD tests - ensure loopbacks etc. are connected\n\n");
 357
 358#if 0
 359        /* Load FPGA with test program */
 360
 361        printf ("Loading test FPGA program ...");
 362
 363        rc = fpga_load (0, test_bitfile, sizeof (test_bitfile));
 364
 365        switch (rc) {
 366
 367        case LOAD_SUCCESS:
 368                printf (" SUCCEEDED\n");
 369                break;
 370
 371        case LOAD_FAIL_NOCONF:
 372                printf (" FAILED (no configuration space defined)\n");
 373                return 1;
 374
 375        case LOAD_FAIL_NOINIT:
 376                printf (" FAILED (timeout - no INIT signal seen)\n");
 377                return 1;
 378
 379        case LOAD_FAIL_NODONE:
 380                printf (" FAILED (timeout - no DONE signal seen)\n");
 381                return 1;
 382
 383        default:
 384                printf (" FAILED (unknown return code from fpga_load\n");
 385                return 1;
 386        }
 387
 388        /* run Local Bus <=> Xilinx tests */
 389
 390        /* tell Xilinx to run ZBT Ram, High Speed serial and Mezzanine tests */
 391
 392        /* run SDRAM test */
 393#endif
 394
 395#ifdef CONFIG_ETHER_LOOPBACK_TEST
 396        /* run Ethernet test */
 397        eth_loopback_test ();
 398#endif /* CONFIG_ETHER_LOOPBACK_TEST */
 399
 400        return 0;
 401}
 402
 403#endif
 404