For details about the current modifications, please see README-WIP
+* Patch by Keith Outwate, 21 Aug 2002:
+ - fix/add debug messages in soft_i2c.c
+ - added better memory test (optional)
+ - added support for 3rd status LED
+ - Date & Time support (no alarms) for
+ Dallas Semiconductor (now Maxim) DS1337 Real Time Clock
+ - README fixes / extensions
+ - FPGA device configuration driver (Rich Ireland)
* Patch by Scott McNutt,, 14 Aug 2002:
IBM 440GP Ethernet support
N: Jerry van Baren
E: <vanbaren@cideas.com>
-D: BedBug port to 603e core (MPC82xx)
+D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test.
N: Raphael Bossek
E: raphael.bossek@solutions4linux.de
E: stuarth@lineo.com
D: Port to MPC8260ADS board
+H: Rich Ireland
+E: r.ireland@computer.org
+D: FPGA device configuration driver
+
N: Murray Jensen
E: Murray.Jensen@cmst.csiro.au
D: Initial 8260 support; GDB support
Time to wait after FPGA configuration. The default is
200 mS.
+- FPGA Support: CONFIG_FPGA_COUNT
+
+ Specify the number of FPGA devices to support.
+
+ CONFIG_FPGA
+
+ Used to specify the types of FPGA devices. For example,
+ #define CONFIG_FPGA CFG_XILINX_VIRTEX2
+
+ CFG_FPGA_PROG_FEEDBACK
+
+ Enable printing of hash marks during FPGA configuration.
+
+ CFG_FPGA_CHECK_BUSY
+
+ Enable checks on FPGA configuration interface busy status
+ by the configuration function. This option will require
+ a board or device specific function to be written.
+
+ CONFIG_FPGA_DELAY
+
+ If defined, a function that provides delays in the FPGA
+ configuration driver.
+
+ CFG_FPGA_CHECK_CTRLC
+ Allow Control-C to interrupt FPGA configuration
+
+ CFG_FPGA_CHECK_ERROR
+
+ Check for configuration errors during FPGA bitfile loading.
+ For example, abort during Virtex II configuration if the
+ INIT_B line goes low (which indicated a CRC error).
+
+ CFG_FPGA_WAIT_INIT
+
+ Maximum time to wait for the INIT_B line to deassert after
+ PROB_B has been deasserted during a Virtex II FPGA
+ configuration sequence. The default time is 500 mS.
+
+ CFG_FPGA_WAIT_BUSY
+
+ Maximum time to wait for BUSY to deassert during Virtex II
+ FPGA configuration. The default is 5 mS.
+
+ CFG_FPGA_WAIT_CONFIG
+
+ Time to wait after FPGA configuration. The default is 200 mS.
+
- Configuration Management:
CONFIG_IDENT_STRING
- CFG_EEPROM_SIZE:
The size in bytes of the EEPROM device.
+ - CFG_I2C_EEPROM_ADDR:
+ If defined, specified the chip address of the EEPROM device.
+ The default address is zero.
+
+ - CFG_EEPROM_PAGE_WRITE_BITS:
+ If defined, the number of bits used to address bytes in a
+ single page in the EEPROM device. A 64 byte page, for example
+ would require six bits.
+
+ - CFG_EEPROM_PAGE_WRITE_DELAY_MS:
+ If defined, the number of milliseconds to delay between
+ page writes. The default is zero milliseconds.
+
+ - CFG_I2C_EEPROM_ADDR_LEN:
+ The length in bytes of the EEPROM memory array address. Note
+ that this is NOT the chip address length!
+
+ - CFG_EEPROM_SIZE:
+ The size in bytes of the EEPROM device.
+
- CFG_SPI_INIT_OFFSET
Defines offset to the initial SPI buffer area in DPRAM. The
* Miscelaneous platform dependent initialisations
*/
-int board_init(bd_t *bd)
+int board_init (gd_t *gd)
{
- /* memory and cpu-speed are setup before relocation */
- /* so we do _nothing_ here */
+ /* memory and cpu-speed are setup before relocation */
+ /* so we do _nothing_ here */
- /* arch number of DNP1110-Board */
- bd->bi_arch_number = 255;
+ /* arch number of DNP1110-Board */
+ bd->bi_arch_number = 255;
- /* adress of boot parameters */
- bd->bi_boot_params = 0xc0000100;
+ /* adress of boot parameters */
+ bd->bi_boot_params = 0xc0000100;
- return 1;
+ return 0;
}
-int dram_init(bd_t *bd)
+int dram_init (gd_t *gd)
{
- bd->bi_dram[0].start = PHYS_SDRAM_1;
- bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
- return PHYS_SDRAM_1_SIZE;
+ bd->bi_dram[0].start = PHYS_SDRAM_1;
+ bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return PHYS_SDRAM_1_SIZE;
}
* Miscelaneous platform dependent initialisations
*/
-int board_init(bd_t *bd)
+int board_init (gd_t *gd)
{
- /* Activate LED flasher */
- IO_LEDFLSH = 0x40;
+ /* Activate LED flasher */
+ IO_LEDFLSH = 0x40;
- /* arch number MACH_TYPE_EDB7312 */
- bd->bi_arch_number = 131;
+ /* arch number MACH_TYPE_EDB7312 */
+ bd->bi_arch_number = 131;
- /* location of boot parameters */
- bd->bi_boot_params = 0xc0020100;
+ /* location of boot parameters */
+ bd->bi_boot_params = 0xc0020100;
- return 1;
+ return 0;
}
-int dram_init(bd_t *bd)
+int dram_init (gd_t *gd)
{
- bd->bi_dram[0].start = PHYS_SDRAM_1;
- bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ bd->bi_dram[0].start = PHYS_SDRAM_1;
+ bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
- return PHYS_SDRAM_1_SIZE;
+ return PHYS_SDRAM_1_SIZE;
}
* Miscelaneous platform dependent initialisations
*/
-int board_init(bd_t *bd)
+int board_init (gd_t *gd)
{
- /* Activate LED flasher */
- IO_LEDFLSH = 0x40;
+ /* Activate LED flasher */
+ IO_LEDFLSH = 0x40;
- /* arch number of EP7111 */
- bd->bi_arch_number = 50;
+ /* arch number of EP7111 */
+ bd->bi_arch_number = 50;
- /* location of boot parameters for EP7111 */
- bd->bi_boot_params = 0xc0020100;
+ /* location of boot parameters for EP7111 */
+ bd->bi_boot_params = 0xc0020100;
- return 1;
+ return 0;
}
-int dram_init(bd_t *bd)
+int dram_init (gd_t *gd)
{
- bd->bi_dram[0].start = PHYS_SDRAM_1;
- bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
- bd->bi_dram[1].start = PHYS_SDRAM_2;
- bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
-
- return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;
+ bd->bi_dram[0].start = PHYS_SDRAM_1;
+ bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ bd->bi_dram[1].start = PHYS_SDRAM_2;
+ bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+
+ return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;
}
* Miscelaneous platform dependent initialisations
*/
-int board_init(bd_t *bd)
+int board_init (gd_t *gd)
{
- /* memory and cpu-speed are setup before relocation */
- /* so we do _nothing_ here */
+ /* memory and cpu-speed are setup before relocation */
+ /* so we do _nothing_ here */
- /* arch number of LART-Board */
- bd->bi_arch_number = 27;
+ /* arch number of LART-Board */
+ bd->bi_arch_number = 27;
- /* adress of boot parameters */
- bd->bi_boot_params = 0xc0000100;
+ /* adress of boot parameters */
+ bd->bi_boot_params = 0xc0000100;
- return 1;
+ return 0;
}
-int dram_init(bd_t *bd)
+int dram_init (gd_t *gd)
{
- bd->bi_dram[0].start = PHYS_SDRAM_1;
- bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
- bd->bi_dram[1].start = PHYS_SDRAM_2;
- bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
- bd->bi_dram[2].start = PHYS_SDRAM_3;
- bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
- bd->bi_dram[3].start = PHYS_SDRAM_4;
- bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
- return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE + PHYS_SDRAM_3_SIZE + PHYS_SDRAM_4_SIZE;
+ bd->bi_dram[0].start = PHYS_SDRAM_1;
+ bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ bd->bi_dram[1].start = PHYS_SDRAM_2;
+ bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+ bd->bi_dram[2].start = PHYS_SDRAM_3;
+ bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
+ bd->bi_dram[3].start = PHYS_SDRAM_4;
+ bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
+
+ return (PHYS_SDRAM_1_SIZE +
+ PHYS_SDRAM_2_SIZE +
+ PHYS_SDRAM_3_SIZE +
+ PHYS_SDRAM_4_SIZE );
}
* Miscelaneous platform dependent initialisations
*/
-int board_init(bd_t *bd)
+int board_init (gd_t *gd)
{
- /* memory and cpu-speed are setup before relocation */
- /* but if we use InfernoLoader, we must do some inits here */
+ /* memory and cpu-speed are setup before relocation */
+ /* but if we use InfernoLoader, we must do some inits here */
- #ifdef CONFIG_INFERNO
- {
+#ifdef CONFIG_INFERNO
+ {
unsigned long temp;
__asm__ __volatile__(/* disable MMU, enable icache */
"mrc p15, 0, %0, c1, c0\n"
temp = 0xa0000018;
*(unsigned long *)temp = 0x00060006;
- }
- #endif /* CONFIG_INIT_CRITICAL */
+ }
+#endif /* CONFIG_INIT_CRITICAL */
- /* arch number for shannon */
- bd->bi_arch_number = 97;
+ /* arch number for shannon */
+ bd->bi_arch_number = 97;
- /* adress of boot parameters */
- bd->bi_boot_params = 0xc0000100;
+ /* adress of boot parameters */
+ bd->bi_boot_params = 0xc0000100;
- return 1;
+ return 0;
}
-int dram_init(bd_t *bd)
+int dram_init (gd_t * gd)
{
- #ifdef PHYS_SDRAM_1
- bd->bi_dram[0].start = PHYS_SDRAM_1;
- bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
- #endif
+#ifdef PHYS_SDRAM_1
+ bd->bi_dram[0].start = PHYS_SDRAM_1;
+ bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+#endif
- #ifdef PHYS_SDRAM_2
- bd->bi_dram[1].start = PHYS_SDRAM_2;
- bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
- #endif
+#ifdef PHYS_SDRAM_2
+ bd->bi_dram[1].start = PHYS_SDRAM_2;
+ bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+#endif
- #ifdef PHYS_SDRAM_3
- bd->bi_dram[2].start = PHYS_SDRAM_3;
- bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
- #endif
+#ifdef PHYS_SDRAM_3
+ bd->bi_dram[2].start = PHYS_SDRAM_3;
+ bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
+#endif
- #ifdef PHYS_SDRAM_4
- bd->bi_dram[3].start = PHYS_SDRAM_4;
- bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
- #endif
+#ifdef PHYS_SDRAM_4
+ bd->bi_dram[3].start = PHYS_SDRAM_4;
+ bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
+#endif
- return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE
- #ifdef PHYS_SDRAM_4
- + PHYS_SDRAM_3_SIZE + PHYS_SDRAM_4_SIZE
- #endif
- ;
+ return ( PHYS_SDRAM_1_SIZE
+ + PHYS_SDRAM_2_SIZE
+#ifdef PHYS_SDRAM_4
+ + PHYS_SDRAM_3_SIZE
+ + PHYS_SDRAM_4_SIZE
+#endif
+ );
}
#define FCLK_SPEED 1
-#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
- #define M_MDIV 0xC3
- #define M_PDIV 0x4
- #define M_SDIV 0x1
-#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
- #define M_MDIV 0xA1
- #define M_PDIV 0x3
- #define M_SDIV 0x1
+#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
+#define M_MDIV 0xC3
+#define M_PDIV 0x4
+#define M_SDIV 0x1
+#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
+#define M_MDIV 0xA1
+#define M_PDIV 0x3
+#define M_SDIV 0x1
#endif
#define USB_CLOCK 1
#if USB_CLOCK==0
- #define U_M_MDIV 0xA1
- #define U_M_PDIV 0x3
- #define U_M_SDIV 0x1
+#define U_M_MDIV 0xA1
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x1
#elif USB_CLOCK==1
- #define U_M_MDIV 0x48
- #define U_M_PDIV 0x3
- #define U_M_SDIV 0x2
+#define U_M_MDIV 0x48
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x2
#endif
-static inline
-void delay(unsigned long loops)
+static inline void delay (unsigned long loops)
{
- __asm__ volatile (
- "1:\n"
- "subs %0, %1, #1\n"
- "bne 1b"
- : "=r" (loops) : "0" (loops));
+ __asm__ volatile ("1:\n"
+ "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0" (loops));
}
/*
* Miscellaneous platform dependent initialisations
*/
-int board_init(bd_t *bd)
+int board_init (gd_t *gd)
{
- /* to reduce PLL lock time, adjust the LOCKTIME register */
- rLOCKTIME = 0xFFFFFF;
-
- /* configure MPLL */
- rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
-
- /* some delay between MPLL and UPLL */
- delay(4000);
-
- /* configure UPLL */
- rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
-
- /* some delay between MPLL and UPLL */
- delay(8000);
-
- /* set up the I/O ports */
- rGPACON = 0x007FFFFF;
- rGPBCON = 0x00044555;
- rGPBUP = 0x000007FF;
- rGPCCON = 0xAAAAAAAA;
- rGPCUP = 0x0000FFFF;
- rGPDCON = 0xAAAAAAAA;
- rGPDUP = 0x0000FFFF;
- rGPECON = 0xAAAAAAAA;
- rGPEUP = 0x0000FFFF;
- rGPFCON = 0x000055AA;
- rGPFUP = 0x000000FF;
- rGPGCON = 0xFF95FFBA;
- rGPGUP = 0x0000FFFF;
- rGPHCON = 0x002AFAAA;
- rGPHUP = 0x000007FF;
-
- /* arch number of SMDK2410-Board */
- bd->bi_arch_number = 193;
-
- /* adress of boot parameters */
- bd->bi_boot_params = 0x30000100;
-
- return 1;
+ /* to reduce PLL lock time, adjust the LOCKTIME register */
+ rLOCKTIME = 0xFFFFFF;
+
+ /* configure MPLL */
+ rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ delay (4000);
+
+ /* configure UPLL */
+ rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ delay (8000);
+
+ /* set up the I/O ports */
+ rGPACON = 0x007FFFFF;
+ rGPBCON = 0x00044555;
+ rGPBUP = 0x000007FF;
+ rGPCCON = 0xAAAAAAAA;
+ rGPCUP = 0x0000FFFF;
+ rGPDCON = 0xAAAAAAAA;
+ rGPDUP = 0x0000FFFF;
+ rGPECON = 0xAAAAAAAA;
+ rGPEUP = 0x0000FFFF;
+ rGPFCON = 0x000055AA;
+ rGPFUP = 0x000000FF;
+ rGPGCON = 0xFF95FFBA;
+ rGPGUP = 0x0000FFFF;
+ rGPHCON = 0x002AFAAA;
+ rGPHUP = 0x000007FF;
+
+ /* arch number of SMDK2410-Board */
+ bd->bi_arch_number = 193;
+
+ /* adress of boot parameters */
+ bd->bi_boot_params = 0x30000100;
+
+ return 0;
}
-int dram_init(bd_t *bd)
+int dram_init (gd_t *gd)
{
- bd->bi_dram[0].start = PHYS_SDRAM_1;
- bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
- return PHYS_SDRAM_1_SIZE;
+ bd->bi_dram[0].start = PHYS_SDRAM_1;
+ bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ return PHYS_SDRAM_1_SIZE;
}
-
LIB = libcommon.a
AOBJS =
-COBJS = main.o command.o environment.o bedbug.o \
- cmd_autoscript.o cmd_bedbug.o cmd_boot.o \
- cmd_bootm.o cmd_cache.o cmd_console.o cmd_date.o \
- cmd_dcr.o cmd_doc.o cmd_dtt.o cmd_eeprom.o cmd_elf.o \
- cmd_fdc.o cmd_flash.o cmd_i2c.o cmd_ide.o \
- cmd_immap.o cmd_jffs2.o cmd_mem.o cmd_mii.o \
- cmd_misc.o cmd_net.o cmd_nvedit.o cmd_pcmcia.o \
- cmd_reginfo.o cmd_scsi.o cmd_usb.o cmd_pci.o \
- console.o devices.o dlmalloc.o docecc.o \
- flash.o hush.o kgdb.o lists.o \
- miiphybb.o miiphyutil.o s_record.o \
- usb.o usb_kbd.o usb_storage.o soft_i2c.o
+COBJS = main.o altera.o command.o environment.o bedbug.o \
+ cmd_autoscript.o cmd_bedbug.o cmd_boot.o cmd_bootm.o \
+ cmd_cache.o cmd_console.o cmd_date.o cmd_dcr.o cmd_doc.o \
+ cmd_dtt.o cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_flash.o \
+ cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o cmd_jffs2.o \
+ cmd_mem.o cmd_mii.o cmd_misc.o cmd_net.o cmd_nvedit.o \
+ cmd_pcmcia.o cmd_reginfo.o cmd_scsi.o cmd_usb.o cmd_pci.o \
+ console.o devices.o dlmalloc.o docecc.o flash.o fpga.o \
+ hush.o kgdb.o lists.o miiphybb.o miiphyutil.o s_record.o \
+ soft_i2c.o spartan2.o usb.o usb_kbd.o usb_storage.o \
+ virtex2.o xilinx.o
+
# Temporary hack to get ARM working quickly
ifeq ($(ARCH),ppc)
COBJS += cmd_nvedit.o
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * 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
+ *
+ */
+
+/*
+ * Note that this is just boilerplate - there is no Altera support yet.
+ */
+
+
+/*
+ * Altera FPGA support
+ */
+#include <common.h>
+#include <fpga.h> /* Generic FPGA support */
+#include <altera.h> /* Altera specific stuff */
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+#ifdef FPGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if (CONFIG_FPGA & CFG_FPGA_ALTERA)
+
+/* ------------------------------------------------------------------------- */
+int altera_load( Altera_desc *desc, void *buf, size_t bsize )
+{
+ printf( "No support for Altera devices yet.\n" );
+ return FPGA_FAIL;
+}
+
+int altera_dump( Altera_desc *desc, void *buf, size_t bsize )
+{
+ printf( "No support for Altera devices yet.\n" );
+ return FPGA_FAIL;
+}
+
+int altera_info( Altera_desc *desc )
+{
+ printf( "No support for Altera devices yet.\n" );
+ return FPGA_FAIL;
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* CONFIG_FPGA & CFG_FPGA_ALTERA */
--- /dev/null
+/*
+ * (C) Copyright 2000, 2001
+ * 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
+ *
+ */
+
+/*
+ * FPGA support
+ */
+#include <common.h>
+#include <command.h>
+#include <cmd_fpga.h>
+#include <fpga.h>
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+#include <net.h>
+#endif
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+#ifdef FPGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if defined (CONFIG_FPGA) && ( CONFIG_COMMANDS & CFG_CMD_FPGA )
+
+/* Local functions */
+static void fpga_usage ( cmd_tbl_t *cmdtp );
+static int fpga_get_op( char *opstr );
+
+/* Local defines */
+#define FPGA_NONE -1
+#define FPGA_INFO 0
+#define FPGA_LOAD 1
+#define FPGA_DUMP 3
+
+/* ------------------------------------------------------------------------- */
+/* command form:
+ * fpga <op> <device number> <data addr> <datasize>
+ * where op is 'load', 'dump', or 'info'
+ * If there is no device number field, the fpga environment variable is used.
+ * If there is no data addr field, the fpgadata environment variable is used.
+ * The info command requires no data address field.
+ */
+int
+do_fpga (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[])
+{
+ int op, dev = FPGA_INVALID_DEVICE;
+ size_t data_size = 0;
+ void *fpga_data = NULL;
+ char *devstr = getenv("fpga");
+ char *datastr = getenv("fpgadata");
+
+ if ( devstr ) dev = (int)simple_strtoul( devstr, NULL, 16 );
+ if ( datastr ) fpga_data = (void *)simple_strtoul( datastr, NULL, 16 );
+
+ switch ( argc )
+ {
+ case 5: /* fpga <op> <dev> <data> <datasize> */
+ data_size = simple_strtoul( argv[4], NULL, 16 );
+ case 4: /* fpga <op> <dev> <data> */
+ fpga_data = (void *)simple_strtoul( argv[3], NULL, 16 );
+ PRINTF(__FUNCTION__": fpga_data = 0x%x\n", (uint)fpga_data );
+ case 3: /* fpga <op> <dev | data addr> */
+ dev = (int)simple_strtoul( argv[2], NULL, 16 );
+ PRINTF(__FUNCTION__": device = %d\n", dev );
+ /* FIXME - this is a really weak test */
+ if (( argc == 3 ) && ( dev > fpga_count() )) { /* must be buffer ptr */
+ PRINTF(__FUNCTION__": Assuming buffer pointer in arg 3\n");
+ fpga_data = (void *)dev;
+ PRINTF(__FUNCTION__": fpga_data = 0x%x\n", (uint)fpga_data );
+ dev = FPGA_INVALID_DEVICE; /* reset device num */
+ }
+ case 2: /* fpga <op> */
+ op = (int)fpga_get_op( argv[1] );
+ break;
+ default:
+ PRINTF(__FUNCTION__": Too many or too few args (%d)\n", argc );
+ op = FPGA_NONE; /* force usage display */
+ break;
+ }
+
+ switch ( op ) {
+ case FPGA_NONE:
+ fpga_usage( cmdtp );
+ break;
+
+ case FPGA_INFO:
+ fpga_info( dev );
+ break;
+
+ case FPGA_LOAD:
+ fpga_load( dev, fpga_data, data_size );
+ break;
+
+ case FPGA_DUMP:
+ fpga_dump( dev, fpga_data, data_size );
+ break;
+
+ default:
+ printf( "Unknown operation.\n" );
+ fpga_usage( cmdtp );
+ break;
+ }
+ return 0;
+}
+
+static void fpga_usage ( cmd_tbl_t *cmdtp )
+{
+ printf( "Usage:\n%s\n", cmdtp->usage );
+}
+
+/*
+ * Map op to supported operations. We don't use a table since we
+ * would just have to relocate it from flash anyway.
+ */
+static int fpga_get_op( char *opstr )
+{
+ int op = FPGA_NONE;
+
+ if (!strcmp ("info", opstr)) {
+ op = FPGA_INFO;
+ }
+ else if (!strcmp ("load", opstr)) {
+ op = FPGA_LOAD;
+ }
+ else if (!strcmp ("dump", opstr)) {
+ op = FPGA_DUMP;
+ }
+
+ if ( op == FPGA_NONE ) {
+ printf ("Unknown fpga operation \"%s\"\n", opstr);
+ }
+ return op;
+}
+
+#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */
int len = strlen(arg);
if (len > 2 && arg[len-2] == '.') {
switch(arg[len-1]) {
- case 'b':
- return 1;
- case 'w':
+ case 'b':
+ return 1;
+ case 'w':
return 2;
- case 'l':
+ case 'l':
return 4;
}
}
#endif
#if (CONFIG_COMMANDS & CFG_CMD_MEMORY)
+
+#ifdef CMD_MEM_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
static int mod_mem(cmd_tbl_t *, int, int, int, char *[]);
/* Display values from last command.
int do_mem_mm ( cmd_tbl_t *cmdtp, gd_t *gd,
int flag, int argc, char *argv[])
{
- return mod_mem (cmdtp, 1, flag, argc, argv);
+ return mod_mem (cmdtp, 1, flag, argc, argv);
}
int do_mem_nm ( cmd_tbl_t *cmdtp, gd_t *gd,
int flag, int argc, char *argv[])
}
}
-/* Just a quickie to walk through some memory.
+/*
+ * Perform a memory test. A more complete alternative test can be
+ * configured using CFG_ALT_MEMTEST. The complete test loops until
+ * interrupted by ctrl-c or by a failure of one of the sub-tests.
*/
-
-int do_mem_mtest (cmd_tbl_t *cmdtp, gd_t *gd,
- int flag, int argc, char *argv[])
+int do_mem_mtest (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[])
{
- ulong *addr, *start, *end;
+ vu_long *addr, *start, *end;
ulong val;
+ ulong readback;
+
+#if defined(CFG_ALT_MEMTEST)
+ vu_long addr_mask;
+ vu_long offset;
+ vu_long test_offset;
+ vu_long pattern;
+ vu_long temp;
+ vu_long anti_pattern;
+ vu_long num_words;
+ vu_long *dummy = NULL;
+ int j;
+ int iterations = 1;
+
+ static const ulong bitpattern[] = {
+ 0x00000001, /* single bit */
+ 0x00000003, /* two adjacent bits */
+ 0x00000007, /* three adjacent bits */
+ 0x0000000F, /* four adjacent bits */
+ 0x00000005, /* two non-adjacent bits */
+ 0x00000015, /* three non-adjacent bits */
+ 0x00000055, /* four non-adjacent bits */
+ 0xaaaaaaaa, /* alternating 1/0 */
+ };
+#else
+ ulong incr;
ulong pattern;
int rcode = 0;
+#endif
if (argc > 1) {
start = (ulong *)simple_strtoul(argv[1], NULL, 16);
pattern = 0;
}
+#if defined(CFG_ALT_MEMTEST)
printf ("Testing %08x ... %08x:\n", (uint)start, (uint)end);
+ PRINTF("%s:%d: start 0x%p end 0x%p\n",
+ __FUNCTION__, __LINE__, start, end);
+
+ for (;;) {
+ if (ctrlc()) {
+ putc ('\n');
+ return 1;
+ }
+
+ printf("Iteration: %6d\r", iterations);
+ PRINTF("Iteration: %6d\n", iterations);
+ iterations++;
+
+ /*
+ * Data line test: write a pattern to the first
+ * location, write the 1's complement to a 'parking'
+ * address (changes the state of the data bus so a
+ * floating bus doen't give a false OK), and then
+ * read the value back. Note that we read it back
+ * into a variable because the next time we read it,
+ * it might be right (been there, tough to explain to
+ * the quality guys why it prints a failure when the
+ * "is" and "should be" are obviously the same in the
+ * error message).
+ *
+ * Rather than exhaustively testing, we test some
+ * patterns by shifting '1' bits through a field of
+ * '0's and '0' bits through a field of '1's (i.e.
+ * pattern and ~pattern).
+ */
+ addr = start;
+ for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) {
+ val = bitpattern[j];
+ for(; val != 0; val <<= 1) {
+ *addr = val;
+ *dummy = ~val; /* clear the test data off of the bus */
+ readback = *addr;
+ if(readback != val) {
+ printf ("FAILURE (data line): "
+ "expected %08lx, actual %08lx\n",
+ val, readback);
+ }
+ *addr = ~val;
+ *dummy = val;
+ readback = *addr;
+ if(readback != ~val) {
+ printf ("FAILURE (data line): "
+ "Is %08lx, should be %08lx\n",
+ val, readback);
+ }
+ }
+ }
+
+ /*
+ * Based on code whose Original Author and Copyright
+ * information follows: Copyright (c) 1998 by Michael
+ * Barr. This software is placed into the public
+ * domain and may be used for any purpose. However,
+ * this notice must not be changed or removed and no
+ * warranty is either expressed or implied by its
+ * publication or distribution.
+ */
+
+ /*
+ * Address line test
+ *
+ * Description: Test the address bus wiring in a
+ * memory region by performing a walking
+ * 1's test on the relevant bits of the
+ * address and checking for aliasing.
+ * This test will find single-bit
+ * address failures such as stuck -high,
+ * stuck-low, and shorted pins. The base
+ * address and size of the region are
+ * selected by the caller.
+ *
+ * Notes: For best results, the selected base
+ * address should have enough LSB 0's to
+ * guarantee single address bit changes.
+ * For example, to test a 64-Kbyte
+ * region, select a base address on a
+ * 64-Kbyte boundary. Also, select the
+ * region size as a power-of-two if at
+ * all possible.
+ *
+ * Returns: 0 if the test succeeds, 1 if the test fails.
+ *
+ * ## NOTE ## Be sure to specify start and end
+ * addresses such that addr_mask has
+ * lots of bits set. For example an
+ * address range of 01000000 02000000 is
+ * bad while a range of 01000000
+ * 01ffffff is perfect.
+ */
+ addr_mask = ((ulong)end - (ulong)start)/sizeof(vu_long);
+ pattern = (vu_long) 0xaaaaaaaa;
+ anti_pattern = (vu_long) 0x55555555;
+
+ PRINTF("%s:%d: addr mask = 0x%.8lx\n",
+ __FUNCTION__, __LINE__,
+ addr_mask);
+ /*
+ * Write the default pattern at each of the
+ * power-of-two offsets.
+ */
+ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
+ start[offset] = pattern;
+ }
+
+ /*
+ * Check for address bits stuck high.
+ */
+ test_offset = 0;
+ start[test_offset] = anti_pattern;
+
+ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
+ temp = start[offset];
+ if (temp != pattern) {
+ printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:"
+ " expected 0x%.8lx, actual 0x%.8lx\n",
+ (ulong)&start[offset], pattern, temp);
+ return 1;
+ }
+ }
+ start[test_offset] = pattern;
+ /*
+ * Check for addr bits stuck low or shorted.
+ */
+ for (test_offset = 1; (test_offset & addr_mask) != 0; test_offset <<= 1) {
+ start[test_offset] = anti_pattern;
+
+ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
+ temp = start[offset];
+ if ((temp != pattern) && (offset != test_offset)) {
+ printf ("\nFAILURE: Address bit stuck low or shorted @"
+ " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n",
+ (ulong)&start[offset], pattern, temp);
+ return 1;
+ }
+ }
+ start[test_offset] = pattern;
+ }
+
+ /*
+ * Description: Test the integrity of a physical
+ * memory device by performing an
+ * increment/decrement test over the
+ * entire region. In the process every
+ * storage bit in the device is tested
+ * as a zero and a one. The base address
+ * and the size of the region are
+ * selected by the caller.
+ *
+ * Returns: 0 if the test succeeds, 1 if the test fails.
+ */
+ num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1;
+
+ /*
+ * Fill memory with a known pattern.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ start[offset] = pattern;
+ }
+
+ /*
+ * Check each location and invert it for the second pass.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ temp = start[offset];
+ if (temp != pattern) {
+ printf ("\nFAILURE (read/write) @ 0x%.8lx:"
+ " expected 0x%.8lx, actual 0x%.8lx)\n",
+ (ulong)&start[offset], pattern, temp);
+ return 1;
+ }
+
+ anti_pattern = ~pattern;
+ start[offset] = anti_pattern;
+ }
+
+ /*
+ * Check each location for the inverted pattern and zero it.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ anti_pattern = ~pattern;
+ temp = start[offset];
+ if (temp != anti_pattern) {
+ printf ("\nFAILURE (read/write): @ 0x%.8lx:"
+ " expected 0x%.8lx, actual 0x%.8lx)\n",
+ (ulong)&start[offset], anti_pattern, temp);
+ return 1;
+ }
+ start[offset] = 0;
+ }
+ }
+
+#else /* The original, quickie test */
+ incr = 1;
for (;;) {
if (ctrlc()) {
putc ('\n');
pattern, "");
for (addr=start,val=pattern; addr<end; addr++) {
- *addr = val++;
+ *addr = val;
+ val += incr;
}
printf("Reading...");
for (addr=start,val=pattern; addr<end; addr++) {
- if (*addr != val) {
+ readback = *addr;
+ if (readback != val) {
printf ("\nMem error @ 0x%08X: "
- "found %08lX, expected 0x%08lX\n",
- (uint)addr, *addr, val);
+ "found %08lX, expected %08lX\n",
+ (uint)addr, readback, val);
rcode = 1;
}
- val++;
+ val += incr;
}
- pattern++;
-
+ /*
+ * Flip the pattern each time to make lots of zeros and
+ * then, the next time, lots of ones. We decrement
+ * the "negative" patterns and increment the "positive"
+ * patterns to preserve this feature.
+ */
+ if(pattern & 0x80000000) {
+ pattern = -pattern; /* complement & increment */
+ }
+ else {
+ pattern = ~pattern;
+ }
+ incr = -incr;
}
return rcode;
-
+#endif
}
-
-
/* Modify memory.
*
* Syntax:
* '\0'. New entries are always added at the end. Deleting an entry
* shifts the remaining entries to the front. Replacing an entry is a
* combination of deleting the old value and adding the new one.
- *
+ *
* The environment is preceeded by a 32 bit CRC over the data part.
*
**************************************************************************
#endif
#ifdef CONFIG_EXTRA_ENV_SETTINGS
CONFIG_EXTRA_ENV_SETTINGS
-#endif
+#endif
"\0"
};
return(-1);
}
-#define SAVESTR(type) "Saving Enviroment to " #type "...\n"
+#define SAVESTR(type) "Saving Environment to " #type "...\n"
#ifdef CFG_ENV_IS_IN_NVRAM
#define NVRAM_SAVESTR SAVESTR(NVRAM)
#include <cmd_dcr.h> /* 4xx DCR register access */
#include <cmd_doc.h>
#include <cmd_jffs2.h>
+#include <cmd_fpga.h>
#include <cmd_bsp.h> /* board special functions */
CMD_TBL_FLERASE
CMD_TBL_FDC
CMD_TBL_FLINFO
+ CMD_TBL_FPGA
CMD_TBL_GETDCR
CMD_TBL_GO
CMD_TBL_HELP
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * 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
+ *
+ */
+
+/*
+ * Generic FPGA support
+ */
+#include <common.h> /* core ppcboot definitions */
+#include <xilinx.h> /* xilinx specific definitions */
+#include <altera.h> /* altera specific definitions */
+
+#if defined(CONFIG_FPGA)
+
+#if 0
+#define FPGA_DEBUG /* define FPGA_DEBUG to get debug messages */
+#endif
+
+/* Local definitions */
+#ifndef CONFIG_MAX_FPGA_DEVICES
+#define CONFIG_MAX_FPGA_DEVICES 5
+#endif
+
+/* Enable/Disable debug console messages */
+#ifdef FPGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/* Local static data */
+static ulong relocation_offset = 0;
+static int next_desc = FPGA_INVALID_DEVICE;
+static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
+
+/* Local static functions */
+static const fpga_desc * const fpga_get_desc( int devnum );
+static const fpga_desc * const fpga_validate( int devnum, void *buf,
+ size_t bsize, char *fn );
+static int fpga_dev_info( int devnum );
+
+
+/* ------------------------------------------------------------------------- */
+
+/* fpga_no_sup
+ * 'no support' message function
+ */
+static void fpga_no_sup( char *fn, char *msg )
+{
+ if ( fn && msg ) {
+ printf( "%s: No support for %s. CONFIG_FPGA defined as 0x%x.\n",
+ fn, msg, CONFIG_FPGA );
+ } else if ( msg ) {
+ printf( "No support for %s. CONFIG_FPGA defined as 0x%x.\n",
+ msg, CONFIG_FPGA );
+ } else {
+ printf( "No FPGA suport! CONFIG_FPGA defined as 0x%x.\n",
+ CONFIG_FPGA );
+ }
+}
+
+
+/* fpga_get_desc
+ * map a device number to a descriptor
+ */
+static const fpga_desc * const fpga_get_desc( int devnum )
+{
+ fpga_desc *desc = (fpga_desc * )NULL;
+
+ if (( devnum >= 0 ) && (devnum < next_desc )) {
+ desc = &desc_table[devnum];
+ PRINTF( "%s: found fpga descriptor #%d @ 0x%p\n",
+ __FUNCTION__, devnum, desc );
+ }
+
+ return desc;
+}
+
+
+/* fpga_validate
+ * generic parameter checking code
+ */
+static const fpga_desc * const fpga_validate( int devnum, void *buf,
+ size_t bsize, char *fn )
+{
+ const fpga_desc * const desc = fpga_get_desc( devnum );
+
+ if ( !desc ) {
+ printf( "%s: Invalid device number %d\n", fn, devnum );
+ }
+
+ if ( !buf ) {
+ printf( "%s: Null buffer.\n", fn );
+ return (fpga_desc * const)NULL;
+ }
+ if ( !bsize ) {
+ printf( "%s: Null buffer size.\n", fn );
+ return (fpga_desc * const)NULL;
+ }
+
+ return desc;
+}
+
+
+/* fpga_dev_info
+ * generic multiplexing code
+ */
+static int fpga_dev_info( int devnum )
+{
+ int ret_val = FPGA_FAIL; /* assume failure */
+ const fpga_desc * const desc = fpga_get_desc( devnum );
+
+ if ( desc ) {
+ PRINTF( "%s: Device Descriptor @ 0x%p\n",
+ __FUNCTION__, desc->devdesc );
+
+ switch ( desc->devtype ) {
+ case fpga_xilinx:
+#if CONFIG_FPGA & CFG_FPGA_XILINX
+ printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc );
+ ret_val = xilinx_info( desc->devdesc );
+#else
+ fpga_no_sup( __FUNCTION__, "Xilinx devices" );
+#endif
+ break;
+ case fpga_altera:
+#if CONFIG_FPGA & CFG_FPGA_ALTERA
+ printf( "Altera Device\nDescriptor @ 0x%p\n", desc );
+ ret_val = altera_info( desc->devdesc );
+#else
+ fpga_no_sup( __FUNCTION__, "Altera devices" );
+#endif
+ break;
+ default:
+ printf( "%s: Invalid or unsupported device type %d\n",
+ __FUNCTION__, desc->devtype );
+ }
+ } else {
+ printf( "%s: Invalid device number %d\n",
+ __FUNCTION__, devnum );
+ }
+
+ return ret_val;
+}
+
+
+/* fpga_reloc
+ * generic multiplexing code
+ */
+int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off )
+{
+ int ret_val = FPGA_FAIL;
+
+ PRINTF( "%s: Relocating Device of type %d @ 0x%p with offset %lx\n",
+ __FUNCTION__, devtype, desc, reloc_off );
+
+ switch ( devtype ) {
+ case fpga_xilinx:
+#if CONFIG_FPGA & CFG_FPGA_XILINX
+ ret_val = xilinx_reloc( desc, reloc_off );
+#else
+ fpga_no_sup( __FUNCTION__, "Xilinx devices" );
+#endif
+ break;
+ case fpga_altera:
+#if CONFIG_FPGA & CFG_FPGA_ALTERA
+ ret_val = altera_reloc( desc, reloc_off );
+#else
+ fpga_no_sup( __FUNCTION__, "Altera devices" );
+#endif
+ break;
+ default:
+ printf( "%s: Invalid or unsupported device type %d\n",
+ __FUNCTION__, devtype );
+ }
+
+ return ret_val;
+}
+
+/* ------------------------------------------------------------------------- */
+/* fgpa_init is usually called from misc_init_r() and MUST be called
+ * before any of the other fpga functions are used.
+ */
+void fpga_init( ulong reloc_off )
+{
+ relocation_offset = reloc_off;
+ next_desc = 0;
+ memset( desc_table, 0, sizeof(desc_table));
+
+ PRINTF( "%s: CONFIG_FPGA = 0x%x\n", __FUNCTION__, CONFIG_FPGA );
+#if 0
+ PRINTF( "%s: CFG_FPGA_XILINX = 0x%x\n", __FUNCTION__, CFG_FPGA_XILINX );
+ PRINTF( "%s: CFG_FPGA_ALTERA = 0x%x\n", __FUNCTION__, CFG_FPGA_ALTERA );
+#endif
+}
+
+/* fpga_count
+ * Basic interface function to get the current number of devices available.
+ */
+const int fpga_count( void )
+{
+ return next_desc;
+}
+
+/* fpga_add
+ * Attempts to relocate the device/board specific interface code
+ * to the proper RAM locations and adds the device descriptor to
+ * the device table.
+ */
+int fpga_add( fpga_type devtype, void *desc )
+{
+ int devnum = FPGA_INVALID_DEVICE;
+
+ if ( next_desc < 0 ) {
+ printf( "%s: FPGA support not initialized!\n", __FUNCTION__ );
+ } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) {
+ if ( desc ) {
+ if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) {
+ if ( fpga_reloc( devtype, desc, relocation_offset )
+ == FPGA_SUCCESS ) {
+ devnum = next_desc;
+ desc_table[next_desc].devtype = devtype;
+ desc_table[next_desc++].devdesc = desc;
+ } else {
+ printf( "%s: Unable to relocate device interface table!\n",
+ __FUNCTION__ );
+ }
+ } else {
+ printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ );
+ }
+ } else {
+ printf( "%s: NULL device descriptor\n", __FUNCTION__ );
+ }
+ } else {
+ printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype );
+ }
+
+ return devnum;
+}
+
+/*
+ * Generic multiplexing code
+ */
+int fpga_load( int devnum, void *buf, size_t bsize )
+{
+ int ret_val = FPGA_FAIL; /* assume failure */
+ const fpga_desc * const desc = fpga_validate( devnum, buf, bsize, __FUNCTION__ );
+
+ if ( desc ) {
+ switch ( desc->devtype ) {
+ case fpga_xilinx:
+#if CONFIG_FPGA & CFG_FPGA_XILINX
+ ret_val = xilinx_load( desc->devdesc, buf, bsize );
+#else
+ fpga_no_sup( __FUNCTION__, "Xilinx devices" );
+#endif
+ break;
+ case fpga_altera:
+#if CONFIG_FPGA & CFG_FPGA_ALTERA
+ ret_val = altera_load( desc->devdesc, buf, bsize );
+#else
+ fpga_no_sup( __FUNCTION__, "Altera devices" );
+#endif
+ break;
+ default:
+ printf( "%s: Invalid or unsupported device type %d\n",
+ __FUNCTION__, desc->devtype );
+ }
+ }
+
+ return ret_val;
+}
+
+/* fpga_dump
+ * generic multiplexing code
+ */
+int fpga_dump( int devnum, void *buf, size_t bsize )
+{
+ int ret_val = FPGA_FAIL; /* assume failure */
+ const fpga_desc * const desc = fpga_validate( devnum, buf, bsize, __FUNCTION__ );
+
+ if ( desc ) {
+ switch ( desc->devtype ) {
+ case fpga_xilinx:
+#if CONFIG_FPGA & CFG_FPGA_XILINX
+ ret_val = xilinx_dump( desc->devdesc, buf, bsize );
+#else
+ fpga_no_sup( __FUNCTION__, "Xilinx devices" );
+#endif
+ break;
+ case fpga_altera:
+#if CONFIG_FPGA & CFG_FPGA_ALTERA
+ ret_val = altera_dump( desc->devdesc, buf, bsize );
+#else
+ fpga_no_sup( __FUNCTION__, "Altera devices" );
+#endif
+ break;
+ default:
+ printf( "%s: Invalid or unsupported device type %d\n",
+ __FUNCTION__, desc->devtype );
+ }
+ }
+
+ return ret_val;
+}
+
+
+/* fpga_info
+ * front end to fpga_dev_info. If devnum is invalid, report on all
+ * available devices.
+ */
+int fpga_info( int devnum )
+{
+ if ( devnum == FPGA_INVALID_DEVICE ) {
+ if ( next_desc > 0 ) {
+ int dev;
+
+ for ( dev = 0; dev < next_desc; dev++ ) {
+ fpga_dev_info( dev );
+ }
+ return FPGA_SUCCESS;
+ } else {
+ printf( "%s: No FPGA devices available.\n", __FUNCTION__ );
+ return FPGA_FAIL;
+ }
+ }
+ else return fpga_dev_info( devnum );
+}
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* CONFIG_FPGA */
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
int shift;
- PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len%d\n",
+ PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
chip, addr, alen, buffer, len);
#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
int shift, failures = 0;
+
+ PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n",
+ chip, addr, alen, buffer, len);
send_start();
if(write_byte(chip << 1)) { /* write cycle */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * 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 ppcboot definitions */
+#include <spartan2.h> /* Spartan-II device family */
+
+#if (CONFIG_FPGA & (CFG_XILINX | CFG_SPARTAN2))
+
+/* Define FPGA_DEBUG to get debug printf's */
+#ifdef FPGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#undef CFG_FPGA_CHECK_BUSY
+#define CFG_FPGA_PROG_FEEDBACK
+
+/* 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 10
+#endif
+
+static int Spartan2_sp_load( Xilinx_desc *desc, void *buf, size_t bsize );
+static int Spartan2_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+/* static int Spartan2_sp_info( Xilinx_desc *desc ); */
+static int Spartan2_sp_reloc( Xilinx_desc *desc, ulong reloc_offset );
+
+static int Spartan2_ss_load( Xilinx_desc *desc, void *buf, size_t bsize );
+static int Spartan2_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+/* static int Spartan2_ss_info( Xilinx_desc *desc ); */
+static int Spartan2_ss_reloc( Xilinx_desc *desc, ulong reloc_offset );
+
+/* ------------------------------------------------------------------------- */
+/* Spartan-II Generic Implementation */
+int Spartan2_load (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL;
+
+ switch (desc->iface) {
+ case slave_serial:
+ PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
+ ret_val = Spartan2_ss_load (desc, buf, bsize);
+ break;
+
+ case slave_parallel:
+ PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
+ ret_val = Spartan2_sp_load (desc, buf, bsize);
+ break;
+
+ default:
+ printf ("%s: Unsupported interface type, %d\n",
+ __FUNCTION__, desc->iface);
+ }
+
+ return ret_val;
+}
+
+int Spartan2_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL;
+
+ switch (desc->iface) {
+ case slave_serial:
+ PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
+ ret_val = Spartan2_ss_dump (desc, buf, bsize);
+ break;
+
+ case slave_parallel:
+ PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
+ ret_val = Spartan2_sp_dump (desc, buf, bsize);
+ break;
+
+ default:
+ printf ("%s: Unsupported interface type, %d\n",
+ __FUNCTION__, desc->iface);
+ }
+
+ return ret_val;
+}
+
+int Spartan2_info( Xilinx_desc *desc )
+{
+ return FPGA_SUCCESS;
+}
+
+
+int Spartan2_reloc (Xilinx_desc * desc, ulong reloc_offset)
+{
+ int ret_val = FPGA_FAIL; /* assume a failure */
+
+ if (desc->family != Xilinx_Spartan2) {
+ printf ("%s: Unsupported family type, %d\n",
+ __FUNCTION__, desc->family);
+ return FPGA_FAIL;
+ } else
+ switch (desc->iface) {
+ case slave_serial:
+ ret_val = Spartan2_ss_reloc (desc, reloc_offset);
+ break;
+
+ case slave_parallel:
+ ret_val = Spartan2_sp_reloc (desc, reloc_offset);
+ break;
+
+ default:
+ printf ("%s: Unsupported interface type, %d\n",
+ __FUNCTION__, desc->iface);
+ }
+
+ return ret_val;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* Spartan-II Slave Parallel Generic Implementation */
+
+static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL; /* assume the worst */
+ Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns;
+
+ PRINTF ("%s: start with interface functions @ 0x%p\n",
+ __FUNCTION__, fn);
+
+ if (fn) {
+ size_t bytecount = 0;
+ unsigned char *data = (unsigned char *) buf;
+ 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"
+ "pre: 0x%p\n"
+ "pgm:\t0x%p\n"
+ "init:\t0x%p\n"
+ "err:\t0x%p\n"
+ "clk:\t0x%p\n"
+ "cs:\t0x%p\n"
+ "wr:\t0x%p\n"
+ "read data:\t0x%p\n"
+ "write data:\t0x%p\n"
+ "busy:\t0x%p\n"
+ "abort:\t0x%p\n",
+ "post:\t0x%p\n\n",
+ __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
+ fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
+ fn->abort, fn->post);
+
+ /*
+ * This code is designed to emulate the "Express Style"
+ * Continuous Data Loading in Slave Parallel Mode for
+ * the Spartan-II Family.
+ */
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ printf ("Loading FPGA Device %d...\n", cookie);
+#endif
+ /*
+ * Run the pre configuration function if there is one.
+ */
+ if (*fn->pre) {
+ (*fn->pre) (cookie);
+ }
+
+ /* Establish the initial state */
+ (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */
+
+ /* Get ready for the burn */
+ CONFIG_FPGA_DELAY ();
+ (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */
+
+ ts = get_timer (0); /* get current time */
+ /* Now wait for INIT and BUSY to go high */
+ do {
+ CONFIG_FPGA_DELAY ();
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ puts ("** Timeout waiting for INIT to clear.\n");
+ (*fn->abort) (cookie); /* abort the burn */
+ return FPGA_FAIL;
+ }
+ } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
+
+ (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */
+ (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */
+ (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
+
+ /* Load the data */
+ while (bytecount < bsize) {
+ /* XXX - do we check for an Ctrl-C press in here ??? */
+ /* XXX - Check the error bit? */
+
+ (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
+
+#ifdef CFG_FPGA_CHECK_BUSY
+ ts = get_timer (0); /* get current time */
+ while ((*fn->busy) (cookie)) {
+ /* XXX - we should have a check in here somewhere to
+ * make sure we aren't busy forever... */
+
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
+
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ puts ("** Timeout waiting for BUSY to clear.\n");
+ (*fn->abort) (cookie); /* abort the burn */
+ return FPGA_FAIL;
+ }
+ }
+#endif
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ if (bytecount % (bsize / 40) == 0)
+ putc ('.'); /* let them know we are alive */
+#endif
+ }
+
+ CONFIG_FPGA_DELAY ();
+ (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */
+ (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ putc ('\n'); /* terminate the dotted line */
+#endif
+
+ /* now check for done signal */
+ ts = get_timer (0); /* get current time */
+ ret_val = FPGA_SUCCESS;
+ while ((*fn->done) (cookie) == FPGA_FAIL) {
+ /* XXX - we should have a check in here somewhere to
+ * make sure we aren't busy forever... */
+
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
+
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ puts ("** Timeout waiting for DONE to clear.\n");
+ (*fn->abort) (cookie); /* abort the burn */
+ ret_val = FPGA_FAIL;
+ break;
+ }
+ }
+
+ if (ret_val == FPGA_SUCCESS) {
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ puts ("Done.\n");
+#endif
+ }
+ /*
+ * Run the post configuration function if there is one.
+ */
+ if (*fn->post) {
+ (*fn->post) (cookie);
+ }
+
+ else {
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ puts ("Fail.\n");
+#endif
+ }
+
+ } else {
+ printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ }
+
+ return ret_val;
+}
+
+static int Spartan2_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL; /* assume the worst */
+ Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns;
+
+ if (fn) {
+ unsigned char *data = (unsigned char *) buf;
+ size_t bytecount = 0;
+ int cookie = desc->cookie; /* make a local copy */
+
+ printf ("Starting Dump of FPGA Device %d...\n", cookie);
+
+ (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */
+ (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
+
+ /* dump the data */
+ while (bytecount < bsize) {
+ /* XXX - do we check for an Ctrl-C press in here ??? */
+
+ (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
+ (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
+ (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ if (bytecount % (bsize / 40) == 0)
+ putc ('.'); /* let them know we are alive */
+#endif
+ }
+
+ (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */
+ (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
+ (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ putc ('\n'); /* terminate the dotted line */
+#endif
+ puts ("Done.\n");
+
+ /* XXX - checksum the data? */
+ } else {
+ printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ }
+
+ return ret_val;
+}
+
+
+static int Spartan2_sp_reloc (Xilinx_desc * desc, ulong reloc_offset)
+{
+ int ret_val = FPGA_FAIL; /* assume the worst */
+ Xilinx_Spartan2_Slave_Parallel_fns *fn_r, *fn =
+ (Xilinx_Spartan2_Slave_Parallel_fns *) (desc->iface_fns);
+
+ if (fn) {
+ ulong addr;
+
+ /* Get the relocated table address */
+ addr = (ulong) fn + reloc_offset;
+ fn_r = (Xilinx_Spartan2_Slave_Parallel_fns *) addr;
+
+ if (!fn_r->relocated) {
+
+ if (memcmp (fn_r, fn,
+ sizeof (Xilinx_Spartan2_Slave_Parallel_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 = (Xilinx_pre_fn) addr;
+
+ addr = (ulong) (fn->pgm) + reloc_offset;
+ fn_r->pgm = (Xilinx_pgm_fn) addr;
+
+ addr = (ulong) (fn->init) + reloc_offset;
+ fn_r->init = (Xilinx_init_fn) addr;
+
+ addr = (ulong) (fn->done) + reloc_offset;
+ fn_r->done = (Xilinx_done_fn) addr;
+
+ addr = (ulong) (fn->clk) + reloc_offset;
+ fn_r->clk = (Xilinx_clk_fn) addr;
+
+ addr = (ulong) (fn->err) + reloc_offset;
+ fn_r->err = (Xilinx_err_fn) addr;
+
+ addr = (ulong) (fn->cs) + reloc_offset;
+ fn_r->cs = (Xilinx_cs_fn) addr;
+
+ addr = (ulong) (fn->wr) + reloc_offset;
+ fn_r->wr = (Xilinx_wr_fn) addr;
+
+ addr = (ulong) (fn->rdata) + reloc_offset;
+ fn_r->rdata = (Xilinx_rdata_fn) addr;
+
+ addr = (ulong) (fn->wdata) + reloc_offset;
+ fn_r->wdata = (Xilinx_wdata_fn) addr;
+
+ addr = (ulong) (fn->busy) + reloc_offset;
+ fn_r->busy = (Xilinx_busy_fn) addr;
+
+ addr = (ulong) (fn->abort) + reloc_offset;
+ fn_r->abort = (Xilinx_abort_fn) addr;
+
+ addr = (ulong) (fn->post) + reloc_offset;
+ fn_r->post = (Xilinx_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;
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ printf ("%s: Slave Serial Loading is still unsupported\n",
+ __FUNCTION__);
+ return FPGA_FAIL;
+}
+
+static int Spartan2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ printf ("%s: Slave Serial Dumping is still unsupported\n",
+ __FUNCTION__);
+ return FPGA_FAIL;
+}
+
+static int Spartan2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset)
+{
+ int ret_val = FPGA_FAIL; /* assume the worst */
+ Xilinx_Spartan2_Slave_Serial_fns *fn =
+ (Xilinx_Spartan2_Slave_Serial_fns *) (desc->iface_fns);
+
+ if (fn) {
+ printf ("%s: Slave Serial Loading is still unsupported\n",
+ __FUNCTION__);
+ } else {
+ printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ }
+
+ return ret_val;
+
+}
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * 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
+ *
+ */
+
+/*
+ * Configuration support for Xilinx Virtex2 devices. Based
+ * on spartan2.c (Rich Ireland, rireland@enterasys.com).
+ */
+
+#include <common.h>
+#include <virtex2.h>
+
+#if (CONFIG_FPGA & (CFG_XILINX | CFG_VIRTEX2))
+
+#ifdef FPGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/*
+ * If the SelectMap interface can be overrun by the processor, define
+ * CFG_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration
+ * file and add board-specific support for checking BUSY status. By default,
+ * assume that the SelectMap interface cannot be overrun.
+ */
+#ifndef CFG_FPGA_CHECK_BUSY
+#undef CFG_FPGA_CHECK_BUSY
+#endif
+
+#ifndef CONFIG_FPGA_DELAY
+#define CONFIG_FPGA_DELAY()
+#endif
+
+#ifndef CFG_FPGA_PROG_FEEDBACK
+#define CFG_FPGA_PROG_FEEDBACK
+#endif
+
+/*
+ * Don't allow config cycle to be interrupted
+ */
+#ifndef CFG_FPGA_CHECK_CTRLC
+#undef CFG_FPGA_CHECK_CTRLC
+#endif
+
+/*
+ * Check for errors during configuration by default
+ */
+#ifndef CFG_FPGA_CHECK_ERROR
+#define CFG_FPGA_CHECK_ERROR
+#endif
+
+/*
+ * The default timeout in mS for INIT_B to deassert after PROG_B has
+ * been deasserted. Per the latest Virtex II Handbook (page 347), the
+ * max time from PORG_B deassertion to INIT_B deassertion is 4uS per
+ * data frame for the XC2V8000. The XC2V8000 has 2860 data frames
+ * which yields 11.44 mS. So let's make it bigger in order to handle
+ * an XC2V1000, if anyone can ever get ahold of one.
+ */
+#ifndef CFG_FPGA_WAIT_INIT
+#define CFG_FPGA_WAIT_INIT 500 /* time in milliseconds */
+#endif
+
+/*
+ * The default timeout for waiting for BUSY to deassert during configuration.
+ * This is normally not necessary since for most reasonable configuration
+ * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
+ */
+#ifndef CFG_FPGA_WAIT_BUSY
+#define CFG_FPGA_WAIT_BUSY 5 /* time in milliseconds */
+#endif
+
+/* Default timeout for waiting for FPGA to enter operational mode after
+ * configuration data has been written.
+ */
+#ifndef CFG_FPGA_WAIT_CONFIG
+#define CFG_FPGA_WAIT_CONFIG 200 /* time in milliseconds */
+#endif
+
+static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize);
+static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize);
+static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset);
+
+static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize);
+static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize);
+static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset);
+
+int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL;
+
+ switch (desc->iface) {
+ case slave_serial:
+ PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
+ ret_val = Virtex2_ss_load (desc, buf, bsize);
+ break;
+
+ case slave_selectmap:
+ PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
+ ret_val = Virtex2_ssm_load (desc, buf, bsize);
+ break;
+
+ default:
+ printf ("%s: Unsupported interface type, %d\n",
+ __FUNCTION__, desc->iface);
+ }
+ return ret_val;
+}
+
+int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL;
+
+ switch (desc->iface) {
+ case slave_serial:
+ PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
+ ret_val = Virtex2_ss_dump (desc, buf, bsize);
+ break;
+
+ case slave_parallel:
+ PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
+ ret_val = Virtex2_ssm_dump (desc, buf, bsize);
+ break;
+
+ default:
+ printf ("%s: Unsupported interface type, %d\n",
+ __FUNCTION__, desc->iface);
+ }
+ return ret_val;
+}
+
+int Virtex2_info (Xilinx_desc * desc)
+{
+ return FPGA_SUCCESS;
+}
+
+int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset)
+{
+ int ret_val = FPGA_FAIL;
+
+ if (desc->family != Xilinx_Virtex2) {
+ printf ("%s: Unsupported family type, %d\n",
+ __FUNCTION__, desc->family);
+ return FPGA_FAIL;
+ } else
+ switch (desc->iface) {
+ case slave_serial:
+ ret_val = Virtex2_ss_reloc (desc, reloc_offset);
+ break;
+
+ case slave_selectmap:
+ ret_val = Virtex2_ssm_reloc (desc, reloc_offset);
+ break;
+
+ default:
+ printf ("%s: Unsupported interface type, %d\n",
+ __FUNCTION__, desc->iface);
+ }
+ return ret_val;
+}
+
+/*
+ * Virtex-II Slave SelectMap configuration loader. Configuration via
+ * SelectMap is as follows:
+ * 1. Set the FPGA's PROG_B line low.
+ * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high.
+ * 3. Write data to the SelectMap port. If INIT_B goes low at any time
+ * this process, a configuration error (most likely CRC failure) has
+ * ocurred. At this point a status word may be read from the
+ * SelectMap interface to determine the source of the problem (You
+ * could, for instance, put this in you 'abort' function handler).
+ * 4. After all data has been written, test the state of the FPGA
+ * INIT_B and DONE lines. If both are high, configuration has
+ * succeeded. Congratulations!
+ */
+static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL;
+ Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
+
+ PRINTF ("%s:%d: Start with interface functions @ 0x%p\n",
+ __FUNCTION__, __LINE__, fn);
+
+ if (fn) {
+ size_t bytecount = 0;
+ unsigned char *data = (unsigned char *) buf;
+ int cookie = desc->cookie;
+ unsigned long ts;
+
+ /* Gotta split this one up (so the stack won't blow??) */
+ PRINTF ("%s:%d: Function Table:\n"
+ " base 0x%p\n"
+ " struct 0x%p\n"
+ " pre 0x%p\n"
+ " prog 0x%p\n"
+ " init 0x%p\n"
+ " error 0x%p\n",
+ __FUNCTION__, __LINE__,
+ &fn, fn, fn->pre, fn->pgm, fn->init, fn->err);
+ PRINTF (" clock 0x%p\n"
+ " cs 0x%p\n"
+ " write 0x%p\n"
+ " rdata 0x%p\n"
+ " wdata 0x%p\n"
+ " busy 0x%p\n"
+ " abort 0x%p\n"
+ " post 0x%p\n\n",
+ fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata,
+ fn->busy, fn->abort, fn->post);
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ printf ("Initializing FPGA Device %d...\n", cookie);
+#endif
+ /*
+ * Run the pre configuration function if there is one.
+ */
+ if (*fn->pre) {
+ (*fn->pre) (cookie);
+ }
+
+ /*
+ * Assert the program line. The minimum pulse width for
+ * Virtex II devices is 300 nS (Tprogram parameter in datasheet).
+ * There is no maximum value for the pulse width. Check to make
+ * sure that INIT_B goes low after assertion of PROG_B
+ */
+ (*fn->pgm) (TRUE, TRUE, cookie);
+ udelay (10);
+ ts = get_timer (0);
+ do {
+ if (get_timer (ts) > CFG_FPGA_WAIT_INIT) {
+ printf ("%s:%d: ** Timeout after %d mS waiting for INIT"
+ " to assert.\n", __FUNCTION__, __LINE__,
+ CFG_FPGA_WAIT_INIT);
+ (*fn->abort) (cookie);
+ return FPGA_FAIL;
+ }
+ } while (!(*fn->init) (cookie));
+
+ (*fn->pgm) (FALSE, TRUE, cookie);
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (TRUE, TRUE, cookie);
+
+ /*
+ * Start a timer and wait for INIT_B to go high
+ */
+ ts = get_timer (0);
+ do {
+ CONFIG_FPGA_DELAY ();
+ if (get_timer (ts) > CFG_FPGA_WAIT_INIT) {
+ printf ("%s:%d: ** Timeout after %d mS waiting for INIT"
+ " to deassert.\n", __FUNCTION__, __LINE__,
+ CFG_FPGA_WAIT_INIT);
+ (*fn->abort) (cookie);
+ return FPGA_FAIL;
+ }
+ } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
+
+ (*fn->wr) (TRUE, TRUE, cookie);
+ (*fn->cs) (TRUE, TRUE, cookie);
+
+ udelay (10000);
+
+ /*
+ * Load the data byte by byte
+ */
+ while (bytecount < bsize) {
+#ifdef CFG_FPGA_CHECK_CTRLC
+ if (ctrlc ()) {
+ (*fn->abort) (cookie);
+ return FPGA_FAIL;
+ }
+#endif
+#ifdef CFG_FPGA_CHECK_ERROR
+ if ((*fn->init) (cookie)) {
+ printf ("%s:%d: ** Error: INIT asserted during"
+ " configuration\n", __FUNCTION__, __LINE__);
+ (*fn->abort) (cookie);
+ return FPGA_FAIL;
+ }
+#endif
+ (*fn->wdata) (data[bytecount++], TRUE, cookie);
+ CONFIG_FPGA_DELAY ();
+
+ /*
+ * Cycle the clock pin
+ */
+ (*fn->clk) (FALSE, TRUE, cookie);
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk) (TRUE, TRUE, cookie);
+
+#ifdef CFG_FPGA_CHECK_BUSY
+ ts = get_timer (0);
+ while ((*fn->busy) (cookie)) {
+ if (get_timer (ts) > CFG_FPGA_WAIT_BUSY) {
+ printf ("%s:%d: ** Timeout after %d mS waiting for"
+ " BUSY to deassert\n",
+ __FUNCTION__, __LINE__, CFG_FPGA_WAIT_BUSY);
+ (*fn->abort) (cookie);
+ return FPGA_FAIL;
+ }
+ }
+#endif
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ if (bytecount % (bsize / 40) == 0)
+ putc ('.');
+#endif
+ }
+
+ /*
+ * Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
+ */
+ CONFIG_FPGA_DELAY ();
+ (*fn->cs) (FALSE, TRUE, cookie);
+ (*fn->wr) (FALSE, TRUE, cookie);
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ putc ('\n');
+#endif
+
+ /*
+ * Check for successful configuration. FPGA INIT_B and DONE should
+ * both be high upon successful configuration.
+ */
+ ts = get_timer (0);
+ ret_val = FPGA_SUCCESS;
+ while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) {
+ if (get_timer (ts) > CFG_FPGA_WAIT_CONFIG) {
+ printf ("%s:%d: ** Timeout after %d mS waiting for DONE to"
+ "assert and INIT to deassert\n",
+ __FUNCTION__, __LINE__, CFG_FPGA_WAIT_CONFIG);
+ (*fn->abort) (cookie);
+ ret_val = FPGA_FAIL;
+ break;
+ }
+ }
+
+ if (ret_val == FPGA_SUCCESS) {
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ printf ("Initialization of FPGA device %d complete\n", cookie);
+#endif
+ /*
+ * Run the post configuration function if there is one.
+ */
+ if (*fn->post) {
+ (*fn->post) (cookie);
+ }
+ } else {
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ printf ("** Initialization of FPGA device %d FAILED\n",
+ cookie);
+#endif
+ }
+ } else {
+ printf ("%s:%d: NULL Interface function table!\n",
+ __FUNCTION__, __LINE__);
+ }
+ return ret_val;
+}
+
+/*
+ * Read the FPGA configuration data
+ */
+static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL;
+ Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
+
+ if (fn) {
+ unsigned char *data = (unsigned char *) buf;
+ size_t bytecount = 0;
+ int cookie = desc->cookie;
+
+ printf ("Starting Dump of FPGA Device %d...\n", cookie);
+
+ (*fn->cs) (TRUE, TRUE, cookie);
+ (*fn->clk) (TRUE, TRUE, cookie);
+
+ while (bytecount < bsize) {
+#ifdef CFG_FPGA_CHECK_CTRLC
+ if (ctrlc ()) {
+ (*fn->abort) (cookie);
+ return FPGA_FAIL;
+ }
+#endif
+ /*
+ * Cycle the clock and read the data
+ */
+ (*fn->clk) (FALSE, TRUE, cookie);
+ (*fn->clk) (TRUE, TRUE, cookie);
+ (*fn->rdata) (&(data[bytecount++]), cookie);
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ if (bytecount % (bsize / 40) == 0)
+ putc ('.');
+#endif
+ }
+
+ /*
+ * Deassert CS_B and cycle the clock to deselect the device.
+ */
+ (*fn->cs) (FALSE, FALSE, cookie);
+ (*fn->clk) (FALSE, TRUE, cookie);
+ (*fn->clk) (TRUE, TRUE, cookie);
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ putc ('\n');
+#endif
+ puts ("Done.\n");
+ } else {
+ printf ("%s:%d: NULL Interface function table!\n",
+ __FUNCTION__, __LINE__);
+ }
+ return ret_val;
+}
+
+/*
+ * Relocate the addresses in the function table from FLASH (or ROM,
+ * or whatever) to RAM.
+ */
+static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset)
+{
+ ulong addr;
+ int ret_val = FPGA_FAIL;
+ Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn =
+ (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns);
+
+ if (fn) {
+ /*
+ * Get the relocated table address
+ */
+ addr = (ulong) fn + reloc_offset;
+ fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr;
+
+ /*
+ * Check to see if the table has already been relocated. If not, do
+ * a sanity check to make sure there is a faithful copy of the
+ * FLASH based function table in RAM, then adjust the table.
+ */
+ if (!fn_r->relocated) {
+ if (memcmp
+ (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns))
+ == 0) {
+ desc->iface_fns = fn_r;
+ } else {
+ PRINTF ("%s:%d: Invalid function table at 0x%p\n",
+ __FUNCTION__, __LINE__, fn_r);
+ return FPGA_FAIL;
+ }
+
+ PRINTF ("%s:%d: Relocating descriptor at 0x%p\n",
+ __FUNCTION__, __LINE__, desc);
+
+ addr = (ulong) (fn->pre) + reloc_offset;
+ fn_r->pre = (Xilinx_pre_fn) addr;
+ addr = (ulong) (fn->pgm) + reloc_offset;
+ fn_r->pgm = (Xilinx_pgm_fn) addr;
+ addr = (ulong) (fn->init) + reloc_offset;
+ fn_r->init = (Xilinx_init_fn) addr;
+ addr = (ulong) (fn->done) + reloc_offset;
+ fn_r->done = (Xilinx_done_fn) addr;
+ addr = (ulong) (fn->err) + reloc_offset;
+ fn_r->err = (Xilinx_err_fn) addr;
+ addr = (ulong) (fn->clk) + reloc_offset;
+ fn_r->clk = (Xilinx_clk_fn) addr;
+ addr = (ulong) (fn->cs) + reloc_offset;
+ fn_r->cs = (Xilinx_cs_fn) addr;
+ addr = (ulong) (fn->wr) + reloc_offset;
+ fn_r->wr = (Xilinx_wr_fn) addr;
+ addr = (ulong) (fn->rdata) + reloc_offset;
+ fn_r->rdata = (Xilinx_rdata_fn) addr;
+ addr = (ulong) (fn->wdata) + reloc_offset;
+ fn_r->wdata = (Xilinx_wdata_fn) addr;
+ addr = (ulong) (fn->busy) + reloc_offset;
+ fn_r->busy = (Xilinx_busy_fn) addr;
+ addr = (ulong) (fn->abort) + reloc_offset;
+ fn_r->abort = (Xilinx_abort_fn) addr;
+ addr = (ulong) (fn->post) + reloc_offset;
+ fn_r->post = (Xilinx_post_fn) addr;
+ fn_r->relocated = TRUE;
+ } else {
+ printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r);
+ desc->iface_fns = fn_r;
+ }
+ ret_val = FPGA_SUCCESS;
+ } else {
+ printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ }
+ return ret_val;
+}
+
+static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__);
+ return FPGA_FAIL;
+}
+
+static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__);
+ return FPGA_FAIL;
+}
+
+static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset)
+{
+ int ret_val = FPGA_FAIL;
+ Xilinx_Virtex2_Slave_Serial_fns *fn =
+ (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns);
+
+ if (fn) {
+ printf ("%s:%d: Slave Serial Loading is unsupported\n",
+ __FUNCTION__, __LINE__);
+ } else {
+ printf ("%s:%d: NULL Interface function table!\n",
+ __FUNCTION__, __LINE__);
+ }
+ return ret_val;
+}
+#endif
+
+/* vim: set ts=4 tw=78: */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * 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
+ *
+ */
+
+/*
+ * Xilinx FPGA support
+ */
+
+#include <common.h>
+#include <virtex2.h>
+#include <spartan2.h>
+
+#if (CONFIG_FPGA & CFG_FPGA_XILINX)
+
+#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 xilinx_validate (Xilinx_desc * desc, char *fn);
+
+/* ------------------------------------------------------------------------- */
+
+int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL; /* assume a failure */
+
+ if (!xilinx_validate (desc, __FUNCTION__)) {
+ printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+ } else
+ switch (desc->family) {
+ case Xilinx_Spartan2:
+#if (CONFIG_FPGA & CFG_SPARTAN2)
+ PRINTF ("%s: Launching the Spartan-II Loader...\n",
+ __FUNCTION__);
+ ret_val = Spartan2_load (desc, buf, bsize);
+#else
+ printf ("%s: No support for Spartan-II devices.\n",
+ __FUNCTION__);
+#endif
+ break;
+ case Xilinx_Virtex2:
+#if (CONFIG_FPGA & CFG_VIRTEX2)
+ PRINTF ("%s: Launching the Virtex-II Loader...\n",
+ __FUNCTION__);
+ ret_val = Virtex2_load (desc, buf, bsize);
+#else
+ printf ("%s: No support for Virtex-II devices.\n",
+ __FUNCTION__);
+#endif
+ break;
+
+ default:
+ printf ("%s: Unsupported family type, %d\n",
+ __FUNCTION__, desc->family);
+ }
+
+ return ret_val;
+}
+
+int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+{
+ int ret_val = FPGA_FAIL; /* assume a failure */
+
+ if (!xilinx_validate (desc, __FUNCTION__)) {
+ printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+ } else
+ switch (desc->family) {
+ case Xilinx_Spartan2:
+#if (CONFIG_FPGA & CFG_SPARTAN2)
+ PRINTF ("%s: Launching the Spartan-II Reader...\n",
+ __FUNCTION__);
+ ret_val = Spartan2_dump (desc, buf, bsize);
+#else
+ printf ("%s: No support for Spartan-II devices.\n",
+ __FUNCTION__);
+#endif
+ break;
+ case Xilinx_Virtex2:
+#if (CONFIG_FPGA & CFG_VIRTEX2)
+ PRINTF ("%s: Launching the Virtex-II Reader...\n",
+ __FUNCTION__);
+ ret_val = Virtex2_dump (desc, buf, bsize);
+#else
+ printf ("%s: No support for Virtex-II devices.\n",
+ __FUNCTION__);
+#endif
+ break;
+
+ default:
+ printf ("%s: Unsupported family type, %d\n",
+ __FUNCTION__, desc->family);
+ }
+
+ return ret_val;
+}
+
+int xilinx_info (Xilinx_desc * desc)
+{
+ int ret_val = FPGA_FAIL;
+
+ if (xilinx_validate (desc, __FUNCTION__)) {
+ printf ("Family: \t");
+ switch (desc->family) {
+ case Xilinx_Spartan2:
+ printf ("Spartan-II\n");
+ break;
+ case Xilinx_Virtex2:
+ printf ("Virtex-II\n");
+ break;
+ /* Add new family types here */
+ default:
+ printf ("Unknown family type, %d\n", desc->family);
+ }
+
+ printf ("Interface type:\t");
+ switch (desc->iface) {
+ case slave_serial:
+ printf ("Slave Serial\n");
+ break;
+ case master_serial: /* Not used */
+ printf ("Master Serial\n");
+ break;
+ case slave_parallel:
+ printf ("Slave Parallel\n");
+ break;
+ case jtag_mode: /* Not used */
+ printf ("JTAG Mode\n");
+ break;
+ case slave_selectmap:
+ printf ("Slave SelectMap Mode\n");
+ break;
+ case master_selectmap:
+ printf ("Master SelectMap Mode\n");
+ break;
+ /* Add new interface types here */
+ 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);
+
+ if (desc->iface_fns) {
+ printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
+ switch (desc->family) {
+ case Xilinx_Spartan2:
+#if (CONFIG_FPGA & CFG_SPARTAN2)
+ Spartan2_info (desc);
+#else
+ /* just in case */
+ printf ("%s: No support for Spartan-II devices.\n",
+ __FUNCTION__);
+#endif
+ break;
+ case Xilinx_Virtex2:
+#if (CONFIG_FPGA & CFG_VIRTEX2)
+ Virtex2_info (desc);
+#else
+ /* just in case */
+ printf ("%s: No support for Virtex-II devices.\n",
+ __FUNCTION__);
+#endif
+ break;
+ /* Add new family types here */
+ default:
+ /* we don't need a message here - we give one up above */
+ }
+ } else
+ printf ("No Device Function Table.\n");
+
+ ret_val = FPGA_SUCCESS;
+ } else {
+ printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+ }
+
+ return ret_val;
+}
+
+int xilinx_reloc (Xilinx_desc * desc, ulong reloc_offset)
+{
+ int ret_val = FPGA_FAIL; /* assume a failure */
+
+ if (!xilinx_validate (desc, __FUNCTION__)) {
+ printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+ } else
+ switch (desc->family) {
+ case Xilinx_Spartan2:
+#if (CONFIG_FPGA & CFG_SPARTAN2)
+ ret_val = Spartan2_reloc (desc, reloc_offset);
+#else
+ printf ("%s: No support for Spartan-II devices.\n",
+ __FUNCTION__);
+#endif
+ break;
+ case Xilinx_Virtex2:
+#if (CONFIG_FPGA & CFG_VIRTEX2)
+ ret_val = Virtex2_reloc (desc, reloc_offset);
+#else
+ printf ("%s: No support for Virtex-II 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 xilinx_validate (Xilinx_desc * desc, char *fn)
+{
+ int ret_val = FALSE;
+
+ if (desc) {
+ if ((desc->family > min_xilinx_type) &&
+ (desc->family < max_xilinx_type)) {
+ if ((desc->iface > min_xilinx_iface_type) &&
+ (desc->iface < max_xilinx_iface_type)) {
+ if (desc->size) {
+ ret_val = TRUE;
+ } else
+ printf ("%s: NULL part size\n", fn);
+ } else
+ printf ("%s: Invalid Interface type, %d\n",
+ fn, desc->iface);
+ } else
+ printf ("%s: Invalid family type, %d\n", fn, desc->family);
+ } else
+ printf ("%s: NULL descriptor!\n", fn);
+
+ return ret_val;
+}
+
+#endif /* CONFIG_FPGA & CFG_FPGA_XILINX */
/* read co-processor 15, register #1 (control register) */
static unsigned long read_p15_c1(void)
{
- unsigned long value;
-
- __asm__ __volatile__(
- "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
- : "=r" (value)
- :
- : "memory");
- //printf("p15/c1 is = %08lx\n", value);
- return value;
+ unsigned long value;
+
+ __asm__ __volatile__(
+ "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
+ : "=r" (value)
+ :
+ : "memory");
+ /* printf("p15/c1 is = %08lx\n", value); */
+ return value;
}
/* write to co-processor 15, register #1 (control register) */
static void write_p15_c1(unsigned long value)
{
- //printf("write %08lx to p15/c1\n", value);
- __asm__ __volatile__(
- "mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
- :
- : "r" (value)
- : "memory");
-
- read_p15_c1();
+ /* printf("write %08lx to p15/c1\n", value); */
+ __asm__ __volatile__(
+ "mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
+ :
+ : "r" (value)
+ : "memory");
+
+ read_p15_c1();
}
-static void cp_delay(void)
+static void cp_delay (void)
{
- volatile int i;
+ volatile int i;
- /* copro seems to need some delay between reading and writing */
- for (i=0; i<100; i++);
+ /* copro seems to need some delay between reading and writing */
+ for (i = 0; i < 100; i++);
}
/* See also ARM Ref. Man. */
#define C1_ROM_PROT (1<<9) /* ROM protection */
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
-void cpu_init(bd_t *bd)
+int cpu_init (gd_t * gd)
{
- /*
- * setup up stack if necessary
- */
+ /*
+ * setup up stack if necessary
+ */
#ifdef CONFIG_USE_IRQ
- IRQ_STACK_START = _armboot_end +
- CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
- FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
- _armboot_real_end = FIQ_STACK_START + 4;
+ IRQ_STACK_START = _armboot_end + \
+ CONFIG_STACKSIZE + \
+ CONFIG_STACKSIZE_IRQ - 4;
+ FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
+ _armboot_real_end = FIQ_STACK_START + 4;
#else
- _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
+ _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
#endif
+ return (0);
}
-void cleanup_before_linux(bd_t *bd)
+int cleanup_before_linux (gd_t *dummy)
{
- /*
- * this function is called just before we call linux
- * it prepares the processor for linux
- *
- * we turn off caches etc ...
- * and we set the CPU-speed to 73 MHz - see start.S for details
- */
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ * and we set the CPU-speed to 73 MHz - see start.S for details
+ */
- unsigned long i;
+ unsigned long i;
- disable_interrupts();
+ disable_interrupts ();
- /* turn off I-cache */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
- i &= ~0x1000;
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+ /* turn off I-cache */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ i &= ~0x1000;
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
- /* flush I-cache */
- asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i));
+ /* flush I-cache */
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
#ifdef CONFIG_ARM7_REVD
- /* go to high speed */
- IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73;
+ /* go to high speed */
+ IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73;
#endif
+ return 0;
}
-void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[])
{
- extern void reset_cpu(ulong addr);
+ extern void reset_cpu (ulong addr);
- disable_interrupts();
- reset_cpu(0);
- /*NOTREACHED*/
-}
+ disable_interrupts ();
+ reset_cpu (0);
+ /*NOTREACHED*/}
-void icache_enable(void)
+void icache_enable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- write_p15_c1(reg | C1_IDC);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg | C1_IDC);
}
-void icache_disable(void)
+void icache_disable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- write_p15_c1(reg & ~C1_IDC);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg & ~C1_IDC);
}
-int icache_status(void)
+int icache_status (void)
{
- return (read_p15_c1() & C1_IDC) != 0;
+ return (read_p15_c1 () & C1_IDC) != 0;
}
-void dcache_enable(void)
+void dcache_enable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- write_p15_c1(reg | C1_IDC);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg | C1_IDC);
}
-void dcache_disable(void)
+void dcache_disable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- write_p15_c1(reg & ~C1_IDC);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg & ~C1_IDC);
}
-int dcache_status(void)
+int dcache_status (void)
{
- return (read_p15_c1() & C1_IDC) != 0;
+ return (read_p15_c1 () & C1_IDC) != 0;
}
/* it makes no sense to use the caches if the MMU also isn't used */
#ifdef USE_920T_MMU
/* read co-processor 15, register #1 (control register) */
-static unsigned long read_p15_c1(void)
+static unsigned long read_p15_c1 (void)
{
- unsigned long value;
+ unsigned long value;
+
+ __asm__ __volatile__(
+ "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
+ : "=r" (value)
+ :
+ : "memory");
- __asm__ __volatile__(
- "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
- : "=r" (value)
- :
- : "memory");
#ifdef MMU_DEBUG
- printf("p15/c1 is = %08lx\n", value);
+ printf ("p15/c1 is = %08lx\n", value);
#endif
- return value;
+ return value;
}
/* write to co-processor 15, register #1 (control register) */
-static void write_p15_c1(unsigned long value)
+static void write_p15_c1 (unsigned long value)
{
#ifdef MMU_DEBUG
- printf("write %08lx to p15/c1\n", value);
+ printf ("write %08lx to p15/c1\n", value);
#endif
- __asm__ __volatile__(
- "mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
- :
- : "r" (value)
- : "memory");
- read_p15_c1();
+ __asm__ __volatile__(
+ "mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
+ :
+ : "r" (value)
+ : "memory");
+
+ read_p15_c1 ();
}
-static void cp_delay(void)
+static void cp_delay (void)
{
- volatile int i;
+ volatile int i;
- /* copro seems to need some delay between reading and writing */
- for (i=0; i<100; i++);
+ /* copro seems to need some delay between reading and writing */
+ for (i = 0; i < 100; i++);
}
/* See also ARM Ref. Man. */
-#define C1_MMU (1<<0) /* mmu off/on */
-#define C1_ALIGN (1<<1) /* alignment faults off/on */
-#define C1_DC (1<<2) /* dcache off/on */
+#define C1_MMU (1<<0) /* mmu off/on */
+#define C1_ALIGN (1<<1) /* alignment faults off/on */
+#define C1_DC (1<<2) /* dcache off/on */
#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
-#define C1_SYS_PROT (1<<8) /* system protection */
-#define C1_ROM_PROT (1<<9) /* ROM protection */
-#define C1_IC (1<<12) /* icache off/on */
+#define C1_SYS_PROT (1<<8) /* system protection */
+#define C1_ROM_PROT (1<<9) /* ROM protection */
+#define C1_IC (1<<12) /* icache off/on */
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
-#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */
-#endif
+#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */
+#endif /* USE_920T_MMU */
-void cpu_init(bd_t *bd)
+int cpu_init (gd_t *gd)
{
- /*
- * setup up stack if necessary
- */
+ /*
+ * setup up stack if necessary
+ */
#ifdef CONFIG_USE_IRQ
- IRQ_STACK_START = _armboot_end +
- CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
- FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
- _armboot_real_end = FIQ_STACK_START + 4;
+ IRQ_STACK_START = _armboot_end +
+ CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
+ FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
+ _armboot_real_end = FIQ_STACK_START + 4;
#else
- _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
+ _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
#endif
+ return (0);
}
-void cleanup_before_linux(bd_t *bd)
+int cleanup_before_linux (gd_t *dummy)
{
- /*
- * this function is called just before we call linux
- * it prepares the processor for linux
- *
- * we turn off caches etc ...
- */
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
#ifdef USE_920T_MMU
- unsigned long i;
+ unsigned long i;
#endif
- disable_interrupts();
+ disable_interrupts ();
#ifdef USE_920T_MMU
- /* turn off I/D-cache */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
- i &= ~(C1_DC|C1_IC);
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
-
- /* flush I/D-cache */
- i = 0;
- asm ("mcr p15, 0, %0, c7, c7, 0": : "r" (i));
+ /* turn off I/D-cache */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ i &= ~(C1_DC | C1_IC);
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+
+ /* flush I/D-cache */
+ i = 0;
+ asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
#endif
-
+ return (0);
}
-void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[])
{
- extern void reset_cpu(ulong addr);
+ extern void reset_cpu (ulong addr);
- disable_interrupts();
- reset_cpu(0);
- /*NOTREACHED*/
-}
+ disable_interrupts ();
+ reset_cpu (0);
+ /*NOTREACHED*/}
#ifdef USE_920T_MMU
-void icache_enable(void)
+void icache_enable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- write_p15_c1(reg | C1_IC);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg | C1_IC);
}
-void icache_disable(void)
+void icache_disable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- write_p15_c1(reg & ~C1_IC);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg & ~C1_IC);
}
-int icache_status(void)
+int icache_status (void)
{
- return (read_p15_c1() & C1_IC) != 0;
+ return (read_p15_c1 () & C1_IC) != 0;
}
-void dcache_enable(void)
+void dcache_enable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- write_p15_c1(reg | C1_DC);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg | C1_DC);
}
-void dcache_disable(void)
+void dcache_disable (void)
{
- ulong reg;
- reg = read_p15_c1();
- cp_delay();
- reg &= ~C1_DC;
- write_p15_c1(reg);
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ reg &= ~C1_DC;
+ write_p15_c1 (reg);
}
-int dcache_status(void)
+int dcache_status (void)
{
- return (read_p15_c1() & C1_DC) != 0;
+ return (read_p15_c1 () & C1_DC) != 0;
}
#endif
0,
},
#endif
+#if defined(STATUS_LED_BIT3)
+ { STATUS_LED_BIT3,
+ STATUS_LED_STATE3,
+ STATUS_LED_PERIOD3,
+ 0,
+ },
+#endif
};
#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
#include <common.h>
#include <command.h>
-void cpu_init(bd_t *bd)
+int cpu_init (gd_t *gd)
{
- /*
- * setup up stack if necessary
- */
+ /*
+ * setup up stack if necessary
+ */
#ifdef CONFIG_USE_IRQ
- IRQ_STACK_START = _armboot_end +
- CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
- FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
- _armboot_real_end = FIQ_STACK_START + 4;
+ IRQ_STACK_START = _armboot_end +
+ CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
+ FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
+ _armboot_real_end = FIQ_STACK_START + 4;
#else
- _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
+ _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
#endif
+ return (0);
}
-void cleanup_before_linux(bd_t *bd)
+int cleanup_before_linux (gd_t * gd)
{
- /*
- * this function is called just before we call linux
- * it prepares the processor for linux
- *
- * just disable everything that can disturb booting linux
- */
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * just disable everything that can disturb booting linux
+ */
- unsigned long i;
+ unsigned long i;
- disable_interrupts();
+ disable_interrupts ();
- /* turn off I-cache */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
- i &= ~0x1000;
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+ /* turn off I-cache */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ i &= ~0x1000;
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
- /* flush I-cache */
- asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i));
+ /* flush I-cache */
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
+
+ return (0);
}
-void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[])
{
- extern void reset_cpu(ulong addr);
+ extern void reset_cpu (ulong addr);
+
+ printf ("resetting ...\n");
- printf("reseting ...\n");
+ udelay (50000); /* wait 50 ms */
+ disable_interrupts ();
+ reset_cpu (0);
- udelay(50000); /* wait 50 ms */
- disable_interrupts();
- reset_cpu(0);
- /*NOTREACHED*/
+ /*NOTREACHED*/
+ return (0);
}
/* taken from blob */
-void icache_enable(void)
+void icache_enable (void)
{
- register u32 i;
+ register u32 i;
- /* read control register */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
+ /* read control register */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- /* set i-cache */
- i |= 0x1000;
+ /* set i-cache */
+ i |= 0x1000;
- /* write back to control register */
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+ /* write back to control register */
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
-void icache_disable(void)
+void icache_disable (void)
{
- register u32 i;
+ register u32 i;
- /* read control register */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
+ /* read control register */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- /* clear i-cache */
- i &= ~0x1000;
+ /* clear i-cache */
+ i &= ~0x1000;
- /* write back to control register */
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+ /* write back to control register */
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
- /* flush i-cache */
- asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i));
+ /* flush i-cache */
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
}
-int icache_status(void)
+int icache_status (void)
{
- register u32 i;
+ register u32 i;
- /* read control register */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
+ /* read control register */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- /* return bit */
- return (i & 0x1000);
+ /* return bit */
+ return (i & 0x1000);
}
/* we will never enable dcache, because we have to setup MMU first */
-void dcache_enable(void)
+void dcache_enable (void)
{
- return;
+ return;
}
-void dcache_disable(void)
+void dcache_disable (void)
{
- return;
+ return;
}
-int dcache_status(void)
+int dcache_status (void)
{
- return 0; /* always off */
+ return 0; /* always off */
}
#include <common.h>
#include <command.h>
-void cpu_init(bd_t *bd)
+int cpu_init (gd_t *gd)
{
- /*
- * setup up stack if necessary
- */
+ /*
+ * setup up stack if necessary
+ */
#ifdef CONFIG_USE_IRQ
- IRQ_STACK_START = _armboot_end +
- CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
- FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
- _armboot_real_end = FIQ_STACK_START + 4;
+ IRQ_STACK_START = _armboot_end +
+ CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
+ FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
+ _armboot_real_end = FIQ_STACK_START + 4;
#else
- _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
+ _armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
#endif
+ return (0);
}
-void cleanup_before_linux(bd_t *bd)
+int cleanup_before_linux (gd_t *dummy)
{
- /*
- * this function is called just before we call linux
- * it prepares the processor for linux
- *
- * just disable everything that can disturb booting linux
- */
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * just disable everything that can disturb booting linux
+ */
- unsigned long i;
+ unsigned long i;
- disable_interrupts();
+ disable_interrupts ();
- /* turn off I-cache */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
- i &= ~0x1000;
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+ /* turn off I-cache */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ i &= ~0x1000;
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
- /* flush I-cache */
- asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i));
+ /* flush I-cache */
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
+
+ return (0);
}
-void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[])
{
- extern void reset_cpu(ulong addr);
+ extern void reset_cpu (ulong addr);
+
+ printf ("reseting ...\n");
- printf("reseting ...\n");
+ udelay (50000); /* wait 50 ms */
+ disable_interrupts ();
+ reset_cpu (0);
- udelay(50000); /* wait 50 ms */
- disable_interrupts();
- reset_cpu(0);
- /*NOTREACHED*/
+ /*NOTREACHED*/
+ return (0);
}
/* taken from blob */
-void icache_enable(void)
+void icache_enable (void)
{
- register u32 i;
+ register u32 i;
- /* read control register */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
+ /* read control register */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- /* set i-cache */
- i |= 0x1000;
+ /* set i-cache */
+ i |= 0x1000;
- /* write back to control register */
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+ /* write back to control register */
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
-void icache_disable(void)
+void icache_disable (void)
{
- register u32 i;
+ register u32 i;
- /* read control register */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
+ /* read control register */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- /* clear i-cache */
- i &= ~0x1000;
+ /* clear i-cache */
+ i &= ~0x1000;
- /* write back to control register */
- asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+ /* write back to control register */
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
- /* flush i-cache */
- asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i));
+ /* flush i-cache */
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
}
-int icache_status(void)
+int icache_status (void)
{
- register u32 i;
+ register u32 i;
- /* read control register */
- asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
+ /* read control register */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- /* return bit */
- return (i & 0x1000);
+ /* return bit */
+ return (i & 0x1000);
}
/* we will never enable dcache, because we have to setup MMU first */
-void dcache_enable(void)
+void dcache_enable (void)
{
- return;
+ return;
}
-void dcache_disable(void)
+void dcache_disable (void)
{
- return;
+ return;
}
-int dcache_status(void)
+int dcache_status (void)
{
- return 0; /* always off */
+ return 0; /* always off */
}
fccinfo 3
fdcboot 4
flinfo 3
+fpga 4
getdcr 6 # IBM 4XX DCR registers
go 2
help 1
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * 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 _ALTERA_H_
+#define _ALTERA_H_
+
+/*
+ * Note that this is just Altera FPGA interface boilerplate.
+ * There is no support for Altera devices yet.
+ *
+ * See include/xilinx.h for a working example.
+ */
+
+/* In your board's config.h file you should define CONFIG_FPGA as such:
+ * #define CONFIG_FPGA (CFG_ALTERA_xxx | CFG_ALTERA_IF_xxx )
+ */
+
+/* Altera Model definitions */
+#define CFG_ALTERA_xxxx ( CFG_FPGA_ALTERA | CFG_FPGA_DEV( 0x1 ))
+/* Add new models here */
+
+/* Altera Interface definitions */
+#define CFG_ALTERA_IF_xxx CFG_FPGA_IF( 0x1 )
+/* Add new interfaces here */
+
+typedef enum { /* typedef Altera_iface */
+ min_altera_iface_type, /* insert all new types after this */
+/* Add new interfaces here */
+ max_altera_iface_type /* insert all new types before this */
+} Altera_iface; /* end, typedef Altera_iface */
+
+typedef enum { /* typedef Altera_Family */
+ min_altera_type, /* insert all new types after this */
+/* Add new models here */
+ max_altera_type /* insert all new types before this */
+} Altera_Family; /* end, typedef Altera_Family */
+
+typedef struct { /* typedef Altera_desc */
+ Altera_Family family; /* part type */
+ Altera_iface iface; /* interface type */
+ size_t size; /* bytes of data part can accept */
+ void * base; /* base interface address */
+} Altera_desc; /* end, typedef Altera_desc */
+
+extern int altera_load( Altera_desc *desc, void *image, size_t size );
+extern int altera_dump( Altera_desc *desc, void *buf, size_t bsize );
+extern int altera_info( Altera_desc *desc );
+extern int altera_reloc( Altera_desc *desc, ulong reloc_off );
+
+#endif /* _ALTERA_H_ */
* Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t)
*/
+typedef struct global_data {
+ bd_t *bd;
+ unsigned long baudrate;
+#if 0
+ unsigned long cpu_clk; /* CPU clock in Hz! */
+ unsigned long bus_clk;
+ unsigned long ram_size; /* RAM size */
+ unsigned long reloc_off; /* Relocation Offset */
+ unsigned long reset_status; /* reset status register at boot */
+ unsigned long env_addr; /* Address of Environment struct */
+ unsigned long env_valid; /* Checksum of Environment valid? */
+ unsigned long have_console; /* serial_init() was called */
+#endif
+} gd_t;
+
#endif /* __ASM_GBL_DATA_H */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * 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 _PPCBOOT_ARM_H_
+#define _PPCBOOT_ARM_H_ 1
+
+/* for the following variables, see start.S */
+extern ulong _armboot_start; /* code start */
+extern ulong _armboot_end; /* code end */
+extern ulong IRQ_STACK_START; /* top of IRQ stack */
+extern ulong FIQ_STACK_START; /* top of FIQ stack */
+extern ulong _armboot_real_end; /* first usable RAM address */
+
+/* ------------------------------------------------------------ */
+/* Here is a list of some prototypes which are incompatible to */
+/* the PPCBoot implementation */
+/* To be fixed! */
+/* ------------------------------------------------------------ */
+/* common/cmd_nvedit.c */
+int env_init (gd_t *);
+void env_relocate (gd_t *);
+char *getenv (bd_t *bd, uchar *);
+void setenv (bd_t *bd, char *, char *);
+
+/* cpu/.../cpu.c */
+void cpu_init(bd_t *bd);
+void cleanup_before_linux(bd_t *bd);
+
+/* board/.../... */
+int board_init(bd_t *);
+int dram_init(bd_t *bd);
+
+/* arm/display_options.c */
+void display_banner(bd_t *bd);
+void display_dram_config(bd_t *bd);
+void display_flash_config(bd_t *bd, ulong size);
+
+/* cpu/.../interrupt.c */
+void reset_timer_masked (void);
+ulong get_timer_masked (void);
+void udelay_masked (unsigned long usec);
+
+#if 0 /*------------------------------------------------------------*/
+/* arm/crc32.c */
+ulong crc32 (ulong, const unsigned char *, uint);
+ulong crc32_no_comp (ulong crc, const unsigned char *, uint);
+
+/*
+ * Don't define some stuff private to armboot target code
+ */
+#ifndef HOST_TOOLS
+
+/* board/.../env.c */
+int board_env_getchar(bd_t * bd, int index, uchar *c);
+int board_env_save (bd_t * bd, env_t *data, int size);
+int board_env_copy (bd_t * bd, env_t *data, int size);
+uchar * board_env_getaddr(bd_t * bd, int index);
+
+
+/*
+ * Function Prototypes
+ */
+void hang (void);
+void start_armboot (void);
+void main_loop (bd_t *);
+int run_command (const char *cmd, bd_t *, int flag);
+int readline (const char *const prompt);
+void reset_cmd_timeout(void);
+
+
+/* arm/string.c */
+char * strcpy (char * dest,const char *src);
+char * strncpy (char * dest,const char *src, size_t count);
+size_t strlen (const char *);
+size_t strnlen (const char * s, size_t count);
+int strncmp (const char * cs, const char * ct, size_t count);
+int strcmp (const char * cs, const char * ct);
+void * memcpy (void * dest, const void *src, size_t count);
+int memcmp (const void * dest, const void *src, size_t count);
+void * memset (void * s, char c, size_t count);
+void * memmove (void * dest, const void *src, size_t count);
+char * strchr (const char * s, int c);
+
+/* arm/vsprintf.c */
+ulong simple_strtoul (const char *cp,char **endp,unsigned int base);
+long simple_strtol (const char *cp,char **endp,unsigned int base);
+void panic (const char *fmt, ...);
+int sprintf (char * buf, const char *fmt, ...);
+int vsprintf (char *buf, const char *fmt, va_list args);
+
+void udelay (unsigned long);
+
+int ctrlc (void);
+int had_ctrlc (void);
+void clear_ctrlc (void);
+int disable_ctrlc (int);
+
+int console_assign (int file, char *devname);
+
+/* */
+int icache_status (void);
+void icache_enable (void);
+void icache_disable(void);
+int dcache_status (void);
+void dcache_enable (void);
+void dcache_disable(void);
+
+/* common/cmd_bootm.c */
+void print_image_hdr (image_header_t *hdr);
+
+/* cpu/.../interrupt.c */
+void enable_interrupts (void);
+int disable_interrupts (void);
+void interrupt_init (bd_t *bd);
+void reset_timer (void);
+ulong get_timer (ulong base);
+void set_timer (ulong t);
+
+extern ulong load_addr;
+
+/*
+ * STDIO based functions (can always be used)
+ */
+
+/* serial stuff */
+void serial_printf (const char *fmt, ...);
+
+/* stdin */
+int getc(void);
+int tstc(void);
+
+/* stdout */
+void putc(const char c);
+void puts(const char *s);
+void printf(const char *fmt, ...);
+
+/* stderr */
+#define eputc(c) fputc(stderr, c)
+#define eputs(s) fputs(stderr, s)
+#define eprintf(fmt,args...) fprintf(stderr,fmt ,##args)
+
+/*
+ * FILE based functions (can only be used AFTER relocation!)
+ */
+
+#define stdin 0
+#define stdout 1
+#define stderr 2
+#define MAX_FILES 3
+
+void fprintf(int file, const char *fmt, ...);
+void fputs(int file, const char *s);
+void fputc(int file, const char c);
+int ftstc(int file);
+int fgetc(int file);
+
+/* Byte swapping stuff */
+#define SWAP16(x) ((((x) & 0xff) << 8) | ((x) >> 8))
+#define SWAP16c(x) ((((x) & 0xff) << 8) | ((x) >> 8))
+#define SWAP32(x) ( \
+ (((x) >> 24) & 0x000000ff) | \
+ (((x) >> 8) & 0x0000ff00) | \
+ (((x) << 8) & 0x00ff0000) | \
+ (((x) << 24) & 0xff000000) )
+
+#endif /* HOST_TOOLS */
+#endif /* 0 ------------------------------------------------------------*/
+
+
+#endif /* _PPCBOOT_ARM_H_ */
#define bi_env_data bi_env->data
#define bi_env_crc bi_env->crc
-/* for the following variables, see start.S */
-extern ulong _armboot_start; /* code start */
-extern ulong _armboot_end; /* code end */
-extern ulong IRQ_STACK_START; /* top of IRQ stack */
-extern ulong FIQ_STACK_START; /* top of FIQ stack */
-extern ulong _armboot_real_end; /* first usable RAM address */
-
-/* ------------------------------------------------------------ */
-/* Here is a list of some prototypes which are incompatible to */
-/* the PPCBoot implementation */
-/* To be fixed! */
-/* ------------------------------------------------------------ */
-/* common/cmd_nvedit.c */
-int env_init (gd_t *);
-void env_relocate (gd_t *);
-char *getenv (bd_t *bd, uchar *);
-void setenv (bd_t *bd, char *, char *);
-
-/* cpu/.../cpu.c */
-void cpu_init(bd_t *bd);
-void cleanup_before_linux(bd_t *bd);
-
-/* board/.../... */
-int board_init(bd_t *);
-int dram_init(bd_t *bd);
-
-/* arm/display_options.c */
-void display_banner(bd_t *bd);
-void display_dram_config(bd_t *bd);
-void display_flash_config(bd_t *bd, ulong size);
-
-/* cpu/.../interrupt.c */
-void reset_timer_masked (void);
-ulong get_timer_masked (void);
-void udelay_masked (unsigned long usec);
-
-#if 0 /*------------------------------------------------------------*/
-/* arm/crc32.c */
-ulong crc32 (ulong, const unsigned char *, uint);
-ulong crc32_no_comp (ulong crc, const unsigned char *, uint);
-
-/*
- * Don't define some stuff private to armboot target code
- */
-#ifndef HOST_TOOLS
-
-/* board/.../env.c */
-int board_env_getchar(bd_t * bd, int index, uchar *c);
-int board_env_save (bd_t * bd, env_t *data, int size);
-int board_env_copy (bd_t * bd, env_t *data, int size);
-uchar * board_env_getaddr(bd_t * bd, int index);
-
-/*
- * Function Prototypes
- */
-void hang (void);
-void start_armboot (void);
-void main_loop (bd_t *);
-int run_command (const char *cmd, bd_t *, int flag);
-int readline (const char *const prompt);
-void reset_cmd_timeout(void);
-
-
-/* arm/string.c */
-char * strcpy (char * dest,const char *src);
-char * strncpy (char * dest,const char *src, size_t count);
-size_t strlen (const char *);
-size_t strnlen (const char * s, size_t count);
-int strncmp (const char * cs, const char * ct, size_t count);
-int strcmp (const char * cs, const char * ct);
-void * memcpy (void * dest, const void *src, size_t count);
-int memcmp (const void * dest, const void *src, size_t count);
-void * memset (void * s, char c, size_t count);
-void * memmove (void * dest, const void *src, size_t count);
-char * strchr (const char * s, int c);
-
-/* arm/vsprintf.c */
-ulong simple_strtoul (const char *cp,char **endp,unsigned int base);
-long simple_strtol (const char *cp,char **endp,unsigned int base);
-void panic (const char *fmt, ...);
-int sprintf (char * buf, const char *fmt, ...);
-int vsprintf (char *buf, const char *fmt, va_list args);
-
-void udelay (unsigned long);
-
-int ctrlc (void);
-int had_ctrlc (void);
-void clear_ctrlc (void);
-int disable_ctrlc (int);
-
-int console_assign (int file, char *devname);
-
-/* */
-int icache_status (void);
-void icache_enable (void);
-void icache_disable(void);
-int dcache_status (void);
-void dcache_enable (void);
-void dcache_disable(void);
-
-/* common/cmd_bootm.c */
-void print_image_hdr (image_header_t *hdr);
-
-/* cpu/.../interrupt.c */
-void enable_interrupts (void);
-int disable_interrupts (void);
-void interrupt_init (bd_t *bd);
-void reset_timer (void);
-ulong get_timer (ulong base);
-void set_timer (ulong t);
-
-extern ulong load_addr;
-
-/*
- * STDIO based functions (can always be used)
- */
-
-/* serial stuff */
-void serial_printf (const char *fmt, ...);
-
-/* stdin */
-int getc(void);
-int tstc(void);
-
-/* stdout */
-void putc(const char c);
-void puts(const char *s);
-void printf(const char *fmt, ...);
-
-/* stderr */
-#define eputc(c) fputc(stderr, c)
-#define eputs(s) fputs(stderr, s)
-#define eprintf(fmt,args...) fprintf(stderr,fmt ,##args)
-
-/*
- * FILE based functions (can only be used AFTER relocation!)
- */
-
-#define stdin 0
-#define stdout 1
-#define stderr 2
-#define MAX_FILES 3
-
-void fprintf(int file, const char *fmt, ...);
-void fputs(int file, const char *s);
-void fputc(int file, const char c);
-int ftstc(int file);
-int fgetc(int file);
-
-/* Byte swapping stuff */
-#define SWAP16(x) ((((x) & 0xff) << 8) | ((x) >> 8))
-#define SWAP16c(x) ((((x) & 0xff) << 8) | ((x) >> 8))
-#define SWAP32(x) ( \
- (((x) >> 24) & 0x000000ff) | \
- (((x) >> 8) & 0x0000ff00) | \
- (((x) << 8) & 0x00ff0000) | \
- (((x) << 24) & 0xff000000) )
-
-#endif /* HOST_TOOLS */
-#endif /* 0 ------------------------------------------------------------*/
-
#endif /* _PPCBOOT_H_ */
#define CFG_CMD_JFFS2 0x0000001000000000 /* JFFS2 Support */
#define CFG_CMD_DTT 0x0000002000000000 /* Digital Therm and Thermostat */
#define CFG_CMD_SDRAM 0x0000004000000000 /* SDRAM DIMM SPD info printout */
+#define CFG_CMD_FPGA 0x0000080000000000 /* FPGA configuration Support */
#define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFF /* ALL commands */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * 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
+ *
+ */
+
+/*
+ * FPGA support
+ */
+#ifndef _CMD_FPGA_H
+#define _CMD_FPGA_H
+
+#include <common.h>
+#include <command.h>
+
+#if defined(CONFIG_FPGA) && (CONFIG_COMMANDS & CFG_CMD_FPGA)
+
+#define CMD_TBL_FPGA MK_CMD_TBL_ENTRY( \
+ "fpga", 4, 6, 1, do_fpga, \
+ "fpga - loadable FPGA image support\n", \
+ "fpga [operation type] [device number] [image address] [image size]\n" \
+ "fpga operations:\n" \
+ "\tinfo\tlist known device information.\n" \
+ "\tload\tLoad device from memory buffer.\n" \
+ "\tdump\tLoad device to memory buffer.\n" \
+),
+
+extern int do_fpga (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]);
+
+#else
+#define CMD_TBL_FPGA
+#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */
+
+#endif /* _CMD_FPGA_H */
extern ulong load_addr; /* Default Load Address */
-#ifdef CONFIG_PPC /* ARM version in armboot.h - to be fixed! */
+#ifdef CONFIG_PPC /* ARM version to be fixed! */
/* common/cmd_nvedit.c */
int env_init (gd_t *);
void env_relocate (gd_t *);
int saveenv (void);
void inline setenv (char *, char *);
#endif /* CONFIG_PPC */
+#ifdef CONFIG_ARM
+# include <asm/ppcboot-arm.h> /* ARM version to be fixed! */
+#endif /* CONFIG_ARM */
void pci_init (gd_t *);
void pciinfo (int, int);
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * 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 <linux/types.h> /* for ulong typedef */
+
+#ifndef _FPGA_H_
+#define _FPGA_H_
+
+#ifndef CONFIG_MAX_FPGA_DEVICES
+#define CONFIG_MAX_FPGA_DEVICES 5
+#endif
+
+/* these probably belong somewhere else */
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+/* CONFIG_FPGA bit assignments */
+#define CFG_FPGA_MAN(x) (x)
+#define CFG_FPGA_DEV(x) ((x) << 8 )
+#define CFG_FPGA_IF(x) ((x) << 16 )
+
+/* FPGA Manufacturer bits in CONFIG_FPGA */
+#define CFG_FPGA_XILINX CFG_FPGA_MAN( 0x1 )
+#define CFG_FPGA_ALTERA CFG_FPGA_MAN( 0x2 )
+
+
+/* fpga_xxxx function return value definitions */
+#define FPGA_SUCCESS 0
+#define FPGA_FAIL -1
+
+/* device numbers must be non-negative */
+#define FPGA_INVALID_DEVICE -1
+
+/* root data type defintions */
+typedef enum { /* typedef fpga_type */
+ fpga_min_type, /* range check value */
+ fpga_xilinx, /* Xilinx Family) */
+ fpga_altera, /* unimplemented */
+ fpga_undefined /* invalid range check value */
+} fpga_type; /* end, typedef fpga_type */
+
+typedef struct { /* typedef fpga_desc */
+ fpga_type devtype; /* switch value to select sub-functions */
+ void * devdesc; /* real device descriptor */
+} fpga_desc; /* end, typedef fpga_desc */
+
+
+/* root function definitions */
+extern void fpga_init( ulong reloc_off );
+extern int fpga_add( fpga_type devtype, void *desc );
+extern const int fpga_count( void );
+extern int fpga_load( int devnum, void *buf, size_t bsize );
+extern int fpga_dump( int devnum, void *buf, size_t bsize );
+extern int fpga_info( int devnum );
+
+#endif /* _FPGA_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * 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 _SPARTAN2_H_
+#define _SPARTAN2_H_
+
+#include <xilinx.h>
+
+extern int Spartan2_load( Xilinx_desc *desc, void *image, size_t size );
+extern int Spartan2_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int Spartan2_info( Xilinx_desc *desc );
+extern int Spartan2_reloc( Xilinx_desc *desc, ulong reloc_off );
+
+/* Slave Parallel Implementation function table */
+typedef struct {
+ Xilinx_pre_fn pre;
+ Xilinx_pgm_fn pgm;
+ Xilinx_init_fn init;
+ Xilinx_err_fn err;
+ Xilinx_done_fn done;
+ Xilinx_clk_fn clk;
+ Xilinx_cs_fn cs;
+ Xilinx_wr_fn wr;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ Xilinx_busy_fn busy;
+ Xilinx_abort_fn abort;
+ Xilinx_post_fn post;
+ int relocated;
+} Xilinx_Spartan2_Slave_Parallel_fns;
+
+/* Slave Serial Implementation function table */
+typedef struct {
+ Xilinx_pgm_fn pgm;
+ Xilinx_clk_fn clk;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ int relocated;
+} Xilinx_Spartan2_Slave_Serial_fns;
+
+/* Device Image Sizes
+ *********************************************************************/
+/* Spartan-II (2.5V) */
+#define XILINX_XC2S15_SIZE 197728/8
+#define XILINX_XC2S30_SIZE 336800/8
+#define XILINX_XC2S50_SIZE 559232/8
+#define XILINX_XC2S100_SIZE 781248/8
+#define XILINX_XC2S150_SIZE 1040128/8
+
+/* Descriptor Macros
+ *********************************************************************/
+/* Spartan-II devices */
+#define XILINX_XC2S15_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S15_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S30_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S30_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S50_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S50_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S100_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S100_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S150_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie }
+
+#endif /* _SPARTAN2_H_ */
+
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * 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
+ *
+ */
+
+#ifndef _VIRTEX2_H_
+#define _VIRTEX2_H_
+
+#include <xilinx.h>
+
+extern int Virtex2_load( Xilinx_desc *desc, void *image, size_t size );
+extern int Virtex2_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int Virtex2_info( Xilinx_desc *desc );
+extern int Virtex2_reloc( Xilinx_desc *desc, ulong reloc_off );
+
+/*
+ * Slave SelectMap Implementation function table.
+ */
+typedef struct {
+ Xilinx_pre_fn pre;
+ Xilinx_pgm_fn pgm;
+ Xilinx_init_fn init;
+ Xilinx_err_fn err;
+ Xilinx_done_fn done;
+ Xilinx_clk_fn clk;
+ Xilinx_cs_fn cs;
+ Xilinx_wr_fn wr;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ Xilinx_busy_fn busy;
+ Xilinx_abort_fn abort;
+ Xilinx_post_fn post;
+ int relocated;
+} Xilinx_Virtex2_Slave_SelectMap_fns;
+
+/* Slave Serial Implementation function table */
+typedef struct {
+ Xilinx_pgm_fn pgm;
+ Xilinx_clk_fn clk;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ int relocated;
+} Xilinx_Virtex2_Slave_Serial_fns;
+
+/* Device Image Sizes (in bytes)
+ *********************************************************************/
+#define XILINX_XC2V40_SIZE (338208 / 8)
+#define XILINX_XC2V80_SIZE (597408 / 8)
+#define XILINX_XC2V250_SIZE (1591584 / 8)
+#define XILINX_XC2V500_SIZE (2557857 / 8)
+#define XILINX_XC2V1000_SIZE (3749408 / 8)
+#define XILINX_XC2V1500_SIZE (5166240 / 8)
+#define XILINX_XC2V2000_SIZE (6808352 / 8)
+#define XILINX_XC2V3000_SIZE (9589408 / 8)
+#define XILINX_XC2V4000_SIZE (14220192 / 8)
+#define XILINX_XC2V6000_SIZE (19752096 / 8)
+#define XILINX_XC2V8000_SIZE (26185120 / 8)
+#define XILINX_XC2V10000_SIZE (33519264 / 8)
+
+/* Descriptor Macros
+ *********************************************************************/
+#define XILINX_XC2V40_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V40_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V80_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V80_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V250_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V250_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V500_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V500_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V1000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V1000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V1500_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V1500_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V2000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V2000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V3000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V3000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V4000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V4000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V6000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V6000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V8000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V8000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V10000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V10000_SIZE, fn_table, cookie }
+
+#endif /* _VIRTEX2_H_ */
+
+/* vim: set ts=4 tw=78: */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * 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 _XILINX_H_
+#define _XILINX_H_
+
+/* Xilinx Model definitions
+ *********************************************************************/
+#define CFG_SPARTAN2 CFG_FPGA_DEV( 0x1 )
+#define CFG_VIRTEX_E CFG_FPGA_DEV( 0x2 )
+#define CFG_VIRTEX2 CFG_FPGA_DEV( 0x4 )
+#define CFG_XILINX_SPARTAN2 (CFG_FPGA_XILINX | CFG_SPARTAN2)
+#define CFG_XILINX_VIRTEX_E (CFG_FPGA_XILINX | CFG_VIRTEX_E)
+#define CFG_XILINX_VIRTEX2 (CFG_FPGA_XILINX | CFG_VIRTEX2)
+/* XXX - Add new models here */
+
+
+/* Xilinx Interface definitions
+ *********************************************************************/
+#define CFG_XILINX_IF_SS CFG_FPGA_IF( 0x1 ) /* slave serial */
+#define CFG_XILINX_IF_MS CFG_FPGA_IF( 0x2 ) /* master serial */
+#define CFG_XILINX_IF_SP CFG_FPGA_IF( 0x4 ) /* slave parallel */
+#define CFG_XILINX_IF_JTAG CFG_FPGA_IF( 0x8 ) /* jtag */
+#define CFG_XILINX_IF_MSM CFG_FPGA_IF( 0x10 ) /* master selectmap */
+#define CFG_XILINX_IF_SSM CFG_FPGA_IF( 0x20 ) /* slave selectmap */
+
+/* Xilinx types
+ *********************************************************************/
+typedef enum { /* typedef Xilinx_iface */
+ min_xilinx_iface_type, /* low range check value */
+ slave_serial, /* serial data and external clock */
+ master_serial, /* serial data w/ internal clock (not used) */
+ slave_parallel, /* parallel data w/ external latch */
+ jtag_mode, /* jtag/tap serial (not used ) */
+ master_selectmap, /* master SelectMap (virtex2) */
+ slave_selectmap, /* slave SelectMap (virtex2) */
+ max_xilinx_iface_type /* insert all new types before this */
+} Xilinx_iface; /* end, typedef Xilinx_iface */
+
+typedef enum { /* typedef Xilinx_Family */
+ min_xilinx_type, /* low range check value */
+ Xilinx_Spartan2, /* Spartan-II Family */
+ Xilinx_VirtexE, /* Virtex-E Family */
+ Xilinx_Virtex2, /* Virtex2 Family */
+ max_xilinx_type /* insert all new types before this */
+} Xilinx_Family; /* end, typedef Xilinx_Family */
+
+typedef struct { /* typedef Xilinx_desc */
+ Xilinx_Family family; /* part type */
+ Xilinx_iface iface; /* interface type */
+ size_t size; /* bytes of data part can accept */
+ void * iface_fns; /* interface function table */
+ int cookie; /* implementation specific cookie */
+} Xilinx_desc; /* end, typedef Xilinx_desc */
+
+/* Generic Xilinx Functions
+ *********************************************************************/
+extern int xilinx_load( Xilinx_desc *desc, void *image, size_t size );
+extern int xilinx_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int xilinx_info( Xilinx_desc *desc );
+extern int xilinx_reloc( Xilinx_desc *desc, ulong reloc_offset );
+
+/* Board specific implementation specific function types
+ *********************************************************************/
+typedef int (*Xilinx_pgm_fn)( int assert_pgm, int flush, int cookie );
+typedef int (*Xilinx_init_fn)( int cookie );
+typedef int (*Xilinx_err_fn)( int cookie );
+typedef int (*Xilinx_done_fn)( int cookie );
+typedef int (*Xilinx_clk_fn)( int assert_clk, int flush, int cookie );
+typedef int (*Xilinx_cs_fn)( int assert_cs, int flush, int cookie );
+typedef int (*Xilinx_wr_fn)( int assert_write, int flush, int cookie );
+typedef int (*Xilinx_rdata_fn)( unsigned char *data, int cookie );
+typedef int (*Xilinx_wdata_fn)( unsigned char data, int flush, int cookie );
+typedef int (*Xilinx_busy_fn)( int cookie );
+typedef int (*Xilinx_abort_fn)( int cookie );
+typedef int (*Xilinx_pre_fn)( int cookie );
+typedef int (*Xilinx_post_fn)( int cookie );
+
+#endif /* _XILINX_H_ */
ulong data;
void (*theKernel)(int zero, int arch);
image_header_t *hdr = &header;
+ bd_t *bd = gd->bd;
#ifdef CONFIG_CMDLINE_TAG
char *commandline = getenv("bootargs");
#endif
LIB = librtc.a
-OBJS = date.o ds1302.o ds174x.o ds1306.o ds1556.o \
+OBJS = date.o ds1302.o ds1306.o ds1337.o ds1556.o ds174x.o \
m41t11.o m48t35ax.o mc146818.o mk48t59.o \
mpc8xx.o pcf8563.o
--- /dev/null
+/*
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * 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
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1337 Real Time Clock (RTC).
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_DS1337) && (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR 0x0
+#define RTC_MIN_REG_ADDR 0x1
+#define RTC_HR_REG_ADDR 0x2
+#define RTC_DAY_REG_ADDR 0x3
+#define RTC_DATE_REG_ADDR 0x4
+#define RTC_MON_REG_ADDR 0x5
+#define RTC_YR_REG_ADDR 0x6
+#define RTC_CTL_REG_ADDR 0x0e
+#define RTC_STAT_REG_ADDR 0x0f
+
+/*
+ * RTC control register bits
+ */
+#define RTC_CTL_BIT_A1IE 0x1 /* Alarm 1 interrupt enable */
+#define RTC_CTL_BIT_A2IE 0x2 /* Alarm 2 interrupt enable */
+#define RTC_CTL_BIT_INTCN 0x4 /* Interrupt control */
+#define RTC_CTL_BIT_RS1 0x8 /* Rate select 1 */
+#define RTC_CTL_BIT_RS2 0x10 /* Rate select 2 */
+#define RTC_CTL_BIT_DOSC 0x80 /* Disable Oscillator */
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_A1F 0x1 /* Alarm 1 flag */
+#define RTC_STAT_BIT_A2F 0x2 /* Alarm 2 flag */
+#define RTC_STAT_BIT_OSF 0x80 /* Oscillator stop flag */
+
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tmp)
+{
+ uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
+
+ control = rtc_read (RTC_CTL_REG_ADDR);
+ status = rtc_read (RTC_STAT_REG_ADDR);
+ sec = rtc_read (RTC_SEC_REG_ADDR);
+ min = rtc_read (RTC_MIN_REG_ADDR);
+ hour = rtc_read (RTC_HR_REG_ADDR);
+ wday = rtc_read (RTC_DAY_REG_ADDR);
+ mday = rtc_read (RTC_DATE_REG_ADDR);
+ mon_cent = rtc_read (RTC_MON_REG_ADDR);
+ year = rtc_read (RTC_YR_REG_ADDR);
+
+ DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+ "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
+ year, mon_cent, mday, wday, hour, min, sec, control, status);
+
+ if (status & RTC_STAT_BIT_OSF) {
+ printf ("### Warning: RTC oscillator has stopped\n");
+ /* clear the OSF flag */
+ rtc_write (RTC_STAT_REG_ADDR,
+ rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
+ }
+
+ tmp->tm_sec = bcd2bin (sec & 0x7F);
+ tmp->tm_min = bcd2bin (min & 0x7F);
+ tmp->tm_hour = bcd2bin (hour & 0x3F);
+ tmp->tm_mday = bcd2bin (mday & 0x3F);
+ tmp->tm_mon = bcd2bin (mon_cent & 0x1F);
+ tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+ tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+ tmp->tm_yday = 0;
+ tmp->tm_isdst= 0;
+
+ DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp)
+{
+ uchar century;
+
+ DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+ rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+
+ century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+ rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
+
+ rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+ rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+ rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+ rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+ rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+}
+
+
+/*
+ * Reset the RTC. We also enable the oscillator output on the
+ * SQW/INTB* pin and program it for 32,768 Hz output. Note that
+ * according to the datasheet, turning on the square wave output
+ * increases the current drain on the backup battery from about
+ * 600 nA to 2uA.
+ */
+void rtc_reset (void)
+{
+ rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+ return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+ i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+ return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+ return (((n / 10) << 4) | (n % 10));
+}
+
+#endif /* CONFIG_RTC_DS1337 && (CFG_COMMANDS & CFG_CMD_DATE) */