[U-Boot] [patch V2] U-Boot Firetux board support
Juergen Schoew
Juergen at Schoew.net
Wed Nov 5 12:48:11 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 (mostly used for Audio
processing and VOIP codecs) and a baseband processor (used for DECT). The
chip also features dual ethernet, digital to analog interface, spi, i2c and
other SOC peripherals.
These boards have been build by NXP Semiconductors GmbH, Nuremberg, Germany
and are now build by DSPG Technologies GmbH, Nuremberg, Germany.
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>
---
Here is the next round of the patch. Thanks for the comments so far. I tried
to change the code to meet your requirements. Following changes have been
done:
- use writex/readx for register accesses
- use pointer in readx/writex
- whitespace fixes (use tabs)
- add Maintainer field
- adjust comments to common style
- use conditional settings
- relocate.S bug fixes
- network reworks
I did not move the ethernet driver to drivers/net/ because a lot of hardware
dependencies are in that driver to work. This IP-Core is not used very often
by NXP processors (I don't have numbers) so it may not need to be moved. This
driver does not not use the a struct to save the parameters as suggested
from Jean-Christophe PLAGNIOL-VILLARD. Sorry but time was too short to fix it
right now.
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
MAKEALL | 1 +
Makefile | 7 +
board/firetux/Makefile | 59 +++
board/firetux/config.mk | 44 ++
board/firetux/ethernet.c | 954 +++++++++++++++++++++++++++++++++++++++++
board/firetux/ethernet.h | 213 +++++++++
board/firetux/firetux.c | 619 ++++++++++++++++++++++++++
board/firetux/firetux.h | 109 +++++
board/firetux/lowlevel_init.S | 404 +++++++++++++++++
board/firetux/memsetup.S | 381 ++++++++++++++++
board/firetux/nand.c | 68 +++
board/firetux/relocate.S | 252 +++++++++++
board/firetux/u-boot.lds | 57 +++
drivers/i2c/Makefile | 1 +
drivers/i2c/pnx8181_i2c.c | 302 +++++++++++++
include/configs/firetux.h | 460 ++++++++++++++++++++
net/bootp.c | 11 +
net/eth.c | 7 +
18 files changed, 3949 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..f747759 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
+
+#########################################################################
## S3C44B0 Systems
#########################################################################
diff --git a/board/firetux/Makefile b/board/firetux/Makefile
new file mode 100644
index 0000000..bf1afec
--- /dev/null
+++ b/board/firetux/Makefile
@@ -0,0 +1,59 @@
+# 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-y += firetux.o ethernet.o
+COBJS-$(CONFIG_CMD_NAND) += nand.o
+SOBJS-y += lowlevel_init.o memsetup.o relocate.o
+
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS-y))
+
+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..4c8ab29
--- /dev/null
+++ b/board/firetux/config.mk
@@ -0,0 +1,44 @@
+# 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
+#
+
+
+ifndef CONFIG_SYS_PSRAM
+# SDRAM
+TEXT_BASE = 0x20780000
+else
+# mobile pSRAM
+TEXT_BASE = 0x90700000
+endif
+
+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..a4c1bc2
--- /dev/null
+++ b/board/firetux/ethernet.c
@@ -0,0 +1,954 @@
+/*
+ * 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 <asm/io.h>
+
+#include "ethernet.h"
+#include <miiphy.h>
+
+extern unsigned int boardrevision;
+
+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[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
+ALIGN8 rx_status_t etn1_rxstatus[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
+
+/* ETN1 tx */
+ALIGN8 tx_descriptor_t etn1_txdescriptor[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
+ALIGN4 tx_status_t etn1_txstatus[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
+
+/* ETN2 rx */
+ALIGN8 rx_descriptor_t etn2_rxdescriptor[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
+ALIGN8 rx_status_t etn2_rxstatus[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
+
+/* ETN2 tx */
+ALIGN8 tx_descriptor_t etn2_txdescriptor[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
+ALIGN4 tx_status_t etn2_txstatus[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
+
+/* 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;
+
+
+/* which interface to be currently work on */
+/* default can be set by environment variable ethact */
+static int firetux_eth = 0;
+unsigned short etn1_phy_addr, etn2_phy_addr;
+
+/* also the base address is switched for etn1 and etn2, */
+/* except for the MII registers etn1_m* which are only available */
+/* on etn1 */
+unsigned int etn_base = ETN1_BASE;
+
+/* we first try Vega Platform III-a settings */
+unsigned short firetux_phy_addr = PHYADDR_TO_REG(0x01);
+
+
+/* set all pointer to the right intferace */
+static void firetux_set_ethact(int act, int hardwarerevision)
+{
+ switch (hardwarerevision) {
+ /* EZ_MCP, Vega_pnx8181_basestation Platform III-a */
+ case 1:
+ case 2:
+ etn1_phy_addr = PHYADDR_TO_REG(0x01);
+ etn2_phy_addr = PHYADDR_TO_REG(0x02);
+ break;
+ /* Vega_pnx8181_basestation Platform III-b, III-c */
+ case 3:
+ case 4:
+ default:
+ etn1_phy_addr = PHYADDR_TO_REG(0x1E);
+ etn2_phy_addr = PHYADDR_TO_REG(0x1D);
+ break;
+ }
+ if (act) {
+ etn_rxdescriptor = etn2_rxdescriptor;
+ etn_rxstatus = etn2_rxstatus;
+ etn_txdescriptor = etn2_txdescriptor;
+ etn_txstatus = etn2_txstatus;
+ etn_base = ETN2_BASE;
+ firetux_phy_addr = (unsigned short) etn2_phy_addr;
+ } else {
+ etn_rxdescriptor = etn1_rxdescriptor;
+ etn_rxstatus = etn1_rxstatus;
+ etn_txdescriptor = etn1_txdescriptor;
+ etn_txstatus = etn1_txstatus;
+ etn_base = ETN1_BASE;
+ firetux_phy_addr = (unsigned short) etn1_phy_addr;
+ }
+}
+
+/* phy routines */
+
+/* hardware reset with gpio */
+static void firetux_reset_phy(int hardwareversion)
+{
+ switch (hardwareversion) {
+ case 1:
+ case 2:
+ case 3:
+ /* set GPIOa12 direction to output */
+ writel((readl((void *)PNX8181_GPIOA_DR)
+ & 0xffffefff) | 0x00001000, (void *)PNX8181_GPIOA_DR);
+ /* ETH_RESET_N */
+ writel(readl((void *)PNX8181_GPIOA_OR) & 0xffffefff,
+ (void *)PNX8181_GPIOA_OR);
+ udelay(120); /* min 100us */
+ writel(readl((void *)PNX8181_GPIOA_OR) | 0x00001000,
+ (void *)PNX8181_GPIOA_OR);
+ udelay(1); /* max 800ns */
+ break;
+ case 4:
+ writel((readl((void *)PNX8181_SCON_SYSPAD4) & 0xf7f5755f)
+ | 0x080a8aa0, (void *)PNX8181_SCON_SYSPAD4);
+ writel(readl((void *)PNX8181_SCON_SYSMUX0) & 0xffffff3f,
+ (void *)PNX8181_SCON_SYSMUX0);
+ /* set GPIOa3 direction to output */
+ writel((readl((void *)PNX8181_GPIOA_DR) & 0xfffffff7)
+ | 0x00000008, (void *)PNX8181_GPIOA_DR);
+ /* ETH_RESET_N */
+ writel(readl((void *)PNX8181_GPIOA_OR) & 0xfffffff7,
+ (void *)PNX8181_GPIOA_OR);
+ udelay(120); /* min 100us */
+ writel(readl((void *)PNX8181_GPIOA_OR) | 0x00000008,
+ (void *)PNX8181_GPIOA_OR);
+ udelay(1); /* max 800ns */
+ break;
+ default:
+ puts("Unknown Board, can't reset network phy\n");
+ break;
+ }
+}
+
+static void firetux_phy_write(unsigned short reg, unsigned short data)
+{
+ int status = 1;
+ int i = 0;
+
+ reg &= 0x001f; /* 5 bit PHY register address */
+
+ writel(firetux_phy_addr | reg, (void *)(ETN1_BASE + ETN_MADR));
+ writel(data, (void *)(ETN1_BASE + ETN_MWTD));
+
+ /* poll for done */
+ while (status && i < 1000000) {
+ status = readl((void *)(ETN1_BASE + ETN_MIND)) & 0x7;
+ i++;
+ }
+ if (status) {
+ printf("ERROR: firetux_phy_write(%d) = "
+ "0x%x [eth=%d, phy_addr=%x]\n",
+ reg, status, firetux_eth, firetux_phy_addr);
+ } else {
+ debug("### firetux_phy_write(%2.d, 0x%4.4x) success after"
+ " %d cycles [eth=%d, phy_addr=%x]\n",
+ reg, data, i, firetux_eth, firetux_phy_addr);
+ }
+}
+
+static unsigned short firetux_phy_read(unsigned short reg)
+{
+ unsigned short data;
+ int i = 0, status = 1;
+
+ reg &= 0x001f; /* 5 bit PHY register address */
+ writel(firetux_phy_addr | reg, (void *)(ETN1_BASE + ETN_MADR));
+ writel(0x00000001, (void *)(ETN1_BASE + ETN_MCMD));
+
+ /* poll for done */
+ while (status && i < 1000000) {
+ status = readl((void *)(ETN1_BASE + ETN_MIND)) & 0x7;
+ i++;
+ }
+ data = readl((void *)(ETN1_BASE + ETN_MRDD));
+
+ if (status) {
+ printf("ERROR: firetux_phy_read(%d) = 0x%x after %d cycles "
+ "[eth=%d, phy_addr=%x]\n", reg, data, i, firetux_eth,
+ firetux_phy_addr);
+ } else {
+ debug("### firetux_phy_read(%2.d)=0x%4.4x success after %d "
+ "cycles [eth=%d, phy_addr=%x]\n",
+ reg, data, i, firetux_eth, firetux_phy_addr);
+ }
+
+ writel(0, (void *)(ETN1_BASE + ETN_MCMD)); /* stop MII */
+
+ return data;
+}
+
+#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 = PHYADDR_TO_REG(addr);
+ *value = (unsigned short) firetux_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 = PHYADDR_TO_REG(addr);
+ firetux_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 (firetux_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 */
+ firetux_phy_write(ETN_PHY_AUTONEG_ADV, ((0xf << 5) | 1));
+ /* force autorenegotiation */
+ firetux_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 */
+ firetux_phy_write(ETN_PHY_AUTONEG_ADV, (i|1));
+ /* we set the phy parameter */
+ firetux_phy_write(ETN_PHY_BASIC_CONTROL, ((duplex ? (1<<8) : 0)
+ | (1 << 9) | ((speed == 100) ? (1 << 13) : 0)));
+ }
+
+ /* wait for negotiation finished (max 3.5s) */
+ i = 0;
+ while (((firetux_phy_read(ETN_PHY_BASIC_STATUS) & (1 << 5)) == 0)
+ && (i < 350)) {
+ udelay(10000);
+ i++;
+ }
+ if (i == 350)
+ puts("link negotiation timed out\n");
+
+
+ /* check for link */
+ if (firetux_phy_read(ETN_PHY_BASIC_STATUS) & (1 << 2)) {
+ /* OK link present */
+ status = firetux_phy_read(ETN_PHY_SPECIAL_MODE_CONTROL_STATUS);
+ speed = (status & (1 << 2)) ? 10 : 100;
+ duplex = (status & (1 << 4)) ? 1 : 0;
+ }
+
+ /* program the mac */
+ writel((readl((void *)(etn_base + ETN_SUPP)) & 0x000018fb) |
+ ((speed == 100) ? (1 << 8) : 0),
+ (void *)(etn_base + ETN_SUPP));
+ writel((readl((void *)(etn_base + ETN_MAC2)) & 0x000073fe) | duplex,
+ (void *)(etn_base + ETN_MAC2));
+ /*
+ * release rx-path, tx-path, host registers reset
+ * set Duplex, enable RMII, enable rx+tx
+ * no flow control, no frames<64b
+ */
+ writel(0x00000283 | (duplex ? (1 << 10) : 0),
+ (void *)(etn_base + ETN_COMMAND));
+
+ udelay(100000); /* the mac still needs some time to settle */
+ status = firetux_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");
+ status = firetux_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);
+ 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;
+ }
+ }
+ }
+
+ return 0;
+}
+#endif /* CONFIG_DISCOVER_PHY */
+
+#endif /* defined(CONFIG_MII) || defined(CONFIG_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;
+}
+
+
+/* init routines */
+
+static int firetux_init_ethernet_clocks(void)
+{
+ /* first things first, release the RSTEXT signal,
+ * which keeps the PHYs in reset
+ */
+ writel(readl((void *)(WDRU + WDRUCON)) | 0x0001,
+ (void *)(WDRU + WDRUCON));
+
+ /* 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
+ */
+ writel((15 << 9) | (62 << 3) | 3, (void *)CGU_PER2CON);
+
+ /* turn on PLL */
+ writel(readl((void *)CGU_PER2CON) | 0x00010000, (void *)CGU_PER2CON);
+ /* wait for PLL lock */
+ while (!(readl((void *) CGU_PER2CON) & 0x00020000));
+
+ /* ungate ETN clocks */
+ writel(readl((void *)CGU_PER2CON) | 0x00802000, (void *)CGU_PER2CON);
+
+ return 0;
+}
+
+static int firetux_init_ethernet_descriptors(void)
+{
+ static void *rxbuf = 0;
+ int i;
+
+ /* fill in pointer in regs */
+ writel((unsigned long)etn_rxdescriptor,
+ (void *)(etn_base + ETN_RXDESCRIPTOR));
+ writel((unsigned long)etn_rxstatus, (void *)(etn_base + ETN_RXSTATUS));
+ writel(0x00000000, (void *)(etn_base + ETN_RXCONSUMEINDEX));
+ writel(CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER - 1,
+ (void *)(etn_base + ETN_RXDESCRIPTORNUMBER));
+
+ writel((unsigned long)etn_txdescriptor,
+ (void *)(etn_base + ETN_TXDESCRIPTOR));
+ writel((unsigned long)etn_txstatus, (void *)(etn_base + ETN_TXSTATUS));
+ writel(0x00000000, (void *)(etn_base + ETN_TXPRODUCEINDEX));
+ writel(CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER - 1,
+ (void *)(etn_base + ETN_TXDESCRIPTORNUMBER));
+
+ /* allocate rx-buffers, but only once, we're called multiple times! */
+ if (!rxbuf)
+ rxbuf = malloc(MAX_ETH_FRAME_SIZE
+ * CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER);
+ if (!rxbuf) {
+ puts("ERROR: couldn't allocate rx buffers!\n");
+ return -1;
+ }
+
+ for (i = 0; i < CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER; i++) {
+ etn_rxdescriptor[i].packet = rxbuf + i * MAX_ETH_FRAME_SIZE;
+ etn_rxdescriptor[i].control = MAX_ETH_FRAME_SIZE
+ - sizeof(unsigned long);
+ etn_rxstatus[i].info = 0;
+ etn_rxstatus[i].hashCRC = 0;
+ }
+
+ for (i = 0; i < CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER; i++) {
+ etn_txdescriptor[i].packet = 0;
+ etn_txdescriptor[i].control = 0;
+ etn_txstatus[i].info = 0;
+ }
+ return 0;
+}
+
+int firetux_ethernet_macreset(void)
+{
+ /* reset MAC layer */
+ writel(0x0000cf00, (void *)(etn_base + ETN_MAC1));
+ /* release MAC soft reset */
+ writel(0x00000000, (void *)(etn_base + ETN_MAC1));
+ /* reset rx-path, tx-path, host registers */
+ writel(0x00000038, (void *)(etn_base + ETN_COMMAND));
+ /* reset RMII, 100Mbps MAC, 10Mbps MAC */
+ writel(0x1888, (void *)(etn_base + ETN_SUPP));
+ writel(0x1000, (void *)(etn_base + ETN_SUPP));
+
+ return 0;
+}
+
+/*
+ * returns -2 if phy init failed
+ * returns -1 if rx/tx-path init failed
+ */
+static int firetux_init_ethernet_macinit(void)
+{
+ int error = 0, j = 0, i = 0;
+
+ /* before enabling the rx-path we need to set up rx-descriptors */
+ if (firetux_init_ethernet_descriptors())
+ return -1;
+
+ /* release rx-path, tx-path, host registers reset
+ * set FullDuplex, enable RMMI, enable rx+tx
+ * no flow control, no frames<64b
+ */
+ writel(0x00000683, (void *)(etn_base + ETN_COMMAND));
+
+ debug("PHY init [eth=%d, phy_addr=%x] ...\n",
+ firetux_eth, firetux_phy_addr);
+
+ /* 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 {
+ firetux_phy_write(ETN_PHY_SPECIAL_MODES,
+ 0x4020 | (firetux_phy_addr >> 8));
+ } while (((firetux_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 */
+ firetux_phy_write(ETN_PHY_BASIC_CONTROL, 0x8000);
+ /* HW spec forces min 256 us, IEEE 802.3u allows 500 ms */
+ udelay(280);
+
+ /* still poll for reset done */
+ while ((firetux_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++;
+ }
+
+ debug("RESET DONE after %d cycles\n", i);
+
+ firetux_phy_write(ETN_PHY_BASIC_CONTROL, 0x0100);
+
+ firetux_phy_write(ETN_PHY_MODE_CONTROL_STATUS, 0x0c00);
+ firetux_phy_write(ETN_PHY_SPECIAL_MODE_CONTROL_STATUS, 0x0040);
+
+ debug("PHY init done.\n");
+
+ /* set max packet length to 1536 bytes */
+ writel(MAX_ETH_FRAME_SIZE, (void *)(etn_base + ETN_MAXF));
+ /* full duplex */
+ writel(0x00000023, (void *)(etn_base + ETN_MAC2));
+ /* inter packet gap register */
+ writel(0x15, (void *)(etn_base + ETN_IPGT));
+ writel(0x12, (void *)(etn_base + ETN_IPGR));
+ /* enable rx, receive all frames */
+ writel(0x00000003, (void *)(etn_base + ETN_MAC1));
+ /* accept all multicast, broadcast and station packets */
+ writel(0x00000026, (void *)(etn_base + ETN_RXFILTERCTRL));
+
+ if (error)
+ return -2; /* phy init failed */
+ else
+ return 0;
+}
+
+/* set MAC address */
+
+static int firetux_init_ethernet_setmacaddress(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;
+ }
+
+ /*
+ * The board specification says:
+ * The last bit of the mac address for ETN1 is always zero and the
+ * last bit of ETN2 is always set!
+ */
+ if (firetux_eth)
+ mac[5] |= 1;
+ else
+ mac[5] &= 0xfe;
+
+ debug("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]);
+
+ writel((mac[5] << 8) | mac[4], (void *)(etn_base + ETN_SA0));
+ writel((mac[3] << 8) | mac[2], (void *)(etn_base + ETN_SA1));
+ writel((mac[1] << 8) | mac[0], (void *)(etn_base + ETN_SA2));
+ 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_init_ethernet_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);
+ firetux_ethernet_macreset();
+ }
+
+ /* reset MII mgmt, set MII clock */
+ writel(0x0000801c, (void *)(ETN1_BASE + ETN_MCFG));
+ writel(0x0000001c, (void *)(ETN1_BASE + ETN_MCFG));
+
+ 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_init_ethernet_macinit()) {
+ case -1:
+ return -1;
+ break;
+ case -2:
+ if (i == 0)
+ failed_phy_init = 1;
+ break;
+ }
+ if (firetux_init_ethernet_setmacaddress(bis))
+ return -1;
+
+ }
+
+ firetux_miiphy_initialize(bis);
+
+#ifdef 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;
+ }
+ }
+ }
+
+ debug("using interface ETN%d\n", firetux_eth+1);
+ firetux_set_ethact(firetux_eth, boardrevision);
+
+ if (firetux_init_ethernet_setmacaddress(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 = readl((void *)(etn_base + ETN_TXPRODUCEINDEX));
+ next_packet = (this_packet + 1) % CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER;
+ last_packet = readl((void *)(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 +
+ CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER - 1)
+ % CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER))
+ && (i < ETN_TX_MAX_RETRY)) {
+#ifdef ET_DEBUG
+ /* debug print when FIFO full*/
+ if ((i > 50000) && (!(i % 50000))) {
+ this_packet =
+ readl((void *)(etn_base + ETN_TXPRODUCEINDEX));
+ last_packet =
+ readl((void *)(etn_base + ETN_TXCONSUMEINDEX));
+ printf("this=%3.d, last=%3.d, i=%d\n",
+ this_packet, last_packet, i);
+ }
+#endif
+ i++;
+ last_packet = readl((void *)(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 */
+ writel(next_packet, (void *)(etn_base + ETN_TXPRODUCEINDEX));
+
+ return 0;
+}
+
+/* Check for received packets */
+int eth_rx(void)
+{
+ unsigned short rxconsume = (unsigned short)
+ (readl((void *)(etn_base + ETN_RXCONSUMEINDEX)));
+ unsigned short rxproduce = (unsigned short)
+ (readl((void *)(etn_base + ETN_RXPRODUCEINDEX)));
+ unsigned short psize = 0;
+
+ debug("eth_rx: receive_rsv 0x%08lx\n",
+ readl((void *)(etn_base + ETN_RSV)));
+ debug("eth_rx: consume 0x%04lx produce 0x%04lx\n",
+ rxconsume, rxconsume);
+ while (rxconsume != rxproduce) {
+ rxproduce = (unsigned short)(readl((void *)
+ (etn_base + ETN_RXPRODUCEINDEX)));
+ psize = (etn_rxstatus[rxconsume].info & 0x07ff) + 1;
+ if (psize > MAX_ETH_FRAME_SIZE) {
+ printf("dropping %d bytes frame (too large)!\n",
+ psize);
+ } else {
+ NetReceive(etn_rxdescriptor[rxconsume].packet, psize);
+ }
+ rxconsume = (rxconsume + 1)
+ % CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER;
+ writel(rxconsume, (void *)(etn_base + ETN_RXCONSUMEINDEX));
+ }
+ return psize;
+}
+
+void eth_halt(void)
+{
+}
+
+
+int firetux_eth_check_vega_phy(void)
+{
+ int j, works_ok;
+
+ /* select pull_down for GPIO a3 */
+ writel(readl((void *)PNX8181_SCON_SYSPAD0) | (3 << 6) | (3 << 24),
+ (void *)PNX8181_SCON_SYSPAD0);
+
+ /* set GPIO a3 and a12 to low */
+ writel((readl((void *)PNX8181_GPIOA_DR) & 0xffffeff7) | 0x00001008,
+ (void *)PNX8181_GPIOA_DR);
+ writel(readl((void *)PNX8181_GPIOA_OR) & 0xffffeff7,
+ (void *)PNX8181_GPIOA_OR);
+
+ works_ok = CONFIG_MAX_BOARDREVISIONS;
+ do {
+ /* ETH_RESET_N */
+ firetux_reset_phy(works_ok);
+
+ if (firetux_init_ethernet_clocks())
+ puts("Error setting ETN clock\n");
+
+ /* reset MII mgmt, set MII clock */
+ writel(0x0000801c, (void *)(ETN1_BASE + ETN_MCFG));
+ writel(0x0000001c, (void *)(ETN1_BASE + ETN_MCFG));
+
+ /* enable RMMI */
+ writel(0x00000400, (void *)(ETN1_BASE + ETN_COMMAND));
+
+ firetux_set_ethact(0, works_ok);
+ firetux_ethernet_macreset();
+ /* NOTE: ETN_PHY_SPECIAL_MODES (register 18) must be written
+ * before any other register of the PHY ! */
+ j = 0;
+ do {
+ firetux_phy_write(ETN_PHY_SPECIAL_MODES,
+ 0x40e0 | (firetux_phy_addr>>8));
+ } while (((firetux_phy_read(ETN_PHY_SPECIAL_MODES) & 0x40ff)
+ != (0x40e0|(firetux_phy_addr>>8))) && ((++j) < 500));
+
+ firetux_set_ethact(1, works_ok);
+ firetux_ethernet_macreset();
+
+ /* NOTE: ETN_PHY_SPECIAL_MODES (register 18) must be written
+ * before any other register of the PHY ! */
+ j = 0;
+ do {
+ firetux_phy_write(ETN_PHY_SPECIAL_MODES,
+ 0x40e0 | (firetux_phy_addr>>8));
+ } while (((firetux_phy_read(ETN_PHY_SPECIAL_MODES) & 0x40ff)
+ != (0x40e0 | (firetux_phy_addr >> 8)))
+ && ((++j) < 500));
+
+ if (firetux_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..0182b95
--- /dev/null
+++ b/board/firetux/ethernet.h
@@ -0,0 +1,213 @@
+/*
+ * 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);
+#define PHYADDR_TO_REG(x) (x << 8)
+/* data types */
+
+/* rx */
+typedef struct{
+ volatile void *packet;
+ volatile unsigned long control;
+} rx_descriptor_t;
+
+typedef struct{
+ volatile unsigned long info; /* RO */
+ volatile unsigned long hashCRC; /* RO */
+} rx_status_t;
+
+/* tx */
+typedef struct{
+ volatile void *packet;
+ volatile unsigned long control;
+} tx_descriptor_t;
+
+typedef struct{
+ volatile unsigned long info; /* RO */
+} tx_status_t;
+
+/* NXP's OUI registered @ IEEE */
+#define NXP_ETN_OUI 0x006037
+
+/* pnx8181 ETN registers */
+#define ETN1_BASE 0xC1600000
+#define ETN2_BASE 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
+
+/* 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
+
+/* pnx8181 WDRU (watchdog reset unit) registers */
+#define WDRU 0xC2203000
+#define WDRUCON 0x00
+
+/* 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)
+
+
+/* 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
+
+/* 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..3f1c6d3
--- /dev/null
+++ b/board/firetux/firetux.c
@@ -0,0 +1,619 @@
+/*
+ * 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 <asm/io.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_NANDFLASH
+void firetux_nandflash_init(void);
+#else
+void firetux_norflash_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);
+
+#ifdef 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;
+
+ writel(readw((void *)PNX8181_WDRUCON) | 0x0009, (void *)PNX8181_WDRUCON);
+ writel(0x0079,(void *)PNX8181_DAIF_RVDDC);
+
+ firetux_gpio_init_A(); /* first part */
+
+ /* simple board detection */
+ cgu_sccon = readw((void *)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 */
+ writel(((readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
+ & 0xff3ffff3) | 0x00400004),
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
+ /* select ETN for GPIOc0-16 */
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX5))
+ & 0xfffffffc,
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX5));
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX4))
+ & 0x30000000,
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX4));
+
+ /* use clk26m and fract-n for UART2 */
+ writew(((1 << 7) | (1 << 1)),
+ (void *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_CTRL));
+ writew(0x5F37, (void *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_M));
+ writew(0x32C8, (void *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_N));
+}
+
+
+void firetux_gpio_init_B(void)
+{
+ if (boardrevision < 2) /* EZ_MCP has no leds or keys */
+ return;
+
+ /* set GPIOA10 and GPIOA2 for key input */
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
+ & 0xffcfffcf,
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
+ writel(readl((void *)PNX8181_GPIOA_PAD_LOW) & 0xffcfffcf,
+ (void *)PNX8181_GPIOA_PAD_LOW);
+ writel(readl((void *)PNX8181_GPIOA_DIRECTION) & ~((1 << 2) | (1 << 10)),
+ (void *)PNX8181_GPIOA_DIRECTION);
+
+ /* set GPIOA9 and GPIOA0 for LED output */
+ if (boardrevision > 2) {
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
+ & 0xfff3fffc,
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
+ writel(readl((void *)PNX8181_GPIOA_DIRECTION)
+ | ((1 << 9) | (1 << 0)),
+ (void *)PNX8181_GPIOA_DIRECTION);
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ | ((1 << 9) | (1 << 0)),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ } else { /* Baseboard IIIa */
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
+ & 0xfff3ff3f,
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX1))
+ & 0x3ffffffc,
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX1));
+ writel(readl((void *)PNX8181_GPIOA_DIRECTION)
+ | ((1 << 9) | (1 << 31) | (1 << 16) | (1 << 3)),
+ (void *)PNX8181_GPIOA_DIRECTION);
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ | ((1 << 9) | (1 << 31) | (1 << 16) | (1 << 3)),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ }
+}
+
+
+#ifdef CONFIG_CMD_NAND
+void firetux_nandflash_init(void)
+{
+ /*
+ * Hardware configuration
+ * setup GPIOB18 / FMP40 to GPIO input with internal pullup
+ */
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3)) & ~(0x30),
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3));
+ /* set FPM40 to GPIOb18 */
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3)) |= 0x10,
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3));
+ /* set to input */
+ writel(readl((void *)PNX8181_GPIOB_DIRECTION)
+ & ~(1 << CONFIG_SYS_NAND_RB_BIT),
+ (void *)PNX8181_GPIOB_DIRECTION);
+ /* set pull up */
+ writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSPAD2))
+ & ~(3 << 20),
+ (void *)(PNX8181_SCON_BASE + PNX8181_SYSPAD2));
+
+ /* setup access timing for CS0 / 16bit */
+ writel(0x0001, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_MAIN_OFF));
+ writel(0x1FFFF, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_READ_OFF));
+ writel(0x1FFFF, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_WRITE_OFF));
+ writel(0x0CF8, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_BURST_OFF));
+}
+#else
+void firetux_norflash_init(void)
+{
+#ifdef CONFIG_SYS_OPTIMIZE_NORFLASH
+ /* optimize access speed */
+ writel(0x9, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_MAIN_OFF));
+ writel(0x22D88, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_READ_OFF));
+ writel(0x22D88, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_WRITE_OFF));
+ writel(0x0000, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_BURST_OFF));
+#endif
+}
+#endif
+
+void firetux_irq_disable(void)
+{
+ int i;
+
+ writel(31, (void *)PNX8181_INTC_PRIOMASK_IRQ);
+ writel(31, (void *)PNX8181_INTC_PRIOMASK_FIQ);
+
+ for (i = 1; i < 67; i++)
+ PNX8181_DISABLEIRQ(i);
+
+ writel(readl((void *)PNX8181_CGU_GATESC) & 0xfdd7becd,
+ (void *)PNX8181_CGU_GATESC);
+}
+
+void firetux_ether_init(void)
+{
+/*
+ * priority setting for ETN over CPU for SDRAM access
+ * enable port-aging with priority for ETN
+ */
+#ifdef CONFIG_SYS_ENT_FAIR_SCHEDULE
+ /*
+ * 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
+ */
+ writel(0x80000121, (void *)(PNX8181_SDI_SCHED + PNX8181_SCHED0));
+ writel(0xffff0100, (void *)(PNX8181_SDI_SCHED + PNX8181_SCHED1));
+ writel(0x00030131, (void *)(PNX8181_SDI_SCHED + PNX8181_SCHED2));
+#else
+ /*
+ * highly prioritise the ETN engine and lower CPU priority
+ * to archive a better network thoughput
+ */
+ writel(0xffff0020, (void *)(PNX8181_SDI_SCHED + PNX8181_SCHED0));
+ writel(0xffff0000, (void *)(PNX8181_SDI_SCHED + PNX8181_SCHED1));
+ writel(0xffff0031, (void *)(PNX8181_SDI_SCHED + PNX8181_SCHED2));
+#endif
+
+ /* increase priority for SCRAM access at AHB of descriptors */
+ writew(7, (void *)(PNX8181_SC_ARB_BASE + PNX8181_SC_ARB_CFG2));
+ writew(7, (void *)(PNX8181_SC_ARB_BASE + PNX8181_SC_ARB_CFG3));
+
+ /* 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)
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT) & ~(1 << 9),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ else
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT) | (1 << 9),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ break;
+ case 2: /* GPIOA0 or GPIOA31 */
+ if (boardrevision > 2) {
+ if (brightness)
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ & ~(1 << 0),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ else
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ | (1 << 0),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ } else {
+ if (brightness)
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ & ~(1 << 31),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ else
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ | (1 << 31),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ }
+ break;
+ case 3: /* GPIOA16 */
+ if (boardrevision == 2) {
+ if (brightness)
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ & ~(1 << 16),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ else
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ | (1 << 16),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ }
+ break;
+ case 4: /* GPIOA3 */
+ if (boardrevision == 2) {
+ if (brightness)
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ & ~(1 << 3),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ else
+ writel(readl((void *)PNX8181_GPIOA_OUTPUT)
+ |= (1 << 3),
+ (void *)PNX8181_GPIOA_OUTPUT);
+ }
+ 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 (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 9))
+ firetux_set_led(1, 0);
+ else
+ firetux_set_led(1, 1);
+ break;
+ case 2:
+ if (boardrevision > 2) {
+ if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 0))
+ firetux_set_led(2, 0);
+ else
+ firetux_set_led(2, 1);
+ } else {
+ if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 31))
+ firetux_set_led(2, 0);
+ else
+ firetux_set_led(2, 1);
+ }
+ break;
+ case 3:
+ if (boardrevision == 2) {
+ if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 16))
+ firetux_set_led(3, 0);
+ else
+ firetux_set_led(3, 1);
+ }
+ break;
+ case 4:
+ if (boardrevision == 2) {
+ if (readl((void *)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
+ */
+
+/* U-Boot ticks since startup */
+static ulong timestamp;
+static ulong last_timer_read;
+
+/*
+ * starts up a counter
+ */
+void firetux_timer_init(void)
+{
+ /* set prescaler to have timer run at 64 kHz */
+ writeb(0x00, (void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxPR));
+
+ /* timer reload value = 0xffff - 13824, overflow @ 1kHz */
+ writew(0xca00, (void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxRR));
+
+ /* timer has no interrupt, run */
+ writew(0x0001, (void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxCR));
+
+ /* 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 = readw((void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxWR));
+
+ 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 */
+
+ /* loop till event */
+ while (get_timer_masked() < tmo) {
+ /*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..ca49844
--- /dev/null
+++ b/board/firetux/firetux.h
@@ -0,0 +1,109 @@
+/*
+ * 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) writel((0x1f << 25), \
+ (void *)PNX8181_INTC_REQUEST + (4 * IRQ));
+
+#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
diff --git a/board/firetux/lowlevel_init.S b/board/firetux/lowlevel_init.S
new file mode 100644
index 0000000..66d9b60
--- /dev/null
+++ b/board/firetux/lowlevel_init.S
@@ -0,0 +1,404 @@
+/*
+ * 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 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 */
+#if !defined(CONFIG_NANDFLASH) && !defined(CONFIG_SKIP_RELOCATE_UBOOT)
+
+ /* 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..934fd14
--- /dev/null
+++ b/board/firetux/memsetup.S
@@ -0,0 +1,381 @@
+/*
+ * 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_CTL 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_MOD 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:
+/* with nandflash we have to skip memconfig */
+#if !defined(CONFIG_NANDFLASH) && !defined(CONFIG_SKIP_RELOCATE_UBOOT)
+ /* 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 */
+/* with nandflash we have to skip memconfig */
+#if !defined(CONFIG_NANDFLASH) && !defined(CONFIG_SKIP_RELOCATE_UBOOT)
+ 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:
+/* with nandflash we have to skip memconfig */
+#if !defined(CONFIG_NANDFLASH) && !defined(CONFIG_SKIP_RELOCATE_UBOOT)
+ /*
+ * 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,
+ * 2 instructions 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_CTL
+ 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_MOD
+ 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..04b98d6
--- /dev/null
+++ b/board/firetux/nand.c
@@ -0,0 +1,68 @@
+/*
+ * 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>
+#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;
+ void *IO_ADDR_W = 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 ((readl((void *)CONFIG_SYS_NAND_RB_PORT)
+ >> CONFIG_SYS_NAND_RB_BIT) & 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;
+ return 0;
+}
diff --git a/board/firetux/relocate.S b/board/firetux/relocate.S
new file mode 100644
index 0000000..e1da73c
--- /dev/null
+++ b/board/firetux/relocate.S
@@ -0,0 +1,252 @@
+/*
+ * 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 */
+
+
+/* with nandflash we skipped the lowlevelinit and memsetup */
+/* but we have to provide the memory settings here */
+#if defined(CONFIG_NANDFLASH) || defined(CONFIG_SKIP_RELOCATE_UBOOT)
+
+/* 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 /* if coming from NAND we do */
+ /* relocate, because loader copied */
+ /* us into middle of RAM */
+ 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
+ b firetux_stack_setup
+#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+ ldr r4, =_start /* if not relocated, start of uboot */
+ add r0, r0, r12 /* r0 <- current position of code */
+ /* need to be in r4 for stack setup */
+
+ /* 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..efa27af
--- /dev/null
+++ b/include/configs/firetux.h
@@ -0,0 +1,460 @@
+/*
+ * 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_SKIP_RELOCATE_UBOOT 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 CONFIG_SYS_ENT_FAIR_SCHEDULE 1 */ /* Use fair or eth schedule */
+#define CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER 16
+#define CONFIG_SYS_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 (CONFIG_SYS_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_NAND_RB_BIT 18
+#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/20081105/5e6528aa/attachment-0001.pgp
More information about the U-Boot
mailing list