uboot/drivers/fpga/cyclon2.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2006
   3 * Heiko Schocher, hs@denx.de
   4 * Based on ACE1XK.c
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>             /* core U-Boot definitions */
  10#include <altera.h>
  11#include <ACEX1K.h>             /* ACEX device family */
  12
  13/* Define FPGA_DEBUG to get debug printf's */
  14#ifdef  FPGA_DEBUG
  15#define PRINTF(fmt,args...)     printf (fmt ,##args)
  16#else
  17#define PRINTF(fmt,args...)
  18#endif
  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/10           /* 100 ms */
  31#endif
  32
  33static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
  34static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
  35/* static int CYC2_ps_info( Altera_desc *desc ); */
  36
  37/* ------------------------------------------------------------------------- */
  38/* CYCLON2 Generic Implementation */
  39int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
  40{
  41        int ret_val = FPGA_FAIL;
  42
  43        switch (desc->iface) {
  44        case passive_serial:
  45                PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__);
  46                ret_val = CYC2_ps_load (desc, buf, bsize);
  47                break;
  48
  49        case fast_passive_parallel:
  50                /* Fast Passive Parallel (FPP) and PS only differ in what is
  51                 * done in the write() callback. Use the existing PS load
  52                 * function for FPP, too.
  53                 */
  54                PRINTF ("%s: Launching Fast Passive Parallel Loader\n",
  55                      __FUNCTION__);
  56                ret_val = CYC2_ps_load(desc, buf, bsize);
  57                break;
  58
  59                /* Add new interface types here */
  60
  61        default:
  62                printf ("%s: Unsupported interface type, %d\n",
  63                                __FUNCTION__, desc->iface);
  64        }
  65
  66        return ret_val;
  67}
  68
  69int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
  70{
  71        int ret_val = FPGA_FAIL;
  72
  73        switch (desc->iface) {
  74        case passive_serial:
  75                PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__);
  76                ret_val = CYC2_ps_dump (desc, buf, bsize);
  77                break;
  78
  79                /* Add new interface types here */
  80
  81        default:
  82                printf ("%s: Unsupported interface type, %d\n",
  83                                __FUNCTION__, desc->iface);
  84        }
  85
  86        return ret_val;
  87}
  88
  89int CYC2_info( Altera_desc *desc )
  90{
  91        return FPGA_SUCCESS;
  92}
  93
  94/* ------------------------------------------------------------------------- */
  95/* CYCLON2 Passive Serial Generic Implementation                                  */
  96static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
  97{
  98        int ret_val = FPGA_FAIL;        /* assume the worst */
  99        Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
 100        int     ret = 0;
 101
 102        PRINTF ("%s: start with interface functions @ 0x%p\n",
 103                        __FUNCTION__, fn);
 104
 105        if (fn) {
 106                int cookie = desc->cookie;      /* make a local copy */
 107                unsigned long ts;               /* timestamp */
 108
 109                PRINTF ("%s: Function Table:\n"
 110                                "ptr:\t0x%p\n"
 111                                "struct: 0x%p\n"
 112                                "config:\t0x%p\n"
 113                                "status:\t0x%p\n"
 114                                "write:\t0x%p\n"
 115                                "done:\t0x%p\n\n",
 116                                __FUNCTION__, &fn, fn, fn->config, fn->status,
 117                                fn->write, fn->done);
 118#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 119                printf ("Loading FPGA Device %d...", cookie);
 120#endif
 121
 122                /*
 123                 * Run the pre configuration function if there is one.
 124                 */
 125                if (*fn->pre) {
 126                        (*fn->pre) (cookie);
 127                }
 128
 129                /* Establish the initial state */
 130                (*fn->config) (false, true, cookie);    /* De-assert nCONFIG */
 131                udelay(100);
 132                (*fn->config) (true, true, cookie);     /* Assert nCONFIG */
 133
 134                udelay(2);              /* T_cfg > 2us  */
 135
 136                /* Wait for nSTATUS to be asserted */
 137                ts = get_timer (0);             /* get current time */
 138                do {
 139                        CONFIG_FPGA_DELAY ();
 140                        if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
 141                                puts ("** Timeout waiting for STATUS to go high.\n");
 142                                (*fn->abort) (cookie);
 143                                return FPGA_FAIL;
 144                        }
 145                } while (!(*fn->status) (cookie));
 146
 147                /* Get ready for the burn */
 148                CONFIG_FPGA_DELAY ();
 149
 150                ret = (*fn->write) (buf, bsize, true, cookie);
 151                if (ret) {
 152                        puts ("** Write failed.\n");
 153                        (*fn->abort) (cookie);
 154                        return FPGA_FAIL;
 155                }
 156#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 157                puts(" OK? ...");
 158#endif
 159
 160                CONFIG_FPGA_DELAY ();
 161
 162#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 163                putc (' ');                     /* terminate the dotted line */
 164#endif
 165
 166        /*
 167         * Checking FPGA's CONF_DONE signal - correctly booted ?
 168         */
 169
 170        if ( ! (*fn->done) (cookie) ) {
 171                puts ("** Booting failed! CONF_DONE is still deasserted.\n");
 172                (*fn->abort) (cookie);
 173                return (FPGA_FAIL);
 174        }
 175#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 176        puts(" OK\n");
 177#endif
 178
 179        ret_val = FPGA_SUCCESS;
 180
 181#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
 182        if (ret_val == FPGA_SUCCESS) {
 183                puts ("Done.\n");
 184        }
 185        else {
 186                puts ("Fail.\n");
 187        }
 188#endif
 189        (*fn->post) (cookie);
 190
 191        } else {
 192                printf ("%s: NULL Interface function table!\n", __FUNCTION__);
 193        }
 194
 195        return ret_val;
 196}
 197
 198static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
 199{
 200        /* Readback is only available through the Slave Parallel and         */
 201        /* boundary-scan interfaces.                                         */
 202        printf ("%s: Passive Serial Dumping is unavailable\n",
 203                        __FUNCTION__);
 204        return FPGA_FAIL;
 205}
 206