Add FPGA Altera Cyclone 2 support

Patch by Heiko Schocher, 15 Aug 2006
This commit is contained in:
Stefan Roese 2006-08-15 14:15:51 +02:00
parent c72d9c5285
commit f0ff4692ff
7 changed files with 372 additions and 1 deletions

View file

@ -2,6 +2,9 @@
Changes since U-Boot 1.1.4: 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 * Fix control-c handing in CONFIG_CMDLINE_EDITING
Properly pass break code back from readline. Properly pass break code back from readline.
Patch by Roger Blofeld, 31 Jul 2006 Patch by Roger Blofeld, 31 Jul 2006

View file

@ -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_pci.o cmd_pcmcia.o cmd_portio.o \
cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \ cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
cmd_usb.o cmd_vfd.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 \ environment.o env_common.o \
env_nand.o env_dataflash.o env_flash.o env_eeprom.o \ env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
env_nvram.o env_nowhere.o \ env_nvram.o env_nowhere.o \

View file

@ -55,10 +55,15 @@ int altera_load( Altera_desc *desc, void *buf, size_t bsize )
} else { } else {
switch (desc->family) { switch (desc->family) {
case Altera_ACEX1K: case Altera_ACEX1K:
case Altera_CYC2:
#if (CONFIG_FPGA & CFG_ACEX1K) #if (CONFIG_FPGA & CFG_ACEX1K)
PRINTF ("%s: Launching the ACEX1K Loader...\n", PRINTF ("%s: Launching the ACEX1K Loader...\n",
__FUNCTION__); __FUNCTION__);
ret_val = ACEX1K_load (desc, buf, bsize); 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 #else
printf ("%s: No support for ACEX1K devices.\n", printf ("%s: No support for ACEX1K devices.\n",
__FUNCTION__); __FUNCTION__);
@ -113,6 +118,9 @@ int altera_info( Altera_desc *desc )
printf ("ACEX1K\n"); printf ("ACEX1K\n");
break; break;
/* Add new family types here */ /* Add new family types here */
case Altera_CYC2:
printf ("CYCLON II\n");
break;
default: default:
printf ("Unknown family type, %d\n", desc->family); 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); printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
switch (desc->family) { switch (desc->family) {
case Altera_ACEX1K: case Altera_ACEX1K:
case Altera_CYC2:
#if (CONFIG_FPGA & CFG_ACEX1K) #if (CONFIG_FPGA & CFG_ACEX1K)
ACEX1K_info (desc); ACEX1K_info (desc);
#elif (CONFIG_FPGA & CFG_CYCLON2)
CYC2_info (desc);
#else #else
/* just in case */ /* just in case */
printf ("%s: No support for ACEX1K devices.\n", printf ("%s: No support for ACEX1K devices.\n",
@ -186,6 +197,14 @@ int altera_reloc( Altera_desc *desc, ulong reloc_offset)
#else #else
printf ("%s: No support for ACEX devices.\n", printf ("%s: No support for ACEX devices.\n",
__FUNCTION__); __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 #endif
break; break;
/* Add new family types here */ /* Add new family types here */

View file

@ -55,6 +55,7 @@ static int fpga_get_op (char *opstr);
#define FPGA_LOAD 1 #define FPGA_LOAD 1
#define FPGA_LOADB 2 #define FPGA_LOADB 2
#define FPGA_DUMP 3 #define FPGA_DUMP 3
#define FPGA_LOADMK 4
/* Convert bitstream data and load into the fpga */ /* Convert bitstream data and load into the fpga */
int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) 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); rc = fpga_loadbitstream(dev, fpga_data, data_size);
break; 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: case FPGA_DUMP:
rc = fpga_dump (dev, fpga_data, data_size); rc = fpga_dump (dev, fpga_data, data_size);
break; break;
@ -282,6 +300,8 @@ static int fpga_get_op (char *opstr)
op = FPGA_LOADB; op = FPGA_LOADB;
} else if (!strcmp ("load", opstr)) { } else if (!strcmp ("load", opstr)) {
op = FPGA_LOAD; op = FPGA_LOAD;
} else if (!strcmp ("loadmk", opstr)) {
op = FPGA_LOADMK;
} else if (!strcmp ("dump", opstr)) { } else if (!strcmp ("dump", opstr)) {
op = FPGA_DUMP; op = FPGA_DUMP;
} }
@ -299,5 +319,6 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
"\tinfo\tlist known device information\n" "\tinfo\tlist known device information\n"
"\tload\tLoad device from memory buffer\n" "\tload\tLoad device from memory buffer\n"
"\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\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"); "\tdump\tLoad device to memory buffer\n");
#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */ #endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */

305
common/cyclon2.c Normal file
View 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)) */

View file

@ -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_info( Altera_desc *desc );
extern int ACEX1K_reloc( Altera_desc *desc, ulong reloc_off ); 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 */ /* Slave Serial Implementation function table */
typedef struct { typedef struct {
Altera_pre_fn pre; Altera_pre_fn pre;
@ -48,6 +53,18 @@ typedef struct {
int relocated; int relocated;
} Altera_ACEX1K_Passive_Serial_fns; } 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 /* Device Image Sizes
*********************************************************************/ *********************************************************************/
/* ACEX1K */ /* ACEX1K */
@ -60,6 +77,8 @@ typedef struct {
#endif #endif
#define Altera_EP1K100_SIZE (166965*8) #define Altera_EP1K100_SIZE (166965*8)
#define Altera_EP2C35_SIZE 883905
/* Descriptor Macros /* Descriptor Macros
*********************************************************************/ *********************************************************************/
/* ACEX1K devices */ /* ACEX1K devices */

View file

@ -34,8 +34,10 @@
/* Altera Model definitions /* Altera Model definitions
*********************************************************************/ *********************************************************************/
#define CFG_ACEX1K CFG_FPGA_DEV( 0x1 ) #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_ACEX1K (CFG_FPGA_ALTERA | CFG_ACEX1K)
#define CFG_ALTERA_CYCLON2 (CFG_FPGA_ALTERA | CFG_CYCLON2)
/* Add new models here */ /* Add new models here */
/* Altera Interface definitions /* Altera Interface definitions
@ -56,6 +58,7 @@ typedef enum { /* typedef Altera_iface */
typedef enum { /* typedef Altera_Family */ typedef enum { /* typedef Altera_Family */
min_altera_type, /* insert all new types after this */ min_altera_type, /* insert all new types after this */
Altera_ACEX1K, /* ACEX1K Family */ Altera_ACEX1K, /* ACEX1K Family */
Altera_CYC2, /* CYCLONII Family */
/* Add new models here */ /* Add new models here */
max_altera_type /* insert all new types before this */ max_altera_type /* insert all new types before this */
} Altera_Family; /* end, typedef Altera_Family */ } 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_done_fn)( int cookie );
typedef int (*Altera_clk_fn)( int assert_clk, int flush, 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_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_abort_fn)( int cookie );
typedef int (*Altera_post_fn)( int cookie ); typedef int (*Altera_post_fn)( int cookie );