[U-Boot] [patch] U-Boot Firetux board support

Juergen Schoew Juergen at Schoew.net
Fri Oct 31 15:30:33 CET 2008


Hi U-Boot mailling list,

This patchset adds a new ARM board with the NXP PNX8181 cpu to u-boot.
The PNX8181 is an ARM926ej with an internal DSP and a baseband processor
(used for DECT). The chip also features dual ethernet, digital to analog
interface, spi, i2c and other SOC peripherals. 

The patch is against u-boot commit 055b12f2ffd7c34eea7e983a0588b24f2e69e0e3
(Date: Sun Oct 19 21:54:30 2008 +0200) but should apply to newer commits as
well, because the code is mostly seperated.

If you have any comments please email to me.

Is is possible to include that patch in the new version of u-boot?

Regards

Jürgen Schöw

--
Dipl.-Ing. Jürgen Schöw, emlix GmbH, http://www.emlix.com, mailto:js at emlix.com
Fon +49 551 30664-0, Fax -11, Bahnhofsallee 1b, 37081 Göttingen, Germany
Geschäftsführung: Dr. Uwe Kracke, Dr. Cord Seele, Ust-IdNr.: DE 205 198 055
Sitz der Gesellschaft: Göttingen, Amtsgericht Göttingen HR B 3160

emlix - your embedded linux partner
-----

Signed-off-by: Jürgen Schöw <js at emlix.com>
Signed-off-by: Sebastian Hess <sh at emlix.com>
Signed-off-by: Matthias Mwenzel <nxp at mazzoo.de>
Signed-off-by: Dirk Hörner <dirk.hoerner at dspg.com>
Signed-off-by: Andreas Weißel <andreas.weissel at dspg.com>

Diffstat:
 MAKEALL                       |    1 +
 Makefile                      |    7 +
 board/firetux/Makefile        |   62 +++
 board/firetux/config.mk       |   45 ++
 board/firetux/ethernet.c      |  970 +++++++++++++++++++++++++++++++++++++++++
 board/firetux/ethernet.h      |  234 ++++++++++
 board/firetux/firetux.c       |  554 +++++++++++++++++++++++
 board/firetux/firetux.h       |  118 +++++
 board/firetux/lowlevel_init.S |  413 ++++++++++++++++++
 board/firetux/memsetup.S      |  366 ++++++++++++++++
 board/firetux/nand.c          |   74 ++++
 board/firetux/relocate.S      |  246 +++++++++++
 board/firetux/u-boot.lds      |   57 +++
 drivers/i2c/Makefile          |    1 +
 drivers/i2c/pnx8181_i2c.c     |  302 +++++++++++++
 include/configs/firetux.h     |  455 +++++++++++++++++++
 net/bootp.c                   |   11 +
 net/eth.c                     |    7 +
 18 files changed, 3923 insertions(+), 0 deletions(-)


diff --git a/MAKEALL b/MAKEALL
index 9ccb9ac..0ba8e4d 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -480,6 +480,7 @@ LIST_ARM9="			\
 	cp926ejs		\
 	cp946es			\
 	cp966			\
+	firetux			\
 	lpd7a400		\
 	mx1ads			\
 	mx1fs2			\
diff --git a/Makefile b/Makefile
index 9a132f7..8c3b076 100644
--- a/Makefile
+++ b/Makefile
@@ -2683,6 +2683,13 @@ voiceblue_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm925t voiceblue
 
 #########################################################################
+## NXP PNX8181 "firetux"
+#########################################################################
+
+firetux_config:unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm926ejs firetux # manufacturer SOC
+
+#########################################################################
 ## S3C44B0 Systems
 #########################################################################
 
