[U-Boot-Users] [PATCH 2/8] Support LATTICE FPGA parts using JTAG programming. Interface to FPGA API.

Pantelis Antoniou pantelis at embeddedalley.com
Sat Dec 2 23:15:57 CET 2006


Add support for Lattice FPGA parts programmed using JTAG.

---
Signed-off-by: Pantelis Antoniou <pantelis at embeddedalley.com>
---

 common/Makefile      |    4 
 common/fpga.c        |   30 +++
 common/lattice.c     |  218 ++++++++++++++++++++++++
 common/lattice_ec.c  |  461 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/fpga.h       |    3 
 include/lattice.h    |   85 +++++++++
 include/lattice_ec.h |   85 +++++++++
 7 files changed, 884 insertions(+), 2 deletions(-)

diff --git a/common/Makefile b/common/Makefile
index 0106088..79d11a5 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -47,7 +47,9 @@ COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o \
 	  env_nvram.o env_nowhere.o \
 	  exports.o \
 	  flash.o fpga.o ft_build.o \
-	  hush.o kgdb.o lcd.o lists.o lynxkdi.o \
+ 	  hush.o kgdb.o \
+	  lattice.o lattice_ec.o lattice_ivm_core.o lattice_ivm_supp.o \
+	  lcd.o lists.o lynxkdi.o \
 	  memsize.o miiphybb.o miiphyutil.o \
 	  s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
 	  usb.o usb_kbd.o usb_storage.o \
diff --git a/common/fpga.c b/common/fpga.c
index 2eff239..8374814 100644
--- a/common/fpga.c
+++ b/common/fpga.c
@@ -28,6 +28,7 @@
 #include <common.h>             /* core U-Boot definitions */
 #include <xilinx.h>             /* xilinx specific definitions */
 #include <altera.h>             /* altera specific definitions */
+#include <lattice.h>            /* lattice specific definitions */
 
 #if defined(CONFIG_FPGA)
 
@@ -150,6 +151,14 @@ static int fpga_dev_info( int devnum )
 			fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
 #endif
 			break;
+		case fpga_lattice:
+#if CONFIG_FPGA & CFG_FPGA_LATTICE
+			printf( "Lattice Device\nDescriptor @ 0x%p\n", desc );
+			ret_val = lattice_info( desc->devdesc );
+#else
+			fpga_no_sup( __FUNCTION__, "Lattice devices" );
+#endif
+			break;
 		default:
 			printf( "%s: Invalid or unsupported device type %d\n",
 					__FUNCTION__, desc->devtype );
@@ -188,6 +197,13 @@ int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off )
 		fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
 #endif
 		break;
+	case fpga_lattice:
+#if CONFIG_FPGA & CFG_FPGA_LATTICE
+		ret_val = lattice_reloc( desc, reloc_off );
+#else
+		fpga_no_sup( __FUNCTION__, "Lattice devices" );
+#endif
+		break;
 	default:
 		printf( "%s: Invalid or unsupported device type %d\n",
 			__FUNCTION__, devtype );
@@ -281,6 +297,13 @@ int fpga_load( int devnum, void *buf, size_t bsize )
 			fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
 #endif
 			break;
+		case fpga_lattice:
+#if CONFIG_FPGA & CFG_FPGA_LATTICE
+			ret_val = lattice_load( desc->devdesc, buf, bsize );
+#else
+			fpga_no_sup( __FUNCTION__, "Lattice devices" );
+#endif
+			break;
 		default:
 			printf( "%s: Invalid or unsupported device type %d\n",
 				__FUNCTION__, desc->devtype );
@@ -314,6 +337,13 @@ int fpga_dump( int devnum, void *buf, size_t bsize )
 			fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
 #endif
 			break;
