Browse Source

Add FPGA Altera Cyclone 2 support
Patch by Heiko Schocher, 15 Aug 2006

Stefan Roese 19 years ago
parent
commit
f0ff4692ff
7 changed files with 372 additions and 1 deletions
  1. 3 0
      CHANGELOG
  2. 1 1
      common/Makefile
  3. 19 0
      common/altera.c
  4. 21 0
      common/cmd_fpga.c
  5. 305 0
      common/cyclon2.c
  6. 19 0
      include/ACEX1K.h
  7. 4 0
      include/altera.h

+ 3 - 0
CHANGELOG

@@ -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

+ 1 - 1
common/Makefile

@@ -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 \

+ 19 - 0
common/altera.c

@@ -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 */

+ 21 - 0
common/cmd_fpga.c

@@ -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 - 0
common/cyclon2.c

@@ -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)) */

+ 19 - 0
include/ACEX1K.h

@@ -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 */

+ 4 - 0
include/altera.h

@@ -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 );