diff --git a/board/firetux/Makefile b/board/firetux/Makefile
new file mode 100644
index 0000000..a643a5e
--- /dev/null
+++ b/board/firetux/Makefile
@@ -0,0 +1,62 @@
+# firetux makefile
+#
+# (C) Copyright 2007-2008, emlix GmbH, Germany
+# Juergen Schoew <js at emlix.com>
+#
+# (C) Copyright 2008, DSPG Technologies GmbH, Germany
+# (C) Copyright 2007, NXP Semiconductors Germany GmbH
+# Matthias Wenzel, <nxp at mazzoo.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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= firetux.o ethernet.o
+SOBJS	:= lowlevel_init.o memsetup.o relocate.o
+
+#ifdef CONFIG_CMD_NAND
+COBJS	+= nand.o
+#endif
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/firetux/config.mk b/board/firetux/config.mk
new file mode 100644
index 0000000..bcdd671
--- /dev/null
+++ b/board/firetux/config.mk
@@ -0,0 +1,45 @@
+# firetux compiler config
+#
+# (C) Copyright 2007-2008, emlix GmbH, Germany
+# Juergen Schoew <js at emlix.com>
+#
+# (C) Copyright 2008, DSPG Technologies GmbH, Germany
+# (C) Copyright 2007, NXP Semiconductors Germany GmbH
+# Matthias Wenzel, <nxp at mazzoo.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
+#
+
+
+#
+# image should be loaded at 0x01000000
+#
+
+# SDRAM
+TEXT_BASE = 0x20780000
+# mobile pSRAM
+#TEXT_BASE = 0x90700000
+
+PLATFORM_CPPFLAGS += -fPIC -fPIE -fno-jump-tables # -msingle-pic-base
+
+ifneq ($(OBJTREE),$(SRCTREE))
+# We are building u-boot in a separate directory, use generated
+# .lds script from OBJTREE directory.
+LDSCRIPT := $(OBJTREE)/board/$(BOARDDIR)/u-boot.lds
+endif
diff --git a/board/firetux/ethernet.c b/board/firetux/ethernet.c
new file mode 100644
index 0000000..866d578
--- /dev/null
+++ b/board/firetux/ethernet.c
@@ -0,0 +1,970 @@
+/*
+ * pnx8181 ethernet driver (ip3912)
+ *
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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
+ */
+
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+
+#include "ethernet.h"
+#include <miiphy.h>
+
+extern unsigned int boardrevision;
+uint16_t ETN1_MADR_PHY_ADDR, ETN2_MADR_PHY_ADDR;
+
+int firetux_miiphy_initialize(bd_t *bis);
+int mii_discover_phy(void);
+int mii_negotiate_phy(void);
+
+#define ALIGN8	static __attribute__ ((aligned(8)))
+#define ALIGN4	static __attribute__ ((aligned(4)))
+
+#define PNX8181_SCON_SYSPAD0    0xc2204034
+#define PNX8181_SCON_SYSPAD4    0xc2204044
+#define PNX8181_SCON_SYSMUX0    0xc220400c
+#define PNX8181_GPIOA_PINS      0xc2104000
+#define PNX8181_GPIOA_OR        0xc2104004
+#define PNX8181_GPIOA_DR        0xc2104008
+
+/* globals */
+/* ETN1 rx */
+ALIGN8 rx_descriptor_t etn1_rxdescriptor[ETN_RX_DESCRIPTOR_NUMBER];
+ALIGN8 rx_status_t     etn1_rxstatus    [ETN_RX_DESCRIPTOR_NUMBER];
+
+/* ETN1 tx */
+ALIGN8 tx_descriptor_t etn1_txdescriptor[ETN_TX_DESCRIPTOR_NUMBER];
+ALIGN4 tx_status_t     etn1_txstatus    [ETN_TX_DESCRIPTOR_NUMBER];
+
+/* ETN2 rx */
+ALIGN8 rx_descriptor_t etn2_rxdescriptor[ETN_RX_DESCRIPTOR_NUMBER];
+ALIGN8 rx_status_t     etn2_rxstatus    [ETN_RX_DESCRIPTOR_NUMBER];
+
+/* ETN2 tx */
+ALIGN8 tx_descriptor_t etn2_txdescriptor[ETN_TX_DESCRIPTOR_NUMBER];
+ALIGN4 tx_status_t     etn2_txstatus    [ETN_TX_DESCRIPTOR_NUMBER];
+
+
+/* which interface to be currently work on           */
+/* default can be set by environment variable ethact */
+static int firetux_eth = 0;
+
+/* in the code we use the following descriptors which are either */
+/* set to the etn1 or the etn2 descriptors, depending on ethact  */
+ALIGN8 rx_descriptor_t *etn_rxdescriptor = etn1_rxdescriptor;
+ALIGN8 rx_status_t     *etn_rxstatus     = etn1_rxstatus;
+ALIGN8 tx_descriptor_t *etn_txdescriptor = etn1_txdescriptor;
+ALIGN8 tx_status_t     *etn_txstatus     = etn1_txstatus;
+
+/* also the base address is switched for etn1 and etn2,          */
+/* except for the MII registers etn1_m* which are only available */
+/* on etn1 */
+uint32_t etn_base = ETN1;
+/* we first try Vega Platform III-a settings */
+uint16_t firetux_phy_addr = 0x0100;
+
+
+static void firetux_set_ethact(int act, int hardwarerevision)
+{
+	switch (hardwarerevision) {
+	/* EZ_MCP, Vega_pnx8181_basestation Platform III-a */
+	case 1:
+	case 2:
+		ETN1_MADR_PHY_ADDR = 0x00000100;
+		ETN2_MADR_PHY_ADDR = 0x00000200;
+		break;
+	/* Vega_pnx8181_basestation Platform III-b, III-c */
+	case 3:
+	case 4:
+	default:
+		ETN1_MADR_PHY_ADDR = 0x00001E00;
+		ETN2_MADR_PHY_ADDR = 0x00001D00;
+		break;
+	}
+	if (act) {
+		etn_rxdescriptor = etn2_rxdescriptor;
+		etn_rxstatus     = etn2_rxstatus;
+		etn_txdescriptor = etn2_txdescriptor;
+		etn_txstatus     = etn2_txstatus;
+		etn_base         = ETN2;
+		firetux_phy_addr = (uint16_t) ETN2_MADR_PHY_ADDR;
+	} else {
+		etn_rxdescriptor = etn1_rxdescriptor;
+		etn_rxstatus     = etn1_rxstatus;
+		etn_txdescriptor = etn1_txdescriptor;
+		etn_txstatus     = etn1_txstatus;
+		etn_base         = ETN1;
+		firetux_phy_addr = (uint16_t) ETN1_MADR_PHY_ADDR;
+	}
+}
+
+static void firetux_reset_phy(int hardwareversion)
+{
+	switch (hardwareversion) {
+	case 1:
+	case 2:
+	case 3:
+		/* set GPIOa12 direction to output */
+		*(vu_long *)(PNX8181_GPIOA_DR) = (((*(vu_long *)
+				(PNX8181_GPIOA_DR)) & 0xffffefff) | 0x00001000);
+		/* ETH_RESET_N */
+		*(vu_long *)(PNX8181_GPIOA_OR) = ((*(vu_long *)
+				(PNX8181_GPIOA_OR)) & 0xffffefff);
+		udelay(256000);
+		*(vu_long *)(PNX8181_GPIOA_OR) = (((*(vu_long *)
+				(PNX8181_GPIOA_OR)) & 0xffffefff) | 0x00001000);
+		udelay(100000);
+		break;
+	case 4:
+		*(vu_long *) (PNX8181_SCON_SYSPAD4) = (((*(vu_long *)
+			(PNX8181_SCON_SYSPAD4)) & 0xf7f5755f) | 0x080a8aa0);
+		*(vu_long *) (PNX8181_SCON_SYSMUX0) = ((*(vu_long *)
+					(PNX8181_SCON_SYSMUX0)) & 0xffffff3f);
+		/* set GPIOa3 direction to output */
+		*(vu_long *) (PNX8181_GPIOA_DR) = (((*(vu_long *)
+				(PNX8181_GPIOA_DR)) & 0xfffffff7) | 0x00000008);
+		/* ETH_RESET_N */
+		*(vu_long *) (PNX8181_GPIOA_OR) = ((*(vu_long *)
+					(PNX8181_GPIOA_OR)) & 0xfffffff7);
+		udelay(256000);
+		*(vu_long *) (PNX8181_GPIOA_OR) = (((*(vu_long *)
+				(PNX8181_GPIOA_OR)) & 0xfffffff7) | 0x00000008);
+		udelay(100000);
+		break;
+	default:
+		puts("Unknown Board, can't reset network phy\n");
+		break;
+	}
+}
+
+static int firetux_eth_init_clocks(void)
+{
+	/* first things first, release the RSTEXT signal,
+	 * which keeps the PHYs in reset */
+	*(vu_long *) (WDRU + WDRUCON) |= 0x0001;
+
+	/* init ETN clocks */
+
+	/* set ETNREFCLK to internal CGU clock, assuming a 13.824MHz crystal */
+	/* for other xtals see NXP's validation tests,
+	 * lib/tools/source/swift_tools.c  */
+	*(vu_long *) CGU_PER2CON = (15<<9) | (62<<3) | 3;
+
+	/* turn on PLL */
+	*(vu_long *) CGU_PER2CON |= 0x00010000;
+	/* wait for PLL lock */
+	while (!(*(vu_long *) CGU_PER2CON & 0x00020000));
+
+	/* ungate ETN clocks */
+	*(vu_long *) CGU_PER2CON |= 0x00802000;
+
+	return 0;
+}
+
+static int firetux_eth_init_rxdescriptor(void)
+{
+	*(vu_long *) (etn_base + ETN_RXDESCRIPTOR) = (vu_long) etn_rxdescriptor;
+	*(vu_long *) (etn_base + ETN_RXSTATUS)     = (vu_long) etn_rxstatus;
+	*(vu_long *) (etn_base + ETN_RXCONSUMEINDEX) = 0x00000000;
+	*(vu_long *) (etn_base + ETN_RXDESCRIPTORNUMBER) =
+						ETN_RX_DESCRIPTOR_NUMBER - 1;
+
+	/* allocate rx-buffers, but only once, we're called multiple times! */
+	static void *rxbuf = 0;
+	if (!rxbuf)
+		rxbuf = malloc(MAX_ETH_FRAME_SIZE * ETN_RX_DESCRIPTOR_NUMBER);
+	if (!rxbuf) {
+		puts("ERROR: couldn't allocate rx buffers!\n");
+		return -1;
+	}
+
+	int i;
+	for (i = 0; i < ETN_RX_DESCRIPTOR_NUMBER; i++) {
+		etn_rxdescriptor[i].packet = rxbuf + i * MAX_ETH_FRAME_SIZE;
+		etn_rxdescriptor[i].control =
+					MAX_ETH_FRAME_SIZE - sizeof(vu_long);
+		etn_rxstatus[i].info = 0;
+		etn_rxstatus[i].hashCRC = 0;
+	}
+	return 0;
+}
+
+static int firetux_eth_init_txdescriptor(void)
+{
+	*(vu_long *) (etn_base + ETN_TXDESCRIPTOR) =
+						(vu_long) etn_txdescriptor;
+	*(vu_long *) (etn_base + ETN_TXSTATUS)     = (vu_long) etn_txstatus;
+	*(vu_long *) (etn_base + ETN_TXPRODUCEINDEX) = 0x00000000;
+	*(vu_long *) (etn_base + ETN_TXDESCRIPTORNUMBER) =
+						ETN_TX_DESCRIPTOR_NUMBER - 1;
+
+	int i;
+	for (i = 0; i < ETN_TX_DESCRIPTOR_NUMBER; i++) {
+		etn_txdescriptor[i].packet = 0;
+		etn_txdescriptor[i].control = 0;
+		etn_txstatus[i].info = 0;
+	}
+	return 0;
+}
+
+static void PHY_write(uint16_t a, uint16_t d)
+{
+	uint32_t status;
+	int i = 0;
+
+	a &= 0x001f; /* 5 bit PHY register address */
+
+	*(vu_long *) (ETN1 + ETN_MADR) = firetux_phy_addr | a;
+	*(vu_long *) (ETN1 + ETN_MWTD) = d;
+
+	/* poll for done */
+	while ((status = *(vu_long *) (ETN1 + ETN_MIND)) && i < 1000000)
+		i++;
+	if (status) {
+		printf("ERROR: PHY_write(%d) = 0x%x [eth=%d, phy_addr=%x]\n",
+			a, status, firetux_eth, firetux_phy_addr);
+	} else {
+#ifdef ET_DEBUG
+		printf("### PHY_write(%2.d, 0x%4.4x) success after %d cycles "
+			"[eth=%d, phy_addr=%x]\n", a, d, i, firetux_eth,
+							firetux_phy_addr);
+#endif
+	}
+}
+
+static uint16_t PHY_read(uint16_t a)
+{
+	uint32_t status;
+	int i = 0;
+
+	a &= 0x001f; /* 5 bit PHY register address */
+	*(vu_long *) (ETN1 + ETN_MADR) = firetux_phy_addr | a;
+	*(vu_long *) (ETN1 + ETN_MCMD) = 0x00000001;
+
+	/* poll for done */
+	while ((status = ((*(vu_long *)
+			    (ETN1 + ETN_MIND))) & 0x7) && i < 1000000)
+		i++;
+
+	uint16_t d = *(vu_long *) (ETN1 + ETN_MRDD);
+
+	if (status) {
+		printf("ERROR: PHY_read(%d) = 0x%x after %d cycles [eth=%d, "
+			"phy_addr=%x]\n", a, status, i, firetux_eth,
+							firetux_phy_addr);
+	} else {
+#ifdef ET_DEBUG
+		printf("### PHY_read(%2.d)=0x%4.4x success after %d cycles "
+			"[eth=%d, phy_addr=%x]\n", a, d, i, firetux_eth,
+							firetux_phy_addr);
+#endif
+	}
+
+	*(vu_long *) (ETN1 + ETN_MCMD) = 0x00000000;
+
+	return d;
+}
+
+
+int eth_init_macreset(void)
+{
+	/* reset MAC layer */
+	*(vu_long *) (etn_base + ETN_MAC1) = 0x0000cf00;
+	/* release MAC soft reset */
+	*(vu_long *) (etn_base + ETN_MAC1) = 0x00000000;
+	/* reset rx-path, tx-path, host registers */
+	*(vu_long *) (etn_base + ETN_COMMAND) = 0x00000038;
+	/* reset RMII, 100Mbps MAC, 10Mbps MAC */
+	*(vu_long *) (etn_base + ETN_SUPP) = 0x1888;
+	*(vu_long *) (etn_base + ETN_SUPP) = 0x1000;
+
+	return 0;
+}
+
+/*
+ * returns -2 if phy init failed
+ * returns -1 if rx/tx-path init failed
+ */
+static int firetux_eth_init_macinit(void)
+{
+	int error = 0, j = 0, i = 0;
+
+	/* before enabling the rx-path we need to set up rx-descriptors */
+	if (firetux_eth_init_rxdescriptor())
+		return -1;
+	if (firetux_eth_init_txdescriptor())
+		return -1;
+
+	/* release rx-path, tx-path, host registers reset
+	 * set FullDuplex, enable RMMI, enable rx+tx
+	 * no flow control, no frames<64b */
+	*(vu_long *) (etn_base + ETN_COMMAND) = 0x00000683;
+
+#ifdef ET_DEBUG
+	printf("PHY init [eth=%d, phy_addr=%x] ...\n",
+					firetux_eth, firetux_phy_addr);
+#endif
+
+	/* NOTE: ETN_PHY_SPECIAL_MODES (register 18) must be written
+	 * before any other register of the PHY !
+	 * NOTE: for unknown reason the first write after
+	 * starting u-boot from power down will fail for the PHY
+	 * first addressed.  Also if not resetting BOTH MAC cores
+	 * prior this, we will fail ad infimum in writing this register
+	 * via following loop on the PHY addressed first.
+	 * NOTE also: unfortunatly this behaviour is not deterministic
+	 */
+	do {
+		PHY_write(ETN_PHY_SPECIAL_MODES,
+					0x4020 | (firetux_phy_addr >> 8));
+	} while (((PHY_read(ETN_PHY_SPECIAL_MODES) & 0x40ff)
+		    != (0x4020 | (firetux_phy_addr >> 8))) &&  ((++j) < 500));
+	if (j == 500) {
+		printf("PHY init failed to set SPECIAL MODES reg "
+			"[eth=%d, phy_addr=%x]\n", firetux_eth, firetux_phy_addr);
+		error++;
+	}
+
+	/* PHY soft reset */
+	PHY_write(ETN_PHY_BASIC_CONTROL, 0x8000);
+	/* HW spec recommends 256 ms, IEEE recommends 500 ms */
+	udelay(256000);
+
+	/* still poll for reset done */
+	while ((PHY_read(ETN_PHY_BASIC_CONTROL) & 0x8000) && i < 50)
+		i++;
+	if (i == 50) {
+		printf("PHY init failed: reset timed out [eth=%d, phy_addr=%x]"
+					"\n", firetux_eth, firetux_phy_addr);
+		error++;
+	}
+
+#ifdef ET_DEBUG
+	printf("RESET DONE after %d cycles\n", i);
+#endif
+
+	PHY_write(ETN_PHY_BASIC_CONTROL, 0x0100);
+
+	PHY_write(ETN_PHY_MODE_CONTROL_STATUS, 0x0c00);
+	PHY_write(ETN_PHY_SPECIAL_MODE_CONTROL_STATUS, 0x0040);
+
+#ifdef ET_DEBUG
+	printf("PHY init done.\n");
+#endif
+
+	/* set max packet length to 1536 bytes */
+	*(vu_long *) (etn_base + ETN_MAXF) = MAX_ETH_FRAME_SIZE;
+
+	/* full duplex */
+	*(vu_long *) (etn_base + ETN_MAC2) = 0x00000023;
+
+	/* inter packet gap register */
+	*(vu_long *) (etn_base + ETN_IPGT) = 0x15;
+	*(vu_long *) (etn_base + ETN_IPGR) = 0x12;
+
+	/* enable rx, receive all frames */
+	*(vu_long *) (etn_base + ETN_MAC1) = 0x00000003;
+
+	/* accept all multicast, broadcast and station packets */
+	*(vu_long *) (etn_base + ETN_RXFILTERCTRL) = 0x00000026;
+
+	if (error)
+		return -2;
+	else
+		return 0;
+}
+
+
+/**********************************************************************/
+/* set MAC address                                                    */
+/**********************************************************************/
+
+static int firetux_eth_init_setMAC(bd_t *bis)
+{
+
+	uchar mac[6];
+	char *mac_string = getenv("ethaddr");
+	int i;
+	char *pmac = mac_string;
+	char *end;
+
+	if (!mac_string) {
+		puts("ERROR: ethaddr is not set!\n");
+		return -1;
+	}
+	if (strlen(mac_string) != 17) {
+		puts("ERROR: ethaddr is not set propperly!\n");
+		return -1;
+	}
+	for (i = 0; i < 6; i++) {
+		mac[i] = simple_strtoul(pmac, &end, 16);
+		pmac = (*end) ? end + 1 : end;
+	}
+	if (mac_string + 17 != end) {
+		puts("ERROR: couldn't parse ethaddr!\n");
+		return -1;
+	}
+
+	/* we grab two MAC addresses, the even one on ETN1,
+	 * the odd one on ETN2 */
+	if (firetux_eth)
+		mac[5] |= 1;
+	else
+		mac[5] &= 0xfe;
+
+#ifdef ET_DEBUG
+	printf("ETN%d @0x%08lx using mac address "
+		"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", firetux_eth+1,
+		etn_base, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+#endif
+
+	*(vu_long *) (etn_base + ETN_SA0) = (mac[5]<<8) | mac[4];
+	*(vu_long *) (etn_base + ETN_SA1) = (mac[3]<<8) | mac[2];
+	*(vu_long *) (etn_base + ETN_SA2) = (mac[1]<<8) | mac[0];
+	bis->bi_enetaddr[0] = mac[0];
+	bis->bi_enetaddr[1] = mac[1];
+	bis->bi_enetaddr[2] = mac[2];
+	bis->bi_enetaddr[3] = mac[3];
+	bis->bi_enetaddr[4] = mac[4];
+	bis->bi_enetaddr[5] = mac[5];
+
+	return 0;
+}
+
+
+int ip3912_initialize(bd_t *bis)
+{
+	int i, failed_phy_init = 0;
+
+	/* ETH_RESET_N */
+	firetux_reset_phy(boardrevision);
+
+	if (firetux_eth_init_clocks())
+		return -1;
+
+	/*
+	 * In order to get the PHYs initialized both MAC controllers need to
+	 * be resetted.  Note that still the first write access to the PHY
+	 * adressed first will fail (this is cmd to write register 18 in
+	 * function eth_mac_init()).
+	 * Can't explain that, thus this should be a work-around to get
+	 * both PHYs initialized without having to do a 'reset' from u-boot
+	 * shell.
+	 * Maybe this problem is due to heat/warmth.
+	 */
+	for (i = 0; i < 2; i++) {
+		firetux_eth = i;
+		firetux_set_ethact(firetux_eth, boardrevision);
+		eth_init_macreset();
+	}
+
+	/* reset MII mgmt, set MII clock */
+	*(vu_long *) (ETN1 + ETN_MCFG) = 0x0000801c;
+	*(vu_long *) (ETN1 + ETN_MCFG) = 0x0000001c;
+
+	firetux_eth = failed_phy_init;
+	/* We add another work-around here to get both phy's initialized
+	 * If init of the 1st phy did no succeed, try again after init of the
+	 * 2nd phy. */
+	for (i = 0; i < (2 + failed_phy_init); i++) {
+		firetux_eth = (i%2);
+		firetux_set_ethact(firetux_eth, boardrevision);
+		switch (firetux_eth_init_macinit()) {
+		case -1:
+			return -1;
+			break;
+		case -2:
+			if (i == 0)
+				failed_phy_init = 1;
+			break;
+		}
+		if (firetux_eth_init_setMAC(bis))
+			return -1;
+
+	}
+
+	firetux_miiphy_initialize(bis);
+
+#if defined(CONFIG_DISCOVER_PHY)
+	mii_discover_phy();
+#endif
+
+	return 0;
+}
+
+
+int eth_init(bd_t *bis)
+{
+	/* we only set the mac and phy addresses here, the rest of the
+	 * initialisation is already done through ip3912_initialize(), called
+	 * from net/net.c eth_initialize() */
+	char *act = getenv("ethact");
+
+	if (!act) {
+		puts("environment variable \"ethact\" is not set, "
+					"defaulting to interface ETN1\n");
+		firetux_eth = 0;
+	} else {
+		if ((0 == strcmp(act, "ETN1")) || (0 == strcmp(act, "0"))) {
+			firetux_eth = 0;
+		} else {
+			if ((0 == strcmp(act, "ETN2"))
+			    || (0 == strcmp(act, "1"))) {
+				firetux_eth = 1;
+			} else {
+				puts("supported interfaces are: "
+						"ETN1 or ETN2, using ETN1\n");
+				firetux_eth = 0;
+			}
+		}
+	}
+
+#ifdef ET_DEBUG
+	printf("using interface ETN%d\n", firetux_eth+1);
+#endif
+	firetux_set_ethact(firetux_eth, boardrevision);
+
+	if (firetux_eth_init_setMAC(bis))
+		return -1;
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	/* check autonegotiation */
+	mii_negotiate_phy();
+#endif
+
+	return 0;
+}
+
+int firetux_select_eth(void)
+{
+	/* hack to make net/bootp.c BootpRequest happy,
+	 * which need the correct MAC */
+	bd_t *bis = NULL;
+	eth_init(bis);
+	return firetux_eth;
+}
+
+/* Send a packet */
+int eth_send(volatile void *packet, int length)
+{
+	if ((length > MAX_ETH_FRAME_SIZE) || (length <= 0)) {
+		printf("ERROR: cannot transmit a %d bytes frame!\n", length);
+		return -1;
+	}
+
+	uint32_t next_packet;
+	uint32_t this_packet;
+	uint32_t last_packet;
+
+	this_packet = *(vu_long *) (etn_base + ETN_TXPRODUCEINDEX);
+	next_packet = (this_packet + 1) % ETN_TX_DESCRIPTOR_NUMBER;
+	last_packet = *(vu_long *) (etn_base + ETN_TXCONSUMEINDEX);
+
+#define ETN_TX_MAX_RETRY	1000000
+	int i = 0;
+	/* wait until the FIFO is ready to accept a new packet */
+
+	while ((this_packet == ((last_packet + ETN_TX_DESCRIPTOR_NUMBER - 1)
+		    % ETN_TX_DESCRIPTOR_NUMBER)) && (i < ETN_TX_MAX_RETRY)) {
+#ifdef ET_DEBUG
+		/* debug print when FIFO full*/
+		if ((i > 50000) && (!(i % 50000))) {
+			this_packet = *(vu_long *)
+						(etn_base + ETN_TXPRODUCEINDEX);
+			last_packet = *(vu_long *)
+						(etn_base + ETN_TXCONSUMEINDEX);
+			printf("this=%3.d, last=%3.d, i=%d\n",
+						this_packet, last_packet, i);
+		}
+#endif
+		i++;
+		last_packet = *(vu_long *) (etn_base + ETN_TXCONSUMEINDEX);
+	}
+	if (i == ETN_TX_MAX_RETRY) {
+		printf("tx FAILED after %d cycles\n", i);
+		return -1;
+	}
+	if (i)
+		printf("tx after %d cycles\n", i);
+
+	etn_txdescriptor[this_packet].packet  = packet;
+	etn_txdescriptor[this_packet].control = (length-1) |
+		ETN_CONTROL_INTERRUPT | ETN_CONTROL_LAST;
+
+	/* let the HW know a new packet is ready */
+	*(vu_long *) (etn_base + ETN_TXPRODUCEINDEX) = next_packet;
+
+	return 0;
+}
+
+/* Check for received packets */
+int eth_rx(void)
+{
+	uint16_t rxconsume = (uint16_t)(*(vu_long *)
+					(etn_base + ETN_RXCONSUMEINDEX));
+	uint16_t rxproduce = (uint16_t)(*(vu_long *)
+					(etn_base + ETN_RXPRODUCEINDEX));
+	uint16_t psize = 0;
+#ifdef ET_DEBUG
+	printf("eth_rx: receive_rsv 0x%08lx\n", *(vu_long *)
+							(etn_base + ETN_RSV));
+	printf("eth_rx: consume 0x%04lx produce 0x%04lx\n",
+							rxconsume, rxconsume);
+#endif
+	while (rxconsume != rxproduce) {
+		rxproduce = (uint16_t)(*(vu_long *)
+					    (etn_base + ETN_RXPRODUCEINDEX));
+		/* psize = etn_rxdescriptor[rxconsume].control & 0x07ff; */
+		psize = (etn_rxstatus[rxconsume].info & 0x07ff) + 1;
+		/* psize = (*(vu_long *) (etn_base + ETN_RSV)) & 0xffff; */
+		if (psize > MAX_ETH_FRAME_SIZE) {
+			printf("dropping %d bytes frame (too large)!\n",
+									psize);
+		} else {
+#ifdef ET_DEBUG
+			printf("Ethernet receive packet: %d bytes\n", psize);
+			printf("ETH receive status: 0x%08lx\n",
+						etn_rxstatus[rxconsume].info);
+			print_buffer(
+				(vu_long)etn_rxdescriptor[rxconsume].packet,
+				(void *)etn_rxdescriptor[rxconsume].packet,
+								1, psize, 16);
+#endif
+			NetReceive(etn_rxdescriptor[rxconsume].packet, psize);
+		}
+		rxconsume = (rxconsume + 1) % ETN_RX_DESCRIPTOR_NUMBER;
+		*(vu_long *) (etn_base + ETN_RXCONSUMEINDEX) = rxconsume;
+	}
+	return psize;
+}
+
+/* stop SCC */
+void eth_halt(void)
+{
+}
+
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+int firetux_miiphy_read(char *devname, unsigned char addr,
+				unsigned char reg, unsigned short *value)
+{
+	int saved_eth = firetux_eth, saved_phy_addr = firetux_phy_addr;
+
+	addr = addr & 0x1f;
+
+	switch (addr) {
+	case  1:
+	case 30:
+		firetux_eth = 0;
+		break;
+	case  2:
+	case 29:
+		firetux_eth = 1;
+		break;
+	default:
+		*value = 0xffff;
+		return -1;
+		break;
+	}
+	firetux_phy_addr = addr << 8;
+	*value = (unsigned short) PHY_read(reg);
+	firetux_eth = saved_eth;
+	firetux_phy_addr = saved_phy_addr;
+
+	return 0;
+}
+
+int firetux_miiphy_write(char *devname, unsigned char addr,
+				unsigned char reg, unsigned short value)
+{
+	int saved_eth = firetux_eth, saved_phy_addr = firetux_phy_addr;
+
+	addr = addr & 0x1f;
+
+	switch (addr) {
+	case  1:
+	case 30:
+		firetux_eth = 0;
+		break;
+	case  2:
+	case 29:
+		firetux_eth = 1;
+		break;
+	default:
+		return -1;
+		break;
+	}
+	firetux_phy_addr = addr << 8;
+	PHY_write(reg, value);
+	firetux_eth = saved_eth;
+	firetux_phy_addr = saved_phy_addr;
+
+	return 0;
+}
+
+int mii_negotiate_phy(void)
+{
+	char *mode;
+	int speed = 0, duplex = 0, autonegotiate = 0, status, i;
+
+
+	/* only set phy if exists */
+	if (PHY_read(PHY_PHYIDR1) == 0xffff)
+		return -1;
+
+	/* get mode from environment */
+	mode = getenv("phymode");
+	if (mode  != NULL) {
+		if (0 == strcmp(mode, "auto")) {
+			autonegotiate = 1;
+			speed = 100;
+			duplex = 1;
+		} else {
+			if (0 == strcmp(mode, "100FD")) {
+				speed = 100;
+				duplex = 1;
+			}
+			if (0 == strcmp(mode, "100HD")) {
+				speed = 100;
+				duplex = 0;
+			}
+			if (0 == strcmp(mode, "10FD")) {
+				speed = 10;
+				duplex = 1;
+			}
+			if (0 == strcmp(mode, "10HD")) {
+				speed = 10;
+				duplex = 0;
+			}
+			autonegotiate = 0;
+		}
+	} else {
+		/* we use 10Mbit FD as fallback */
+		autonegotiate = 0;
+		speed = 10;
+		duplex = 1;
+	}
+
+	/* do autonegotiation */
+	if (autonegotiate) {
+		/* 10/100 and FD/HD mode supported, ieee802.3 */
+		PHY_write(ETN_PHY_AUTONEG_ADV, ((0xf << 5)|1));
+		/* force autorenegotiation */
+		PHY_write(ETN_PHY_BASIC_CONTROL,
+					((1<<13)|(1<<12)|(1<<9)|(1<<8)));
+	} else {
+		/* only advertise the selected mode */
+		i = 0x1e0;
+		if (speed == 100)
+			i &= 0x180;
+		else
+			i &= 0x060;
+		if (duplex)
+			i &= 0x140;
+		else
+			i &= 0x0a0;
+		/* set advertise mode */
+		PHY_write(ETN_PHY_AUTONEG_ADV, (i|1));
+		/* we set the phy parameter */
+		PHY_write(ETN_PHY_BASIC_CONTROL, ((duplex ? (1<<8) : 0) |
+				(1<<9) | ((speed == 100) ? (1<<13) : 0)));
+	}
+
+	/* wait for negotiation finished (max 2.5s) */
+	i = 0;
+	while (((PHY_read(ETN_PHY_BASIC_STATUS) & (1<<5)) == 0) && (i < 250)) {
+		udelay(10000);
+		i++;
+	}
+	if (i == 250)
+		puts("link detection failed\n");
+
+
+	/* check for link */
+	if (PHY_read(ETN_PHY_BASIC_STATUS) & (1<<2)) {
+		/* OK link present */
+		status = PHY_read(ETN_PHY_SPECIAL_MODE_CONTROL_STATUS);
+		speed = (status & (1<<2)) ? 10 : 100;
+		duplex = (status & (1<<4)) ? 1 : 0;
+	}
+
+	/* program the mac */
+	*(vu_long *) (etn_base + ETN_SUPP) =
+		 ((*(vu_long *) (etn_base + ETN_SUPP) & 0x000018fb) |
+						((speed == 100) ? (1<<8) : 0));
+	*(vu_long *) (etn_base + ETN_MAC2) =
+		 ((*(vu_long *) (etn_base + ETN_MAC2) & 0x000073fe) | duplex);
+	/* release rx-path, tx-path, host registers reset
+	 * set Duplex, enable RMII, enable rx+tx
+	 * no flow control, no frames<64b */
+	*(vu_long *) (etn_base + ETN_COMMAND) =
+					0x00000283 | (duplex ? (1<<10) : 0);
+
+	status = PHY_read(ETN_PHY_SPECIAL_MODE_CONTROL_STATUS);
+	printf(" ETN%d %s negotiation", (firetux_eth + 1),
+				(status & (1<<12)) ? "Auto" : "Manual");
+	printf(" (10%s Mbit", (status & (1<<3)) ? "0" : "");
+	printf(" %sD", (status & (1<<4)) ? "F" : "H");
+	udelay(256000);
+	status = PHY_read(ETN_PHY_BASIC_STATUS);
+	printf(" (%s)\n", (status & 1<<2)
+			? "Link detected" : "No Link detected, trying anyway");
+
+	return 0;
+}
+
+#if defined(CONFIG_DISCOVER_PHY)
+int mii_discover_phy(void)
+{
+	unsigned short id1, id2;
+	int phytype, phyno;
+
+	for (phyno = 0; phyno <= 31 ; ++phyno) {
+		firetux_miiphy_read("mii_discover_phy",
+						phyno, PHY_PHYIDR1, &id1);
+		if (id1 != 0xffff) {
+			firetux_miiphy_read("mii_discover_phy",
+						phyno, PHY_PHYIDR2, &id2);
+			phytype = ((id1 << 16) | id2);
+#ifdef ET_DEBUG
+			puts("Using Transceiver: ");
+			switch (phytype & 0xfffffff0) {
+			case PHY_ID_LXT970:
+						puts("LXT970");
+						break;
+			case PHY_ID_LXT971:
+						puts("LXT971");
+						break;
+			case PHY_ID_82555:
+						puts("82555");
+						break;
+			case PHY_ID_QS6612:
+						puts("QS6612");
+						break;
+			case PHY_ID_AMD79C784:
+						puts("AMD79C784");
+						break;
+			case PHY_ID_LSI80225:
+						puts("LSI L80225");
+						break;
+			case PHY_ID_LSI80225B:
+						puts("LSI L80225/B");
+						break;
+			case PHY_ID_DM9161:
+						puts("Davicom DM9161");
+						break;
+			case PHY_ID_KSM8995M:
+						puts("MICREL KS8995M");
+						break;
+			case PHY_ID_SMSC8700:
+						puts("SMSC Lan 8700");
+						break;
+			default:
+						printf("0x%08x", phytype);
+						break;
+		}
+		printf(" @ ETN%d\n", phyno);
+#endif
+	    }
+	}
+
+	return 0;
+}
+#endif /* CONFIG_DISCOVER_PHY */
+
+#endif /* defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) */
+
+int firetux_miiphy_initialize(bd_t *bis)
+{
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register("pnx8181", firetux_miiphy_read, firetux_miiphy_write);
+#endif
+	return 0;
+}
+
+
+int firetux_eth_check_vega_phy(void)
+{
+	int j, works_ok;
+
+	/* select pull_down for GPIO a3 */
+	*(vu_long *)(PNX8181_SCON_SYSPAD0) |= ((3<<6)|(3<<24));
+
+	/* set GPIO a3 and a12 to low */
+	*(vu_long *)(PNX8181_GPIOA_DR) =
+		(((*(vu_long *) (PNX8181_GPIOA_DR)) & 0xffffeff7) | 0x00001008);
+	*(vu_long *)(PNX8181_GPIOA_OR) =
+		((*(vu_long *) (PNX8181_GPIOA_OR)) & 0xffffeff7);
+
+	works_ok = CONFIG_MAX_BOARDREVISIONS;
+	do {
+		/* ETH_RESET_N */
+		firetux_reset_phy(works_ok);
+
+		if (firetux_eth_init_clocks())
+			puts("Error setting ETN clock\n");
+
+		/* reset MII mgmt, set MII clock */
+		*(vu_long *) (ETN1 + ETN_MCFG) = 0x0000801c;
+		*(vu_long *) (ETN1 + ETN_MCFG) = 0x0000001c;
+
+		/* enable RMMI */
+		*(vu_long *) (etn_base + ETN_COMMAND) = 0x00000400;
+
+		firetux_set_ethact(0, works_ok);
+		eth_init_macreset();
+		/* NOTE: ETN_PHY_SPECIAL_MODES (register 18) must be written
+		 * before any other register of the PHY ! */
+		j = 0;
+		do {
+			PHY_write(ETN_PHY_SPECIAL_MODES,
+					0x40e0 | (firetux_phy_addr>>8));
+		} while (((PHY_read(ETN_PHY_SPECIAL_MODES) & 0x40ff)
+			!= (0x40e0|(firetux_phy_addr>>8))) && ((++j) < 500));
+
+		firetux_set_ethact(1, works_ok);
+		eth_init_macreset();
+
+		/* NOTE: ETN_PHY_SPECIAL_MODES (register 18) must be written
+		 * before any other register of the PHY ! */
+		j = 0;
+		do {
+			PHY_write(ETN_PHY_SPECIAL_MODES,
+					0x40e0 | (firetux_phy_addr>>8));
+		} while (((PHY_read(ETN_PHY_SPECIAL_MODES) & 0x40ff)
+			    != (0x40e0 | (firetux_phy_addr >> 8)))
+			&& ((++j) < 500));
+
+		if (PHY_read(PHY_PHYIDR1) != 0xffff)
+			return works_ok;
+
+		works_ok--;
+	    } while (works_ok >= boardrevision);
+
+	    return 0; /* we did not find a working ethernet phy */
+}
+
diff --git a/board/firetux/ethernet.h b/board/firetux/ethernet.h
new file mode 100644
index 0000000..6caea11
--- /dev/null
+++ b/board/firetux/ethernet.h
@@ -0,0 +1,234 @@
+/*
+ * pnx8181 ethernet driver interface (ip3912)
+ *
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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
+ */
+
+/*******************************/
+/* exported ethernet functions */
+/*******************************/
+int firetux_eth_check_vega_phy(void);
+int mii_discover_phy(void);
+int firetux_miiphy_write(char *devname, unsigned char addr,
+				unsigned char reg, unsigned short value);
+int firetux_miiphy_read(char *devname, unsigned char addr,
+				unsigned char reg, unsigned short *value);
+
+
+/* NXP's OUI registered @ IEEE  */
+#define NXP_ETN_OUI		0x006037
+
+
+/*************************/
+/* pnx8181 ETN registers */
+/*************************/
+#define ETN1			0xC1600000
+#define ETN2			0xC1700000
+
+#define ETN_MAC1                 0x0000
+#define ETN_MAC2                 0x0004
+#define ETN_IPGT                 0x0008
+#define ETN_IPGR                 0x000c
+#define ETN_CLRT                 0x0010
+#define ETN_MAXF                 0x0014
+#define ETN_SUPP                 0x0018
+#define ETN_TEST                 0x001c
+#define ETN_MCFG                 0x0020
+#define ETN_MCMD                 0x0024
+#define ETN_MADR                 0x0028
+#define ETN_MWTD                 0x002c
+#define ETN_MRDD                 0x0030
+#define ETN_MIND                 0x0034
+#define ETN_SA0                  0x0040
+#define ETN_SA1                  0x0044
+#define ETN_SA2                  0x0048
+#define ETN_COMMAND              0x0100
+#define ETN_STATUS               0x0104
+#define ETN_RXDESCRIPTOR         0x0108
+#define ETN_RXSTATUS             0x010c
+#define ETN_RXDESCRIPTORNUMBER   0x0110
+#define ETN_RXPRODUCEINDEX       0x0114
+#define ETN_RXCONSUMEINDEX       0x0118
+#define ETN_TXDESCRIPTOR         0x011c
+#define ETN_TXSTATUS             0x0120
+#define ETN_TXDESCRIPTORNUMBER   0x0124
+#define ETN_TXPRODUCEINDEX       0x0128
+#define ETN_TXCONSUMEINDEX       0x012c
+#define ETN_TXRTDESCRIPTOR       0x0130
+#define ETN_TXRTSTATUS           0x0134
+#define ETN_TXRTDESCRIPTORNUMBER 0x0138
+#define ETN_TXRTPRODUCEINDEX     0x013c
+#define ETN_TXRTCONSUMEINDEX     0x0140
+#define ETN_QOSTIMEOUT           0x0148
+#define ETN_TSV0                 0x0158
+#define ETN_TSV1                 0x015c
+#define ETN_RSV                  0x0160
+#define ETN_FLOWCONTROLCOUNTER   0x0170
+#define ETN_FLOWCONTROLSTATUS    0x0174
+#define ETN_RXFILTERCTRL         0x0200
+#define ETN_RXFILTERWOLSTATUS    0x0204
+#define ETN_RXFILTERWOLCLEAR     0x0208
+#define ETN_HASHFILTERL          0x0210
+#define ETN_HASHFILTERH          0x0214
+#define ETN_INTSTATUS            0x0fe0
+#define ETN_INTENABLE            0x0fe4
+#define ETN_INTCLEAR             0x0fe8
+#define ETN_INTSET               0x0fec
+#define ETN_POWERDOWN            0x0ff4
+#define ETN_MODULEID             0x0ffc
+
+
+/************************************************/
+/* pnx8181 WDRU (watchdog reset unit) registers */
+/************************************************/
+
+#define WDRU			0xC2203000
+#define WDRUCON			0x00
+
+
+/*************************************/
+/* registers in the SMSC LAN8700 PHY */
+/*************************************/
+/*
+00 Basic Control Register                             Basic
+01 Basic Status Register                              Basic
+02 PHY Identifier 1                                 Extended
+03 PHY Identifier 2                                 Extended
+04 Auto-Negotiation Advertisement Register          Extended
+05 Auto-Negotiation Link Partner Ability Register   Extended
+06 Auto-Negotiation Expansion Register              Extended
+16 Silicon Revision Register                      Vendor-specific
+17 Mode Control/Status Register                   Vendor-specific
+18 Special Modes                                  Vendor-specific
+20 Reserved                                       Vendor-specific
+21 Reserved                                       Vendor-specific
+22 Reserved                                       Vendor-specific
+23 Reserved                                       Vendor-specific
+27 Control / Status Indication Register           Vendor-specific
+28 Special internal testability controls          Vendor-specific
+29 Interrupt Source Register                      Vendor-specific
+30 Interrupt Mask Register                        Vendor-specific
+31 PHY Special Control/Status Register            Vendor-specific
+*/
+
+#define ETN_PHY_00		0x00
+#define ETN_PHY_01		0x01
+#define ETN_PHY_02		0x02
+#define ETN_PHY_03		0x03
+#define ETN_PHY_04		0x04
+#define ETN_PHY_05		0x05
+#define ETN_PHY_06		0x06
+#define ETN_PHY_16		0x10
+#define ETN_PHY_17		0x11
+#define ETN_PHY_18		0x12
+#define ETN_PHY_27		0x1b
+#define ETN_PHY_28		0x1c
+#define ETN_PHY_29		0x1d
+#define ETN_PHY_30		0x1e
+#define ETN_PHY_31		0x1f
+
+#define ETN_PHY_BASIC_CONTROL			ETN_PHY_00
+#define ETN_PHY_BASIC_STATUS			ETN_PHY_01
+#define ETN_PHY_ID1				ETN_PHY_02
+#define ETN_PHY_ID2				ETN_PHY_03
+#define ETN_PHY_AUTONEG_ADV			ETN_PHY_04
+#define ETN_PHY_AUTONEG_LINK			ETN_PHY_05
+#define ETN_PHY_AUTONEG_EXP			ETN_PHY_06
+#define ETN_PHY_SILICON				ETN_PHY_16
+#define ETN_PHY_MODE_CONTROL_STATUS		ETN_PHY_17
+#define ETN_PHY_SPECIAL_MODES			ETN_PHY_18
+#define ETN_PHY_CONTROL_STATUS_INDICATION	ETN_PHY_27
+#define ETN_PHY_INTERNAL_TESTABILITY		ETN_PHY_28
+#define ETN_PHY_INTERRUPT_SOURCE		ETN_PHY_29
+#define ETN_PHY_INTERRUPT_MASK			ETN_PHY_30
+#define ETN_PHY_SPECIAL_MODE_CONTROL_STATUS	ETN_PHY_31
+
+/*******************************************/
+/* registers in the CGU used for ETNREFCLK */
+/*******************************************/
+#define CGU		0xC2200000
+#define CGU_PER2CON	(CGU+0x0018)
+#define CGU_GATESC	(CGU+0x0008)
+
+/*************************/
+/* registers in the SCTU */
+/*************************/
+#define SCTU1		0xC2102000
+#define SCTU1_TIM1CR	(SCTU1+0x0000)
+#define SCTU1_TIM1RR	(SCTU1+0x0004)
+#define SCTU1_TIM1PR	(SCTU1+0x0020)
+#define SCTU2		0xC2103000
+#define SCTU2_TIM2CR	(SCTU2+0x0000)
+#define SCTU2_TIM2RR	(SCTU2+0x0004)
+#define SCTU2_TIM2PR	(SCTU2+0x0020)
+
+
+/*******************************************/
+/* data types                              */
+/*******************************************/
+
+/* rx */
+typedef struct{
+	volatile void *packet;
+	vu_long control;
+} rx_descriptor_t;
+
+typedef struct{
+	vu_long info;    /* RO */
+	vu_long hashCRC; /* RO */
+} rx_status_t;
+
+/* tx */
+
+/* values for control */
+#define ETN_CONTROL_INTERRUPT	0x80000000
+#define ETN_CONTROL_LAST	0x40000000
+#define ETN_CONTROL_CRC		0x20000000
+#define ETN_CONTROL_PAD		0x10000000
+#define ETN_CONTROL_HUGE	0x08000000
+#define ETN_CONTROL_OVERRIDE	0x04000000
+
+typedef struct{
+	volatile void *packet;
+	vu_long control;
+} tx_descriptor_t;
+
+typedef struct{
+	vu_long info;    /* RO */
+} tx_status_t;
+
+/* PHY identification */
+#define PHY_ID_LXT970           0x78100000      /* LXT970 */
+#define PHY_ID_LXT971           0x001378e0      /* LXT971 and 972 */
+#define PHY_ID_82555            0x02a80150      /* Intel 82555 */
+#define PHY_ID_QS6612           0x01814400      /* QS6612 */
+#define PHY_ID_AMD79C784        0x00225610      /* AMD 79C784 */
+#define PHY_ID_LSI80225         0x0016f870      /* LSI 80225 */
+#define PHY_ID_LSI80225B        0x0016f880      /* LSI 80225/B */
+#define PHY_ID_DM9161           0x0181B880      /* Davicom DM9161 */
+#define PHY_ID_KSM8995M         0x00221450      /* MICREL KS8995MA */
+#define PHY_ID_SMSC8700		0x0007C0C0	/* SMSC LAN 8700 */
+
diff --git a/board/firetux/firetux.c b/board/firetux/firetux.c
new file mode 100644
index 0000000..591fcaa
--- /dev/null
+++ b/board/firetux/firetux.c
@@ -0,0 +1,558 @@
+/*
+ * firetux board specific setup
+ *
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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
+ */
+
+#include <common.h>
+#include <status_led.h>
+#include "firetux.h"
+#include "ethernet.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void firetux_gpio_init_A(void);
+void firetux_gpio_init_B(void);
+void firetux_timer_init(void);
+int firetux_keystatus(int key);
+void firetux_set_led(int led, int brightness);
+void firetux_check_bootkey(void);
+#ifdef CONFIG_CMD_NAND
+void firetux_nand_init(void);
+#else
+void firetux_flash_init(void);
+#endif
+void firetux_irq_disable(void);
+void firetux_ether_init(void);
+void peripheral_power_enable(void);
+
+unsigned int boardrevision = 0;
+
+extern int firetux_eth_check_vega_phy(void);
+
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+	printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init(void)
+{
+	int cgu_sccon;
+
+	/* arch number of Firetux Platform Boards */
+	gd->bd->bi_arch_number = MACH_TYPE_PNX8181;
+
+	/* adress of boot parameters / atags */
+	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+       *(vu_long *)PNX8181_WDRUCON |= 0x0009;
+       *(vu_long *)PNX8181_DAIF_RVDDC = 0x0079;
+
+	firetux_gpio_init_A();	    /* first part */
+
+	/* simple board detection */
+	cgu_sccon = *(vu_short *)PNX8181_REG_CGU_SCCON;
+	cgu_sccon = ((cgu_sccon >> 3) & 0x3f);
+	if (cgu_sccon == 11) {
+		/* ez_mcp_pnx8181 */
+		boardrevision = 1;
+	} else if (cgu_sccon == 14) {
+		/* vega_pnx8181_basestation Platform III a, b, c
+		 * we need futher inevestigation by network test */
+		boardrevision = 2;
+	}
+
+	firetux_timer_init();
+
+	firetux_ether_init();
+
+	firetux_gpio_init_B();	    /* we need correct boardversion first */
+
+	icache_enable();
+	dcache_enable();
+
+#ifdef CONFIG_CMD_NAND
+	firetux_nandflash_init();
+#else
+	firetux_norflash_init();
+#endif
+
+	firetux_irq_disable();
+
+	return 0;
+}
+
+
+int misc_init_r(void)
+{
+	if (boardrevision > 1)	    /* ez_mcp_pnx8181 has no keys */
+		firetux_check_bootkey();
+
+	setenv("verify", "n");
+	return 0;
+}
+
+void firetux_gpio_init_A(void)
+{
+	/* select TXD2 for GPIOa11 and select RXD2 for GPIOa1 */
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0) =
+		(((*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
+						& 0xff3ffff3) | 0x00400004);
+	/* select ETN for GPIOc0-16 */
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX5) =
+	    (*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX5)) & 0xfffffffc;
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX4) =
+	    (*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX4)) & 0x30000000;
+
+	/* use clk26m and fract-n for UART2 */
+	*(vu_short *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_CTRL) =
+							((1<<7) | (1<<1));
+	*(vu_short *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_M)    = 0x5F37;
+	*(vu_short *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_N)    = 0x32C8;
+}
+
+
+void firetux_gpio_init_B(void)
+{
+	if (boardrevision < 2)	    /* EZ_MCP has no leds or keys */
+		return;
+
+	/* set GPIOA10 and GPIOA2 for key input */
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0) &= 0xffcfffcf;
+	*(vu_long *)PNX8181_GPIOA_PAD_LOW &= 0xffcfffcf;
+	*(vu_long *)PNX8181_GPIOA_DIRECTION &= ~((1 << 2) | (1 << 10));
+
+	/* set GPIOA9 and GPIOA0 for LED output */
+	if (boardrevision > 2) {
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0) &= 0xfff3fffc;
+	*(vu_long *)PNX8181_GPIOA_DIRECTION |= ((1 << 9) | (1 << 0));
+	*(vu_long *)PNX8181_GPIOA_OUTPUT |= ((1 << 9) | (1 << 0));
+	} else {    /* Baseboard IIIa */
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0) &= 0xfff3ff3f;
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX1) &= 0x3ffffffc;
+	*(vu_long *)PNX8181_GPIOA_DIRECTION |=
+				((1 << 9) | (1 << 31) | (1 << 16) | (1 << 3));
+	*(vu_long *)PNX8181_GPIOA_OUTPUT |=
+				((1 << 9) | (1 << 31) | (1 << 16) | (1 << 3));
+	}
+}
+
+
+#ifdef CONFIG_CMD_NAND
+void firetux_nandflash_init(void)
+{
+	/* Hardware configuration */
+	/* setup GPIOB18 / FMP40 to GPIO input with internal pullup */
+	/* clear bits */
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3) &= ~(0x30);
+	/* set FPM40 to GPIOb18 */
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3) |= 0x10;
+	/* set to input */
+	*(vu_long *)PNX8181_GPIOB_DIRECTION &= ~(1 << 18);
+	/* set pull up */
+	*(vu_long *)(PNX8181_SCON_BASE + PNX8181_SYSPAD2) &= ~(3 << 20);
+
+	/* setup access timing for CS0 */
+	/* 16bit */
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_MAIN_OFF)  = 0x0001;
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_READ_OFF)  = 0x1FFFF;
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_WRITE_OFF) = 0x1FFFF;
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_BURST_OFF) = 0x0CF8;
+}
+#else
+void firetux_norflash_init(void)
+{
+#ifdef CONFIG_SYS_OPTIMIZE_NORFLASH
+	/* optimize access speed */
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_MAIN_OFF) = 0x9;
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_READ_OFF) = 0x22D88;
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_WRITE_OFF) = 0x22D88;
+	*(vu_long *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_BURST_OFF) = 0x0000;
+#endif
+}
+#endif
+
+void firetux_irq_disable(void)
+{
+	int i;
+
+	*(vu_long *)PNX8181_INTC_PRIOMASK_IRQ = 31;
+	*(vu_long *)PNX8181_INTC_PRIOMASK_FIQ = 31;
+
+	for (i = 1; i < 67; i++)
+		PNX8181_DISABLEIRQ(i);
+
+	*(vu_long *)PNX8181_CGU_GATESC &= 0xfdd7becd;
+}
+
+void firetux_ether_init(void)
+{
+/* priority setting for ETN over CPU for SDRAM access */
+/* enable port-aging with priority for ETN */
+#if 0
+	/* be fair: ETN and CPU are both high priority, but ETN gets
+	 * higher priority and a much lower ageing penatly to get
+	 * much more accesses to RAM */
+	*(vu_long *)(SDI_SCHED + SCHED0) = 0x80000121;
+	*(vu_long *)(SDI_SCHED + SCHED1) = 0xffff0100;
+	*(vu_long *)(SDI_SCHED + SCHED2) = 0x00030131;
+#else
+	/* highly prioritise the ETN engine and lower CPU priority
+	 * to archive a better network thoughput */
+	*(vu_long *)(PNX8181_SDI_SCHED + PNX8181_SCHED0) = 0xffff0020;
+	*(vu_long *)(PNX8181_SDI_SCHED + PNX8181_SCHED1) = 0xffff0000;
+	*(vu_long *)(PNX8181_SDI_SCHED + PNX8181_SCHED2) = 0xffff0031;
+#endif
+
+/* increase priority for SCRAM access at AHB of descriptors */
+	*(vu_long *)(PNX8181_SC_ARB_BASE + PNX8181_SC_ARB_CFG2) = 7;
+	*(vu_long *)(PNX8181_SC_ARB_BASE + PNX8181_SC_ARB_CFG3) = 7;
+
+	/* OK, we have to check if we are a Platform III a, b, c */
+	if (boardrevision == 2)
+	    boardrevision = firetux_eth_check_vega_phy();
+}
+
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+	int sysver, cgu_sccon, armclk, hclk;
+
+	puts("CPU: ");
+	sysver = *(vu_short *)PNX8181_REG_SC_SYSVER;
+	printf("PNX8181-%d%c %s-ARM926EJ-S(ARMv5TEJ) ",
+		((sysver >> 4) & 0xf), ((sysver & 0xf) + 64),
+		(((sysver >> 8) & 0xf) == 1) ? "OM6xxx" : "unknown");
+
+	cgu_sccon = *(vu_short *)PNX8181_REG_CGU_SCCON;
+	/* armclk = bbcki * nsc / msc / ksc */
+	armclk = 13824 * (((cgu_sccon >> 3) & 0x3f) + 1)
+		/ ((cgu_sccon & 0x7) + 1)
+		/ (((cgu_sccon >> 10) & 0x3) + 1);
+	hclk = armclk / (((cgu_sccon >> 12) & 0xf) + 1);
+
+	printf("@ %dMHz(armclk), %dMHz(hclk)\n",
+		(armclk / 1000), (hclk / 1000));
+	return 0;
+}
+#endif
+
+
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+int checkboard(void)
+{
+	puts("Board: ");
+
+	switch (boardrevision) {
+	case 1:	puts("EZ_MCP_PNX8181\n");
+		break;
+	case 2:	puts("Vega_PNX8181_BaseStation Platform III-a\n");
+		break;
+	case 3:	puts("Vega_PNX8181_BaseStation Platform III-b\n");
+		break;
+	case 4:	puts("Vega_PNX8181_BaseStation Platform III-c\n");
+		break;
+	case 0:
+	default:
+		puts("unknown PNX8181 board\n");
+		break;
+	}
+
+	return 0;
+}
+#endif
+
+
+int dram_init(void)
+{
+	int reg;
+
+	reg = *(vu_long *)PNX8181_SDI_CFG_1;
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size	 = 1 << (
+		(reg & 0x3) +			/* dram width 8, 16, 32, 64 */
+		(((reg & 0x30) >> 4) + 8) +	/* columns 8, 9, 10, 11 */
+		(((reg & 0x700) >> 8) + 9) +	/* rows 9 .. 16 */
+		((reg & 0x3000) >> 12));	/* nr banks 1, 2, 4 */
+
+	return 0;
+}
+
+
+int firetux_keystatus(int key)
+{
+	int ret = 0;
+
+	switch (key) {
+	case 1:	/* GPIOA2 */
+		ret = (((*(vu_long *)PNX8181_GPIOA_PINS) >> 2) & 1);
+		break;
+	case 2:	/* GPIOA10 */
+		ret = (((*(vu_long *)PNX8181_GPIOA_PINS) >> 10) & 1);
+		break;
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+
+void firetux_set_led(int led, int brightness)
+{
+	/* check for boardrevision, EZ_MCP does not have leds */
+	if (boardrevision < 2)
+		return;
+
+	switch (led) {
+	case 1:	/* GPIOA9 */
+		if (brightness)
+			*(vu_long *)PNX8181_GPIOA_OUTPUT &= ~(1 << 9);
+		else
+			*(vu_long *)PNX8181_GPIOA_OUTPUT |= (1 << 9);
+		break;
+	case 2:	/* GPIOA0 or GPIOA31 */
+		if (boardrevision > 2) {
+			if (brightness)
+				*(vu_long *)PNX8181_GPIOA_OUTPUT &= ~(1 << 0);
+			else
+				*(vu_long *)PNX8181_GPIOA_OUTPUT |= (1 << 0);
+		} else {
+			if (brightness)
+				*(vu_long *)PNX8181_GPIOA_OUTPUT &= ~(1 << 31);
+			else
+				*(vu_long *)PNX8181_GPIOA_OUTPUT |= (1 << 31);
+		}
+		break;
+	case 3:	/* GPIOA16 */
+		if (boardrevision == 2) {
+			if (brightness)
+				*(vu_long *)PNX8181_GPIOA_OUTPUT &= ~(1 << 16);
+			else
+				*(vu_long *)PNX8181_GPIOA_OUTPUT |= (1 << 16);
+		}
+		break;
+	case 4: /* GPIOA3 */
+		if (boardrevision == 2) {
+			if (brightness)
+				*(vu_long *)PNX8181_GPIOA_OUTPUT &= ~(1 << 3);
+			else
+				*(vu_long *)PNX8181_GPIOA_OUTPUT |= (1 << 3);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+
+void __led_toggle(led_id_t mask)
+{
+	/* check for boardrevision, EZ_MCP does not have leds */
+	if (boardrevision < 2)
+		return;
+
+	switch (mask) {
+	case 1:
+		if ((*(vu_long *)PNX8181_GPIOA_OUTPUT) & (1 << 9))
+			firetux_set_led(1, 0);
+		else
+			firetux_set_led(1, 1);
+		break;
+	case 2:
+		if (boardrevision > 2) {
+		if ((*(vu_long *)PNX8181_GPIOA_OUTPUT) & (1 << 0))
+			firetux_set_led(2, 0);
+		else
+			firetux_set_led(2, 1);
+		} else {
+		if ((*(vu_long *)PNX8181_GPIOA_OUTPUT) & (1 << 31))
+			firetux_set_led(2, 0);
+		else
+			firetux_set_led(2, 1);
+		}
+		break;
+	case 3:
+		if (boardrevision == 2) {
+		if ((*(vu_long *)PNX8181_GPIOA_OUTPUT) & (1 << 16))
+			firetux_set_led(3, 0);
+		else
+			firetux_set_led(3, 1);
+		}
+		break;
+	case 4:
+		if (boardrevision == 2) {
+		if ((*(vu_long *)PNX8181_GPIOA_OUTPUT) & (1 << 3))
+			firetux_set_led(4, 0);
+		else
+			firetux_set_led(4, 1);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+
+void __led_init(led_id_t mask, int state)
+{
+}
+
+
+void __led_set(led_id_t mask, int state)
+{
+	firetux_set_led(mask, state);
+}
+
+
+void firetux_check_bootkey(void)
+{
+	int i = 0, abort = 0;
+
+	while ((abort == 0) && (i < 500)) {
+		if (firetux_keystatus(2) == 1) {
+			setenv("bootcmd", "run bootcmd1");
+			firetux_set_led(2, 0);
+			abort = 1;
+		}
+		i++;
+		udelay(10000);
+	}
+	if (abort == 0) {
+		setenv("bootcmd", "run bootcmd2");
+		puts("using alternative bootcmd\n");
+		firetux_set_led(2, 1);
+	}
+}
+
+
+int interrupt_init(void)
+{
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+
+/* U-Boot expects a 32 bit timer, running at CONFIG_SYS_HZ */
+/* Keep total timer count to avoid losing decrements < div_timer */
+static ulong timestamp;		/* U-Boot ticks since startup	      */
+static ulong last_timer_read;
+
+/* starts up a counter
+ * - the Integrator/CP timer can be set up to issue an interrupt */
+void firetux_timer_init(void)
+{
+	/* set prescaler to have timer run at 64 kHz */
+	*(vu_char *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxPR) = 0x00;
+
+	/* timer reload value = 0xffbf, overflow @ 1kHz */
+	*(vu_short *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxRR) =
+							0x10000 - 13824;
+
+	/* timer has no interrupt, run */
+	*(vu_short *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxCR) = 0x0001;
+
+	/* init the timestamp */
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base_ticks)
+{
+	return get_timer_masked() - base_ticks;
+}
+
+/* converts the timer reading to U-Boot ticks	       */
+/* the timestamp is the number of ticks since reset    */
+ulong get_timer_masked(void)
+{
+	/* get current count */
+	ulong now = READ_TIMER1;
+
+	if (now < last_timer_read)
+		timestamp += 13824;
+	last_timer_read = now;
+
+	/* FIXME this value is empirical!
+	 *       for some reason the calculated values are way to fast */
+	return (timestamp + now) / 64;
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+
+/* busy-loop spin-delay */
+void sdelay(unsigned long usec)
+{
+	ulong i, tmp;
+	tmp = 42;
+	for (i = 0 ; i < usec*3 ; i++)
+		/* avoid compiler optimisation */
+		tmp = -tmp;
+}
+
+/* delay usec useconds */
+void udelay(unsigned long usec)
+{
+	ulong tmo, tmp;
+
+	/* Convert to U-Boot ticks */
+	tmo  = usec / 1500;
+
+	tmp  = get_timer_masked();	/* get current timestamp */
+	tmo += tmp;			/* form target timestamp */
+
+	while (get_timer_masked() < tmo) {/* loop till event */
+		/*NOP*/;
+	}
+}
+
+void reset_timer_masked(void)
+{
+	/* start "advancing" time stamp from 0 */
+	timestamp = 0L;
+}
+
+int timer_init(void)
+{
+	return 0;
+}
diff --git a/board/firetux/firetux.h b/board/firetux/firetux.h
new file mode 100644
index 0000000..d2cf3c5
--- /dev/null
+++ b/board/firetux/firetux.h
@@ -0,0 +1,118 @@
+/*
+ * firetux board specific defines
+ *
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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
+ */
+
+
+#define PNX8181_WDRUCON		0xc2203000
+#define PNX8181_DAIF_RVDDC	0xc2000000
+
+/* console port */
+#define PNX8181_UART2_BASE	0xc2005000
+#define PNX8181_UART_FDIV_CTRL	0xc00
+#define PNX8181_UART_FDIV_M	0xc04
+#define PNX8181_UART_FDIV_N	0xc08
+
+/* gpio settings */
+#define PNX8181_SCON_BASE	0xC2204000
+#define PNX8181_SYSMUX0		0x0C
+#define PNX8181_SYSMUX1		0x10
+#define PNX8181_SYSMUX2		0x14
+#define PNX8181_SYSMUX3		0x18
+#define PNX8181_SYSMUX4		0x1C
+#define PNX8181_SYSMUX5		0x20
+#define PNX8181_SYSPAD2		0x3c
+#define PNX8181_GPIOA_PINS	0xc2104000
+#define PNX8181_GPIOA_OUTPUT	0xc2104004
+#define PNX8181_GPIOA_DIRECTION	0xc2104008
+#define PNX8181_GPIOA_PAD_LOW	0xC2204034
+#define PNX8181_GPIOB_DIRECTION	0xc2104208
+
+/* timing for CS0 (NAND) */
+#define PNX8181_REG_EBI1_BASE	0xBC000000
+#define PNX8181_REG_EBI1_CS0	(PNX8181_REG_EBI1_BASE + 0x00)
+#define PNX8181_EBI_MAIN_OFF	0x00
+#define PNX8181_EBI_READ_OFF	0x04
+#define PNX8181_EBI_WRITE_OFF	0x08
+#define PNX8181_EBI_BURST_OFF	0x0C
+
+/* irq resetting */
+#define PNX8181_INTC_REQUEST	0xC1100400
+
+#define PNX8181_DISABLEIRQ(IRQ)	*(vu_long *)(PNX8181_INTC_REQUEST + \
+				(4 * IRQ)) = \
+				((1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25));
+
+#define PNX8181_INTC_PRIOMASK_IRQ   0xC1100000
+#define PNX8181_INTC_PRIOMASK_FIQ   0xC1100004
+
+/* clock speed */
+#define PNX8181_REG_CGU_SCCON	0xC2200004
+/* clock gate */
+#define PNX8181_CGU_GATESC	0xC2200008
+
+/* priority for ETN over CPU for SDRAM access */
+#define PNX8181_SDI_SCHED	0xC1200100
+#define PNX8181_SCHED0		0x00
+#define PNX8181_SCHED1		0x04
+#define PNX8181_SCHED2		0x08
+
+/* priority for SCRAM access at AHB */
+#define PNX8181_SC_ARB_BASE	0xc200ea00
+#define PNX8181_SC_ARB_CFG2	0x08
+#define PNX8181_SC_ARB_CFG3	0x0c
+
+/* boarddetection */
+#define PNX8181_REG_SC_SYSVER	0xC2204000
+
+/* clock settings */
+#define PNX8181_REG_CGU_SCCON	0xC2200004
+
+/* sdram configuration */
+#define PNX8181_SDI_CFG_1	0xC1200000
+
+/* timer */
+#define PNX8181_SCTU1_BASE	0xC2102000
+#define PNX8181_SCTU2_BASE	0xC2103000
+
+#define PNX8181_SCTU_TIMxCR	0x00
+#define PNX8181_SCTU_TIMxRR	0x04
+#define PNX8181_SCTU_TIMxWR	0x08
+#define PNX8181_SCTU_TIMxC0	0x0c
+#define PNX8181_SCTU_TIMxC1	0x10
+#define PNX8181_SCTU_TIMxC2	0x14
+#define PNX8181_SCTU_TIMxC3	0x18
+#define PNX8181_SCTU_TIMxSR	0x1c
+#define PNX8181_SCTU_TIMxPR	0x20
+
+#define READ_TIMER1		(*(vu_short *) \
+				(PNX8181_SCTU1_BASE+PNX8181_SCTU_TIMxWR))
+#define READ_TIMER1_STATUS	(*(vu_short *) \
+				(PNX8181_SCTU1_BASE+PNX8181_SCTU_TIMxSR))
+#define TIMER_LOAD_VAL		((ushort)0xFFBF)
+
+#define TIMER_LOAD_VAL		((ushort)0xFFBF)
diff --git a/board/firetux/lowlevel_init.S b/board/firetux/lowlevel_init.S
new file mode 100644
index 0000000..f3ade8c
--- /dev/null
+++ b/board/firetux/lowlevel_init.S
@@ -0,0 +1,412 @@
+/*
+ * firetux board specific setup
+ *
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew, <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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
+ */
+
+#include <config.h>
+#include <version.h>
+
+#define RESET_ADDRESS	0xffff0000
+
+.global reset_cpu
+reset_cpu:
+	ldr	lr, =RESET_ADDRESS
+	mov	pc, lr
+
+/* address/register map */
+
+#define FLASH_BASE	0x80000000
+#define FLASH_CFG_OFF_0	0x0555
+#define FLASH_CFG_OFF_1	0x02AA
+#define FLASH_MAGIC_0	0x0AA
+#define FLASH_MAGIC_1	0x055
+#define FLASH_MAGIC_R	0x0D0
+#define FLASH_MAGIC_W	0x0C6
+
+#define RAM_BASE	0x90000000
+
+/* EBI */
+#define REG_EBI1_BASE	0xBC000000
+
+#define REG_EBI1_CS0_V1	(REG_EBI1_BASE + 0x00)
+#define REG_EBI1_CS1_V1	(REG_EBI1_BASE + 0x10)
+#define REG_EBI1_CS2_V1	(REG_EBI1_BASE + 0x20)
+#define REG_EBI1_CS3_V1	(REG_EBI1_BASE + 0x30)
+#define REG_EBI1_CS4_V1	(REG_EBI1_BASE + 0x40)
+#define REG_EBI1_CS5_V1	(REG_EBI1_BASE + 0x50)
+#define REG_EBI1_IPID_V1	(REG_EBI1_BASE + 0xF0)
+
+#define REG_EBI1_CS0	(REG_EBI1_BASE + 0x00)
+#define REG_EBI1_CS1	(REG_EBI1_BASE + 0x20)
+#define REG_EBI1_CS2	(REG_EBI1_BASE + 0x40)
+#define REG_EBI1_CS3	(REG_EBI1_BASE + 0x60)
+#define REG_EBI1_CS4	(REG_EBI1_BASE + 0x80)
+#define REG_EBI1_CS5	(REG_EBI1_BASE + 0xA0)
+#define REG_EBI1_IPID	(REG_EBI1_BASE + 0xFFC)
+
+/* read-only values identifying silicon version */
+#define REG_SCON_SYSVER	0xC2204000
+#define VAL_SYSVER_1	0x4111
+#define VAL_SYSVER_2A	0x4121
+#define VAL_SYSVER_2B	0x4122              /* 2B is a metalfix version */
+
+#define VAL_EBI1_IPID_V1	0xB0503101
+#define VAL_EBI1_IPID_V2	0x20165100  /* value of datasheet */
+#define VAL_EBI1_IPID_V2a	0x20165000  /* value of hardware */
+
+#define REG_EBI2_BASE	0xC0380000
+
+#define REG_EBI2_CS0_V1	(REG_EBI2_BASE + 0x00)
+#define REG_EBI2_CS1_V1	(REG_EBI2_BASE + 0x10)
+#define REG_EBI2_CS2_V1	(REG_EBI2_BASE + 0x20)
+#define REG_EBI2_CS3_V1	(REG_EBI2_BASE + 0x30)
+#define REG_EBI2_CS4_V1	(REG_EBI2_BASE + 0x40)
+#define REG_EBI2_CS5_V1	(REG_EBI2_BASE + 0x50)
+#define REG_EBI2_IPID_V1	(REG_EBI2_BASE + 0xF0)
+
+#define REG_EBI2_CS0	(REG_EBI2_BASE + 0x00)
+#define REG_EBI2_CS1	(REG_EBI2_BASE + 0x20)
+#define REG_EBI2_CS2	(REG_EBI2_BASE + 0x40)
+#define REG_EBI2_CS3	(REG_EBI2_BASE + 0x60)
+#define REG_EBI2_CS4	(REG_EBI2_BASE + 0x80)
+#define REG_EBI2_CS5	(REG_EBI2_BASE + 0xA0)
+#define REG_EBI2_IPID	(REG_EBI2_BASE + 0xFFC)
+
+#define EBI_MAIN_OFF	0x00
+#define EBI_READ_OFF	0x04
+#define EBI_WRITE_OFF	0x08
+#define EBI_BURST_OFF	0x0C
+
+/* CGU */
+/* Register definitions */
+#define REG_CGU_BASE	0xC2200000
+#define REG_CGU_DSPCON	0xC2200000
+#define REG_CGU_SCCON	0xC2200004
+#define REG_CGU_GATESC	0xC2200008
+#define REG_CGU_SLEEPSC	0xC220000C
+#define REG_CGU_FDIV	0xC2200010
+#define REG_CGU_PER1CON	0xC2200014
+#define REG_CGU_PER2CON	0xC2200018
+#define REG_CGU_PER2BWCON	0xC220001C
+#define REG_CGU_FIXCON	0xC2200020
+#define REG_CGU_DIVCON	0xC2200024
+
+
+#ifdef CONFIG_FIRETUX_HAS_CGU_SCCON_MSC_BUG
+/* on some early PNX8181 V1 CPUs a sporadic bug on the silicon doesn't allow
+ * writing values > 3 to the msc field of SCCON, still the reset value is 5
+ */
+# define SCCON		0x0011005b
+#else
+# define SCCON		0x0011005d
+#endif
+/* default reset value */
+#define PER1CON		0x00601be2
+#define PER2CON		0x01801ff3
+#define PER2BWCON	0x0000038d
+#define FIXCON		0x000f07cf
+#define DIVCON		0x102335e8
+/* clock gate:
+ * disabled: ebi2 fir usb fci usim pwm[123] kbs uart1 i2s ipint spi[12]
+ *  enabled: ebi1 sdi adpcm etn[12] daif dmau drt gpio bmp uart2 i2c
+ *	     sctu extint intc
+ */
+#define GATESC		0x7ef803a7
+#define SLEEPSC		0x00000000
+#define FDIV		0x25ed097c
+
+
+/* Set up the platform, once the cpu has been initialized */
+.globl lowlevel_init
+lowlevel_init:
+
+/* with nandflash we have to skip the lowlevelinit */
+/* all setup is done with preloader of nandboot */
+#ifndef CONFIG_NANDFLASH
+
+	/* currently we run from flash, via EBI1/CS0 */
+
+	/* accesses to addresses not decoded result in hang  */
+	/* check for V2 CPU */
+check_for_v1_core:
+	ldr     r2, =REG_SCON_SYSVER
+	ldr     r0, [r2]
+	ldr     r1, =VAL_SYSVER_1
+	cmp     r0, r1
+	bne     check_for_v2_core   /* if not v1 core check for v2 */
+
+	/* validate EBI1 silicon version */
+	ldr	r2, =REG_EBI1_IPID_V1
+	ldr	r0, [r2]
+	ldr	r1, =VAL_EBI1_IPID_V1
+	cmp	r0, r1
+	beq	pnx8181_v1_init	    /* v1 core has only one ebi version */
+	b	reset_cpu
+
+check_for_v2_core:
+	ldr     r2, =REG_SCON_SYSVER
+	ldr     r0, [r2]
+	ldr     r1, =VAL_SYSVER_2A
+	cmp     r0, r1
+	beq     is_v2_core
+
+	ldr     r1, =VAL_SYSVER_2B
+	cmp     r0, r1
+	beq     is_v2_core
+	b	reset_cpu   /* if not v2 core jump to reset */
+
+is_v2_core:
+	ldr	r2, =REG_EBI1_IPID
+	ldr	r0, [r2]
+	ldr	r1, =VAL_EBI1_IPID_V2
+	cmp	r0, r1
+	beq	pnx8181_v2_init	    /*	v2 core has only one ebi version */
+	ldr	r1, =VAL_EBI1_IPID_V2a
+	cmp	r0, r1
+	beq	pnx8181_v2_init	    /*	v2 core has only one ebi version */
+	b	reset_cpu
+
+pnx8181_v1_init:
+	/* configure flash (CS0) for minimum wait states */
+	ldr	r2, =(REG_EBI1_CS0_V1 + EBI_MAIN_OFF)
+	ldr	r1, =0x0001
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS0_V1 + EBI_READ_OFF)
+	ldr	r1, =0x22D8C
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS0_V1 + EBI_WRITE_OFF)
+	ldr	r1, =0x22D8C
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS0_V1 + EBI_BURST_OFF)
+	ldr	r1, =0x05b5
+	str	r1, [r2]
+
+	/* configure pSRAM (CS1) for minimum wait states */
+	ldr	r2, =(REG_EBI1_CS1_V1 + EBI_MAIN_OFF)
+	ldr	r1, =0x0001
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS1_V1 + EBI_READ_OFF)
+	ldr	r1, =0x22D88
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS1_V1 + EBI_WRITE_OFF)
+	ldr	r1, =0x22D88
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS1_V1 + EBI_BURST_OFF)
+	ldr	r1, =0x0000
+	str	r1, [r2]
+	b	ez_mcp_memtest
+
+pnx8181_v2_init:
+	/* configure flash (CS0) for minimum wait states */
+	ldr	r2, =(REG_EBI1_CS0 + EBI_MAIN_OFF)
+	ldr	r1, =0x0001
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS0 + EBI_READ_OFF)
+	ldr	r1, =0x22D8C
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS0 + EBI_WRITE_OFF)
+	ldr	r1, =0x22D8C
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS0 + EBI_BURST_OFF)
+	ldr	r1, =0x05b5
+	str	r1, [r2]
+
+	/* configure pSRAM (CS1) for minimum wait states */
+	ldr	r2, =(REG_EBI1_CS1 + EBI_MAIN_OFF)
+	ldr	r1, =0x0001
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS1 + EBI_READ_OFF)
+	ldr	r1, =0x22D88
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS1 + EBI_WRITE_OFF)
+	ldr	r1, =0x22D88
+	str	r1, [r2]
+	ldr	r2, =(REG_EBI1_CS1 + EBI_BURST_OFF)
+	ldr	r1, =0x0000
+	str	r1, [r2]
+
+	/* try to determine if we are on a EZ_MCP_PNX8181 */
+	/* we assume that all EZ boards have a PSRAM @0x90000000 */
+ez_mcp_memtest:
+	mov	r1, #100
+        mov	r2, #0x90000000
+1:
+	str	r2, [r2]
+        add     r2, r2, #4
+        sub     r1, r1, #1
+	cmp	r1, #0
+	bgt	1b
+
+	mov	r1, #100
+	mov	r2, #0x90000000
+1:
+	ldr	r0, [r2]
+	cmp	r0, r2
+	bne	vega_detected
+	add     r2, r2, #4
+	sub     r1, r1, #1
+	cmp     r1, #0
+	bgt	1b
+	b	ez_mcp_detected
+
+vega_detected:
+	mov	r0, #1
+	b	1f
+
+ez_mcp_detected:
+	mov	r0, #0
+	b	1f
+	nop
+	nop
+
+1:
+	/* setup Clock Generation Unit CGU */
+	/* setting default values */
+	ldr	r2, =REG_CGU_FDIV
+	ldr	r1, =FDIV
+	str	r1, [r2]
+	ldr	r2, =REG_CGU_FIXCON
+	ldr	r1, =FIXCON
+	str	r1, [r2]
+	ldr	r2, =REG_CGU_DIVCON
+	ldr	r1, =DIVCON
+	str	r1, [r2]
+	ldr	r2, =REG_CGU_PER1CON
+	ldr	r1, =PER1CON
+	str	r1, [r2]
+	ldr	r2, =REG_CGU_GATESC
+	ldr	r1, =GATESC
+	str	r1, [r2]
+	ldr	r2, =REG_CGU_SLEEPSC
+	ldr	r1, =SLEEPSC
+	str	r1, [r2]
+
+	/* in case we already run on PLL_SC (e.g. when we don't start from
+	 * a power cycle) we need to enable and switch back to PLL_FIX */
+	ldr	r2, =REG_CGU_SCCON
+	ldr	r1, [r2]		/* read sccon */
+	ands	r1, r1, #(1<<16)	/* mask scby */
+	bne	sccon_reset
+
+switch_to_pll_fix:
+	ldr	r1, [r2]		/* read sccon */
+	orr	r1, r1, #(1<<16)	/* switch to pll_fix */
+	str	r1, [r2]
+
+sccon_reset:
+	/* reset value, see CONFIG_FIRETUX_HAS_CGU_SCCON_MSC_BUG */
+	ldr	r1, =SCCON
+	str	r1, [r2]
+
+
+	/* check for vega or ez_mcp */
+	cmp	r0, #0
+	beq	ez_mcp_settings
+
+vega_settings:
+	/* vega settings */
+	/* SC: armclk=208Mhz, hclk,pclk=104MHz */
+	orr	r1, r1, #(1<<16)	/* use pll_fix */
+	str	r1, [r2]
+	bic	r1, r1, #(0x7f<<3)	/* clear nsc */
+	bic	r1, r1, #(3<<10)	/* clear ksc */
+	orr	r1, r1, #(14<<3)	/* nsc=14, ksc=0 */
+	str	r1, [r2]
+	orr	r1, r1, #(1<<18)	/* enable pll_sc */
+	str	r1, [r2]
+	b	speed_ok
+
+ez_mcp_settings:
+	/* ez_mcp settings */
+	/* reduced clock because of hardware constrains */
+	/* SC: armclk=165MHz, hclk,pclk=83MHz */
+	orr	r1, r1, #(1<<16)	/* use pll_fix */
+	str	r1, [r2]
+	bic	r1, r1, #(0x7f<<3)	/* clear nsc */
+	bic	r1, r1, #(3<<10)	/* clear ksc */
+	orr	r1, r1, #(11<<3)	/* nsc=11, ksc=0 */
+	str	r1, [r2]
+	orr	r1, r1, #(1<<18)	/* enable pll_sc */
+	str	r1, [r2]
+
+speed_ok:
+	mov	r0, #(0x29<<8)		/* wait max 250us */
+					/* roughly calculated 208MHz,
+					   -> 52000ticks,
+					   5intructions -> 10400 */
+wait_scpll:				/* wait for pll lock */
+	ldr	r1, [r2]
+	ands	r1, r1, #(1<<19)
+	bne	scpll_ok
+	subs	r0, r0, #1
+	bne	wait_scpll
+
+scpll_ok:
+	ldr	r1, [r2]
+	bic	r1, r1, #(0xf<<12)	/* clear mahb */
+	orr	r1, r1, #(1<<12)	/* mahb=1 hclk,pclk1=armclk/2 */
+	bic	r1, r1, #(0x7)		/* clear msc */
+	str     r1, [r2]
+	bic	r1, r1, #(1<<16)	/* switch to SC */
+	str	r1, [r2]
+
+	/* per2: etnrefclk 50MHz */
+	ldr	r2, =REG_CGU_PER2CON
+	ldr	r1, =PER2CON		/* reset value */
+	str	r1, [r2]
+	mov	r1, #0
+	orr	r1, r1, #(15<<9)
+	orr	r1, r1, #(63<<3)
+	orr	r1, r1, #(3)
+	orr	r1, r1, #(1<<19)
+	bic	r1, r1, #(1<<21)
+	str	r1, [r2]
+	orr	r1, r1, #(1<<16)	/* enable pll_per2 */
+	str	r1, [r2]
+	mov	r0, #(0x29<<8)		/* wait max 250us */
+wait_per2pll:				/* wait for pll lock */
+	ldr	r1, [r2]
+	ands	r1, r1, #(1<<17)
+	bne	per2pll_ok
+	subs	r0, r0, #1
+	bne	wait_per2pll
+per2pll_ok:
+	ldr	r1, [r2]
+	orr	r1, r1, #(1<<23)
+	orr	r1, r1, #(1<<13)
+	str	r1, [r2]
+
+	ldr	r2, =REG_CGU_PER2BWCON	/* set default value */
+	ldr	r1, =PER2BWCON
+	str	r1, [r2]
+
+
+#endif
+	/* setup memory controller */
+	b	memsetup		/* jump to the next assembler code */
+					/* board/firetux/memsetup.S */
+
diff --git a/board/firetux/memsetup.S b/board/firetux/memsetup.S
new file mode 100644
index 0000000..8fd178e
--- /dev/null
+++ b/board/firetux/memsetup.S
@@ -0,0 +1,366 @@
+/*
+ * Memory setup for PNX8181
+ *
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew, <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ *
+ * 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
+ */
+
+/*
+ * 	Memory setup
+ *      - the reset defaults are assumed sufficient
+ */
+
+#include <config.h>
+#include <version.h>
+
+#ifndef CONFIG_NANDFLASH /* with nandflash we have to skip memconfig */
+
+/* SDI */
+#define REG_SDI_CFG1	    0xC1200000	/* SDRAM controller configuration 1 */
+#define REG_SDI_PWR_CTRL    0xC1200004	/* Power savings parameters */
+#define REG_SDI_RFRSH1	    0xC1200008	/* Refresh parameters 1 */
+#define REG_SDI_RFRSH2	    0xC120000C	/* Refresh parameters 2 */
+#define REG_SDI_TIM1	    0xC1200010	/* Timings parameters 1 */
+#define REG_SDI_TIM2	    0xC1200014	/* Timings parameters 2 */
+#define REG_SDI_MODE	    0xC1200018	/* Mode */
+#define REG_SDI_EXT_MODE    0xC120001C	/* Extended mode */
+#define REG_SDI_CFG2	    0xC1200020	/* SDRAM controller configuration 2 */
+#define REG_SDI_SCHED0	    0xC1200100	/* Data port #0 scheduler */
+#define REG_SDI_SCHED1	    0xC1200104	/* Data port #1 scheduler */
+#define REG_SDI_SCHED2	    0xC1200108	/* Data port #2 scheduler */
+#define REG_SDI_WTAG0	    0xC1200300	/* Data port #0 write tag enable */
+#define REG_SDI_WTAG1	    0xC1200304	/* Data port #1 write tag enable */
+#define REG_SDI_WTAG2	    0xC1200308	/* Data port #2 write tag enable */
+#define REG_SDI_TAM	    0xC1200310	/* Tag address mask */
+#define REG_SDI_SW_CTRL	    0xC1200400	/* Software control register */
+#define REG_SDI_STAT	    0xC1200800	/* Status register */
+#define REG_SDI_IP_ID	    0xC1200FFC	/* IP identification */
+
+/* table offsets */
+#define SDI_CFG1	    0x00
+#define SDI_CFG2	    0x04
+#define SDI_PWR_CTRL	    0x08
+#define SDI_RFRSH1	    0x0c
+#define SDI_RFRSH2	    0x10
+#define SDI_TIM1	    0x14
+#define SDI_TIM2	    0x18
+#define SDI_MODE	    0x1c
+#define SDI_EXT_MODE	    0x20
+#define SDI_SCHED0	    0x24
+#define SDI_SCHED1	    0x28
+#define SDI_SCHED2	    0x2c
+#define SDI_WTAG0	    0x30
+#define SDI_WTAG1	    0x34
+#define SDI_WTAG2	    0x38
+#define SDI_TAM		    0x3c
+
+#define REG_CGU_SCCON	    0xC2200004	/* SC Controller for hclk */
+
+/* table for memory settings */
+    .align	4
+memsetting_EZ_MCP_PNX8181_89MHZ:
+/* settings for Samsung K4M64163PK */
+/* 8MB @hclk=89.86MHz */
+    .long	0x22301	    /* define SDI_CFG1 */
+    .long	0x100       /* define SDI_CFG2 */
+    .long	0x1000000   /* define SDI_PWR_CTRL */
+    .long	0x579       /* define SDI_RFRSH1 */
+    .long	0x0         /* define SDI_RFRSH2 */
+    .long	0x1131242   /* define SDI_TIM1 */
+    .long	0xb08       /* define SDI_TIM2 */
+    .long	0x23        /* define SDI_MODE */
+    .long	0x18        /* define SDI_EXT_MODE */
+    .long	0x80000121  /* define SDI_SCHED0 */
+    .long	0xffff0100  /* define SDI_SCHED1 */
+    .long	0x00030131  /* define SDI_SCHED2 */
+    .long	0xf         /* define SDI_WTAG0 */
+    .long	0xf         /* define SDI_WTAG1 */
+    .long	0xf         /* define SDI_WTAG2 */
+    .long	0x0         /* define SDI_TAM */
+
+    .align	4
+memsetting_EZ_MCP_PNX8181_103MHZ:
+/* settings for Samsung K4M64163PK */
+/* 8MB @hclk=103.68MHz */
+    .long	0x22301	    /* define SDI_CFG1 */
+    .long	0x100       /* define SDI_CFG2 */
+    .long	0x1000000   /* define SDI_PWR_CTRL */
+    .long	0x651       /* define SDI_RFRSH1 */
+    .long	0x0         /* define SDI_RFRSH2 */
+    .long	0x1131262   /* define SDI_TIM1 */
+    .long	0xc0a       /* define SDI_TIM2 */
+    .long	0x23        /* define SDI_MODE */
+    .long	0x18        /* define SDI_EXT_MODE */
+    .long	0x80000121  /* define SDI_SCHED0 */
+    .long	0xffff0100  /* define SDI_SCHED1 */
+    .long	0x00030131  /* define SDI_SCHED2 */
+    .long	0xf         /* define SDI_WTAG0 */
+    .long	0xf         /* define SDI_WTAG1 */
+    .long	0xf         /* define SDI_WTAG2 */
+    .long	0x0         /* define SDI_TAM */
+
+    .align	4
+memsetting_VEGA_PNX8181_BASESTATION_III_a:
+/* settings for Micron MT48LC8M16A2 */
+/* 16MB @hclk=103.68MHz */
+    .long	0x22311	    /* define SDI_CFG1 */
+    .long	0x100       /* define SDI_CFG2 */
+    .long	0x1000000   /* define SDI_PWR_CTRL */
+    .long	0x651       /* define SDI_RFRSH1 */
+    .long	0x0         /* define SDI_RFRSH2 */
+    .long	0x1131262   /* define SDI_TIM1 */
+    .long	0xc0a       /* define SDI_TIM2 */
+    .long	0x23        /* define SDI_MODE */
+    .long	0x18        /* define SDI_EXT_MODE */
+    .long	0x80000121  /* define SDI_SCHED0 */
+    .long	0xffff0100  /* define SDI_SCHED1 */
+    .long	0x00030131  /* define SDI_SCHED2 */
+    .long	0xf         /* define SDI_WTAG0 */
+    .long	0xf         /* define SDI_WTAG1 */
+    .long	0xf         /* define SDI_WTAG2 */
+    .long	0x0         /* define SDI_TAM */
+
+    .align	4
+memsetting_VEGA_PNX8181_BASESTATION_III_b:
+/* settings for Micron MT48LC16M16A2 */
+/* 32MB @hclk=103.68MHz */
+    .long	0x22411	    /* define SDI_CFG1 */
+    .long	0x100       /* define SDI_CFG2 */
+    .long	0x1000000   /* define SDI_PWR_CTRL */
+    .long	0x651       /* define SDI_RFRSH1 */
+    .long	0x0         /* define SDI_RFRSH2 */
+    .long	0x1131262   /* define SDI_TIM1 */
+    .long	0xc0a       /* define SDI_TIM2 */
+    .long	0x23        /* define SDI_MODE */
+    .long	0x18        /* define SDI_EXT_MODE */
+    .long	0x80000121  /* define SDI_SCHED0 */
+    .long	0xffff0100  /* define SDI_SCHED1 */
+    .long	0x00030131  /* define SDI_SCHED2 */
+    .long	0xf         /* define SDI_WTAG0 */
+    .long	0xf         /* define SDI_WTAG1 */
+    .long	0xf         /* define SDI_WTAG2 */
+    .long	0x0         /* define SDI_TAM */
+
+#endif
+
+.globl memsetup
+memsetup:
+#ifndef CONFIG_NANDFLASH /* with nandflash we have to skip memconfig */
+	/* check 32MB of Vega III-b / III-c */
+	adr	r3, memsetting_VEGA_PNX8181_BASESTATION_III_b
+	mov	r4, lr
+	bl	do_memsetup
+	mov	lr, r4
+#endif
+	mov	r3, #(32<<20)		/* check for 32MB */
+#ifndef CONFIG_NANDFLASH /* with nandflash we have to skip memconfig */
+	bl	memtest
+	mov	lr, r4
+	cmp	r3, #0
+	bne	2f
+
+	/* check 16MB of Vega III-a */
+	adr	r3, memsetting_VEGA_PNX8181_BASESTATION_III_a
+	mov	r4, lr
+	bl	do_memsetup
+	mov	lr, r4
+	mov	r3, #(16<<20)		/* check for 16MB */
+	bl	memtest
+	mov	lr, r4
+	cmp	r3, #0
+	bne	2f
+
+	/* fallback, check for 8MB of EZ_MCP */
+	adr	r3, memsetting_EZ_MCP_PNX8181_103MHZ
+	ldr	r1, =REG_CGU_SCCON
+	ldr	r0, [r1]
+	mov	r1, #(0x7f<<3)
+	ands	r0, r0, r1
+	cmp	r0, #(14<<3)		/* check for hclk=103 */
+	bge	1f
+	/* OK, we do not have 103MHz, so chosse other setting */
+	adr	r3, memsetting_EZ_MCP_PNX8181_89MHZ
+1:
+	mov	r4, lr
+	bl	do_memsetup
+
+	mov	r1, #0x01		/* precharge all */
+	ldr	r2, =REG_SDI_SW_CTRL
+	str	r1, [r2]
+	mov	r1, #0x09		/* load extended mode register */
+	ldr	r2, =REG_SDI_SW_CTRL
+	str	r1, [r2]
+
+	mov	lr, r4
+	mov	r3, #(8<<20)		/* check for 8MB */
+	bl	memtest
+	mov	lr, r4
+	cmp	r3, #0
+	bne	2f
+	nop
+	nop
+2:					/* setup done */
+#endif
+	mov	r4, r3			/* r3 holds the memory size */
+					/* save a copy in r4 */
+	b	firetux_relocate_code	/* jump to the next assembler code */
+					/* board/firetux/relocate.S */
+
+
+
+/* Fill the sdram controller with the values from the table */
+
+do_memsetup:
+#ifndef CONFIG_NANDFLASH /* with nandflash we have to skip memconfig */
+	/* CGU setup */
+	/* pin multiplexing */
+	/* SDRAM config */
+	mov	r1, #0x00		/* NOP */
+	ldr	r2, =REG_SDI_SW_CTRL
+	str	r1, [r2]
+
+	mov	r0, #(0x50<<8)		/* wait 200us */
+					/* roughly calculated 208MHz,
+					   40960ticks,
+					   2instructions per loop */
+1:
+	subs	r0, r0, #1
+	bne	1b
+
+	mov	r1, #0x07		/* exit power down */
+	ldr	r2, =REG_SDI_SW_CTRL
+	str	r1, [r2]
+
+	mov	r0, #(0x50<<8)		/* wait 200us */
+1:
+	subs	r0, r0, #1
+	bne	1b
+
+	ldr	r2, =REG_SDI_CFG1
+	ldr	r1, [r3, #SDI_CFG1]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_CFG2
+	ldr	r1, [r3, #SDI_CFG2]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_PWR_CTRL
+	ldr	r1, [r3, #SDI_PWR_CTRL]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_RFRSH1
+	ldr	r1, [r3, #SDI_RFRSH1]
+	str	r1, [r2]
+	mov	r0, #(0x50<<8)		/* wait 200us */
+1:
+	subs	r0, r0, #1
+	bne	1b
+	orr	r1, r1, #(1<<24)	/* enable auto refresh generation */
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_MODE
+	ldr	r1, [r3, #SDI_MODE]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_EXT_MODE
+	ldr	r1, [r3, #SDI_EXT_MODE]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_RFRSH2
+	ldr	r1, [r3, #SDI_RFRSH2]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_TIM1
+	ldr	r1, [r3, #SDI_TIM1]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_TIM2
+	ldr	r1, [r3, #SDI_TIM2]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_SCHED0
+	ldr	r1, [r3, #SDI_SCHED0]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_SCHED1
+	ldr	r1, [r3, #SDI_SCHED1]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_SCHED2
+	ldr	r1, [r3, #SDI_SCHED2]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_WTAG0
+	ldr	r1, [r3, #SDI_WTAG0]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_WTAG1
+	ldr	r1, [r3, #SDI_WTAG1]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_WTAG2
+	ldr	r1, [r3, #SDI_WTAG2]
+	str	r1, [r2]
+	ldr	r2, =REG_SDI_TAM
+	ldr	r1, [r3, #SDI_TAM]
+	str	r1, [r2]
+
+	/* send power-up info */
+	mov	r1, #0x01		/* precharge all */
+	ldr	r2, =REG_SDI_SW_CTRL
+	str	r1, [r2]
+
+	mov	r0, #8			/* 8 times */
+1:
+	mov	r1, #0x03		/* auto refresh */
+	ldr	r2, =REG_SDI_SW_CTRL
+	str	r1, [r2]
+	subs	r0, r0, #1
+	bne	1b
+
+	mov	r1, #0x08		/* load mode register */
+	ldr	r2, =REG_SDI_SW_CTRL
+	str	r1, [r2]
+	mov	pc,lr
+
+
+/* check if the memory is working */
+
+memtest:
+	mov	r1, r3
+1:
+	ldr     r2, =CONFIG_SYS_SDRAM_BASE
+	add     r2, r2, r1
+	sub	r2, r2, #4
+	str	r1, [r2]
+	mov	r1, r1, LSR #1
+	cmp	r1, #4
+	bgt	1b
+	mov	r1, r3
+1:
+	ldr	r2, =CONFIG_SYS_SDRAM_BASE
+	add	r2, r2, r1
+	sub	r2, r2, #4
+	ldr	r0, [r2]
+	cmp	r0, r1
+	bne	2f
+	mov	r1, r1, LSR #1
+	cmp	r1, #4
+	bgt	1b
+	mov	pc, lr
+2:
+	mov	r3, #0
+	mov	pc, lr
+
+	nop
+	nop
+	nop
+	nop
+
+#endif
diff --git a/board/firetux/nand.c b/board/firetux/nand.c
new file mode 100644
index 0000000..7af7081
--- /dev/null
+++ b/board/firetux/nand.c
@@ -0,0 +1,74 @@
+/*
+ * pnx8181 nandflash driver
+ *
+ * (C) Copyright 2008, emlix GmbH, Germany
+ * Juergen Schoew <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ *
+ * 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>
+
+#ifdef CONFIG_NANDFLASH
+
+#include <nand.h>
+#include <asm/io.h>
+
+static void firetux_nand_hwcontrol(struct mtd_info *mtd, int dat,
+						unsigned int ctrl)
+{
+	struct nand_chip *chip = mtd->priv;
+	unsigned long IO_ADDR_W = (ulong)chip->IO_ADDR_W;
+
+	if (ctrl & NAND_CLE)
+		IO_ADDR_W += CONFIG_SYS_NAND_CLE_ADDR;
+
+	if (ctrl & NAND_ALE)
+		IO_ADDR_W += CONFIG_SYS_NAND_ALE_ADDR;
+
+	if (dat != NAND_CMD_NONE) {
+		if (chip->options & NAND_BUSWIDTH_16)
+			writew((unsigned short)dat, IO_ADDR_W);
+		else
+			writeb((unsigned char)dat, IO_ADDR_W);
+	}
+}
+
+
+static int firetux_nand_readybusy(struct mtd_info *mtd)
+{
+	return (int)((readl(CONFIG_SYS_NAND_RB_PORT) >> 18) & 1);
+}
+
+
+int board_nand_init(struct nand_chip *nand)
+{
+	nand->cmd_ctrl	 = firetux_nand_hwcontrol;
+	nand->dev_ready	 = firetux_nand_readybusy;
+	nand->chip_delay = 20;
+	nand->ecc.mode	 = NAND_ECC_SOFT;
+	nand->options	 = NAND_USE_FLASH_BBT | NAND_BBT_CREATE | NAND_BBT_WRITE
+			 | NAND_BBT_VERSION ;
+	return 0;
+}
+
+#endif
+
diff --git a/board/firetux/relocate.S b/board/firetux/relocate.S
new file mode 100644
index 0000000..679b0ee
--- /dev/null
+++ b/board/firetux/relocate.S
@@ -0,0 +1,246 @@
+/*
+ * firetux board specific setup
+ * based on cpu/arm926ejs/start.S
+ * modified to relocate the u-boot code at end of RAM
+ *
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew, <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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
+ */
+
+
+#include <config.h>
+#include <version.h>
+
+/* external labels needed for calculation */
+.extern _start
+.extern _armboot_start
+.extern _bss_start
+.extern _bss_end
+
+/* these are defined in the board-specific linker script */
+.global _relocation_table
+_relocation_table:
+	.word __relocation_table
+.global _got
+_got:
+	.word _GLOBAL_OFFSET_TABLE_
+
+/* local labels */
+_start_armboot:
+	.word start_armboot
+__start:
+	.word _start
+_armbootstart:
+	.word _armboot_start
+_bssstart:
+	.word _bss_start
+_bssend:
+	.word _bss_end
+_rel_offset:
+	.word .
+
+
+.global firetux_relocate_code
+firetux_relocate_code:
+
+/* input from memsetup:
+   r3 and r4 hold the size of the installed memory */
+
+
+#ifdef CONFIG_NANDFLASH
+/* with nandflash we skipped the lowlevelinit and memsetup */
+/* but we have to provide the memory settings here */
+
+/* read sdram settings from the controller */
+#define REG_SDI_CFG1        0xC1200000  /* SDRAM controller configuration 1 */
+	ldr	r1, =REG_SDI_CFG1
+	ldr	r2, [r1]
+	ands	r0, r2, #0x3		/* dram width 8, 16, 32, 64bit */
+	lsr	r2, r2, #4
+	ands	r4, r2, #0x3		/* columns 8, 9, 10, 11 */
+	add	r4, r4, #8
+	add	r0, r0, r4
+	lsr	r2, r2, #4
+	ands	r4, r2, #0x7		/* rows 9 .. 16 */
+	add	r4, r4, #9
+	add	r0, r0, r4
+	lsr	r2, r2, #4
+	ands	r4, r2, #0x3		/* nr banks 1, 2, 4 */
+	add	r0, r0, r4
+	mov	r2, #1
+	lsl	r3, r2, r0
+	mov	r4, r3			/* save size in r3 and r4 */
+#endif
+
+/* calculate address offset */
+	adr	r0, _rel_offset
+	ldr	r1, =_rel_offset
+	sub	r2, r0, r1
+	mov	r12, r2			/* offset to _start saved in r12    */
+
+/* if running from sdram, skip relocating */
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+	ldr	r0, =_start		/* original start		    */
+	add	r0, r0, r12		/* r0 <- current position of code   */
+	mov	r2, r0			/* save in r2			    */
+	mov	r1, #PHYS_SDRAM_1	/* test if we run from flash or RAM */
+	and	r0, r0, #0xf0000000	/* check if segment addr match	    */
+	and	r1, r1, #0xf0000000	/* check if segment addr match	    */
+#ifndef CONFIG_NANDFLASH
+	cmp     r0, r1                  /* don't reloc when already in ram  */
+	bne	firetux_relocate
+	mov	r4, r2			/* if not relocated, start of uboot */
+					/* need to be in r4 for stack setup */
+	b	firetux_stack_setup
+#endif
+
+/* relocation code */
+firetux_relocate:			/* relocate U-Boot to RAM	    */
+	ldr	r3, _bssend		/* address of label		    */
+	ldr	r3, [r3, r12]		/* address of _bss_end		    */
+	ldr	r2, __start		/* address of _start		    */
+	sub	r3, r3, r2		/* space needed for uboot with bss  */
+	mov	r2, #PHYS_SDRAM_1	/* ram start			    */
+	add	r2, r2, r4		/* add ram_size (memsetup.S)	    */
+	sub	r2, r2, #4		/* adjust off by one opcode	    */
+	sub	r2, r2, r3		/* sub size of uboot		    */
+	mvn	r1, #0xff		/* load 0xffffff00		    */
+	and	r1, r2, r1		/* clear last 8bit to get alignment */
+					/* r1 <- destination address	    */
+	ldr	r0, __start
+	add	r0, r0, r12		/* r0 <- current position of code   */
+					/*       source address		    */
+	mov	r4, r1			/* save destination addr	    */
+	ldr	r2, __start		/* address of _start		    */
+	ldr	r3, _bssstart		/* address of label		    */
+	ldr	r3, [r3, r12]		/* address of _bss_start	    */
+	sub	r2, r3, r2		/* r2 <- size of armboot without bss*/
+	add	r2, r0, r2		/* r2 <- end of source address	    */
+
+firetux_copy_loop:
+	ldmia	r0!, {r5-r10}		/* copy from source address [r0]    */
+	stmia	r1!, {r5-r10}		/* copy to   target address [r1]    */
+	cmp	r0, r2			/* until source end addreee [r2]    */
+	ble	firetux_copy_loop
+#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
+
+	/* Set up the stack						    */
+firetux_stack_setup:
+	mov	r0, r4					/* relocated uboot  */
+	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN		/* malloc area	    */
+	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE	/* bdinfo	    */
+#ifdef CONFIG_USE_IRQ
+	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
+
+firetux_clear_bss:
+	mov	r0, r4			/* start address of relocated uboot */
+	ldr	r2, __start		/* address of _start		    */
+	ldr	r3, _bssstart		/* address of label		    */
+	ldr	r3, [r3, r12]		/* address of _bss_start	    */
+	sub	r2, r3, r2		/* offset from start		    */
+	add	r0, r0, r2		/* new bss_start in ram		    */
+					/* r0 <- new _bss_start		    */
+	ldr	r1, _bssstart		/* address of label		    */
+	ldr	r1, [r1, r12]		/* address of _bss_start	    */
+	ldr	r2, _bssend		/* address of label                 */
+	ldr	r2, [r2, r12]		/* address of _bss_end		    */
+	sub	r1, r2, r1		/* calc length of bss		    */
+	add	r1, r0, r1		/* r1 <- new bss_end in ram	    */
+	mov 	r2, #0x00000000		/* clear                            */
+
+firetux_clbss_l:
+	str	r2, [r0]		/* clear loop...                    */
+	add	r0, r0, #4
+	cmp	r0, r1
+	ble	firetux_clbss_l
+
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+relocate_variables:
+	/* we need to relocate the _armboot_start, _bss_start and _bss_end
+	 * variables to the new u-boot location, which is needed for
+	 * lib_arm/board.c for the caculation of the memory locations for
+	 * board setup */
+	ldr	r0, __start		/* start of old code		    */
+	sub	r3, r4, r0		/* calculate offset between old/new */
+					/* r3 <- value to add		    */
+	ldr	r0, _armbootstart	/* start of old code		    */
+	ldr	r2, [r0, r12]		/* read value			    */
+	add	r2, r2, r3		/* add offset			    */
+	str	r2, [r0, r3]		/* store new value		    */
+	ldr	r0, _bssstart		/* get old address		    */
+	ldr	r2, [r0, r12]		/* read value			    */
+	add	r2, r2, r3		/* add offset			    */
+	str	r2, [r0, r3]		/* store new value		    */
+	ldr	r0, _bssend		/* get old address		    */
+	ldr	r2, [r0, r12]		/* read value			    */
+	add	r2, r2, r3		/* add offset			    */
+	str	r2, [r0, r3]		/* store new value		    */
+
+	/* OK, we need to fix the whole _GLOBAL_OFFSET_TABLE_ till bss section*/
+fix_global_offset_table:
+	ldr	r0, __start		/* get old starting point	    */
+	mov	r3, r0			/* r3 <- save for compare lower limit*/
+	sub	r0, r4, r0		/* r0 <- calculate offset to new start*/
+	ldr	r1, _relocation_table	/* get old table address	    */
+	add	r1, r1, r0		/* r1 <- calculate new table address*/
+	ldr	r2, _bssend		/* get label address		    */
+	ldr	r2, [r2, r12]		/* get old table end		    */
+	mov	r5, r2			/* r5 <- save for compare upper limit*/
+	sub	r2, r2, #4
+	add	r2, r2, r0		/* r2 <- calculate new end address  */
+
+2:	ldr	r6, [r1]		/* load table value		    */
+	cmp	r6, r3			/* check for lower value	    */
+	blt	1f
+	cmp	r6, r5			/* check for upper limit	    */
+	bgt	1f
+	add	r6, r6, r0
+	str	r6, [r1]
+1:	add	r1, r1, #4		/* increase address		    */
+	cmp	r1, r2			/* compare with end address	    */
+	ble	2b
+#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
+
+	/* calculate addr for start_armboot, because jump maybe more than 32MB*/
+	ldr	r0, __start		/* start of code		    */
+	ldr	r1, _start_armboot	/* start of c-function		    */
+	sub	r0, r1, r0		/* offset from beginning	    */
+	add	r0, r0, r4		/* calculate new addr in ram	    */
+	mov	lr, r0			/* save start addr in lr	    */
+
+	/* set PIC offset register (sl/r10) */
+	ldr	r1, __start
+	add	r1, r1, r12		/* addr of original u-boot	    */
+	adr	r2, _got		/* addr of _got label		    */
+	sub	r1, r2, r1		/* offset from _start		    */
+
+	ldr	sl, _got		/* get got offset from _got	    */
+	add	sl, sl, r1		/* add offset of _got		    */
+	add	sl, sl, r4		/* add start + offset for new got   */
+
+	mov	pc, r0			/* jump into C code   start_armboot */
+					/* lib_arm/board.c */
diff --git a/board/firetux/u-boot.lds b/board/firetux/u-boot.lds
new file mode 100644
index 0000000..3f35557
--- /dev/null
+++ b/board/firetux/u-boot.lds
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2007-2008, emlix GmbH, Germany
+ * Juergen Schoew <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+	. = ALIGN(4);
+	.text	:
+	{
+		cpu/arm926ejs/start.o (.text)
+		*(.text)
+	}
+	.rodata : { *(.rodata) }
+	. = ALIGN(4);
+	.data : { *(.data)
+		  __relocation_table = .;
+		}
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	. = .;
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss (NOLOAD) : { *(.bss) }
+	_end = .;
+}
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 6079c05..ef457a5 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -31,6 +31,7 @@ COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_PNX8181_I2C) += pnx8181_i2c.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/i2c/pnx8181_i2c.c b/drivers/i2c/pnx8181_i2c.c
new file mode 100644
index 0000000..9979ebe
--- /dev/null
+++ b/drivers/i2c/pnx8181_i2c.c
@@ -0,0 +1,302 @@
+/*
+ * (C) Copyright 2008 emlix GmbH
+ * Author: Juergen Schoew <js at emlix.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 <config.h>
+#include <common.h>
+
+#if defined(CONFIG_CMD_I2C) && defined(CONFIG_FIRETUX)
+
+#undef  DEBUG_I2C
+
+#ifdef DEBUG_I2C
+#define DPRINT(args...)		printf(args)
+#else
+#define DPRINT(args...)
+#endif
+
+#define ARM_VPB1_BASE_ADDR	0xC2000000
+#define ARM_VPB3_BASE_ADDR	0xC2200000
+#define ARM_VPB_SIZE_SHIFT	12
+#define SCON_BASE_ADDR		(ARM_VPB3_BASE_ADDR + (4<<ARM_VPB_SIZE_SHIFT))
+#define SCON_BASE		SCON_BASE_ADDR
+#define SCON_SYSMUX1_OFFSET	(0x010)
+#define SCON_SYSMUX1_REG	(*(vu_long *)(SCON_BASE + SCON_SYSMUX1_OFFSET))
+#define SCON_GPIOA27_MUX_SHIFT	22
+#define SCON_GPIOA27_MUX_FIELD	(0xFFFFFFFF-(3<<SCON_GPIOA27_MUX_SHIFT))
+#define SCON_GPIOA27_SCL	(1<<SCON_GPIOA27_MUX_SHIFT)
+#define SCON_GPIOA28_MUX_SHIFT	24
+#define SCON_GPIOA28_MUX_FIELD	(0xFFFFFFFF-(3<<SCON_GPIOA28_MUX_SHIFT))
+#define SCON_GPIOA28_SDA	(1<<SCON_GPIOA28_MUX_SHIFT)
+#define CGU_BASE_ADDR		(ARM_VPB3_BASE_ADDR + (0<<ARM_VPB_SIZE_SHIFT))
+#define CGU_BASE		(CGU_BASE_ADDR)
+#define CGU_GATESC_OFFSET	(0x008)
+#define CGU_GATESC_REG		(*(vu_long *)(CGU_BASE + CGU_GATESC_OFFSET))
+#define CGU_I2C1EN		0x00000020
+#define CGU_I2CEN		CGU_I2C1EN
+#define I2C1_BASE_ADDR		(ARM_VPB1_BASE_ADDR + (1<<ARM_VPB_SIZE_SHIFT))
+#define I2C1_BASE		I2C1_BASE_ADDR
+#define I2C1_RX_REG		(*(vu_long *)(I2C1_BASE + I2C_RX_OFFSET))
+#define I2C_CLKHI_OFFSET	(0x00C)
+#define I2C_CLKHI_REG		(*(vu_long *)(I2C1_BASE + I2C_CLKHI_OFFSET))
+#define I2C_CLKLO_OFFSET	(0x010)
+#define I2C_CLKLO_REG		(*(vu_long *)(I2C1_BASE + I2C_CLKLO_OFFSET))
+#define I2C_ADR_OFFSET		(0x014)
+#define I2C1_ADR_REG            (*(vu_long *)(I2C1_BASE + I2C_ADR_OFFSET))
+#define I2C_ADR_REG             (*(vu_long *)(I2C1_BASE + I2C_ADR_OFFSET))
+#define I2C_SADDR_FIELD         0xFFFFFF80
+#define I2C_HOLDDAT_OFFSET	(0x018)
+#define I2C_HOLDDAT_REG		(*(vu_long *)(I2C1_BASE + I2C_HOLDDAT_OFFSET))
+#define I2C_CLKDIV_FIELD	0xFFFFFC00
+#define I2C_STS_OFFSET		(0x004)
+#define I2C_STS_REG		(*(vu_long *)(I2C1_BASE + I2C_STS_OFFSET))
+#define I2C_CTL_OFFSET		(0x008)
+#define I2C_CTL_REG		(*(vu_long *)(I2C1_BASE + I2C_CTL_OFFSET))
+#define I2C_TX_OFFSET		(0x000)
+#define I2C_TX_REG		(*(vu_long *)(I2C1_BASE + I2C_TX_OFFSET))
+#define I2C_RX_OFFSET		(0x000)
+#define I2C1_RX_REG		(*(vu_long *)(I2C1_BASE + I2C_RX_OFFSET))
+#define I2C_RX_REG		(*(vu_long *)(I2C1_BASE + I2C_RX_OFFSET))
+#define I2C_TDI			0x00000001
+#define I2C_AFI			0x00000002
+#define I2C_NAI			0x00000004
+#define I2C_DRMI		0x00000008
+#define I2C_DRSI		0x00000010
+#define I2C_ACTIVE		0x00000020
+#define I2C_SCL			0x00000040
+#define I2C_SDA			0x00000080
+#define I2C_RFF			0x00000100
+#define I2C_RFE			0x00000200
+#define I2C_TFF			0x00000400
+#define I2C_TFE			0x00000800
+#define I2C_TFFS		0x00001000
+#define I2C_TFES		0x00002000
+#define I2C_MAST		0x00004000
+
+#define I2C_RESET		0x00000100
+
+#define I2C_TIMEOUT		10000
+#define I2C_DELAY		10
+
+
+#define SEND_I2C_DEVICE_ADDRESS_START_STOP(addr)	\
+					I2C_TX_REG = (((0x80+addr)<<1) + 0x200);
+#define SEND_I2C_START_ADDRESS(addr)	I2C_TX_REG = ((0x80+addr)<<1);
+#define SEND_I2C_STOP_DATA(data)	I2C_TX_REG = (0x200+data);
+#define SEND_I2C_READ_ADDRESS(addr)	I2C_TX_REG = (((0x80+addr)<<1)+1);
+#define SOFT_I2C_RESET			I2C_CTL_REG |= I2C_RESET ;
+
+int eeprom_write_enable(unsigned dev_addr, int state)
+{
+	/* nothing to be done here */
+	return 0;
+}
+
+void i2c_init(int speed, int slaveadd)
+{
+	unsigned long timeout;
+
+	SCON_SYSMUX1_REG &= SCON_GPIOA27_MUX_FIELD & SCON_GPIOA28_MUX_FIELD;
+	SCON_SYSMUX1_REG |= SCON_GPIOA27_SCL | SCON_GPIOA28_SDA;
+	CGU_GATESC_REG |= CGU_I2CEN;
+	if (speed == 400000) {
+	} else {
+		speed = 100000;
+		/* here the registers are set in order to have a 100KHz clk
+		 * for a pclk1 of 23Mhz */
+		I2C_CLKHI_REG   = I2C_CLKDIV_FIELD  | 0x50;
+		I2C_CLKLO_REG   = I2C_CLKDIV_FIELD  | 0x96;
+		I2C_HOLDDAT_REG = 0x10;
+	}
+	I2C_ADR_REG = slaveadd & ~I2C_SADDR_FIELD;
+	SOFT_I2C_RESET;
+	timeout = 0;
+	while ((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE) {
+		if (timeout > I2C_TIMEOUT)
+			break;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	DPRINT("%s: speed: %d\n", __func__, speed);
+}
+
+
+int i2c_probe(uchar chip)
+{
+	unsigned long timeout;
+
+	SEND_I2C_DEVICE_ADDRESS_START_STOP(chip);
+	timeout = 0;
+	while ((I2C_TDI & I2C_STS_REG) != I2C_TDI) {
+		if (timeout > I2C_TIMEOUT)
+			return -1;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	I2C_STS_REG |= I2C_TDI;
+	if ((I2C_NAI & I2C_STS_REG) == I2C_NAI)
+		return -1;
+	return 0;
+}
+
+static int i2c_read_byte(u8 chip, u16 addr, u8 *byte)
+{
+	unsigned long timeout;
+
+	timeout = 0;
+	while ((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE) {
+		if (timeout > I2C_TIMEOUT)
+			return -1;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	SEND_I2C_START_ADDRESS(chip);
+	/* loop if scl=1, active=0 or drmi=0 */
+	timeout = 0;
+	while (((I2C_SCL & I2C_STS_REG)      == I2C_SCL)    ||
+		((I2C_ACTIVE & I2C_STS_REG)  != I2C_ACTIVE) ||
+		((I2C_DRMI & I2C_STS_REG)    != I2C_DRMI))
+		if (timeout > I2C_TIMEOUT) {
+			return -1;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	I2C_TX_REG = ((addr & 0xFF00) >> 8);		/* ADDRESS_MODE16 */
+	I2C_TX_REG = ((addr & 0x00FF) >> 0);
+	SEND_I2C_READ_ADDRESS(chip);			/* Dev Sel to Read */
+	SEND_I2C_STOP_DATA(0x00);			/* dummy write */
+	timeout = 0;
+	while (((I2C_NAI & I2C_STS_REG)     == I2C_NAI)     ||
+		((I2C_TDI & I2C_STS_REG)    != I2C_TDI)     ||
+		((I2C_SCL & I2C_STS_REG)    != I2C_SCL)     ||
+		((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE)  ||
+		((I2C_DRMI & I2C_STS_REG)   == I2C_DRMI))
+		if (timeout > I2C_TIMEOUT) {
+			return -1;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	I2C_STS_REG |= I2C_TDI;
+	timeout = 0;
+	while ((I2C_TDI & I2C_STS_REG) == I2C_TDI) {
+		if (timeout > I2C_TIMEOUT)
+			return -1;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	*byte = I2C_RX_REG & 0xff;
+	return 0;
+}
+
+static int i2c_write_byte(u8 chip, u16 addr, u8 *byte)
+{
+	u8 dummy;
+	unsigned long timeout;
+
+	/* wait until data is written and eeprom back again */
+	timeout = 0;
+	dummy = 1;
+	while ((timeout < I2C_TIMEOUT) && (dummy != 0)) {
+		dummy = -i2c_probe(chip);
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	timeout = 0;
+	while ((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE) {
+		if (timeout > I2C_TIMEOUT)
+			return -1;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	SEND_I2C_START_ADDRESS(chip);
+	/* loop if scl=1, active=0 or drmi=0 */
+	timeout = 0;
+	while (((I2C_SCL & I2C_STS_REG)      == I2C_SCL)    ||
+		  ((I2C_ACTIVE & I2C_STS_REG)  != I2C_ACTIVE) ||
+		  ((I2C_DRMI & I2C_STS_REG)    != I2C_DRMI)) {
+		if (timeout > I2C_TIMEOUT)
+			return -2;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	I2C_TX_REG = ((addr & 0xFF00) >> 8);		/* ADDRESS_MODE16 */
+	I2C_TX_REG = ((addr & 0x00FF) >> 0);
+	SEND_I2C_STOP_DATA(*byte);
+	timeout = 0;
+	while (((I2C_NAI & I2C_STS_REG)      == I2C_NAI)     ||
+		((I2C_TDI & I2C_STS_REG)     != I2C_TDI)     ||
+		((I2C_SCL & I2C_STS_REG)     != I2C_SCL)     ||
+		((I2C_ACTIVE & I2C_STS_REG)  == I2C_ACTIVE)  ||
+		((I2C_DRMI & I2C_STS_REG)    == I2C_DRMI)) {
+		if (timeout > I2C_TIMEOUT)
+			return -3;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	I2C_STS_REG |= I2C_TDI;
+	timeout = 0;
+	while ((I2C_TDI & I2C_STS_REG) == I2C_TDI) {
+		if (timeout > I2C_TIMEOUT)
+			return -4;
+		timeout++;
+		udelay(I2C_DELAY);
+	}
+	dummy = I2C_RX_REG & 0xff;
+	return 0;
+}
+
+int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	int ret;
+	u8 byte;
+
+	DPRINT("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
+		__func__, chip, addr, alen, len);
+	while (len--) {
+		ret = i2c_read_byte(chip, addr, &byte);
+		if (ret < 0)
+			return -1;
+		*buf++ = byte;
+		addr++;
+	}
+	return 0;
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	int ret;
+
+	DPRINT("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
+		__func__, chip, addr, alen, len);
+	while (len--) {
+		ret = i2c_write_byte(chip, addr++, buf++);
+		if (ret) {
+			printf("i2c_write failed chip: 0x%x addr: "
+				"0x%04x error %d\n", chip, addr, ret);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+#endif
diff --git a/include/configs/firetux.h b/include/configs/firetux.h
new file mode 100644
index 0000000..8300b87
--- /dev/null
+++ b/include/configs/firetux.h
@@ -0,0 +1,457 @@
+/*
+ * firetux board configuration
+ *
+ * (C) Copyright 2007-2008 emlix GmbH
+ * Juergen Schoew <js at emlix.com>
+ *
+ * (C) Copyright 2008, DSPG Technologies GmbH, Germany
+ * (C) Copyright 2007, NXP Semiconductors Germany GmbH
+ * Matthias Wenzel, <nxp at mazzoo.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 __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_FIRETUX			1
+#define CONFIG_ARCH_FIRETUX		1
+#define CONFIG_ARM926EJS		1
+
+/* we can have nand _or_ nor flash */
+/* #define CONFIG_NANDFLASH		1 */
+
+/* #define CONFIG_SHOW_BOOT_PROGRESS	1 */
+#define CONFIG_DISPLAY_CPUINFO		1
+#define CONFIG_DISPLAY_BOARDINFO	1
+
+#define CONFIG_BOOT_LINUX		1
+
+/* #define CONFIG_USE_IRQ		1 */
+
+/* #define CONFIG_SKIP_LOWLEVEL_INIT	1 */
+
+#define CONFIG_SYS_ARM_DEBUG_MEM	1
+
+/* MWe has a buggy piece of silicon */
+/* #define CONFIG_FIRETUX_HAS_CGU_SCCON_MSC_BUG	1 */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+/* Timer 1 is clocked at 1Mhz */
+#define CONFIG_SYS_HZ			1000000
+
+/* enable passing of ATAGs  */
+#define CONFIG_CMDLINE_TAG		1
+#define CONFIG_SETUP_MEMORY_TAGS	1
+/* call misc_init_r during start up */
+#define CONFIG_MISC_INIT_R		1
+#define CONFIG_INITRD_TAG		1
+/* mount rootfs read-only */
+#define CONFIG_ROOT_RDONLY		1
+#define CONFIG_STATUS_LED		1
+#define CONFIG_BOARD_SPECIFIC_LED	1
+#define STATUS_LED_BIT			1
+#define STATUS_LED_PERIOD		(CONFIG_SYS_HZ / 2)
+#define STATUS_LED_STATE		STATUS_LED_BLINKING
+#define STATUS_LED_ACTIVE		1
+#define STATUS_LED_BOOT			1
+
+/* BZIP2 needs 4MB Malloc Size */
+/* #define CONFIG_BZIP2			1 */
+#define CONFIG_LZMA			1
+
+/*
+ * Boardrevisions:
+ *  0: unknown PNX8181 board
+ *  1: EZ_MCP_PNX8181
+ *  2: Vega_PNX8181_BaseStation Platform III-a
+ *  3: Vega_PNX8181_BaseStation Platform III-b
+ *  4: Vega_PNX8181_BaseStation Platform III-c
+ */
+#define CONFIG_MAX_BOARDREVISIONS	4
+
+/*
+ * ethernet
+ */
+
+/* #define ET_DEBUG			1 */
+#define CONFIG_NET_RETRY_COUNT		7
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE		1
+#ifdef CONFIG_NANDFLASH
+#define CONFIG_EXTRA_ENV_SETTINGS     \
+		"ethaddr=00:60:37:C0:FF:EE\0"	\
+		"netmask=255.255.255.0\0"	\
+		"ipaddr=192.168.3.183\0"	\
+		"serverip=192.168.3.60\0"	\
+		"bootfile=firetux.kernel\0"	\
+		"bootcmd=run bootcmd1\0"	\
+		"bootcmd1=nboot 0x20200000 0 0x80000 " \
+			"&& bootm 0x20200000\0" \
+		"bootcmd2=tftpboot 0x20200000 firetux.kernel " \
+			"&& bootm 0x20200000\0" \
+		"ethact=ETN1\0"			\
+		"phymode=auto\0"		\
+		"mtdids=nor0=firetux\0"		\
+		"mtdparts=mtdparts=firetux:" \
+			"384k(U-Boot)," \
+			"128k(U-Bootenv)," \
+			"1536k(kernel)," \
+			"1M(config)," \
+			"2M(data)," \
+			"-(rootfs)\0" \
+		"partition=nor0,5\0"		\
+		"unlock=yes\0"			\
+		"update.eeprom=echo Update eeprom " \
+			"&& tftpboot 0x20000000 firetux.eeprom " \
+			"&& eeprom write 0x20000000 0x0 ${filesize}\0" \
+		"update.uboot=echo Update u-boot " \
+			"&& tftpboot 0x20000000 firetux.nandboot.flash " \
+			"&& nand erase 0x0 0x03ffff " \
+			"&& nand write.jffs2 0x20000000 0x0 ${filesize}\0" \
+		"update.kernel=echo Update kernel " \
+			"&& tftpboot 0x20000000 firetux.kernel " \
+			"&& nand erase 0x80000 0x17ffff " \
+			"&& nand write.jffs2 20000000 0x80000 ${filesize}\0" \
+		"update.config=echo Update config " \
+			"&& tftpboot 0x20000000 firetux.config " \
+			"&& nand erase clean 0x200000 0xfffff " \
+			"&& nand write.jffs2 20000000 0x200000 ${filesize}\0" \
+		"update.data=echo Update data " \
+			"&& tftpboot 0x20000000 firetux.data " \
+			"&& nand erase clean 0x300000 0x1fffff " \
+			"&& nand write.jffs2 20000000 0x300000 ${filesize}\0" \
+		"update.rootfs=echo Update rootfs " \
+			"&& tftpboot 0x20000000 firetux.targetfs " \
+			"&& nand erase clean 0x500000 " \
+			"&& nand write.jffs2 20000000 0x500000 ${filesize}\0" \
+		"update.user=run update.rootfs " \
+			"&& run update.data " \
+			"&& run update.config\0" \
+		"update.linux=run update.kernel " \
+			"&& run update.user\0" \
+		"update.all=run update.uboot " \
+			"&& run update.linux\0" \
+		""
+#else
+#define CONFIG_EXTRA_ENV_SETTINGS     \
+		"ethaddr=00:60:37:C0:FF:EE\0"	\
+		"netmask=255.255.255.0\0"	\
+		"ipaddr=192.168.3.183\0"	\
+		"serverip=192.168.3.60\0"	\
+		"bootfile=firetux.kernel\0"	\
+		"bootcmd=run bootcmd1\0"	\
+		"bootcmd1=bootm 0x80080000\0" \
+		"bootcmd2=tftp 20200000 firetux.kernel  " \
+			"&&  bootm 20200000\0" \
+		"ethact=ETN1\0"			\
+		"phymode=auto\0"		\
+		"mtdids=nor0=firetux\0"		\
+		"mtdparts=mtdparts=firetux:" \
+			"384k(U-Boot)," \
+			"128k(U-Bootenv)," \
+			"1536k(kernel)," \
+			"1M(config)," \
+			"2M(data)," \
+			"-(rootfs)\0" \
+		"partition=nor0,5\0"		\
+		"unlock=yes\0"			\
+		"update.uboot=echo Update u-boot " \
+			"&& tftpboot 0x20000000 firetux.uboot " \
+			"&& protect off 0x80000000 0x8005ffff " \
+			"&& erase 0x80000000 0x8005ffff " \
+			"&& cp.b 0x20000000 0x80000000 ${filesize}\0" \
+		"update.kernel=echo Update kernel " \
+			"&& tftpboot 0x20000000 firetux.kernel " \
+			"&& erase 0x80080000 0x801fffff " \
+			"&& cp.b 20000000 0x80080000 ${filesize}\0" \
+		"update.config=echo Update config " \
+			"&& tftpboot 0x20000000 firetux.config " \
+			"&& erase 0x80200000 0x802fffff " \
+			"&& cp.b 20000000 0x80200000 ${filesize}\0" \
+		"update.data=echo Update data " \
+			"&& tftpboot 0x20000000 firetux.data " \
+			"&& erase 0x80300000 0x804fffff " \
+			"&& cp.b 20000000 0x80300000 ${filesize}\0" \
+		"update.rootfs=echo Update rootfs " \
+			"&& tftpboot 0x20000000 firetux.targetfs " \
+			"&& erase 0x80500000 0x81ffffff " \
+			"&& cp.b 20000000 0x80500000 ${filesize}\0" \
+		"update.user=run update.rootfs " \
+			"&& run update.data " \
+			"&& run update.config\0" \
+		"update.linux=run update.kernel " \
+			"&& run update.user\0" \
+		"update.all=run update.uboot " \
+			"&& run update.linux\0" \
+		""
+#endif
+				/* better not set "gatewayip" */
+
+#define ETN_RX_DESCRIPTOR_NUMBER	16
+#define ETN_TX_DESCRIPTOR_NUMBER	16
+
+#define MAX_ETH_FRAME_SIZE		1536
+
+#define CONFIG_ENV_SIZE			0x20000		/* 128KB */
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN_ETN	(ETN_RX_DESCRIPTOR_NUMBER * \
+						MAX_ETH_FRAME_SIZE)
+#define CONFIG_SYS_MALLOC_LEN		(4*128*1024 + CONFIG_ENV_SIZE + \
+						CONFIG_SYS_MALLOC_LEN_ETN)
+/* min 4MB for bzip2 */
+/* #define CONFIG_SYS_MALLOC_LEN		(4 * 1024 * 1024)*/
+/* #define CONFIG_SYS_MALLOC_LEN		0x70000 */
+
+/* size in bytes reserved for initial data */
+#define CONFIG_SYS_GBL_DATA_SIZE	128
+
+
+/*
+ * Hardware drivers
+ */
+
+/*
+ * NS16550 Configuration
+ */
+#define CONFIG_SYS_NS16550		1
+#define CONFIG_SYS_NS16550_SERIAL	1
+#define CONFIG_CONS_INDEX		2
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_SYS_SERIAL0		0xC2004000
+#define CONFIG_SYS_SERIAL1		0xC2005000
+#define CONFIG_SYS_NS16550_COM1		CONFIG_SYS_SERIAL0
+#define CONFIG_SYS_NS16550_COM2		CONFIG_SYS_SERIAL1
+#define CONFIG_SYS_NS16550_REG_SIZE	4
+/* fclk=27.648==clk26m, uclk=14.756 */
+#define CONFIG_SYS_NS16550_CLK		14745600
+
+#define CONFIG_CRC32_VERIFY		1
+
+#define CONFIG_CMDLINE_EDITING		1
+#define CONFIG_AUTO_COMPLETE		1
+#define CONFIG_MX_CYCLIC		1
+
+
+
+/*
+ * command line
+ */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_XIMG
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_MISC
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_CONSOLE
+#define CONFIG_CMD_AUTOSCRIPT
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_NFS
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_ITEST
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_EEPROM
+#ifdef CONFIG_NANDFLASH
+#define CONFIG_CMD_NAND
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_FLASH
+#else
+#define CONFIG_CMD_IMLS
+#define CONFIG_CMD_FLASH
+#define CONFIG_CMD_JFFS2
+#define CONFIG_CMD_CRAMFS
+#endif
+
+/* #define CONFIG_BOOTP_MASK	CONFIG_BOOTP_DEFAULT */
+
+
+#define CONFIG_BOOTDELAY		10
+#define CONFIG_BOOTARGS			"console=ttyS1,115200n8 " \
+					"root=/dev/mtdblock5 rootfstype=jffs2" \
+					" noalign"
+#define CONFIG_BOOTCOMMAND		"run bootcmd1"
+#define CONFIG_MII			1
+#define CONFIG_DISCOVER_PHY		1
+#define CONFIG_TIMESTAMP		1
+#define CONFIG_TFTP_PORT		1
+
+/*
+ * Physical Memory Map
+ */
+/* if we have psRAM and SDRAM */
+/* #define CONFIG_SYS_PSRAM		1 */
+#undef  CONFIG_SYS_PSRAM
+
+#define CONFIG_NR_DRAM_BANKS		1
+#ifdef CONFIG_SYS_PSRAM
+  #define CONFIG_SYS_SDRAM_BASE		0x90000000
+#else
+  #define CONFIG_SYS_SDRAM_BASE		0x20000000
+#endif
+
+#define PHYS_SDRAM_1			CONFIG_SYS_SDRAM_BASE
+#define PHYS_SDRAM_1_SIZE		(8<<20)		/* min 8 MB */
+#define CONFIG_SYS_MEMTEST_START	PHYS_SDRAM_1
+#define CONFIG_SYS_MEMTEST_END		(PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE - \
+					    (1<<20) - 1) /* ramsize - 1MB */
+#define CONFIG_SYS_ALT_MEMTEST		1
+
+/*
+ * FLASH and environment organization
+ */
+#ifdef CONFIG_NANDFLASH
+
+#define NAND_MAX_CHIPS			1
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_BASE		0x80000000
+#define CONFIG_SYS_NAND_ALE_ADDR	(1<<10)
+#define CONFIG_SYS_NAND_CLE_ADDR	(1<<12)
+#define CONFIG_SYS_NAND_RB_PORT		0xC2104200
+#define CONFIG_SYS_NO_FLASH		1
+
+#define CONFIG_ENV_IS_IN_NAND		1
+#define CONFIG_ENV_OFFSET		0x40000
+#define CONFIG_ENV_OFFSET_REDUND	0x60000
+#define CONFIG_ENV_OVERWRITE		1
+
+
+#else /* NOR-FLASH */
+/* set optimized access throug board_init */
+/* CONFIG_SYS_OPTIMIZE_NORFLASH		1 */
+
+#define CONFIG_ENV_IS_IN_FLASH		1
+#define CONFIG_ENV_ADDR			0x80060000
+#define CONFIG_ENV_SECT_SIZE		0x20000		/* 128KB */
+
+/* Use drivers/cfi_flash.c */
+#define CONFIG_FLASH_CFI_DRIVER		1
+/* Flash memory is CFI compliant */
+#define CONFIG_SYS_FLASH_CFI		1
+/* Use buffered writes (~20x faster) */
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE	1
+/* Use hardware sector protection */
+#define CONFIG_SYS_FLASH_PROTECTION	1
+/* Use Spansion hardware sector protection */
+/* #define CONFIG_SYS_AMD_PPB_PROTECTION	1 */
+
+#define CONFIG_SYS_FLASH_BASE		0x80000000
+#define CONFIG_SYS_FLASH_BANKS_LIST	{ CONFIG_SYS_FLASH_BASE }
+#define CONFIG_SYS_FLASH_EMPTY_INFO	1
+/* see include/flash.h for details FLASH_CFI_8BIT */
+#define CONFIG_SYS_FLASH_CFI_WIDTH	0x1
+/* 4* 32K + 254* 128k + 4* 32k = 262 Sectors */
+#define CONFIG_SYS_MAX_FLASH_SECT	262
+/* max number of memory banks */
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+
+/* Flash banks JFFS2 should use */
+#define CONFIG_SYS_JFFS_CUSTOM_PART	1
+#define CONFIG_SYS_JFFS2_SORT_FRAGMENTS	1
+#define CONFIG_JFFS2_CMDLINE		1
+#define CONFIG_JFFS2_LZO_LZARI		1
+#define CONFIG_JFFS2_DEV		"firetux"
+#define CONFIG_FLASH_SHOW_PROGRESS	45
+#define MTDIDS_DEFAULT			"nor0=firetux"
+#define MTDPARTS_DEFAULT		"mtdparts=firetux:" \
+						"384k(U-Boot)," \
+						"128k(U-Bootenv)," \
+						"1536k(kernel)," \
+						"1M(config)," \
+						"2M(data)," \
+						"-(rootfs)"
+
+#ifndef CONFIG_SYS_JFFS_CUSTOM_PART
+#define CONFIG_SYS_JFFS2_FIRST_BANK	0
+#define CONFIG_SYS_JFFS2_NUM_BANKS	1
+/* start addr 0x80500000 */
+#define CONFIG_SYS_JFFS2_FIRST_SECTOR	40
+#define CONFIG_SYS_JFFS_SINGLE_PART	1
+#endif
+
+#endif /* NOR-FLASH */
+
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_MONITOR_LEN		0x0005ffff
+
+/*
+ * Miscellaneous configurable options
+ */
+/* undef to save memory */
+#define CONFIG_SYS_LONGHELP		1
+#define CONFIG_SYS_HUSH_PARSER		1
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+/* Monitor Command Prompt */
+#define CONFIG_SYS_PROMPT		"firetux # "
+/* Console I/O Buffer Size*/
+#define CONFIG_SYS_CBSIZE		512
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + \
+						sizeof(CONFIG_SYS_PROMPT)+16)
+/* max number of command args */
+#define CONFIG_SYS_MAXARGS		16
+/* Boot Argument Buffer Size*/
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+/* default load address, keep 2 MByte for u-boot/kernel */
+#define CONFIG_SYS_LOAD_ADDR		(PHYS_SDRAM_1 + (2<<20))
+
+#ifdef CONFIG_CMD_EEPROM
+#define CONFIG_PNX8181_I2C		1
+#define CONFIG_SYS_EEPROM_WREN		1
+#undef CONFIG_SYS_I2C_MULTI_EEPROMS
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2
+#define CONFIG_SYS_I2C_EEPROM_ADDR	0x50
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	1
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+#define CONFIG_HARD_I2C			1
+#endif
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+/* regular stack */
+#define CONFIG_STACKSIZE	(128*1024)
+#ifdef CONFIG_USE_IRQ
+/* IRQ stack */
+#define CONFIG_STACKSIZE_IRQ	(4*1024)
+/* FIQ stack */
+#define CONFIG_STACKSIZE_FIQ	(4*1024)
+#endif
+
+#endif /* __CONFIG_H */
diff --git a/net/bootp.c b/net/bootp.c
index 83465e4..30bf0a3 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -81,6 +81,10 @@ extern u8 *dhcp_vendorex_prep (u8 *e); /*rtn new e after add own opts. */
 extern u8 *dhcp_vendorex_proc (u8 *e); /*rtn next e if mine,else NULL  */
 #endif
 
+#if defined(CONFIG_FIRETUX)
+extern int firetux_select_eth(void);
+#endif
+
 #endif
 
 static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
@@ -594,6 +598,13 @@ BootpRequest (void)
 				s = (*e) ? e+1 : e;
 			}
 		}
+#if defined(CONFIG_FIRETUX)
+		/* ETN1 has even and ETN2 odd MAC address */
+		if (firetux_select_eth())
+			bi_enetaddr[5] = bi_enetaddr[5] | 1;
+		else
+			bi_enetaddr[5] = bi_enetaddr[5] & 0xfe;
+#endif
 #ifdef DEBUG
 		puts ("BootpRequest => Our Mac: ");
 		for (reg=0; reg<6; reg++) {
diff --git a/net/eth.c b/net/eth.c
index ccd871a..b60de4d 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -196,6 +196,9 @@ int eth_initialize(bd_t *bis)
 #if defined(CONFIG_IXP4XX_NPE)
 	npe_initialize(bis);
 #endif
+#if defined(CONFIG_FIRETUX)
+	ip3912_initialize(bis);
+#endif
 	if (!eth_devices) {
 		puts ("No ethernet found.\n");
 		show_boot_progress (-64);
@@ -514,6 +517,7 @@ extern int emac4xx_miiphy_initialize(bd_t *bis);
 extern int mcf52x2_miiphy_initialize(bd_t *bis);
 extern int ns7520_miiphy_initialize(bd_t *bis);
 extern int davinci_eth_miiphy_initialize(bd_t *bis);
+extern int ip3912_initialize(bd_t *bis);
 
 
 int eth_initialize(bd_t *bis)
@@ -535,6 +539,9 @@ int eth_initialize(bd_t *bis)
 #if defined(CONFIG_DRIVER_NS7520_ETHERNET)
 	ns7520_miiphy_initialize(bis);
 #endif
+#if defined(CONFIG_FIRETUX)
+	ip3912_initialize(bis);
+#endif
 #if defined(CONFIG_DRIVER_TI_EMAC)
 	davinci_eth_miiphy_initialize(bis);
 #endif

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
Url : http://lists.denx.de/pipermail/u-boot/attachments/20081031/e5ea7138/attachment-0001.pgp 


More information about the U-Boot mailing list