+		case fpga_lattice:
+#if CONFIG_FPGA & CFG_FPGA_LATTICE
+			ret_val = lattice_dump( desc->devdesc, buf, bsize );
+#else
+			fpga_no_sup( __FUNCTION__, "Lattice devices" );
+#endif
+			break;
 		default:
 			printf( "%s: Invalid or unsupported device type %d\n",
 				__FUNCTION__, desc->devtype );
diff --git a/common/lattice.c b/common/lattice.c
new file mode 100644
index 0000000..26e1aa2
--- /dev/null
+++ b/common/lattice.c
@@ -0,0 +1,218 @@
+/*
+ * (C) Copyright 2006 - Embedded Alley Solutions Inc.
+ * by Pantelis Antoniou, pantelis at embeddedalley.com
+ *
+ * Based on common/lattice.c (C) Copyright 2002
+ *   by Rich Ireland, Enterasys Networks, rireland at enterasys.com.
+ *   by Keith Outwater, keith_outwater at mvis.com
+ *
+ * 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
+ *
+ */
+
+/*
+ * Lattice FPGA support
+ */
+
+#include <common.h>
+#include <lattice_ec.h>
+
+#include <lattice_vmopcode.h>
+
+#if (CONFIG_FPGA & CFG_FPGA_LATTICE)
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+/* Define FPGA_DEBUG to get debug printf's */
+#ifdef	FPGA_DEBUG
+#define	PRINTF(fmt,args...)	printf(fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/* Local Static Functions */
+static int lattice_validate(Lattice_desc *desc, char *fn);
+
+int lattice_load(Lattice_desc *desc, void *buf, size_t bsize)
+{
+	int ret_val = FPGA_FAIL;	/* assume a failure */
+
+	if (!lattice_validate(desc, (char *)__FUNCTION__)) {
+		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+		return FPGA_FAIL;
+	} 
+
+	switch (desc->family) {
+	case Lattice_EC:
+#if (CONFIG_FPGA & CFG_EC)
+		PRINTF("%s: Launching the EC Loader...\n",
+				__FUNCTION__);
+		ret_val = EC_load(desc, buf, bsize);
+#else
+		printf("%s: No support for EC devices.\n",
+				__FUNCTION__);
+#endif
+		break;
+	default:
+		printf("%s: Unsupported family type, %d\n",
+				__FUNCTION__, desc->family);
+	}
+
+	return ret_val;
+}
+
+int lattice_dump(Lattice_desc *desc, void *buf, size_t bsize)
+{
+	int ret_val = FPGA_FAIL;	/* assume a failure */
+
+	if (!lattice_validate(desc, (char *)__FUNCTION__)) {
+		printf("%s: Invalid device descriptor\n", __FUNCTION__);
+		return FPGA_FAIL;
+	} 
+
+	switch (desc->family) {
+	case Lattice_EC:
+#if (CONFIG_FPGA & CFG_EC)
+		PRINTF("%s: Launching the EC Reader...\n",
+				__FUNCTION__);
+		ret_val = EC_dump(desc, buf, bsize);
+#else
+		printf("%s: No support for EC devices.\n",
+				__FUNCTION__);
+#endif
+		break;
+
+	default:
+		printf("%s: Unsupported family type, %d\n",
+				__FUNCTION__, desc->family);
+	}
+
+	return ret_val;
+}
+
+int lattice_info(Lattice_desc *desc)
+{
+	if (!lattice_validate(desc, (char *)__FUNCTION__)) {
+		printf("%s: Invalid device descriptor\n", __FUNCTION__);
+		return FPGA_FAIL;
+	}
+
+	if (!desc->iface_fns) {
+		printf("No Device Function Table.\n");
+		return FPGA_FAIL;
+	}
+
+	printf ("Family:        \t");
+	switch (desc->family) {
+	case Lattice_EC:
+		printf ("EC\n");
+		break;
+		/* Add new family types here */
+	default:
+		printf("Unknown family type, %d\n", desc->family);
+	}
+
+	printf ("Interface type:\t");
+	switch (desc->iface) {
+	case lattice_jtag_mode:
+		printf("JTAG Mode\n");
+		break;
+	default:
+		printf("Unsupported interface type, %d\n", desc->iface);
+	}
+
+	printf("Device Size:   \t%d bytes\n"
+			"Cookie:        \t0x%x (%d)\n",
+			desc->size, desc->cookie, desc->cookie);
+
+	printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
+	switch (desc->family) {
+	case Lattice_EC:
+#if (CONFIG_FPGA & CFG_EC)
+		EC_info(desc);
+#else
+		/* just in case */
+		printf("%s: No support for EC devices.\n",
+				__FUNCTION__);
+#endif
+		break;
+		/* Add new family types here */
+	default:
+		/* we don't need a message here - we give one up above */
+		;
+	}
+
+	return FPGA_SUCCESS;
+}
+
+int lattice_reloc(Lattice_desc *desc, ulong reloc_offset)
+{
+	int ret_val = FPGA_FAIL;	/* assume a failure */
+
+	if (!lattice_validate (desc, (char *)__FUNCTION__)) {
+		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+		return FPGA_FAIL;
+	}
+
+	switch (desc->family) {
+	case Lattice_EC:
+#if (CONFIG_FPGA & CFG_EC)
+		ret_val = EC_reloc(desc, reloc_offset);
+#else
+		printf("%s: No support for EC devices.\n",
+				__FUNCTION__);
+#endif
+		break;
+		/* Add new family types here */
+	default:
+		printf("%s: Unsupported family type, %d\n",
+				__FUNCTION__, desc->family);
+	}
+
+	return ret_val;
+}
+
+static int lattice_validate(Lattice_desc *desc, char *fn)
+{
+	if (!desc) {
+		printf ("%s: NULL descriptor!\n", fn);
+		return 0;
+	}
+
+	if (desc->family <= min_lattice_type &&
+			desc->family >= max_lattice_type) {
+		printf ("%s: Invalid family type, %d\n", fn, desc->family);
+		return 0;
+	}
+	if (desc->iface <= min_lattice_iface_type &&
+			desc->iface >= max_lattice_iface_type) {
+		printf ("%s: Invalid Interface type, %d\n", fn, desc->iface);
+		return 0;
+	}
+	if (!desc->size) {
+		printf ("%s: NULL part size\n", fn);
+		return 0;
+	}
+
+	return 1;
+}
+
+#endif
diff --git a/common/lattice_ec.c b/common/lattice_ec.c
new file mode 100644
index 0000000..1b8b485
--- /dev/null
+++ b/common/lattice_ec.c
@@ -0,0 +1,461 @@
+/*
+ * (C) Copyright 2006 - Embedded Alley Solutions Inc.
+ * by Pantelis Antoniou, pantelis at embeddedalley.com
+ *
+ * Based on common/spartan2.c
+ *   (C) Copyright 2002
+ *   by Rich Ireland, Enterasys Networks, rireland at enterasys.com.
+ *
+ * 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 <asm/types.h>
+
+#include <lattice_ec.h>			/* Lattice EC device family */
+
+#include <lattice_vmopcode.h>
+#include <lattice_ivm_core.h>
+
+#if (CONFIG_FPGA & (CFG_LATTICE | CFG_EC))
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+/* 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/100	/* 10 ms */
+#endif
+
+static int EC_jtag_load( Lattice_desc *desc, void *buf, size_t bsize);
+static int EC_jtag_dump( Lattice_desc *desc, void *buf, size_t bsize);
+/* static int EC_jtag_info( Lattice_desc *desc ); */
+static int EC_jtag_reloc( Lattice_desc *desc, ulong reloc_offset);
+
+/* Lattice EC Generic Implementation */
+int EC_load (Lattice_desc * desc, void *buf, size_t bsize)
+{
+	int ret_val = FPGA_FAIL;
+
+	switch (desc->iface) {
+	case lattice_jtag_mode:
+		PRINTF ("%s: Launching JTAG Load\n", __FUNCTION__);
+		ret_val = EC_jtag_load (desc, buf, bsize);
+		break;
+
+	default:
+		printf ("%s: Unsupported interface type, %d\n",
+				__FUNCTION__, desc->iface);
+	}
+
+	return ret_val;
+}
+
+int EC_dump (Lattice_desc * desc, void *buf, size_t bsize)
+{
+	int ret_val = FPGA_FAIL;
+
+	switch (desc->iface) {
+	case lattice_jtag_mode:
+		PRINTF ("%s: Launching JTAG Dump\n", __FUNCTION__);
+		ret_val = EC_jtag_dump (desc, buf, bsize);
+		break;
+
+	default:
+		printf ("%s: Unsupported interface type, %d\n",
+				__FUNCTION__, desc->iface);
+	}
+
+	return ret_val;
+}
+
+int EC_info( Lattice_desc *desc )
+{
+	return FPGA_SUCCESS;
+}
+
+
+int EC_reloc (Lattice_desc * desc, ulong reloc_offset)
+{
+	int ret_val = FPGA_FAIL;	/* assume a failure */
+
+	if (desc->family != Lattice_EC) {
+		printf ("%s: Unsupported family type, %d\n",
+				__FUNCTION__, desc->family);
+		return FPGA_FAIL;
+	} else
+		switch (desc->iface) {
+		case lattice_jtag_mode:
+			ret_val = EC_jtag_reloc (desc, reloc_offset);
+			break;
+
+		default:
+			printf ("%s: Unsupported interface type, %d\n",
+					__FUNCTION__, desc->iface);
+		}
+
+	return ret_val;
+}
+
+/*********************************************************************/
+
+static void rewind_buffer(void *cookie);
+
+static int lattice_ec_verbose = 0;
+
+static int EC_jtag_load (Lattice_desc * desc, void *buf, size_t bsize)
+{
+	static struct Lattice_EC_private priv;
+	Lattice_EC_JTAG_fns *fn = desc->iface_fns;
+	char version[9];
+	int j, ret;
+	u16 ecrc = 0;
+	u16 ccrc = 0;
+	int val;
+
+	/* play it safe */
+	version[0] = '\0';
+
+	PRINTF ("%s: start with interface functions @ 0x%p\n",
+			__FUNCTION__, fn);
+
+	if (!fn) {
+		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+		return FPGA_FAIL;
+	}
+
+	PRINTF ("%s: Function Table:\n"
+			"ptr:\t0x%p\n"
+			"struct: 0x%p\n"
+			"pre:\t0x%p\n"
+			"post:\t0x%p\n"
+			"jtag_write_port:\t0x%p\n"
+			"jtag_read_port:\t0x%p\n\n",
+			__FUNCTION__, &fn, fn, fn->pre, fn->post,
+			fn->jtag_write_port, fn->jtag_read_port);
+
+	priv.fpga_prog_base = buf;
+	priv.fpga_prog_end = buf + bsize;
+	priv.fpga_prog_next = buf;
+	priv.fpga_steps_reset = (bsize * 2 / 50); /* one step */
+	priv.fpga_steps = 0;
+	priv.fpga_spin = 0;
+	desc->priv = &priv;
+
+	ispvm_reset(&priv.d, desc);	/* Reset state of programming code */
+	rewind_buffer(desc);
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+	printf("FPGA:   ");	/* Two spaces (at least)! */
+#endif
+
+	lattice_ec_verbose = 0;
+
+	ccrc = 0;
+	val = lattice_ec_next_byte(desc);
+	if (val == -1) {
+		PRINTF("Invalid file\n");
+		return VME_INVALID_FILE;
+	}
+	switch(val) {
+		case FILE_CRC:
+			val = lattice_ec_next_byte(desc);
+			if (val == -1) {
+				PRINTF("Invalid file\n");
+				return VME_INVALID_FILE;
+			}
+			ecrc = (val & 0xff) << 8;
+			val = lattice_ec_next_byte(desc);
+			if (val == -1) {
+				PRINTF("Invalid file\n");
+				return VME_INVALID_FILE;
+			}
+			ecrc |= val & 0xff;
+
+			while ((val = lattice_ec_next_byte(desc)) != -1)
+				ccrc = ispvm_crc(&priv.d, (u8)val, ccrc);
+
+			if (ecrc && ecrc != ccrc) {
+				PRINTF("Expected CRC:   0x%.4X\n", ecrc);
+				PRINTF("Calculated CRC: 0x%.4X\n", ccrc);
+				return VME_CRC_FAILURE;
+			}
+
+			rewind_buffer(desc);
+#ifdef FPGA_DEBUG
+			lattice_ec_verbose = 1;
+#endif
+			(void)lattice_ec_next_byte(desc);
+			(void)lattice_ec_next_byte(desc);
+			(void)lattice_ec_next_byte(desc);
+
+			for (j = 0; j < 8; j++) {
+				val = lattice_ec_next_byte(desc);
+				if (val == -1)
+					break;
+				version[j] = val & 0xff;
+			}
+
+			break;
+
+		default:
+			version[0] = (signed char) val;
+			for (j = 1; j < 8; j++) {
+				val = lattice_ec_next_byte(desc);
+				if (val == -1)
+					break;
+				version[j] = val & 0xff;
+			}
+			break;
+	}
+
+	ret = ispvm_validate_version(&priv.d, version);
+	if (ret < 0)
+		return VME_VERSION_FAILURE;
+
+	PRINTF("FPGA pre-program\n");
+	if (fn->pre)
+		fn->pre(0);
+
+	/* Reset FPGA */
+	PRINTF("FPGA reset\n");
+	fn->jtag_write_port(0, LATTICE_JTAG_RST, 1);
+	udelay(1000);
+	fn->jtag_write_port(0, LATTICE_JTAG_RST, 0);
+
+	/* lattice_ec_verbose = 0; */
+
+	ispvm_start(&priv.d);
+	ret = ispvm_code(&priv.d);
+	ispvm_end(&priv.d);
+
+	if (ret != 0) {
+		if (fn->post)
+			(*fn->post)(0, 0);
+
+		PRINTF(" FAILED! (code = %d)\n", cRetCode);
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+		printf(" FAIL!\n");
+#endif
+		return FPGA_FAIL;
+	}
+
+	PRINTF(" OK\n");
+
+	PRINTF("FPGA post-program\n");
+	if (fn->post)
+		(*fn->post)(0, 1);
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+	printf("\b\b done.\n");
+#endif
+
+	return FPGA_SUCCESS;
+}
+
+static int EC_jtag_dump (Lattice_desc * desc, void *buf, size_t bsize)
+{
+	/* Readback is only available through the Slave Parallel and */
+	/* boundary-scan interfaces.				     */
+	printf ("%s: JTAG Dumping is unavailable\n",
+			__FUNCTION__);
+	return FPGA_FAIL;
+}
+
+static int EC_jtag_reloc (Lattice_desc * desc, ulong reloc_offset)
+{
+	ulong addr;
+	Lattice_EC_JTAG_fns *fn_r, *fn = desc->iface_fns;
+
+	if (!fn) {
+		printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+		return FPGA_FAIL;
+	}
+
+	/* Get the relocated table address */
+	addr = (ulong) fn + reloc_offset;
+	fn_r = (Lattice_EC_JTAG_fns *) addr;
+
+	if (fn_r->relocated) {
+		/* this table has already been moved */
+		/* XXX - should check to see if the descriptor is correct */
+		desc->iface_fns = fn_r;
+		return FPGA_SUCCESS;
+	}
+
+	if (memcmp(fn_r, fn, sizeof(Lattice_EC_JTAG_fns)) != 0) {
+		PRINTF ("%s: Invalid function table at 0x%p\n",
+				__FUNCTION__, fn_r);
+		return FPGA_FAIL;
+	}
+
+	/* good copy of the table, 
+	 * fix the descriptor pointer
+	 */
+	desc->iface_fns = fn_r;
+	PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__,
+			desc);
+
+	addr = (ulong) (fn->pre) + reloc_offset;
+	fn_r->pre = (Lattice_pre_fn) addr;
+
+	addr = (ulong) (fn->post) + reloc_offset;
+	fn_r->post = (Lattice_post_fn) addr;
+
+	addr = (ulong) (fn->jtag_write_port) + reloc_offset;
+	fn_r->jtag_write_port = (Lattice_jtag_write_port_fn) addr;
+
+	addr = (ulong) (fn->jtag_read_port) + reloc_offset;
+	fn_r->jtag_read_port = (Lattice_jtag_read_port_fn) addr;
+
+	fn_r->relocated = TRUE;
+
+	return FPGA_SUCCESS;
+}
+
+/****************************************************************************/
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+
+static const char spin_txt[] = "|/-\\";
+
+static inline void fpga_progress(Lattice_desc *desc)
+{
+	struct Lattice_EC_private *priv = desc->priv;
+
+	if (--priv->fpga_steps >= 0)
+		return;
+
+	priv->fpga_steps = priv->fpga_steps_reset;
+	printf("\b%c", spin_txt[priv->fpga_spin]);
+	if (++priv->fpga_spin >= 4)
+		priv->fpga_spin = 0;
+}
+
+#else
+
+#define fpga_progress(desc) do { } while(0)
+
+#endif
+
+static void rewind_buffer(void *cookie)
+{
+	Lattice_desc * desc = cookie;
+	struct Lattice_EC_private *priv = desc->priv;
+
+	priv->fpga_prog_next = priv->fpga_prog_base;
+
+	if (lattice_ec_verbose)
+		printf("\nRewind:\n");
+}
+
+int lattice_ec_next_byte(void *cookie)
+{
+	Lattice_desc * desc = cookie;
+	struct Lattice_EC_private *priv = desc->priv;
+	unsigned char val;
+	int pos;
+
+	if (priv == NULL || priv->fpga_prog_next == NULL ||
+			priv->fpga_prog_next >= priv->fpga_prog_end)
+		return -1;
+
+	val = *priv->fpga_prog_next & 0xff;
+
+	if (lattice_ec_verbose) {
+		pos = priv->fpga_prog_next - priv->fpga_prog_base;
+		if ((pos % 16) == 0)
+			PRINTF("[%04x]", pos & 0xffff);
+
+		PRINTF(" %02x", val);
+	}
+
+	priv->fpga_prog_next++;
+
+	if (lattice_ec_verbose) {
+		pos = priv->fpga_prog_next - priv->fpga_prog_base;
+		if ((pos % 16) == 0)
+			PRINTF("\n");
+	}
+
+	fpga_progress(desc);
+
+	return val;
+}
+
+#ifdef	FPGA_DEBUG
+static const char *pin_txt[] = {
+	[LATTICE_JTAG_TDI]	= "TDI",
+	[LATTICE_JTAG_TCK]	= "TCK",
+	[LATTICE_JTAG_TMS]	= "TMS",
+	[LATTICE_JTAG_TDO]	= "TDO",
+	[LATTICE_JTAG_CE]	= "CE",
+	[LATTICE_JTAG_RST]	= "RST",
+};
+#endif
+
+int lattice_ec_read_port(void *cookie)
+{
+	Lattice_desc * desc = cookie;
+	Lattice_EC_JTAG_fns *fn = desc->iface_fns;
+	struct Lattice_EC_private *priv = desc->priv;
+	int val;
+
+	(void)priv;
+	val = fn->jtag_read_port(0);
+
+	if (lattice_ec_verbose)
+		PRINTF("R-TDO=%d\n", val);
+
+	return val;
+}
+
+void lattice_ec_write_port(void *cookie, int pin, int value)
+{
+	Lattice_desc * desc = cookie;
+	Lattice_EC_JTAG_fns *fn = desc->iface_fns;
+	struct Lattice_EC_private *priv = desc->priv;
+
+	(void)priv;
+
+	if (lattice_ec_verbose)
+		PRINTF("W-%s=%d\n", pin_txt[pin], value & 1);
+
+	fn->jtag_write_port(0, pin, value);
+}
+
+#endif
diff --git a/include/fpga.h b/include/fpga.h
index a038aa1..f04b64a 100644
--- a/include/fpga.h
+++ b/include/fpga.h
@@ -47,7 +47,7 @@
 /* FPGA Manufacturer bits in CONFIG_FPGA */
 #define CFG_FPGA_XILINX 		CFG_FPGA_MAN( 0x1 )
 #define CFG_FPGA_ALTERA			CFG_FPGA_MAN( 0x2 )
