
Add support for Lattice FPGA parts programmed using JTAG.
--- Signed-off-by: Pantelis Antoniou pantelis@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@embeddedalley.com + * + * Based on common/lattice.c (C) Copyright 2002 + * by Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * by Keith Outwater, keith_outwater@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@embeddedalley.com + * + * Based on common/spartan2.c + * (C) Copyright 2002 + * by Rich Ireland, Enterasys Networks, rireland@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@embeddedalley.com + * + * Based on include/xilinx.h + * (C) Copyright 2002 + * by Rich Ireland, Enterasys Networks, rireland@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@embeddedalley.com + * + * Based on include/spartan2.h + * (C) Copyright 2002 + * by Rich Ireland, Enterasys Networks, rireland@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