uboot/drivers/fpga/cyclon2.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2006
   3 * Heiko Schocher, hs@denx.de
   4 * Based on ACE1XK.c
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 *
  24 */
  25
  26#include <common.h>             /* core U-Boot definitions */
  27#include <altera.h>
  28#include <ACEX1K.h>             /* ACEX device family */
  29
  30/* Define FPGA_DEBUG to get debug printf's */
  31#ifdef  FPGA_DEBUG
  32#define PRINTF(fmt,args...)     printf (fmt ,##args)
  33#else
  34#define PRINTF(fmt,args...)
  35#endif
  36
  37/* Note: The assumption is that we cannot possibly run fast enough to
  38 * overrun the device (the Slave Parallel mode can free run at 50MHz).
  39 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
  40 * the board config file to slow things down.
  41 */
  42#ifndef CONFIG_FPGA_DELAY
  43#define CONFIG_FPGA_DELAY()
  44#endif
  45
  46#ifndef CONFIG_SYS_FPGA_WAIT
  47#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10           /* 100 ms */
  48#endif
  49
  50static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize );
  51static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize );
  52/* static int CYC2_ps_info( Altera_desc *desc ); */
  53
  54/* ------------------------------------------------------------------------- */
  55/* CYCLON2 Generic Implementation */
  56int CYC2_load (Altera_desc * desc, void *buf, size_t bsize)
  57{
  58        int ret_val = FPGA_FAIL;
  59
  60        switch (desc->iface) {
  61        case passive_serial:
  62                PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__);
  63                ret_val = CYC2_ps_load (desc, buf, bsize);
  64                break;
  65
  66                /* Add new interface types here */
  67
  68        default:
  69                printf ("%s: Unsupported interface type, %d\n",
  70                                __FUNCTION__, desc->iface);
  71        }
  72
  73        return ret_val;
  74}
  75
  76int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize)
  77{
  78        int ret_val = FPGA_FAIL;
  79
  80        switch (desc->iface) {
  81        case passive_serial:
  82                PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__);
  83                ret_val = CYC2_ps_dump (desc, buf, bsize);
  84                break;
  85
  86                /* Add new interface types here */
  87
  88        default:
  89                printf ("%s: Unsupported interface type, %d\n",
  90                                __FUNCTION__, desc->iface);
  91        }
  92
  93        return ret_val;
  94}
  95
  96int CYC2_info( Altera_desc *desc )
  97{
  98        return FPGA_SUCCESS;
  99}
 100
 101/* ------------------------------------------------------------------------- */
 102/* CYCLON2 Passive Serial Generic Implementation                                  */
 103static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize)
 104{
 105        int ret_val = FPGA_FAIL;        /* assume the worst */
 106        Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
 107        int     ret = 0;
 108
 109        PRINTF ("%s: start with interface functions @ 0x%p\n",
 110                        __FUNCTION__, fn);
 111
 112        if (fn) {
 113                int cookie = desc->cookie;      /* make a local copy */
 114                unsigned long ts;               /* timestamp */
 115
 116                PRINTF ("%s: Function Table:\n"
 117                                "ptr:\t0x%p\n"
 118                                "struct: 0x%p\n"
 119                                "config:\t0x%p\n"
 120                                "status:\t0x%p\n"
 121                                "write:\t0x%p\n"
 122                                "done:\t0x%p\n\n",
 123                                __FUNCTION__, &fn, fn, fn->config, fn->status,
 124                                fn->write, fn->done);
 125#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 126                printf ("Loading FPGA Device %d...", cookie);
 127#endif
 128
 129                /*
 130                 * Run the pre configuration function if there is one.
 131                 */
 132                if (*fn->pre) {
 133                        (*fn->pre) (cookie);
 134                }
 135
 136                /* Establish the initial state */
 137                (*fn->config) (TRUE, TRUE, cookie);     /* Assert nCONFIG */
 138
 139                udelay(2);              /* T_cfg > 2us  */
 140
 141                /* Wait for nSTATUS to be asserted */
 142                ts = get_timer (0);             /* get current time */
 143                do {
 144                        CONFIG_FPGA_DELAY ();
 145                        if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
 146                                puts ("** Timeout waiting for STATUS to go high.\n");
 147                                (*fn->abort) (cookie);
 148                                return FPGA_FAIL;
 149                        }
 150                } while (!(*fn->status) (cookie));
 151
 152                /* Get ready for the burn */
 153                CONFIG_FPGA_DELAY ();
 154
 155                ret = (*fn->write) (buf, bsize, TRUE, cookie);
 156                if (ret) {
 157                        puts ("** Write failed.\n");
 158                        (*fn->abort) (cookie);
 159                        return FPGA_FAIL;
 160                }
 161#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 162                puts(" OK? ...");
 163#endif
 164
 165                CONFIG_FPGA_DELAY ();
 166
 167#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 168                putc (' ');                     /* terminate the dotted line */
 169#endif
 170
 171        /*
 172         * Checking FPGA's CONF_DONE signal - correctly booted ?
 173         */
 174
 175        if ( ! (*fn->done) (cookie) ) {
 176                puts ("** Booting failed! CONF_DONE is still deasserted.\n");
 177                (*fn->abort) (cookie);
 178                return (FPGA_FAIL);
 179        }
 180#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 181        puts(" OK\n");
 182#endif
 183
 184        ret_val = FPGA_SUCCESS;
 185
 186#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 187        if (ret_val == FPGA_SUCCESS) {
 188                puts ("Done.\n");
 189        }
 190        else {
 191                puts ("Fail.\n");
 192        }
 193#endif
 194        (*fn->post) (cookie);
 195
 196        } else {
 197                printf ("%s: NULL Interface function table!\n", __FUNCTION__);
 198        }
 199
 200        return ret_val;
 201}
 202
 203static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize)
 204{
 205        /* Readback is only available through the Slave Parallel and         */
 206        /* boundary-scan interfaces.                                         */
 207        printf ("%s: Passive Serial Dumping is unavailable\n",
 208                        __FUNCTION__);
 209        return FPGA_FAIL;
 210}
 211