-
+#define CFG_FPGA_LATTICE		CFG_FPGA_MAN( 0x4 )
 
 /* fpga_xxxx function return value definitions */
 #define FPGA_SUCCESS         0
@@ -61,6 +61,7 @@ typedef enum {                 /* typedef fpga_type */
 	fpga_min_type,             /* range check value */
     fpga_xilinx,               /* Xilinx Family) */
     fpga_altera,               /* unimplemented */
+    fpga_lattice,		/* lattice */
     fpga_undefined             /* invalid range check value */
 } fpga_type;                   /* end, typedef fpga_type */
 
diff --git a/include/lattice.h b/include/lattice.h
new file mode 100644
index 0000000..edd3e74
--- /dev/null
+++ b/include/lattice.h
@@ -0,0 +1,85 @@
+/*
+ * (C) Copyright 2006 - Embedded Alley Solutions Inc.
+ * by Pantelis Antoniou, pantelis at embeddedalley.com
+ *
+ * Based on include/xilinx.h
+ *   (C) Copyright 2002
+ *   by Rich Ireland, Enterasys Networks, rireland at enterasys.com.
+ *
+ * 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 <fpga.h>
+
+#ifndef _LATTICE_H_
+#define _LATTICE_H_
+
+/* Lattice Model definitions */
+#define CFG_EC			CFG_FPGA_DEV( 0x1 )
+#define CFG_LATTICE_EC		(CFG_FPGA_LATTICE | CFG_EC)
+
+/* Lattice Interface definitions */
+#define CFG_LATTICE_IF_JTAG	CFG_FPGA_IF( 0x1 )	/* jtag	*/
+
+/* Lattice types */
+typedef enum {				/* typedef Lattice_iface            */
+	min_lattice_iface_type,		/* low range check value            */
+	lattice_jtag_mode,		/* jtag/tap serial                  */
+	max_lattice_iface_type		/* insert all new types before this */
+} Lattice_iface;			/* end, typedef Lattice_iface       */
+
+typedef enum {				/* typedef Lattice_Family           */
+	min_lattice_type,		/* low range check value            */
+	Lattice_EC,			/* EC Family                        */
+	max_lattice_type		/* insert all new types before this */
+} Lattice_Family;			/* end, typedef Lattice_Family      */
+
+typedef struct {			/* typedef Lattice_desc             */
+	Lattice_Family	family;		/* part type                        */
+	Lattice_iface	iface;		/* interface type                   */
+	size_t		size;		/* bytes of data part can accept    */
+	void *		iface_fns;	/* interface function table         */
+	int		cookie;		/* implementation specific cookie   */
+	void *		priv;		/* private info                     */
+} Lattice_desc;				/* end, typedef Lattice_desc        */
+
+/* Generic Lattice Functions */
+extern int lattice_load( Lattice_desc *desc, void *image, size_t size );
+extern int lattice_dump( Lattice_desc *desc, void *buf, size_t bsize );
+extern int lattice_info( Lattice_desc *desc );
+extern int lattice_reloc( Lattice_desc *desc, ulong reloc_offset );
+
+/* Board specific implementation specific function types */
+
+#define LATTICE_JTAG_TDI	0
+#define LATTICE_JTAG_TCK	1
+#define LATTICE_JTAG_TMS	2
+#define LATTICE_JTAG_TDO	3
+#define LATTICE_JTAG_CE		4
+#define LATTICE_JTAG_RST	5
+
+typedef int (*Lattice_pre_fn)( int cookie );
+typedef int (*Lattice_post_fn)( int cookie, int success);
+
+typedef void (*Lattice_jtag_write_port_fn)(int cookie, unsigned int pin,
+		unsigned int value);
+typedef int (*Lattice_jtag_read_port_fn)(int cookie);
+
+#endif	/* _LATTICE_H_ */
diff --git a/include/lattice_ec.h b/include/lattice_ec.h
new file mode 100644
index 0000000..f92a87c
--- /dev/null
+++ b/include/lattice_ec.h
@@ -0,0 +1,85 @@
+/*
+ * (C) Copyright 2006 - Embedded Alley Solutions Inc.
+ * by Pantelis Antoniou, pantelis at embeddedalley.com
+ *
+ * Based on include/spartan2.h
+ *   (C) Copyright 2002
+ *   by Rich Ireland, Enterasys Networks, rireland at enterasys.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef _EC_H_
+#define _EC_H_
+
+#include <lattice.h>
+#include <lattice_ivm_core.h>
+
+struct Lattice_EC_private {
+	unsigned char *fpga_prog_base;
+	unsigned char *fpga_prog_end;
+	unsigned char *fpga_prog_next;
+	int fpga_steps_reset;
+	int fpga_steps;
+	int fpga_spin;
+	struct ispvm_desc d;
+};
+
+extern int EC_load(Lattice_desc *desc, void *image, size_t size);
+extern int EC_dump(Lattice_desc *desc, void *buf, size_t bsize);
+extern int EC_info(Lattice_desc *desc);
+extern int EC_reloc(Lattice_desc *desc, ulong reloc_off);
+
+/* JTAG Implementation function table */
+typedef struct {
+	Lattice_pre_fn pre;
+	Lattice_post_fn post;
+	Lattice_jtag_write_port_fn jtag_write_port;
+	Lattice_jtag_read_port_fn jtag_read_port;
+	int relocated;
+} Lattice_EC_JTAG_fns;
+
+/* Device Image Sizes
+ *********************************************************************/
+/* Lattice EC (1.8V) */
+#define LATTICE_LFEC1_SIZE	6144/8
+#define LATTICE_LFEC3_SIZE	12288/8
+#define LATTICE_LFEC6_SIZE	25600/8
+
+/* Descriptor Macros
+ *********************************************************************/
+/* CE devices */
+#define LATTICE_LFEC1_DESC(iface, fn_table, cookie) \
+{ Lattice_CE, iface, LATTICE_LFEC1_SIZE, fn_table, cookie }
+
+#define LATTICE_LFEC3_DESC(iface, fn_table, cookie) \
+{ Lattice_CE, iface, LATTICE_LFEC3_SIZE, fn_table, cookie }
+
+#define LATTICE_LFEC6_DESC(iface, fn_table, cookie) \
+{ Lattice_CE, iface, LATTICE_LFEC6_SIZE, fn_table, cookie }
+
+/* API to the IVM */
+/*********************************************************************/
+
+extern int lattice_ec_next_byte(void *cookie);
+extern int lattice_ec_read_port(void *cookie);
+extern void lattice_ec_write_port(void *cookie, int pin, int value);
+
+#endif




More information about the U-Boot mailing list