mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 06:31:31 +00:00
Add FPGA Altera Cyclone 2 support
Patch by Heiko Schocher, 15 Aug 2006
This commit is contained in:
parent
c72d9c5285
commit
f0ff4692ff
7 changed files with 372 additions and 1 deletions
|
@ -2,6 +2,9 @@
|
|||
Changes since U-Boot 1.1.4:
|
||||
======================================================================
|
||||
|
||||
* Add FPGA Altera Cyclone 2 support
|
||||
Patch by Heiko Schocher, 15 Aug 2006
|
||||
|
||||
* Fix control-c handing in CONFIG_CMDLINE_EDITING
|
||||
Properly pass break code back from readline.
|
||||
Patch by Roger Blofeld, 31 Jul 2006
|
||||
|
|
|
@ -41,7 +41,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \
|
|||
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
|
||||
cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
|
||||
cmd_usb.o cmd_vfd.o \
|
||||
command.o console.o devices.o dlmalloc.o docecc.o \
|
||||
command.o console.o cyclon2.o devices.o dlmalloc.o docecc.o \
|
||||
environment.o env_common.o \
|
||||
env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
|
||||
env_nvram.o env_nowhere.o \
|
||||
|
|
|
@ -55,10 +55,15 @@ int altera_load( Altera_desc *desc, void *buf, size_t bsize )
|
|||
} else {
|
||||
switch (desc->family) {
|
||||
case Altera_ACEX1K:
|
||||
case Altera_CYC2:
|
||||
#if (CONFIG_FPGA & CFG_ACEX1K)
|
||||
PRINTF ("%s: Launching the ACEX1K Loader...\n",
|
||||
__FUNCTION__);
|
||||
ret_val = ACEX1K_load (desc, buf, bsize);
|
||||
#elif (CONFIG_FPGA & CFG_CYCLON2)
|
||||
PRINTF ("%s: Launching the CYCLON II Loader...\n",
|
||||
__FUNCTION__);
|
||||
ret_val = CYC2_load (desc, buf, bsize);
|
||||
#else
|
||||
printf ("%s: No support for ACEX1K devices.\n",
|
||||
__FUNCTION__);
|
||||
|
@ -113,6 +118,9 @@ int altera_info( Altera_desc *desc )
|
|||
printf ("ACEX1K\n");
|
||||
break;
|
||||
/* Add new family types here */
|
||||
case Altera_CYC2:
|
||||
printf ("CYCLON II\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown family type, %d\n", desc->family);
|
||||
}
|
||||
|
@ -147,8 +155,11 @@ int altera_info( Altera_desc *desc )
|
|||
printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
|
||||
switch (desc->family) {
|
||||
case Altera_ACEX1K:
|
||||
case Altera_CYC2:
|
||||
#if (CONFIG_FPGA & CFG_ACEX1K)
|
||||
ACEX1K_info (desc);
|
||||
#elif (CONFIG_FPGA & CFG_CYCLON2)
|
||||
CYC2_info (desc);
|
||||
#else
|
||||
/* just in case */
|
||||
printf ("%s: No support for ACEX1K devices.\n",
|
||||
|
@ -186,6 +197,14 @@ int altera_reloc( Altera_desc *desc, ulong reloc_offset)
|
|||
#else
|
||||
printf ("%s: No support for ACEX devices.\n",
|
||||
__FUNCTION__);
|
||||
#endif
|
||||
break;
|
||||
case Altera_CYC2:
|
||||
#if (CONFIG_FPGA & CFG_CYCLON2)
|
||||
ret_val = CYC2_reloc (desc, reloc_offset);
|
||||
#else
|
||||
printf ("%s: No support for CYCLON II devices.\n",
|
||||
__FUNCTION__);
|
||||
#endif
|
||||
break;
|
||||
/* Add new family types here */
|
||||
|
|
|
@ -55,6 +55,7 @@ static int fpga_get_op (char *opstr);
|
|||
#define FPGA_LOAD 1
|
||||
#define FPGA_LOADB 2
|
||||
#define FPGA_DUMP 3
|
||||
#define FPGA_LOADMK 4
|
||||
|
||||
/* Convert bitstream data and load into the fpga */
|
||||
int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
|
||||
|
@ -251,6 +252,23 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||
rc = fpga_loadbitstream(dev, fpga_data, data_size);
|
||||
break;
|
||||
|
||||
case FPGA_LOADMK:
|
||||
{
|
||||
image_header_t header;
|
||||
image_header_t *hdr = &header;
|
||||
ulong data;
|
||||
|
||||
memmove (&header, (char *)fpga_data, sizeof(image_header_t));
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
puts ("Bad Magic Number\n");
|
||||
return 1;
|
||||
}
|
||||
data = (char *)(fpga_data + sizeof(image_header_t));
|
||||
data_size = ntohl(hdr->ih_size);
|
||||
rc = fpga_load (dev, data, data_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case FPGA_DUMP:
|
||||
rc = fpga_dump (dev, fpga_data, data_size);
|
||||
break;
|
||||
|
@ -282,6 +300,8 @@ static int fpga_get_op (char *opstr)
|
|||
op = FPGA_LOADB;
|
||||
} else if (!strcmp ("load", opstr)) {
|
||||
op = FPGA_LOAD;
|
||||
} else if (!strcmp ("loadmk", opstr)) {
|
||||
op = FPGA_LOADMK;
|
||||
} else if (!strcmp ("dump", opstr)) {
|
||||
op = FPGA_DUMP;
|
||||
}
|
||||
|
@ -299,5 +319,6 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
|
|||
"\tinfo\tlist known device information\n"
|
||||
"\tload\tLoad device from memory buffer\n"
|
||||
"\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
|
||||
"\tloadmk\tLoad device generated with mkimage\n"
|
||||
"\tdump\tLoad device to memory buffer\n");
|
||||
#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */
|
||||
|
|
305
common/cyclon2.c
Normal file
305
common/cyclon2.c
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* (C) Copyright 2006
|
||||
* Heiko Schocher, hs@denx.de
|
||||
* Based on ACE1XK.c
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h> /* core U-Boot definitions */
|
||||
#include <altera.h>
|
||||
#include <ACEX1K.h> /* ACEX device family */
|
||||
|
||||
#if (CONFIG_FPGA & (CFG_ALTERA | CFG_CYCLON2))
|
||||
|
||||
/* Define FPGA_DEBUG to get debug printf's */
|
||||
#ifdef FPGA_DEBUG
|
||||
#define PRINTF(fmt,args...) printf (fmt ,##args)
|
||||
#else
|
||||
#define PRINTF(fmt,args...)
|
||||
#endif
|
||||
|
||||
/* Note: The assumption is that we cannot possibly run fast enough to
|
||||
* overrun the device (the Slave Parallel mode can free run at 50MHz).
|
||||
* If there is a need to operate slower, define CONFIG_FPGA_DELAY in
|
||||
* the board config file to slow things down.
|
||||
*/
|
||||
#ifndef CONFIG_FPGA_DELAY
|
||||
#define CONFIG_FPGA_DELAY()
|
||||
#endif
|
||||
|
||||
#ifndef CFG_FPGA_WAIT
|
||||
#define CFG_FPGA_WAIT CFG_HZ/10 /* 100 ms */
|
||||
#endif
|
||||
|
||||
static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize );
|
||||
static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize );
|
||||
/* static int CYC2_ps_info( Altera_desc *desc ); */
|
||||
static int CYC2_ps_reloc( Altera_desc *desc, ulong reloc_offset );
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* CYCLON2 Generic Implementation */
|
||||
int CYC2_load (Altera_desc * desc, void *buf, size_t bsize)
|
||||
{
|
||||
int ret_val = FPGA_FAIL;
|
||||
|
||||
switch (desc->iface) {
|
||||
case passive_serial:
|
||||
PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__);
|
||||
ret_val = CYC2_ps_load (desc, buf, bsize);
|
||||
break;
|
||||
|
||||
/* Add new interface types here */
|
||||
|
||||
default:
|
||||
printf ("%s: Unsupported interface type, %d\n",
|
||||
__FUNCTION__, desc->iface);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize)
|
||||
{
|
||||
int ret_val = FPGA_FAIL;
|
||||
|
||||
switch (desc->iface) {
|
||||
case passive_serial:
|
||||
PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__);
|
||||
ret_val = CYC2_ps_dump (desc, buf, bsize);
|
||||
break;
|
||||
|
||||
/* Add new interface types here */
|
||||
|
||||
default:
|
||||
printf ("%s: Unsupported interface type, %d\n",
|
||||
__FUNCTION__, desc->iface);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
int CYC2_info( Altera_desc *desc )
|
||||
{
|
||||
return FPGA_SUCCESS;
|
||||
}
|
||||
|
||||
int CYC2_reloc (Altera_desc * desc, ulong reloc_offset)
|
||||
{
|
||||
int ret_val = FPGA_FAIL; /* assume a failure */
|
||||
|
||||
if (desc->family != Altera_CYC2) {
|
||||
printf ("%s: Unsupported family type, %d\n",
|
||||
__FUNCTION__, desc->family);
|
||||
return FPGA_FAIL;
|
||||
} else
|
||||
switch (desc->iface) {
|
||||
case passive_serial:
|
||||
ret_val = CYC2_ps_reloc (desc, reloc_offset);
|
||||
break;
|
||||
|
||||
/* Add new interface types here */
|
||||
|
||||
default:
|
||||
printf ("%s: Unsupported interface type, %d\n",
|
||||
__FUNCTION__, desc->iface);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* CYCLON2 Passive Serial Generic Implementation */
|
||||
static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize)
|
||||
{
|
||||
int ret_val = FPGA_FAIL; /* assume the worst */
|
||||
Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
|
||||
int ret = 0;
|
||||
|
||||
PRINTF ("%s: start with interface functions @ 0x%p\n",
|
||||
__FUNCTION__, fn);
|
||||
|
||||
if (fn) {
|
||||
int cookie = desc->cookie; /* make a local copy */
|
||||
unsigned long ts; /* timestamp */
|
||||
|
||||
PRINTF ("%s: Function Table:\n"
|
||||
"ptr:\t0x%p\n"
|
||||
"struct: 0x%p\n"
|
||||
"config:\t0x%p\n"
|
||||
"status:\t0x%p\n"
|
||||
"write:\t0x%p\n"
|
||||
"done:\t0x%p\n\n",
|
||||
__FUNCTION__, &fn, fn, fn->config, fn->status,
|
||||
fn->write, fn->done);
|
||||
#ifdef CFG_FPGA_PROG_FEEDBACK
|
||||
printf ("Loading FPGA Device %d...", cookie);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Run the pre configuration function if there is one.
|
||||
*/
|
||||
if (*fn->pre) {
|
||||
(*fn->pre) (cookie);
|
||||
}
|
||||
|
||||
/* Establish the initial state */
|
||||
(*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */
|
||||
|
||||
udelay(2); /* T_cfg > 2us */
|
||||
|
||||
/* Wait for nSTATUS to be asserted */
|
||||
ts = get_timer (0); /* get current time */
|
||||
do {
|
||||
CONFIG_FPGA_DELAY ();
|
||||
if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
|
||||
puts ("** Timeout waiting for STATUS to go high.\n");
|
||||
(*fn->abort) (cookie);
|
||||
return FPGA_FAIL;
|
||||
}
|
||||
} while (!(*fn->status) (cookie));
|
||||
|
||||
/* Get ready for the burn */
|
||||
CONFIG_FPGA_DELAY ();
|
||||
|
||||
ret = (*fn->write) (buf, bsize, TRUE, cookie);
|
||||
if (ret) {
|
||||
puts ("** Write failed.\n");
|
||||
(*fn->abort) (cookie);
|
||||
return FPGA_FAIL;
|
||||
}
|
||||
#ifdef CFG_FPGA_PROG_FEEDBACK
|
||||
puts(" OK? ...");
|
||||
#endif
|
||||
|
||||
CONFIG_FPGA_DELAY ();
|
||||
|
||||
#ifdef CFG_FPGA_PROG_FEEDBACK
|
||||
putc (' '); /* terminate the dotted line */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Checking FPGA's CONF_DONE signal - correctly booted ?
|
||||
*/
|
||||
|
||||
if ( ! (*fn->done) (cookie) ) {
|
||||
puts ("** Booting failed! CONF_DONE is still deasserted.\n");
|
||||
(*fn->abort) (cookie);
|
||||
return (FPGA_FAIL);
|
||||
}
|
||||
#ifdef CFG_FPGA_PROG_FEEDBACK
|
||||
puts(" OK\n");
|
||||
#endif
|
||||
|
||||
ret_val = FPGA_SUCCESS;
|
||||
|
||||
#ifdef CFG_FPGA_PROG_FEEDBACK
|
||||
if (ret_val == FPGA_SUCCESS) {
|
||||
puts ("Done.\n");
|
||||
}
|
||||
else {
|
||||
puts ("Fail.\n");
|
||||
}
|
||||
#endif
|
||||
(*fn->post) (cookie);
|
||||
|
||||
} else {
|
||||
printf ("%s: NULL Interface function table!\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize)
|
||||
{
|
||||
/* Readback is only available through the Slave Parallel and */
|
||||
/* boundary-scan interfaces. */
|
||||
printf ("%s: Passive Serial Dumping is unavailable\n",
|
||||
__FUNCTION__);
|
||||
return FPGA_FAIL;
|
||||
}
|
||||
|
||||
static int CYC2_ps_reloc (Altera_desc * desc, ulong reloc_offset)
|
||||
{
|
||||
int ret_val = FPGA_FAIL; /* assume the worst */
|
||||
Altera_CYC2_Passive_Serial_fns *fn_r, *fn =
|
||||
(Altera_CYC2_Passive_Serial_fns *) (desc->iface_fns);
|
||||
|
||||
if (fn) {
|
||||
ulong addr;
|
||||
|
||||
/* Get the relocated table address */
|
||||
addr = (ulong) fn + reloc_offset;
|
||||
fn_r = (Altera_CYC2_Passive_Serial_fns *) addr;
|
||||
|
||||
if (!fn_r->relocated) {
|
||||
|
||||
if (memcmp (fn_r, fn,
|
||||
sizeof (Altera_CYC2_Passive_Serial_fns))
|
||||
== 0) {
|
||||
/* good copy of the table, fix the descriptor pointer */
|
||||
desc->iface_fns = fn_r;
|
||||
} else {
|
||||
PRINTF ("%s: Invalid function table at 0x%p\n",
|
||||
__FUNCTION__, fn_r);
|
||||
return FPGA_FAIL;
|
||||
}
|
||||
|
||||
PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__,
|
||||
desc);
|
||||
|
||||
addr = (ulong) (fn->pre) + reloc_offset;
|
||||
fn_r->pre = (Altera_pre_fn) addr;
|
||||
|
||||
addr = (ulong) (fn->config) + reloc_offset;
|
||||
fn_r->config = (Altera_config_fn) addr;
|
||||
|
||||
addr = (ulong) (fn->status) + reloc_offset;
|
||||
fn_r->status = (Altera_status_fn) addr;
|
||||
|
||||
addr = (ulong) (fn->done) + reloc_offset;
|
||||
fn_r->done = (Altera_done_fn) addr;
|
||||
|
||||
addr = (ulong) (fn->write) + reloc_offset;
|
||||
fn_r->write = (Altera_write_fn) addr;
|
||||
|
||||
addr = (ulong) (fn->abort) + reloc_offset;
|
||||
fn_r->abort = (Altera_abort_fn) addr;
|
||||
|
||||
addr = (ulong) (fn->post) + reloc_offset;
|
||||
fn_r->post = (Altera_post_fn) addr;
|
||||
|
||||
fn_r->relocated = TRUE;
|
||||
|
||||
} else {
|
||||
/* this table has already been moved */
|
||||
/* XXX - should check to see if the descriptor is correct */
|
||||
desc->iface_fns = fn_r;
|
||||
}
|
||||
|
||||
ret_val = FPGA_SUCCESS;
|
||||
} else {
|
||||
printf ("%s: NULL Interface function table!\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#endif /* (CONFIG_FPGA & (CFG_ALTERA | CFG_CYCLON2)) */
|
|
@ -35,6 +35,11 @@ extern int ACEX1K_dump( Altera_desc *desc, void *buf, size_t bsize );
|
|||
extern int ACEX1K_info( Altera_desc *desc );
|
||||
extern int ACEX1K_reloc( Altera_desc *desc, ulong reloc_off );
|
||||
|
||||
extern int CYC2_load( Altera_desc *desc, void *image, size_t size );
|
||||
extern int CYC2_dump( Altera_desc *desc, void *buf, size_t bsize );
|
||||
extern int CYC2_info( Altera_desc *desc );
|
||||
extern int CYC2_reloc( Altera_desc *desc, ulong reloc_off );
|
||||
|
||||
/* Slave Serial Implementation function table */
|
||||
typedef struct {
|
||||
Altera_pre_fn pre;
|
||||
|
@ -48,6 +53,18 @@ typedef struct {
|
|||
int relocated;
|
||||
} Altera_ACEX1K_Passive_Serial_fns;
|
||||
|
||||
/* Slave Serial Implementation function table */
|
||||
typedef struct {
|
||||
Altera_pre_fn pre;
|
||||
Altera_config_fn config;
|
||||
Altera_status_fn status;
|
||||
Altera_done_fn done;
|
||||
Altera_write_fn write;
|
||||
Altera_abort_fn abort;
|
||||
Altera_post_fn post;
|
||||
int relocated;
|
||||
} Altera_CYC2_Passive_Serial_fns;
|
||||
|
||||
/* Device Image Sizes
|
||||
*********************************************************************/
|
||||
/* ACEX1K */
|
||||
|
@ -60,6 +77,8 @@ typedef struct {
|
|||
#endif
|
||||
#define Altera_EP1K100_SIZE (166965*8)
|
||||
|
||||
#define Altera_EP2C35_SIZE 883905
|
||||
|
||||
/* Descriptor Macros
|
||||
*********************************************************************/
|
||||
/* ACEX1K devices */
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
/* Altera Model definitions
|
||||
*********************************************************************/
|
||||
#define CFG_ACEX1K CFG_FPGA_DEV( 0x1 )
|
||||
#define CFG_CYCLON2 CFG_FPGA_DEV( 0x2 )
|
||||
|
||||
#define CFG_ALTERA_ACEX1K (CFG_FPGA_ALTERA | CFG_ACEX1K)
|
||||
#define CFG_ALTERA_CYCLON2 (CFG_FPGA_ALTERA | CFG_CYCLON2)
|
||||
/* Add new models here */
|
||||
|
||||
/* Altera Interface definitions
|
||||
|
@ -56,6 +58,7 @@ typedef enum { /* typedef Altera_iface */
|
|||
typedef enum { /* typedef Altera_Family */
|
||||
min_altera_type, /* insert all new types after this */
|
||||
Altera_ACEX1K, /* ACEX1K Family */
|
||||
Altera_CYC2, /* CYCLONII Family */
|
||||
/* Add new models here */
|
||||
max_altera_type /* insert all new types before this */
|
||||
} Altera_Family; /* end, typedef Altera_Family */
|
||||
|
@ -84,6 +87,7 @@ typedef int (*Altera_status_fn)( int cookie );
|
|||
typedef int (*Altera_done_fn)( int cookie );
|
||||
typedef int (*Altera_clk_fn)( int assert_clk, int flush, int cookie );
|
||||
typedef int (*Altera_data_fn)( int assert_data, int flush, int cookie );
|
||||
typedef int (*Altera_write_fn)(void *buf, size_t len, int flush, int cookie);
|
||||
typedef int (*Altera_abort_fn)( int cookie );
|
||||
typedef int (*Altera_post_fn)( int cookie );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue