[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