summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG12
-rw-r--r--CREDITS5
-rw-r--r--MAINTAINERS8
-rw-r--r--MAKEALL6
-rw-r--r--Makefile3
-rw-r--r--board/eXalion/Makefile41
-rw-r--r--board/eXalion/config.mk31
-rw-r--r--board/eXalion/eXalion.c292
-rw-r--r--board/eXalion/eXalion.h52
-rw-r--r--board/eXalion/piix_pci.h172
-rw-r--r--board/eXalion/u-boot.lds133
-rw-r--r--board/ns9750dev/Makefile47
-rw-r--r--board/ns9750dev/config.mk16
-rw-r--r--board/ns9750dev/flash.c477
-rw-r--r--board/ns9750dev/led.c46
-rw-r--r--board/ns9750dev/ns9750dev.c127
-rw-r--r--board/ns9750dev/platform.S298
-rw-r--r--board/ns9750dev/u-boot.lds58
-rw-r--r--board/omap1610inn/platform.S8
-rw-r--r--common/cmd_mii.c1
-rw-r--r--common/usb_storage.c84
-rw-r--r--cpu/mpc5xxx/Makefile2
-rw-r--r--cpu/mpc5xxx/usb_ohci.c1602
-rw-r--r--cpu/mpc5xxx/usb_ohci.h424
-rw-r--r--doc/README.ns9750dev36
-rw-r--r--drivers/ns9750_eth.c797
-rw-r--r--drivers/ns9750_serial.c212
-rw-r--r--fs/fat/fat.c3
-rw-r--r--include/configs/IceCube.h15
-rw-r--r--include/configs/eXalion.h454
-rw-r--r--include/configs/ns9750dev.h211
-rw-r--r--include/mpc5xxx.h2
-rw-r--r--include/ns9750_bbus.h125
-rw-r--r--include/ns9750_eth.h526
-rw-r--r--include/ns9750_mem.h172
-rw-r--r--include/ns9750_ser.h202
-rw-r--r--include/ns9750_sys.h215
37 files changed, 6866 insertions, 49 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 85394aa..64277b1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,18 @@
Changes for U-Boot 1.0.2:
======================================================================
+* Patch by Markus Pietrek, 24 Feb 2004:
+ NS9750 DevBoard added
+
+* Patch by Pierre AUBERT, 24 Feb 2004
+ add USB support for MPC5200
+
+* Patch by Steven Scholz, 24 Feb 2004:
+ - fix MII commands to use values from last command
+
+* Patch by Torsten Demke, 24 Feb 2004:
+ Add support for the eXalion platform (SPSW-8240, F-30, F-300)
+
* Patch by Rahul Shanbhag, 19 Feb 2004:
Fixes for for OMAP1610 board:
- shift some IRQ specific code to platform.S file
diff --git a/CREDITS b/CREDITS
index 047240d..c6ebb4a 100644
--- a/CREDITS
+++ b/CREDITS
@@ -103,6 +103,11 @@ N: Dave Ellis
E: DGE@sixnetio.com
D: EEPROM Speedup, SXNI855T port
+N: Thomas Elste
+E: info@elste.org
+D: Port for the ModNET50 Board, NET+50 CPU Port
+W: http://www.imms.de
+
N: Daniel Engström
E: daniel@omicron.se
D: x86 port, Support for sc520_cdp board
diff --git a/MAINTAINERS b/MAINTAINERS
index f23d9e2..b692c19 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -49,6 +49,10 @@ Kári Davíđsson <kd@flaga.is>
FLAGADM MPC823
+Torsten Demke <torsten.demke@fci.com>
+
+ eXalion MPC824x
+
Wolfgang Denk <wd@denx.de>
AMX860 MPC860
@@ -289,6 +293,10 @@ Unknown / orphaned boards:
# Board CPU #
#########################################################################
+Thomas Elste <info@elste.org>
+
+ modnet50 ARM720T (NET+50)
+
Peter Figuli <peposh@etc.sk>
wepep250 xscale
diff --git a/MAKEALL b/MAKEALL
index a099980..dec6f53 100644
--- a/MAKEALL
+++ b/MAKEALL
@@ -73,9 +73,9 @@ LIST_4xx=" \
LIST_824x=" \
A3000 BMW CPC45 CU824 \
- debris MOUSSE MUSENKI MVBLUE \
- OXC PN62 Sandpoint8240 Sandpoint8245 \
- SL8245 utx8245 \
+ debris eXalion MOUSSE MUSENKI \
+ MVBLUE OXC PN62 Sandpoint8240 \
+ Sandpoint8245 SL8245 utx8245 \
"
#########################################################################
diff --git a/Makefile b/Makefile
index 6dab719..8c822c6 100644
--- a/Makefile
+++ b/Makefile
@@ -671,6 +671,9 @@ CPC45_ROMBOOT_config: unconfig
CU824_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x cu824
+eXalion_config: unconfig
+ @./mkconfig $(@:_config=) ppc mpc824x eXalion
+
MOUSSE_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x mousse
diff --git a/board/eXalion/Makefile b/board/eXalion/Makefile
new file mode 100644
index 0000000..110d09d
--- /dev/null
+++ b/board/eXalion/Makefile
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2001
+# Wolfgang Denk, DENX Software Engineering, wd@denx.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 = lib$(BOARD).a
+
+OBJS = $(BOARD).o
+SOBJS =
+
+$(LIB): .depend $(OBJS) $(SOBJS)
+ $(AR) crv $@ $^
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/eXalion/config.mk b/board/eXalion/config.mk
new file mode 100644
index 0000000..b3f65eb
--- /dev/null
+++ b/board/eXalion/config.mk
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2000, 2001
+# Wolfgang Denk, DENX Software Engineering, wd@denx.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
+#
+
+#
+# Sandpoint boards
+#
+
+#TEXT_BASE = 0x00090000
+TEXT_BASE = 0xFFF00000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
diff --git a/board/eXalion/eXalion.c b/board/eXalion/eXalion.c
new file mode 100644
index 0000000..2e3f519
--- /dev/null
+++ b/board/eXalion/eXalion.c
@@ -0,0 +1,292 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Torsten Demke, FORCE Computers GmbH. torsten.demke@fci.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <ide.h>
+#include "piix_pci.h"
+#include "eXalion.h"
+
+int checkboard (void)
+{
+ ulong busfreq = get_bus_freq (0);
+ char buf[32];
+
+ printf ("Board: eXalion MPC824x - CHRP (MAP B)\n");
+ printf ("Built: %s at %s\n", __DATE__, __TIME__);
+ printf ("Local Bus: %s MHz\n", strmhz (buf, busfreq));
+
+ return 0;
+}
+
+int checkflash (void)
+{
+ printf ("checkflash\n");
+ flash_init ();
+ return (0);
+}
+
+long int initdram (int board_type)
+{
+ int i, cnt;
+ volatile uchar *base = CFG_SDRAM_BASE;
+ volatile ulong *addr;
+ ulong save[32];
+ ulong val, ret = 0;
+
+ for (i = 0, cnt = (CFG_MAX_RAM_SIZE / sizeof (long)) >> 1; cnt > 0;
+ cnt >>= 1) {
+ addr = (volatile ulong *) base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *) base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0) {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof (long); cnt <<= 1) {
+ addr = (volatile ulong *) base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ ulong new_bank0_end = cnt * sizeof (long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg (MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg (EMEAR1);
+
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >>
+ MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >>
+ MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg (MEAR1, mear1);
+ mpc824x_mpc107_setreg (EMEAR1, emear1);
+
+ ret = cnt * sizeof (long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+ Done:
+ return ret;
+}
+
+int misc_init_r (void)
+{
+ pci_dev_t bdf;
+ u32 val32;
+ u8 val8;
+
+ puts ("ISA: ");
+ bdf = pci_find_device (PIIX4_VENDOR_ID, PIIX4_ISA_DEV_ID, 0);
+ if (bdf == -1) {
+ puts ("Unable to find PIIX4 ISA bridge !\n");
+ hang ();
+ }
+
+ /* set device for normal ISA instead EIO */
+ pci_read_config_dword (bdf, PCI_CFG_PIIX4_GENCFG, &val32);
+ val32 |= 0x00000001;
+ pci_write_config_dword (bdf, PCI_CFG_PIIX4_GENCFG, val32);
+ printf ("PIIX4 ISA bridge (%d,%d,%d)\n", PCI_BUS (bdf),
+ PCI_DEV (bdf), PCI_FUNC (bdf));
+
+ puts ("ISA: ");
+ bdf = pci_find_device (PIIX4_VENDOR_ID, PIIX4_IDE_DEV_ID, 0);
+ if (bdf == -1) {
+ puts ("Unable to find PIIX4 IDE controller !\n");
+ hang ();
+ }
+
+ /* Init BMIBA register */
+ /* pci_read_config_dword(bdf, PCI_CFG_PIIX4_BMIBA, &val32); */
+ /* val32 |= 0x1000; */
+ /* pci_write_config_dword(bdf, PCI_CFG_PIIX4_BMIBA, val32); */
+
+ /* Enable BUS master and IO access */
+ val32 = PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_dword (bdf, PCI_COMMAND, val32);
+
+ /* Set latency */
+ pci_read_config_byte (bdf, PCI_LATENCY_TIMER, &val8);
+ val8 = 0x40;
+ pci_write_config_byte (bdf, PCI_LATENCY_TIMER, val8);
+
+ /* Enable Primary ATA/IDE */
+ pci_read_config_dword (bdf, PCI_CFG_PIIX4_IDETIM, &val32);
+ /* val32 = 0xa307a307; */
+ val32 = 0x00008000;
+ pci_write_config_dword (bdf, PCI_CFG_PIIX4_IDETIM, val32);
+
+
+ printf ("PIIX4 IDE controller (%d,%d,%d)\n", PCI_BUS (bdf),
+ PCI_DEV (bdf), PCI_FUNC (bdf));
+
+ /* Try to get FAT working... */
+ /* fat_register_read(ide_read); */
+
+
+ return (0);
+}
+
+/*
+ * Show/Init PCI devices on the specified bus number.
+ */
+
+void pci_eXalion_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned char line;
+
+ switch (PCI_DEV (dev)) {
+ case 16:
+ line = PCI_INT_A;
+ break;
+ case 17:
+ line = PCI_INT_B;
+ break;
+ case 18:
+ line = PCI_INT_C;
+ break;
+ case 19:
+ line = PCI_INT_D;
+ break;
+#if defined (CONFIG_MPC8245)
+ case 20:
+ line = PCI_INT_A;
+ break;
+ case 21:
+ line = PCI_INT_B;
+ break;
+ case 22:
+ line = PCI_INT_NA;
+ break;
+#endif
+ default:
+ line = PCI_INT_A;
+ break;
+ }
+ pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, line);
+}
+
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+#if defined (CONFIG_MPC8240)
+static struct pci_config_table pci_eXalion_config_table[] = {
+ {
+ /* Intel 82559ER ethernet controller */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 18, 0x00,
+ pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER}},
+ {
+ /* Intel 82371AB PIIX4 PCI to ISA bridge */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x00,
+ pci_cfgfunc_config_device, {0,
+ 0,
+ PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
+ {
+ /* Intel 82371AB PIIX4 IDE controller */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x01,
+ pci_cfgfunc_config_device, {0,
+ 0,
+ PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
+ {}
+};
+#elif defined (CONFIG_MPC8245)
+static struct pci_config_table pci_eXalion_config_table[] = {
+ {
+ /* Intel 82559ER ethernet controller */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 17, 0x00,
+ pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER}},
+ {
+ /* Intel 82559ER ethernet controller */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 18, 0x00,
+ pci_cfgfunc_config_device, {PCI_ENET1_IOADDR,
+ PCI_ENET1_MEMADDR,
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER}},
+ {
+ /* Broadcom BCM5690 Gigabit switch */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x00,
+ pci_cfgfunc_config_device, {PCI_ENET2_IOADDR,
+ PCI_ENET2_MEMADDR,
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER}},
+ {
+ /* Broadcom BCM5690 Gigabit switch */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 21, 0x00,
+ pci_cfgfunc_config_device, {PCI_ENET3_IOADDR,
+ PCI_ENET3_MEMADDR,
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER}},
+ {
+ /* Intel 82371AB PIIX4 PCI to ISA bridge */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 22, 0x00,
+ pci_cfgfunc_config_device, {0,
+ 0,
+ PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
+ {
+ /* Intel 82371AB PIIX4 IDE controller */
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 22, 0x01,
+ pci_cfgfunc_config_device, {0,
+ 0,
+ PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
+ {}
+};
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+#endif /* #ifndef CONFIG_PCI_PNP */
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_eXalion_config_table,
+ fixup_irq:pci_eXalion_fixup_irq,
+#endif
+};
+
+void pci_init_board (void)
+{
+ pci_mpc824x_init (&hose);
+}
diff --git a/board/eXalion/eXalion.h b/board/eXalion/eXalion.h
new file mode 100644
index 0000000..8dccabb
--- /dev/null
+++ b/board/eXalion/eXalion.h
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2002
+ * Torsten Demke, FORCE Computers GmbH. torsten.demke@fci.com
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * James Dougherty (jfd@broadcom.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __EXALION_H
+#define __EXALION_H
+
+/* IRQ settings */
+#define PCI_INT_NA (0xff) /* PCI Intr. not used */
+#define PCI_INT_A (0x09) /* PCI Intr. A Interrupt Request Line Nr. */
+#define PCI_INT_B (0x0a) /* PCI Intr. B Interrupt Request Line Nr. */
+#define PCI_INT_C (0x0b) /* PCI Intr. C Interrupt Request Line Nr. */
+#define PCI_INT_D (0x0c) /* PCI Intr. D Interrupt Request Line Nr. */
+#if defined (CPU_MPC8245)
+#define LN_1_INT PCI_INT_B /* ethernet interrupt level */
+#define LN_2_INT PCI_INT_C /* ethernet interrupt level */
+#define BCM_1_INT PCI_INT_A /* BCM5690 interrupt level */
+#define BCM_2_INT PCI_INT_B /* BCM5690 interrupt level */
+#elif defined (CPU_MPC8240)
+#define BCM_INT PCI_INT_B /* BCM5600 interrupt level */
+#define LN_INT PCI_INT_C /* ethernet interrupt level */
+#endif
+
+#ifndef __ASSEMBLY__
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __EXALION_H */
diff --git a/board/eXalion/piix_pci.h b/board/eXalion/piix_pci.h
new file mode 100644
index 0000000..b3c9c16
--- /dev/null
+++ b/board/eXalion/piix_pci.h
@@ -0,0 +1,172 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Torsten Demke, FORCE Computers GmbH. torsten.demke@fci.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _PIIX4_PCI_H
+#define _PIIX4_PCI_H
+
+#include <common.h>
+#include <mpc824x.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define PIIX4_VENDOR_ID 0x8086
+#define PIIX4_ISA_DEV_ID 0x7110
+#define PIIX4_IDE_DEV_ID 0x7111
+
+/* Function 0 ISA Bridge */
+#define PCI_CFG_PIIX4_IORT 0x4C /* 8 bit ISA Recovery Timer Reg (default 0x4D) */
+#define PCI_CFG_PIIX4_XBCS 0x4E /* 16 bit XBus Chip select reg (default 0x0003) */
+#define PCI_CFG_PIIX4_PIRQC 0x60 /* PCI IRQ Route Register 4 x 8bit (default )*/
+#define PCI_CFG_PIIX4_SERIRQ 0x64
+#define PCI_CFG_PIIX4_TOM 0x69
+#define PCI_CFG_PIIX4_MSTAT 0x6A
+#define PCI_CFG_PIIX4_MBDMA 0x76
+#define PCI_CFG_PIIX4_APICBS 0x80
+#define PCI_CFG_PIIX4_DLC 0x82
+#define PCI_CFG_PIIX4_PDMACFG 0x90
+#define PCI_CFG_PIIX4_DDMABS 0x92
+#define PCI_CFG_PIIX4_GENCFG 0xB0
+#define PCI_CFG_PIIX4_RTCCFG 0xCB
+
+/* IO Addresses */
+#define PIIX4_ISA_DMA1_CH0BA 0x00
+#define PIIX4_ISA_DMA1_CH0CA 0x01
+#define PIIX4_ISA_DMA1_CH1BA 0x02
+#define PIIX4_ISA_DMA1_CH1CA 0x03
+#define PIIX4_ISA_DMA1_CH2BA 0x04
+#define PIIX4_ISA_DMA1_CH2CA 0x05
+#define PIIX4_ISA_DMA1_CH3BA 0x06
+#define PIIX4_ISA_DMA1_CH3CA 0x07
+#define PIIX4_ISA_DMA1_CMDST 0x08
+#define PIIX4_ISA_DMA1_REQ 0x09
+#define PIIX4_ISA_DMA1_WSBM 0x0A
+#define PIIX4_ISA_DMA1_CH_MOD 0x0B
+#define PIIX4_ISA_DMA1_CLR_PT 0x0C
+#define PIIX4_ISA_DMA1_M_CLR 0x0D
+#define PIIX4_ISA_DMA1_CLR_M 0x0E
+#define PIIX4_ISA_DMA1_RWAMB 0x0F
+
+#define PIIX4_ISA_DMA2_CH0BA 0xC0
+#define PIIX4_ISA_DMA2_CH0CA 0xC1
+#define PIIX4_ISA_DMA2_CH1BA 0xC2
+#define PIIX4_ISA_DMA2_CH1CA 0xC3
+#define PIIX4_ISA_DMA2_CH2BA 0xC4
+#define PIIX4_ISA_DMA2_CH2CA 0xC5
+#define PIIX4_ISA_DMA2_CH3BA 0xC6
+#define PIIX4_ISA_DMA2_CH3CA 0xC7
+#define PIIX4_ISA_DMA2_CMDST 0xD0
+#define PIIX4_ISA_DMA2_REQ 0xD2
+#define PIIX4_ISA_DMA2_WSBM 0xD4
+#define PIIX4_ISA_DMA2_CH_MOD 0xD6
+#define PIIX4_ISA_DMA2_CLR_PT 0xD8
+#define PIIX4_ISA_DMA2_M_CLR 0xDA
+#define PIIX4_ISA_DMA2_CLR_M 0xDC
+#define PIIX4_ISA_DMA2_RWAMB 0xDE
+
+#define PIIX4_ISA_INT1_ICW1 0x20
+#define PIIX4_ISA_INT1_OCW2 0x20
+#define PIIX4_ISA_INT1_OCW3 0x20
+#define PIIX4_ISA_INT1_ICW2 0x21
+#define PIIX4_ISA_INT1_ICW3 0x21
+#define PIIX4_ISA_INT1_ICW4 0x21
+#define PIIX4_ISA_INT1_OCW1 0x21
+
+#define PIIX4_ISA_INT1_ELCR 0x4D0
+
+#define PIIX4_ISA_INT2_ICW1 0xA0
+#define PIIX4_ISA_INT2_OCW2 0xA0
+#define PIIX4_ISA_INT2_OCW3 0xA0
+#define PIIX4_ISA_INT2_ICW2 0xA1
+#define PIIX4_ISA_INT2_ICW3 0xA1
+#define PIIX4_ISA_INT2_ICW4 0xA1
+#define PIIX4_ISA_INT2_OCW1 0xA1
+#define PIIX4_ISA_INT2_IMR 0xA1 /* read only */
+
+#define PIIX4_ISA_INT2_ELCR 0x4D1
+
+#define PIIX4_ISA_TMR0_CNT_ST 0x40
+#define PIIX4_ISA_TMR1_CNT_ST 0x41
+#define PIIX4_ISA_TMR2_CNT_ST 0x42
+#define PIIX4_ISA_TMR_TCW 0x43
+
+#define PIIX4_ISA_RST_XBUS 0x60
+
+#define PIIX4_ISA_NMI_CNT_ST 0x61
+#define PIIX4_ISA_NMI_ENABLE 0x70
+
+#define PIIX4_ISA_RTC_INDEX 0x70
+#define PIIX4_ISA_RTC_DATA 0x71
+#define PIIX4_ISA_RTCEXT_IND 0x70
+#define PIIX4_ISA_RTCEXT_DATA 0x71
+
+#define PIIX4_ISA_DMA1_CH2LPG 0x81
+#define PIIX4_ISA_DMA1_CH3LPG 0x82
+#define PIIX4_ISA_DMA1_CH1LPG 0x83
+#define PIIX4_ISA_DMA1_CH0LPG 0x87
+#define PIIX4_ISA_DMA2_CH2LPG 0x89
+#define PIIX4_ISA_DMA2_CH3LPG 0x8A
+#define PIIX4_ISA_DMA2_CH1LPG 0x8B
+#define PIIX4_ISA_DMA2_LPGRFR 0x8F
+
+#define PIIX4_ISA_PORT_92 0x92
+
+#define PIIX4_ISA_APM_CONTRL 0xB2
+#define PIIX4_ISA_APM_STATUS 0xB3
+
+#define PIIX4_ISA_COCPU_ERROR 0xF0
+
+/* Function 1 IDE Controller */
+#define PCI_CFG_PIIX4_BMIBA 0x20
+#define PCI_CFG_PIIX4_IDETIM 0x40
+#define PCI_CFG_PIIX4_SIDETIM 0x44
+#define PCI_CFG_PIIX4_UDMACTL 0x48
+#define PCI_CFG_PIIX4_UDMATIM 0x4A
+
+/* Function 2 USB Controller */
+#define PCI_CFG_PIIX4_SBRNUM 0x60
+#define PCI_CFG_PIIX4_LEGSUP 0xC0
+
+/* Function 3 Power Management */
+#define PCI_CFG_PIIX4_PMAB 0x40
+#define PCI_CFG_PIIX4_CNTA 0x44
+#define PCI_CFG_PIIX4_CNTB 0x48
+#define PCI_CFG_PIIX4_GPICTL 0x4C
+#define PCI_CFG_PIIX4_DEVRESD 0x50
+#define PCI_CFG_PIIX4_DEVACTA 0x54
+#define PCI_CFG_PIIX4_DEVACTB 0x58
+#define PCI_CFG_PIIX4_DEVRESA 0x5C
+#define PCI_CFG_PIIX4_DEVRESB 0x60
+#define PCI_CFG_PIIX4_DEVRESC 0x64
+#define PCI_CFG_PIIX4_DEVRESE 0x68
+#define PCI_CFG_PIIX4_DEVRESF 0x6C
+#define PCI_CFG_PIIX4_DEVRESG 0x70
+#define PCI_CFG_PIIX4_DEVRESH 0x74
+#define PCI_CFG_PIIX4_DEVRESI 0x78
+#define PCI_CFG_PIIX4_PMMISC 0x80
+#define PCI_CFG_PIIX4_SMBBA 0x90
+
+
+#endif /* _PIIX4_PCI_H */
diff --git a/board/eXalion/u-boot.lds b/board/eXalion/u-boot.lds
new file mode 100644
index 0000000..98584dc
--- /dev/null
+++ b/board/eXalion/u-boot.lds
@@ -0,0 +1,133 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc824x/start.o (.text)
+ lib_ppc/board.o (.text)
+ lib_ppc/ppcstring.o (.text)
+ lib_generic/vsprintf.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_generic/zlib.o (.text)
+
+ . = DEFINED(env_offset) ? env_offset : .;
+ common/environment.o (.text)
+
+ *(.text)
+
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/ns9750dev/Makefile b/board/ns9750dev/Makefile
new file mode 100644
index 0000000..d2718cc
--- /dev/null
+++ b/board/ns9750dev/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.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 = lib$(BOARD).a
+
+OBJS := ns9750dev.o flash.o led.o
+SOBJS := platform.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
diff --git a/board/ns9750dev/config.mk b/board/ns9750dev/config.mk
new file mode 100644
index 0000000..6a22cee
--- /dev/null
+++ b/board/ns9750dev/config.mk
@@ -0,0 +1,16 @@
+#######################################################################
+#
+# Copyright (C) 2004 by FS Forth-Systeme GmbH.
+# Markus Pietrek <mpietrek@fsforth.de>
+#
+# @TODO
+# Linux-Kernel is expected to be at 0000'8000, entry 0000'8000
+# optionally with a ramdisk at 0080'0000
+#
+# we load ourself to 0078'0000
+#
+# download area is 0060'0000
+#
+
+
+TEXT_BASE = 0x00780000
diff --git a/board/ns9750dev/flash.c b/board/ns9750dev/flash.c
new file mode 100644
index 0000000..e7d6515
--- /dev/null
+++ b/board/ns9750dev/flash.c
@@ -0,0 +1,477 @@
+/*
+ * (C) Copyright 2001
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2003
+ * Texas Instruments, <www.ti.com>
+ * Kshitij Gupta <Kshitij@ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/byteorder/swab.h>
+
+#define PHYS_FLASH_SECT_SIZE 0x00020000 /* 256 KB sectors (x2) */
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/* Board support for 1 or 2 flash devices */
+#undef FLASH_PORT_WIDTH32
+#define FLASH_PORT_WIDTH16
+
+#ifdef FLASH_PORT_WIDTH16
+#define FLASH_PORT_WIDTH ushort
+#define FLASH_PORT_WIDTHV vu_short
+#define SWAP(x) __swab16(x)
+#else
+#define FLASH_PORT_WIDTH ulong
+#define FLASH_PORT_WIDTHV vu_long
+#define SWAP(x) __swab32(x)
+#endif
+
+#define FPW FLASH_PORT_WIDTH
+#define FPWV FLASH_PORT_WIDTHV
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+
+
+/* Flash Organization Structure */
+typedef struct OrgDef {
+ unsigned int sector_number;
+ unsigned int sector_size;
+} OrgDef;
+
+
+/* Flash Organizations */
+OrgDef OrgIntel_28F256L18T[] = {
+ {4, 32 * 1024}, /* 4 * 32kBytes sectors */
+ {255, 128 * 1024}, /* 255 * 128kBytes sectors */
+};
+
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+unsigned long flash_init (void);
+static ulong flash_get_size (FPW * addr, flash_info_t * info);
+static int write_data (flash_info_t * info, ulong dest, FPW data);
+static void flash_get_offsets (ulong base, flash_info_t * info);
+void inline spin_wheel (void);
+void flash_print_info (flash_info_t * info);
+void flash_unprotect_sectors (FPWV * addr);
+int flash_erase (flash_info_t * info, int s_first, int s_last);
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ int i;
+ ulong size = 0;
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+ switch (i) {
+ case 0:
+ flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
+ flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
+ break;
+ default:
+ panic ("configured too many flash banks!\n");
+ break;
+ }
+ size += flash_info[i].size;
+ }
+
+ /* Protect monitor and environment sectors
+ */
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_FLASH_BASE,
+ CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]);
+
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t * info)
+{
+ int i;
+ OrgDef *pOrgDef;
+
+ pOrgDef = OrgIntel_28F256L18T;
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+ for (i = 0; i < info->sector_count; i++) {
+ if (i > 255) {
+ info->start[i] = base + (i * 0x8000);
+ info->protect[i] = 0;
+ } else {
+ info->start[i] = base +
+ (i * PHYS_FLASH_SECT_SIZE);
+ info->protect[i] = 0;
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+ int i;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_INTEL:
+ printf ("INTEL ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F256L18T:
+ printf ("FLASH 28F256L18T\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s",
+ info->start[i], info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+ return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (FPW * addr, flash_info_t * info)
+{
+ volatile FPW value;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr[0x5555] = (FPW) 0x00AA00AA;
+ addr[0x2AAA] = (FPW) 0x00550055;
+ addr[0x5555] = (FPW) 0x00900090;
+
+ mb ();
+ value = addr[0];
+
+ switch (value) {
+
+ case (FPW) INTEL_MANUFACT:
+ info->flash_id = FLASH_MAN_INTEL;
+ break;
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
+ return (0); /* no or unknown flash */
+ }
+
+ mb ();
+ value = addr[1]; /* device ID */
+ switch (value) {
+
+ case (FPW) (INTEL_ID_28F256L18T):
+ info->flash_id += FLASH_28F256L18T;
+ info->sector_count = 259;
+ info->size = 0x02000000;
+ break; /* => 32 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ break;
+ }
+
+ if (info->sector_count > CFG_MAX_FLASH_SECT) {
+ printf ("** ERROR: sector count %d > max (%d) **\n",
+ info->sector_count, CFG_MAX_FLASH_SECT);
+ info->sector_count = CFG_MAX_FLASH_SECT;
+ }
+
+ addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
+
+ return (info->size);
+}
+
+
+/* unprotects a sector for write and erase
+ * on some intel parts, this unprotects the entire chip, but it
+ * wont hurt to call this additional times per sector...
+ */
+void flash_unprotect_sectors (FPWV * addr)
+{
+#define PD_FINTEL_WSMS_READY_MASK 0x0080
+
+ *addr = (FPW) 0x00500050; /* clear status register */
+
+ /* this sends the clear lock bit command */
+ *addr = (FPW) 0x00600060;
+ *addr = (FPW) 0x00D000D0;
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ int flag, prot, sect;
+ ulong type, start, last;
+ int rcode = 0;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("- missing\n");
+ } else {
+ printf ("- no sectors to erase\n");
+ }
+ return 1;
+ }
+
+ type = (info->flash_id & FLASH_VENDMASK);
+ if ((type != FLASH_MAN_INTEL)) {
+ printf ("Can't erase unknown flash type %08lx - aborted\n",
+ info->flash_id);
+ return 1;
+ }
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+
+ if (prot) {
+ printf ("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ } else {
+ printf ("\n");
+ }
+
+
+ start = get_timer (0);
+ last = start;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts ();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ FPWV *addr = (FPWV *) (info->start[sect]);
+ FPW status;
+
+ printf ("Erasing sector %2d ... ", sect);
+
+ flash_unprotect_sectors (addr);
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ *addr = (FPW) 0x00500050;/* clear status register */
+ *addr = (FPW) 0x00200020;/* erase setup */
+ *addr = (FPW) 0x00D000D0;/* erase confirm */
+
+ while (((status =
+ *addr) & (FPW) 0x00800080) !=
+ (FPW) 0x00800080) {
+ if (get_timer_masked () >
+ CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ /* suspend erase */
+ *addr = (FPW) 0x00B000B0;
+ /* reset to read mode */
+ *addr = (FPW) 0x00FF00FF;
+ rcode = 1;
+ break;
+ }
+ }
+
+ /* clear status register cmd. */
+ *addr = (FPW) 0x00500050;
+ *addr = (FPW) 0x00FF00FF;/* resest to read mode */
+ printf (" done\n");
+ }
+ }
+ return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ ulong cp, wp;
+ FPW data;
+ int count, i, l, rc, port_width;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return 4;
+ }
+/* get lower word aligned address */
+#ifdef FLASH_PORT_WIDTH16
+ wp = (addr & ~1);
+ port_width = 2;
+#else
+ wp = (addr & ~3);
+ port_width = 4;
+#endif
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i = 0, cp = wp; i < l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+ for (; i < port_width && cnt > 0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt == 0 && i < port_width; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+ return (rc);
+ }
+ wp += port_width;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ count = 0;
+ while (cnt >= port_width) {
+ data = 0;
+ for (i = 0; i < port_width; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+ return (rc);
+ }
+ wp += port_width;
+ cnt -= port_width;
+ if (count++ > 0x800) {
+ spin_wheel ();
+ count = 0;
+ }
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i < port_width; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ return (write_data (info, wp, SWAP (data)));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word or halfword to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_data (flash_info_t * info, ulong dest, FPW data)
+{
+ FPWV *addr = (FPWV *) dest;
+ ulong status;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*addr & data) != data) {
+ printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
+ return (2);
+ }
+ flash_unprotect_sectors (addr);
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts ();
+ *addr = (FPW) 0x00400040; /* write setup */
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ /* wait while polling the status register */
+ while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
+ if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+ *addr = (FPW) 0x00FF00FF; /* restore read mode */
+ return (1);
+ }
+ }
+ *addr = (FPW) 0x00FF00FF; /* restore read mode */
+ return (0);
+}
+
+void inline spin_wheel (void)
+{
+ static int p = 0;
+ static char w[] = "\\/-";
+
+ printf ("\010%c", w[p]);
+ (++p == 3) ? (p = 0) : 0;
+}
diff --git a/board/ns9750dev/led.c b/board/ns9750dev/led.c
new file mode 100644
index 0000000..ab27f7b
--- /dev/null
+++ b/board/ns9750dev/led.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: led.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Defines helper functions for toggeling LEDs
+ * @Usage:
+ * @References: [1]
+ *
+ * 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
+ *
+ ***********************************************************************/
+
+#ifdef CONFIG_STATUS_LED
+
+#include <ns9750_bbus.h>
+
+static inline void __led_init( led_id_t mask, int state )
+{
+ XXXX;
+}
+
+static inline void __led_toggle( led_id_t mask )
+{
+}
+
+static inline void __led_set( led_id_t mask, int state )
+{
+}
+
+#endif /* CONFIG_STATUS_LED */
diff --git a/board/ns9750dev/ns9750dev.c b/board/ns9750dev/ns9750dev.c
new file mode 100644
index 0000000..0ea89a5
--- /dev/null
+++ b/board/ns9750dev/ns9750dev.c
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * (C) Copyright 2003
+ * Texas Instruments, <www.ti.com>
+ * Kshitij Gupta <Kshitij@ti.com>
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ * Markus Pietrek <mpietrek@fsforth.de>
+ * derived from omap1610innovator.c
+ * @References: [1] NS9750 Hardware Reference/December 2003
+ *
+ * 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>
+#if defined(CONFIG_NS9750DEV)
+# include <./configs/ns9750dev.h>
+# include <./ns9750_bbus.h>
+#endif
+
+void flash__init( void );
+void ether__init( void );
+
+static inline void delay( unsigned long loops )
+{
+ __asm__ volatile ("1:\n"
+ "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0" (loops));
+}
+
+
+/***********************************************************************
+ * @Function: board_init
+ * @Return: 0
+ * @Descr: Enables BBUS modules and other devices
+ ***********************************************************************/
+
+int board_init( void )
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* Active BBUS modules */
+ *get_bbus_reg_addr( NS9750_BBUS_MASTER_RESET ) = 0;
+
+#warning TODO check numbers
+ /* arch number of OMAP 1510-Board */
+ /* to be changed for OMAP 1610 Board */
+ gd->bd->bi_arch_number = 234;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0x10000100;
+
+
+/* this speeds up your boot a quite a bit. However to make it
+ * work, you need make sure your kernel startup flush bug is fixed.
+ * ... rkw ...
+ */
+ icache_enable();
+
+ flash__init();
+ ether__init();
+ return 0;
+}
+
+
+int misc_init_r (void)
+{
+ /* currently empty */
+ return (0);
+}
+
+/******************************
+ Routine:
+ Description:
+******************************/
+void flash__init (void)
+{
+}
+/*************************************************************
+ Routine:ether__init
+ Description: take the Ethernet controller out of reset and wait
+ for the EEPROM load to complete.
+*************************************************************/
+void ether__init (void)
+{
+}
+
+/******************************
+ Routine:
+ Description:
+******************************/
+int dram_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+#if CONFIG_NR_DRAM_BANKS > 1
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+#endif
+ return 0;
+}
diff --git a/board/ns9750dev/platform.S b/board/ns9750dev/platform.S
new file mode 100644
index 0000000..11f9aef
--- /dev/null
+++ b/board/ns9750dev/platform.S
@@ -0,0 +1,298 @@
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2003
+ * Texas Instruments, <www.ti.com>
+ * Kshitij Gupta <Kshitij@ti.com>
+ *
+ * Modified for the NS9750 DevBoard by
+ * (C) Copyright 2004 by FS Forth-Systeme GmbH.
+ * Markus Pietrek <mpietrek@fsforth.de>
+ * @References: [1] NS9750 Hardware Reference/December 2003
+ * [2] ns9750_a.cmd from MAJIC configuration
+ *
+ * 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>
+
+#if defined(CONFIG_NS9750DEV)
+# ifdef CONFIG_INIT_CRITICAL
+# include <./ns9750_sys.h>
+# include <./ns9750_mem.h>
+# endif
+#endif
+
+/***********************************************************************
+ * @Function: write_register_block
+ * @Return: nothing
+ * @Descr: Copies the register block of register_offset:register value to
+ * the registers at base r0. The block is assumed to start in RAM at r1
+ * and end at r2. The linked RAM base address of U-Boot is assumed to be
+ * in r5 while the ROM base address we are running from is r6
+ * Uses r3 and r4 as tempory registers
+ ***********************************************************************/
+
+.macro write_register_block
+ @@ map the addresses to high memory
+ sub r1, r1, r5
+ add r1, r1, r6
+ sub r2, r2, r5
+ add r2, r2, r6
+
+ @@ copy all
+1:
+ @@ Write register/value pair starting at [r1] to register base r0
+ ldr r3, [r1], #4
+ ldr r4, [r1], #4
+ str r4, [r0,r3]
+ cmp r1, r2
+ blt 1b
+.endm
+
+_TEXT_BASE:
+ .word TEXT_BASE @ sdram load addr from config.mk
+_PHYS_FLASH:
+ .word PHYS_FLASH_1 @ real flash address (without mirroring)
+_CAS_LATENCY:
+ .word 0x00022000 @ for CAS2 latency
+
+#ifdef CONFIG_INIT_CRITICAL
+.globl platformsetup
+platformsetup:
+
+ /* U-Boot may be linked to RAM at 0x780000. But this code will run in
+ flash from 0x0. But in order to enable RAM we have to disable the
+ mirror bit, therefore we have to jump to our real flash address
+ beginning at PHYS_FLASH_1 (CS4 Base). Therefore,
+ _run_at_real_flash_address may be 0x500003b0 while be linked to
+ 0x7803b0. So we must modify our linked addresses */
+
+ @@ branch to high memory address, away from 0x0
+ ldr r5, _TEXT_BASE
+ ldr r6, _PHYS_FLASH
+ ldr r0, =_run_at_real_flash_address
+ sub r0, r0, r5
+ add r0, r0, r6
+ mov pc, r0
+ nop @ for pipelining
+
+_run_at_real_flash_address:
+ @@ now we are running > PHYS_FLASH_1, safe to enable memory controller
+
+ @@ Write Memory Configuration Registers
+
+ ldr r0, _NS9750_MEM_MODULE_BASE
+ ldr r1, =_MEM_CONFIG_START
+ ldr r2, =_MEM_CONFIG_END
+
+ write_register_block
+
+ @@ Give SDRAM some time to settle
+ @@ @TODO. According to [2] it should be 2 AHB cycles. Check
+
+ ldr r1, =0x50
+_sdram_settle:
+ subs r1, r1, #1
+ bne _sdram_settle
+
+_enable_mappings:
+ @@ Enable SDRAM Mode
+
+ ldr r1, =_MEM_MODE_START
+ ldr r2, =_MEM_MODE_END
+
+ write_register_block
+
+ ldr r3, _CAS_LATENCY @ perform one read from SDRAM
+ ldr r3, [r3]
+
+ @@ Enable SDRAM and memory mappings
+
+ ldr r1, =_MEM_ENABLE_START
+ ldr r2, =_MEM_ENABLE_END
+
+ write_register_block
+
+ @@ Activate AHB monitor
+
+ ldr r0, =NS9750_SYS_MODULE_BASE
+ ldr r1, =_AHB_MONITOR_START
+ ldr r2, =_AHB_MONITOR_END
+
+ write_register_block
+_relocate_lr:
+ /* lr and ip (from cpu_init_crit) are still based on 0x0, relocate it to
+ PHYS_FLASH. */
+ mov r1, ip
+ add r1, r1, r6
+ mov ip, r1
+
+ mov r1, lr
+ add r1, r1, r6
+ mov lr, r1
+
+ @@ back to arch calling code
+ mov pc, lr
+
+ .ltorg
+
+_NS9750_MEM_MODULE_BASE:
+ .word NS9750_MEM_MODULE_BASE
+
+_MEM_CONFIG_START:
+ /* Table of 2 32bit entries. First word is register address offset
+ relative to NS9750_MEM_MODULE_BASE, second one is value. They are
+ written in order of appearance */
+
+ @@ Register values taken from [2]
+ .word NS9750_MEM_CTRL
+ .word NS9750_MEM_CTRL_E
+
+ .word NS9750_MEM_DYN_REFRESH
+ .word (0x6 & NS9750_MEM_DYN_REFRESH_MA)
+
+ .word NS9750_MEM_DYN_READ_CFG
+ .word (0x1 & NS9750_MEM_DYN_READ_CFG_MA)
+
+ .word NS9750_MEM_DYN_TRP
+ .word (0x1 & NS9750_MEM_DYN_TRP_MA)
+
+ .word NS9750_MEM_DYN_TRAS
+ .word (0x4 & NS9750_MEM_DYN_TRAS_MA)
+
+ .word NS9750_MEM_DYN_TAPR
+ .word (0x1 & NS9750_MEM_DYN_TRAS_MA)
+
+ .word NS9750_MEM_DYN_TDAL
+ .word (0x5 & NS9750_MEM_DYN_TDAL_MA)
+
+ .word NS9750_MEM_DYN_TWR
+ .word (0x1 & NS9750_MEM_DYN_TWR_MA)
+
+ .word NS9750_MEM_DYN_TRC
+ .word (0x6 & NS9750_MEM_DYN_TRC_MA)
+
+ .word NS9750_MEM_DYN_TRFC
+ .word (0x6 & NS9750_MEM_DYN_TRFC_MA)
+
+ .word NS9750_MEM_DYN_TRRD
+ .word (0x1 & NS9750_MEM_DYN_TRRD_MA)
+
+ .word NS9750_MEM_DYN_TMRD
+ .word (0x1 & NS9750_MEM_DYN_TMRD_MA)
+
+ @@ CS 4
+ .word NS9750_MEM_DYN_CFG(0)
+ .word (NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+
+ .word NS9750_MEM_DYN_RAS_CAS(0)
+ .word ((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \
+ (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA))
+
+ @@ CS 5
+ .word NS9750_MEM_DYN_CFG(1)
+ .word (NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+
+ .word NS9750_MEM_DYN_RAS_CAS(1)
+ .word ((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \
+ (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA))
+
+ @@ CS 6
+ .word NS9750_MEM_DYN_CFG(2)
+ .word (NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+
+ .word NS9750_MEM_DYN_RAS_CAS(2)
+ .word ((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \
+ (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA))
+
+ @@ CS 7
+ .word NS9750_MEM_DYN_CFG(3)
+ .word (NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+
+ .word NS9750_MEM_DYN_RAS_CAS(3)
+ .word ((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \
+ (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA))
+
+ .word NS9750_MEM_DYN_CTRL
+ .word (NS9750_MEM_DYN_CTRL_I_PALL | \
+ NS9750_MEM_DYN_CTRL_SR | \
+ NS9750_MEM_DYN_CTRL_CE )
+
+ .word NS9750_MEM_DYN_REFRESH
+ .word (0x1 & NS9750_MEM_DYN_REFRESH_MA)
+ @@ No further register settings after refresh
+_MEM_CONFIG_END:
+
+_MEM_MODE_START:
+ .word NS9750_MEM_DYN_REFRESH
+ .word (0x30 & NS9750_MEM_DYN_REFRESH_MA)
+
+ .word NS9750_MEM_DYN_CTRL
+ .word (NS9750_MEM_DYN_CTRL_I_MODE | \
+ NS9750_MEM_DYN_CTRL_SR | \
+ NS9750_MEM_DYN_CTRL_CE )
+_MEM_MODE_END:
+
+_MEM_ENABLE_START:
+ .word NS9750_MEM_DYN_CTRL
+ .word (NS9750_MEM_DYN_CTRL_I_NORMAL | \
+ NS9750_MEM_DYN_CTRL_SR | \
+ NS9750_MEM_DYN_CTRL_CE )
+
+ @@ CS 4
+ .word NS9750_MEM_DYN_CFG(0)
+ .word (NS9750_MEM_DYN_CFG_BDMC | \
+ NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+
+ @@ CS 5
+ .word NS9750_MEM_DYN_CFG(1)
+ .word (NS9750_MEM_DYN_CFG_BDMC | \
+ NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+
+ @@ CS 6
+ .word NS9750_MEM_DYN_CFG(2)
+ .word (NS9750_MEM_DYN_CFG_BDMC | \
+ NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+
+ @@ CS 7
+ .word NS9750_MEM_DYN_CFG(3)
+ .word (NS9750_MEM_DYN_CFG_BDMC | \
+ NS9750_MEM_DYN_CFG_AM | \
+ (0x280 & NS9750_MEM_DYN_CFG_AM_MA))
+_MEM_ENABLE_END:
+
+_AHB_MONITOR_START:
+ .word NS9750_SYS_AHB_TIMEOUT
+ .word 0x01000100 @ @TODO not calculated yet
+
+ .word NS9750_SYS_AHB_MON
+ .word (NS9750_SYS_AHB_MON_BMTC_GEN_IRQ | \
+ NS9750_SYS_AHB_MON_BATC_GEN_IRQ)
+_AHB_MONITOR_END:
+
+#endif /* CONFIG_INIT_CRITICAL */
diff --git a/board/ns9750dev/u-boot.lds b/board/ns9750dev/u-boot.lds
new file mode 100644
index 0000000..8a05892
--- /dev/null
+++ b/board/ns9750dev/u-boot.lds
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm926ejs/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = . ;
+
+}
diff --git a/board/omap1610inn/platform.S b/board/omap1610inn/platform.S
index 2fa4378..441edc2 100644
--- a/board/omap1610inn/platform.S
+++ b/board/omap1610inn/platform.S
@@ -41,15 +41,15 @@ _TEXT_BASE:
platformsetup:
- /*------------------------------------------------------*
- *mask all IRQs by setting all bits in the INTMR default*
- *------------------------------------------------------*/
+ /*------------------------------------------------------*
+ *mask all IRQs by setting all bits in the INTMR default*
+ *------------------------------------------------------*/
mov r1, #0xffffffff
ldr r0, =REG_IHL1_MIR
str r1, [r0]
ldr r0, =REG_IHL2_MIR
str r1, [r0]
-
+
/*------------------------------------------------------*
* Set up ARM CLM registers (IDLECT1) *
*------------------------------------------------------*/
diff --git a/common/cmd_mii.c b/common/cmd_mii.c
index f8ebef6..abbdaa2 100644
--- a/common/cmd_mii.c
+++ b/common/cmd_mii.c
@@ -129,6 +129,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
last_op = op;
last_addr = addr;
last_data = data;
+ last_reg = reg;
return rcode;
}
diff --git a/common/usb_storage.c b/common/usb_storage.c
index d99f259..dbe9cd9 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -19,7 +19,7 @@
*
* 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
+ * 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
@@ -53,10 +53,12 @@
#ifdef CONFIG_USB_STORAGE
-#undef USB_STOR_DEBUG
+#undef USB_STOR_DEBUG
+#undef BBB_COMDAT_TRACE
+#undef BBB_XPORT_TRACE
#ifdef USB_STOR_DEBUG
-#define USB_STOR_PRINTF(fmt,args...) printf (fmt ,##args)
+#define USB_STOR_PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define USB_STOR_PRINTF(fmt,args...)
#endif
@@ -102,7 +104,7 @@ typedef struct {
# define CBWCDBLENGTH 16
__u8 CBWCDB[CBWCDBLENGTH];
} umass_bbb_cbw_t;
-#define UMASS_BBB_CBW_SIZE 31
+#define UMASS_BBB_CBW_SIZE 31
static __u32 CBWTag = 0;
/* Command Status Wrapper */
@@ -113,10 +115,10 @@ typedef struct {
__u32 dCSWDataResidue;
__u8 bCSWStatus;
# define CSWSTATUS_GOOD 0x0
-# define CSWSTATUS_FAILED 0x1
+# define CSWSTATUS_FAILED 0x1
# define CSWSTATUS_PHASE 0x2
} umass_bbb_csw_t;
-#define UMASS_BBB_CSW_SIZE 13
+#define UMASS_BBB_CSW_SIZE 13
#define USB_MAX_STOR_DEV 5
static int usb_max_devs; /* number of highest available usb device */
@@ -128,7 +130,7 @@ typedef int (*trans_cmnd)(ccb*, struct us_data*);
typedef int (*trans_reset)(struct us_data*);
struct us_data {
- struct usb_device *pusb_dev; /* this usb_device */
+ struct usb_device *pusb_dev; /* this usb_device */
unsigned int flags; /* from filter initially */
unsigned char ifnum; /* interface number */
unsigned char ep_in; /* in endpoint */
@@ -136,14 +138,14 @@ struct us_data {
unsigned char ep_int; /* interrupt . */
unsigned char subclass; /* as in overview */
unsigned char protocol; /* .............. */
- unsigned char attention_done; /* force attn on first cmd */
+ unsigned char attention_done; /* force attn on first cmd */
unsigned short ip_data; /* interrupt data */
int action; /* what to do */
int ip_wanted; /* needed */
int *irq_handle; /* for USB int requests */
unsigned int irqpipe; /* pipe for release_irq */
unsigned char irqmaxp; /* max packed for irq Pipe */
- unsigned char irqinterval; /* Intervall for IRQ Pipe */
+ unsigned char irqinterval; /* Intervall for IRQ Pipe */
ccb *srb; /* current srb */
trans_reset transport_reset; /* reset routine */
trans_cmnd transport; /* transport routine */
@@ -152,7 +154,7 @@ struct us_data {
static struct us_data usb_stor[USB_MAX_STOR_DEV];
-#define USB_STOR_TRANSPORT_GOOD 0
+#define USB_STOR_TRANSPORT_GOOD 0
#define USB_STOR_TRANSPORT_FAILED -1
#define USB_STOR_TRANSPORT_ERROR -2
@@ -517,45 +519,47 @@ int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
}
-int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
+int usb_stor_CBI_get_status (ccb * srb, struct us_data *us)
{
int timeout;
- us->ip_wanted=1;
- submit_int_msg(us->pusb_dev,us->irqpipe,
- (void *)&us->ip_data,us->irqmaxp ,us->irqinterval);
- timeout=1000;
- while(timeout--) {
- if((volatile int *)us->ip_wanted==0)
+ us->ip_wanted = 1;
+ submit_int_msg (us->pusb_dev, us->irqpipe,
+ (void *) &us->ip_data, us->irqmaxp, us->irqinterval);
+ timeout = 1000;
+ while (timeout--) {
+ if ((volatile int *) us->ip_wanted == 0)
break;
- wait_ms(10);
+ wait_ms (10);
}
if (us->ip_wanted) {
- printf(" Did not get interrupt on CBI\n");
+ printf (" Did not get interrupt on CBI\n");
us->ip_wanted = 0;
return USB_STOR_TRANSPORT_ERROR;
}
- USB_STOR_PRINTF("Got interrupt data 0x%x, transfered %d status 0x%lX\n", us->ip_data,us->pusb_dev->irq_act_len,us->pusb_dev->irq_status);
+ USB_STOR_PRINTF
+ ("Got interrupt data 0x%x, transfered %d status 0x%lX\n",
+ us->ip_data, us->pusb_dev->irq_act_len,
+ us->pusb_dev->irq_status);
/* UFI gives us ASC and ASCQ, like a request sense */
if (us->subclass == US_SC_UFI) {
if (srb->cmd[0] == SCSI_REQ_SENSE ||
srb->cmd[0] == SCSI_INQUIRY)
return USB_STOR_TRANSPORT_GOOD; /* Good */
+ else if (us->ip_data)
+ return USB_STOR_TRANSPORT_FAILED;
else
- if (us->ip_data)
- return USB_STOR_TRANSPORT_FAILED;
- else
- return USB_STOR_TRANSPORT_GOOD;
+ return USB_STOR_TRANSPORT_GOOD;
}
/* otherwise, we interpret the data normally */
switch (us->ip_data) {
- case 0x0001:
- return USB_STOR_TRANSPORT_GOOD;
- case 0x0002:
- return USB_STOR_TRANSPORT_FAILED;
- default:
- return USB_STOR_TRANSPORT_ERROR;
- } /* switch */
+ case 0x0001:
+ return USB_STOR_TRANSPORT_GOOD;
+ case 0x0002:
+ return USB_STOR_TRANSPORT_FAILED;
+ default:
+ return USB_STOR_TRANSPORT_ERROR;
+ } /* switch */
return USB_STOR_TRANSPORT_ERROR;
}
@@ -601,11 +605,11 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
/* DATA phase + error handling */
- USB_STOR_PRINTF("DATA phase\n");
data_actlen = 0;
/* no data, go immediately to the STATUS phase */
if (srb->datalen == 0)
goto st;
+ USB_STOR_PRINTF("DATA phase\n");
if (dir_in)
pipe = pipein;
else
@@ -732,7 +736,7 @@ do_retry:
}
if((us->protocol==US_PR_CBI) &&
((srb->cmd[0]==SCSI_REQ_SENSE) ||
- (srb->cmd[0]==SCSI_INQUIRY))) { /* do not issue an autorequest after request sense */
+ (srb->cmd[0]==SCSI_INQUIRY))) { /* do not issue an autorequest after request sense */
USB_STOR_PRINTF("No auto request and good\n");
return USB_STOR_TRANSPORT_GOOD;
}
@@ -749,7 +753,7 @@ do_retry:
USB_STOR_PRINTF("auto request returned %d\n",result);
/* if this is an CBI Protocol, get IRQ */
if(us->protocol==US_PR_CBI) {
- status=usb_stor_CBI_get_status(psrb,us);
+ status=usb_stor_CBI_get_status(psrb,us);
}
if((result<0)&&!(us->pusb_dev->status & USB_ST_STALLED)) {
USB_STOR_PRINTF(" AUTO REQUEST ERROR %d\n",us->pusb_dev->status);
@@ -765,7 +769,7 @@ do_retry:
switch(srb->sense_buf[2]) {
case 0x01: /* Recovered Error */
return USB_STOR_TRANSPORT_GOOD;
- break;
+ break;
case 0x02: /* Not Ready */
if(notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X (NOT READY)\n",
@@ -817,7 +821,7 @@ static int usb_inquiry(ccb *srb,struct us_data *ss)
static int usb_request_sense(ccb *srb,struct us_data *ss)
{
char *ptr;
- return 0;
+
ptr=srb->pdata;
memset(&srb->cmd[0],0,12);
srb->cmd[0]=SCSI_REQ_SENSE;
@@ -845,6 +849,8 @@ static int usb_test_unit_ready(ccb *srb,struct us_data *ss)
if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {
return 0;
}
+ usb_request_sense (srb, ss);
+ wait_ms (100);
} while(retries--);
return -1;
@@ -1026,7 +1032,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data
ss->transport_reset = usb_stor_BBB_reset;
break;
default:
- printf("USB Starage Transport unknown / not yet implemented\n");
+ printf("USB Storage Transport unknown / not yet implemented\n");
return 0;
break;
}
@@ -1069,8 +1075,10 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data
/* set class specific stuff */
/* We only handle certain protocols. Currently, these are
* the only ones.
+ * The SFF8070 accepts the requests used in u-boot
*/
- if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI) {
+ if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&
+ ss->subclass != US_SC_8070) {
printf("Sorry, protocol %d not yet supported.\n",ss->subclass);
return 0;
}
diff --git a/cpu/mpc5xxx/Makefile b/cpu/mpc5xxx/Makefile
index a65bc22..5b5a33b 100644
--- a/cpu/mpc5xxx/Makefile
+++ b/cpu/mpc5xxx/Makefile
@@ -28,7 +28,7 @@ LIB = lib$(CPU).a
START = start.o
ASOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
OBJS = i2c.o traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o \
- loadtask.o fec.o pci_mpc5200.o
+ loadtask.o fec.o pci_mpc5200.o usb_ohci.o
all: .depend $(START) $(ASOBJS) $(LIB)
diff --git a/cpu/mpc5xxx/usb_ohci.c b/cpu/mpc5xxx/usb_ohci.c
new file mode 100644
index 0000000..5b5eac2
--- /dev/null
+++ b/cpu/mpc5xxx/usb_ohci.c
@@ -0,0 +1,1602 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the MPC5200.
+ *
+ * (C) Copyright 2003-2004
+ * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Pierre Aubert, Staubli Faverges <p.aubert@staubli.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Note: Part of this code has been derived from linux
+ *
+ */
+/*
+ * IMPORTANT NOTES
+ * 1 - this driver is intended for use with USB Mass Storage Devices
+ * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes!
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_USB_OHCI
+
+#include <malloc.h>
+#include <usb.h>
+#include "usb_ohci.h"
+
+#include <mpc5xxx.h>
+
+#define OHCI_USE_NPS /* force NoPowerSwitching mode */
+#undef OHCI_VERBOSE_DEBUG /* not always helpful */
+#undef DEBUG
+#undef SHOW_INFO
+#undef OHCI_FILL_TRACE
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#define readl(a) (*((vu_long *)(a)))
+#define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
+
+#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#ifdef DEBUG
+#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
+#else
+#define dbg(format, arg...) do {} while(0)
+#endif /* DEBUG */
+#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
+#ifdef SHOW_INFO
+#define info(format, arg...) printf("INFO: " format "\n", ## arg)
+#else
+#define info(format, arg...) do {} while(0)
+#endif
+
+#define m16_swap(x) swap_16(x)
+#define m32_swap(x) swap_32(x)
+
+#ifdef CONFIG_MPC5200
+#define ohci_cpu_to_le16(x) (x)
+#define ohci_cpu_to_le32(x) (x)
+#else
+#define ohci_cpu_to_le16(x) swap_16(x)
+#define ohci_cpu_to_le32(x) swap_32(x)
+#endif
+
+/* global ohci_t */
+static ohci_t gohci;
+/* this must be aligned to a 256 byte boundary */
+struct ohci_hcca ghcca[1];
+/* a pointer to the aligned storage */
+struct ohci_hcca *phcca;
+/* this allocates EDs for all possible endpoints */
+struct ohci_device ohci_dev;
+/* urb_priv */
+urb_priv_t urb_priv;
+/* RHSC flag */
+int got_rhsc;
+/* device which was disconnected */
+struct usb_device *devgone;
+
+/*-------------------------------------------------------------------------*/
+
+/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
+ * The erratum (#4) description is incorrect. AMD's workaround waits
+ * till some bits (mostly reserved) are clear; ok for all revs.
+ */
+#define OHCI_QUIRK_AMD756 0xabcd
+#define read_roothub(hc, register, mask) ({ \
+ u32 temp = readl (&hc->regs->roothub.register); \
+ if (hc->flags & OHCI_QUIRK_AMD756) \
+ while (temp & mask) \
+ temp = readl (&hc->regs->roothub.register); \
+ temp; })
+
+static u32 roothub_a (struct ohci *hc)
+ { return read_roothub (hc, a, 0xfc0fe000); }
+static inline u32 roothub_b (struct ohci *hc)
+ { return readl (&hc->regs->roothub.b); }
+static inline u32 roothub_status (struct ohci *hc)
+ { return readl (&hc->regs->roothub.status); }
+static u32 roothub_portstatus (struct ohci *hc, int i)
+ { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
+
+
+/* forward declaration */
+static int hc_interrupt (void);
+static void
+td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,
+ int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval);
+
+/*-------------------------------------------------------------------------*
+ * URB support functions
+ *-------------------------------------------------------------------------*/
+
+/* free HCD-private data associated with this URB */
+
+static void urb_free_priv (urb_priv_t * urb)
+{
+ int i;
+ int last;
+ struct td * td;
+
+ last = urb->length - 1;
+ if (last >= 0) {
+ for (i = 0; i <= last; i++) {
+ td = urb->td[i];
+ if (td) {
+ td->usb_dev = NULL;
+ urb->td[i] = NULL;
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+static int sohci_get_current_frame_number (struct usb_device * dev);
+
+/* debug| print the main components of an URB
+ * small: 0) header + data packets 1) just header */
+
+static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer,
+ int transfer_len, struct devrequest * setup, char * str, int small)
+{
+ urb_priv_t * purb = &urb_priv;
+
+ dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
+ str,
+ sohci_get_current_frame_number (dev),
+ usb_pipedevice (pipe),
+ usb_pipeendpoint (pipe),
+ usb_pipeout (pipe)? 'O': 'I',
+ usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
+ (usb_pipecontrol (pipe)? "CTRL": "BULK"),
+ purb->actual_length,
+ transfer_len, dev->status);
+#ifdef OHCI_VERBOSE_DEBUG
+ if (!small) {
+ int i, len;
+
+ if (usb_pipecontrol (pipe)) {
+ printf (__FILE__ ": cmd(8):");
+ for (i = 0; i < 8 ; i++)
+ printf (" %02x", ((__u8 *) setup) [i]);
+ printf ("\n");
+ }
+ if (transfer_len > 0 && buffer) {
+ printf (__FILE__ ": data(%d/%d):",
+ purb->actual_length,
+ transfer_len);
+ len = usb_pipeout (pipe)?
+ transfer_len: purb->actual_length;
+ for (i = 0; i < 16 && i < len; i++)
+ printf (" %02x", ((__u8 *) buffer) [i]);
+ printf ("%s\n", i < len? "...": "");
+ }
+ }
+#endif
+}
+
+/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
+void ep_print_int_eds (ohci_t *ohci, char * str) {
+ int i, j;
+ __u32 * ed_p;
+ for (i= 0; i < 32; i++) {
+ j = 5;
+ ed_p = &(ohci->hcca->int_table [i]);
+ if (*ed_p == 0)
+ continue;
+ printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i);
+ while (*ed_p != 0 && j--) {
+ ed_t *ed = (ed_t *)ohci_cpu_to_le32(ed_p);
+ printf (" ed: %4x;", ed->hwINFO);
+ ed_p = &ed->hwNextED;
+ }
+ printf ("\n");
+ }
+}
+
+static void ohci_dump_intr_mask (char *label, __u32 mask)
+{
+ dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
+ label,
+ mask,
+ (mask & OHCI_INTR_MIE) ? " MIE" : "",
+ (mask & OHCI_INTR_OC) ? " OC" : "",
+ (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
+ (mask & OHCI_INTR_FNO) ? " FNO" : "",
+ (mask & OHCI_INTR_UE) ? " UE" : "",
+ (mask & OHCI_INTR_RD) ? " RD" : "",
+ (mask & OHCI_INTR_SF) ? " SF" : "",
+ (mask & OHCI_INTR_WDH) ? " WDH" : "",
+ (mask & OHCI_INTR_SO) ? " SO" : ""
+ );
+}
+
+static void maybe_print_eds (char *label, __u32 value)
+{
+ ed_t *edp = (ed_t *)value;
+
+ if (value) {
+ dbg ("%s %08x", label, value);
+ dbg ("%08x", edp->hwINFO);
+ dbg ("%08x", edp->hwTailP);
+ dbg ("%08x", edp->hwHeadP);
+ dbg ("%08x", edp->hwNextED);
+ }
+}
+
+static char * hcfs2string (int state)
+{
+ switch (state) {
+ case OHCI_USB_RESET: return "reset";
+ case OHCI_USB_RESUME: return "resume";
+ case OHCI_USB_OPER: return "operational";
+ case OHCI_USB_SUSPEND: return "suspend";
+ }
+ return "?";
+}
+
+/* dump control and status registers */
+static void ohci_dump_status (ohci_t *controller)
+{
+ struct ohci_regs *regs = controller->regs;
+ __u32 temp;
+
+ temp = readl (&regs->revision) & 0xff;
+ if (temp != 0x10)
+ dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
+
+ temp = readl (&regs->control);
+ dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
+ (temp & OHCI_CTRL_RWE) ? " RWE" : "",
+ (temp & OHCI_CTRL_RWC) ? " RWC" : "",
+ (temp & OHCI_CTRL_IR) ? " IR" : "",
+ hcfs2string (temp & OHCI_CTRL_HCFS),
+ (temp & OHCI_CTRL_BLE) ? " BLE" : "",
+ (temp & OHCI_CTRL_CLE) ? " CLE" : "",
+ (temp & OHCI_CTRL_IE) ? " IE" : "",
+ (temp & OHCI_CTRL_PLE) ? " PLE" : "",
+ temp & OHCI_CTRL_CBSR
+ );
+
+ temp = readl (&regs->cmdstatus);
+ dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
+ (temp & OHCI_SOC) >> 16,
+ (temp & OHCI_OCR) ? " OCR" : "",
+ (temp & OHCI_BLF) ? " BLF" : "",
+ (temp & OHCI_CLF) ? " CLF" : "",
+ (temp & OHCI_HCR) ? " HCR" : ""
+ );
+
+ ohci_dump_intr_mask ("intrstatus", readl (&regs->intrstatus));
+ ohci_dump_intr_mask ("intrenable", readl (&regs->intrenable));
+
+ maybe_print_eds ("ed_periodcurrent", readl (&regs->ed_periodcurrent));
+
+ maybe_print_eds ("ed_controlhead", readl (&regs->ed_controlhead));
+ maybe_print_eds ("ed_controlcurrent", readl (&regs->ed_controlcurrent));
+
+ maybe_print_eds ("ed_bulkhead", readl (&regs->ed_bulkhead));
+ maybe_print_eds ("ed_bulkcurrent", readl (&regs->ed_bulkcurrent));
+
+ maybe_print_eds ("donehead", readl (&regs->donehead));
+}
+
+static void ohci_dump_roothub (ohci_t *controller, int verbose)
+{
+ __u32 temp, ndp, i;
+
+ temp = roothub_a (controller);
+ ndp = (temp & RH_A_NDP);
+
+ if (verbose) {
+ dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
+ ((temp & RH_A_POTPGT) >> 24) & 0xff,
+ (temp & RH_A_NOCP) ? " NOCP" : "",
+ (temp & RH_A_OCPM) ? " OCPM" : "",
+ (temp & RH_A_DT) ? " DT" : "",
+ (temp & RH_A_NPS) ? " NPS" : "",
+ (temp & RH_A_PSM) ? " PSM" : "",
+ ndp
+ );
+ temp = roothub_b (controller);
+ dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
+ temp,
+ (temp & RH_B_PPCM) >> 16,
+ (temp & RH_B_DR)
+ );
+ temp = roothub_status (controller);
+ dbg ("roothub.status: %08x%s%s%s%s%s%s",
+ temp,
+ (temp & RH_HS_CRWE) ? " CRWE" : "",
+ (temp & RH_HS_OCIC) ? " OCIC" : "",
+ (temp & RH_HS_LPSC) ? " LPSC" : "",
+ (temp & RH_HS_DRWE) ? " DRWE" : "",
+ (temp & RH_HS_OCI) ? " OCI" : "",
+ (temp & RH_HS_LPS) ? " LPS" : ""
+ );
+ }
+
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus (controller, i);
+ dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
+ i,
+ temp,
+ (temp & RH_PS_PRSC) ? " PRSC" : "",
+ (temp & RH_PS_OCIC) ? " OCIC" : "",
+ (temp & RH_PS_PSSC) ? " PSSC" : "",
+ (temp & RH_PS_PESC) ? " PESC" : "",
+ (temp & RH_PS_CSC) ? " CSC" : "",
+
+ (temp & RH_PS_LSDA) ? " LSDA" : "",
+ (temp & RH_PS_PPS) ? " PPS" : "",
+ (temp & RH_PS_PRS) ? " PRS" : "",
+ (temp & RH_PS_POCI) ? " POCI" : "",
+ (temp & RH_PS_PSS) ? " PSS" : "",
+
+ (temp & RH_PS_PES) ? " PES" : "",
+ (temp & RH_PS_CCS) ? " CCS" : ""
+ );
+ }
+}
+
+static void ohci_dump (ohci_t *controller, int verbose)
+{
+ dbg ("OHCI controller usb-%s state", controller->slot_name);
+
+ /* dumps some of the state we know about */
+ ohci_dump_status (controller);
+ if (verbose)
+ ep_print_int_eds (controller, "hcca");
+ dbg ("hcca frame #%04x", controller->hcca->frame_no);
+ ohci_dump_roothub (controller, 1);
+}
+
+
+#endif /* DEBUG */
+
+/*-------------------------------------------------------------------------*
+ * Interface functions (URB)
+ *-------------------------------------------------------------------------*/
+
+/* get a transfer request */
+
+int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval)
+{
+ ohci_t *ohci;
+ ed_t * ed;
+ urb_priv_t *purb_priv;
+ int i, size = 0;
+
+ ohci = &gohci;
+
+ /* when controller's hung, permit only roothub cleanup attempts
+ * such as powering down ports */
+ if (ohci->disabled) {
+ err("sohci_submit_job: EPIPE");
+ return -1;
+ }
+
+ /* every endpoint has a ed, locate and fill it */
+ if (!(ed = ep_add_ed (dev, pipe))) {
+ err("sohci_submit_job: ENOMEM");
+ return -1;
+ }
+
+ /* for the private part of the URB we need the number of TDs (size) */
+ switch (usb_pipetype (pipe)) {
+ case PIPE_BULK: /* one TD for every 4096 Byte */
+ size = (transfer_len - 1) / 4096 + 1;
+ break;
+ case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
+ size = (transfer_len == 0)? 2:
+ (transfer_len - 1) / 4096 + 3;
+ break;
+ }
+
+ if (size >= (N_URB_TD - 1)) {
+ err("need %d TDs, only have %d", size, N_URB_TD);
+ return -1;
+ }
+ purb_priv = &urb_priv;
+ purb_priv->pipe = pipe;
+
+ /* fill the private part of the URB */
+ purb_priv->length = size;
+ purb_priv->ed = ed;
+ purb_priv->actual_length = 0;
+
+ /* allocate the TDs */
+ /* note that td[0] was allocated in ep_add_ed */
+ for (i = 0; i < size; i++) {
+ purb_priv->td[i] = td_alloc (dev);
+ if (!purb_priv->td[i]) {
+ purb_priv->length = i;
+ urb_free_priv (purb_priv);
+ err("sohci_submit_job: ENOMEM");
+ return -1;
+ }
+ }
+
+ if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
+ urb_free_priv (purb_priv);
+ err("sohci_submit_job: EINVAL");
+ return -1;
+ }
+
+ /* link the ed into a chain if is not already */
+ if (ed->state != ED_OPER)
+ ep_link (ohci, ed);
+
+ /* fill the TDs and link it to the ed */
+ td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+/* tell us the current USB frame number */
+
+static int sohci_get_current_frame_number (struct usb_device *usb_dev)
+{
+ ohci_t *ohci = &gohci;
+
+ return ohci_cpu_to_le16 (ohci->hcca->frame_no);
+}
+#endif
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* link an ed into one of the HC chains */
+
+static int ep_link (ohci_t *ohci, ed_t *edi)
+{
+ volatile ed_t *ed = edi;
+
+ ed->state = ED_OPER;
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ ed->hwNextED = 0;
+ if (ohci->ed_controltail == NULL) {
+ writel (ed, &ohci->regs->ed_controlhead);
+ } else {
+ ohci->ed_controltail->hwNextED = ohci_cpu_to_le32 (ed);
+ }
+ ed->ed_prev = ohci->ed_controltail;
+ if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_controltail = edi;
+ break;
+
+ case PIPE_BULK:
+ ed->hwNextED = 0;
+ if (ohci->ed_bulktail == NULL) {
+ writel (ed, &ohci->regs->ed_bulkhead);
+ } else {
+ ohci->ed_bulktail->hwNextED = ohci_cpu_to_le32 (ed);
+ }
+ ed->ed_prev = ohci->ed_bulktail;
+ if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_bulktail = edi;
+ break;
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* unlink an ed from one of the HC chains.
+ * just the link to the ed is unlinked.
+ * the link from the ed still points to another operational ed or 0
+ * so the HC can eventually finish the processing of the unlinked ed */
+
+static int ep_unlink (ohci_t *ohci, ed_t *edi)
+{
+ volatile ed_t *ed = edi;
+
+ ed->hwINFO |= ohci_cpu_to_le32 (OHCI_ED_SKIP);
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_controltail == ed) {
+ ohci->ed_controltail = ed->ed_prev;
+ } else {
+ ((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+
+ case PIPE_BULK:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_bulktail == ed) {
+ ohci->ed_bulktail = ed->ed_prev;
+ } else {
+ ((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+ }
+ ed->state = ED_UNLINK;
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* add/reinit an endpoint; this should be done once at the usb_set_configuration command,
+ * but the USB stack is a little bit stateless so we do it at every transaction
+ * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK
+ * in all other cases the state is left unchanged
+ * the ed info fields are setted anyway even though most of them should not change */
+
+static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
+{
+ td_t *td;
+ ed_t *ed_ret;
+ volatile ed_t *ed;
+
+ ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) |
+ (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))];
+
+ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
+ err("ep_add_ed: pending delete");
+ /* pending delete request */
+ return NULL;
+ }
+
+ if (ed->state == ED_NEW) {
+ ed->hwINFO = ohci_cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */
+ /* dummy td; end of td list for ed */
+ td = td_alloc (usb_dev);
+ ed->hwTailP = ohci_cpu_to_le32 (td);
+ ed->hwHeadP = ed->hwTailP;
+ ed->state = ED_UNLINK;
+ ed->type = usb_pipetype (pipe);
+ ohci_dev.ed_cnt++;
+ }
+
+ ed->hwINFO = ohci_cpu_to_le32 (usb_pipedevice (pipe)
+ | usb_pipeendpoint (pipe) << 7
+ | (usb_pipeisoc (pipe)? 0x8000: 0)
+ | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
+ | usb_pipeslow (pipe) << 13
+ | usb_maxpacket (usb_dev, pipe) << 16);
+
+ return ed_ret;
+}
+
+/*-------------------------------------------------------------------------*
+ * TD handling functions
+ *-------------------------------------------------------------------------*/
+
+/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
+
+static void td_fill (ohci_t *ohci, unsigned int info,
+ void *data, int len,
+ struct usb_device *dev, int index, urb_priv_t *urb_priv)
+{
+ volatile td_t *td, *td_pt;
+#ifdef OHCI_FILL_TRACE
+ int i;
+#endif
+
+ if (index > urb_priv->length) {
+ err("index > length");
+ return;
+ }
+ /* use this td as the next dummy */
+ td_pt = urb_priv->td [index];
+ td_pt->hwNextTD = 0;
+
+ /* fill the old dummy TD */
+ td = urb_priv->td [index] = (td_t *)(ohci_cpu_to_le32 (urb_priv->ed->hwTailP) & ~0xf);
+
+ td->ed = urb_priv->ed;
+ td->next_dl_td = NULL;
+ td->index = index;
+ td->data = (__u32)data;
+#ifdef OHCI_FILL_TRACE
+ if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) {
+ for (i = 0; i < len; i++)
+ printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]);
+ printf("\n");
+ }
+#endif
+ if (!len)
+ data = 0;
+
+ td->hwINFO = ohci_cpu_to_le32 (info);
+ td->hwCBP = ohci_cpu_to_le32 (data);
+ if (data)
+ td->hwBE = ohci_cpu_to_le32 (data + len - 1);
+ else
+ td->hwBE = 0;
+ td->hwNextTD = ohci_cpu_to_le32 (td_pt);
+ td->hwPSW [0] = ohci_cpu_to_le16 (((__u32)data & 0x0FFF) | 0xE000);
+
+ /* append to queue */
+ td->ed->hwTailP = td->hwNextTD;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* prepare all TDs of a transfer */
+
+static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
+{
+ ohci_t *ohci = &gohci;
+ int data_len = transfer_len;
+ void *data;
+ int cnt = 0;
+ __u32 info = 0;
+ unsigned int toggle = 0;
+
+ /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
+ if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
+ toggle = TD_T_TOGGLE;
+ } else {
+ toggle = TD_T_DATA0;
+ usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
+ }
+ urb->td_cnt = 0;
+ if (data_len)
+ data = buffer;
+ else
+ data = 0;
+
+ switch (usb_pipetype (pipe)) {
+ case PIPE_BULK:
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
+ while(data_len > 4096) {
+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb);
+ data += 4096; data_len -= 4096; cnt++;
+ }
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb);
+ cnt++;
+
+ if (!ohci->sleeping)
+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
+ break;
+
+ case PIPE_CONTROL:
+ info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
+ td_fill (ohci, info, setup, 8, dev, cnt++, urb);
+ if (data_len > 0) {
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
+ /* NOTE: mishandles transfers >8K, some >4K */
+ td_fill (ohci, info, data, data_len, dev, cnt++, urb);
+ }
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
+ td_fill (ohci, info, data, 0, dev, cnt++, urb);
+ if (!ohci->sleeping)
+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
+ break;
+ }
+ if (urb->length != cnt)
+ dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
+}
+
+/*-------------------------------------------------------------------------*
+ * Done List handling functions
+ *-------------------------------------------------------------------------*/
+
+
+/* calculate the transfer length and update the urb */
+
+static void dl_transfer_length(td_t * td)
+{
+ __u32 tdINFO, tdBE, tdCBP;
+ urb_priv_t *lurb_priv = &urb_priv;
+
+ tdINFO = ohci_cpu_to_le32 (td->hwINFO);
+ tdBE = ohci_cpu_to_le32 (td->hwBE);
+ tdCBP = ohci_cpu_to_le32 (td->hwCBP);
+
+
+ if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL &&
+ ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
+ if (tdBE != 0) {
+ if (td->hwCBP == 0)
+ lurb_priv->actual_length += tdBE - td->data + 1;
+ else
+ lurb_priv->actual_length += tdCBP - td->data;
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* replies to the request have to be on a FIFO basis so
+ * we reverse the reversed done-list */
+
+static td_t * dl_reverse_done_list (ohci_t *ohci)
+{
+ __u32 td_list_hc;
+ td_t *td_rev = NULL;
+ td_t *td_list = NULL;
+ urb_priv_t *lurb_priv = NULL;
+
+ td_list_hc = ohci_cpu_to_le32 (ohci->hcca->done_head) & 0xfffffff0;
+ ohci->hcca->done_head = 0;
+
+ while (td_list_hc) {
+ td_list = (td_t *)td_list_hc;
+
+ if (TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO))) {
+ lurb_priv = &urb_priv;
+ dbg(" USB-error/status: %x : %p",
+ TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO)), td_list);
+ if (td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x1)) {
+ if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
+ td_list->ed->hwHeadP =
+ (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & ohci_cpu_to_le32 (0xfffffff0)) |
+ (td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x2));
+ lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
+ } else
+ td_list->ed->hwHeadP &= ohci_cpu_to_le32 (0xfffffff2);
+ }
+#ifdef CONFIG_MPC5200
+ td_list->hwNextTD = 0;
+#endif
+ }
+
+ td_list->next_dl_td = td_rev;
+ td_rev = td_list;
+ td_list_hc = ohci_cpu_to_le32 (td_list->hwNextTD) & 0xfffffff0;
+ }
+ return td_list;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* td done list */
+static int dl_done_list (ohci_t *ohci, td_t *td_list)
+{
+ td_t *td_list_next = NULL;
+ ed_t *ed;
+ int cc = 0;
+ int stat = 0xff;
+ /* urb_t *urb; */
+ urb_priv_t *lurb_priv;
+ __u32 tdINFO, edHeadP, edTailP;
+
+ while (td_list) {
+ td_list_next = td_list->next_dl_td;
+
+ lurb_priv = &urb_priv;
+ tdINFO = ohci_cpu_to_le32 (td_list->hwINFO);
+
+ ed = td_list->ed;
+
+ dl_transfer_length(td_list);
+
+ /* error code of transfer */
+ cc = TD_CC_GET (tdINFO);
+ if (++(lurb_priv->td_cnt) == lurb_priv->length) {
+ if ((ed->state & (ED_OPER | ED_UNLINK))
+ && (lurb_priv->state != URB_DEL)) {
+ dbg("ConditionCode %#x", cc);
+ stat = cc_to_error[cc];
+ }
+ }
+
+ if (ed->state != ED_NEW) {
+ edHeadP = ohci_cpu_to_le32 (ed->hwHeadP) & 0xfffffff0;
+ edTailP = ohci_cpu_to_le32 (ed->hwTailP);
+
+ /* unlink eds if they are not busy */
+ if ((edHeadP == edTailP) && (ed->state == ED_OPER))
+ ep_unlink (ohci, ed);
+ }
+
+ td_list = td_list_next;
+ }
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*
+ * Virtual Root Hub
+ *-------------------------------------------------------------------------*/
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] =
+{
+ 0x12, /* __u8 bLength; */
+ 0x01, /* __u8 bDescriptorType; Device */
+ 0x10, /* __u16 bcdUSB; v1.1 */
+ 0x01,
+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 bDeviceSubClass; */
+ 0x00, /* __u8 bDeviceProtocol; */
+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x00, /* __u16 idVendor; */
+ 0x00,
+ 0x00, /* __u16 idProduct; */
+ 0x00,
+ 0x00, /* __u16 bcdDevice; */
+ 0x00,
+ 0x00, /* __u8 iManufacturer; */
+ 0x01, /* __u8 iProduct; */
+ 0x00, /* __u8 iSerialNumber; */
+ 0x01 /* __u8 bNumConfigurations; */
+};
+
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] =
+{
+ 0x09, /* __u8 bLength; */
+ 0x02, /* __u8 bDescriptorType; Configuration */
+ 0x19, /* __u16 wTotalLength; */
+ 0x00,
+ 0x01, /* __u8 bNumInterfaces; */
+ 0x01, /* __u8 bConfigurationValue; */
+ 0x00, /* __u8 iConfiguration; */
+ 0x40, /* __u8 bmAttributes;
+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+ 0x00, /* __u8 MaxPower; */
+
+ /* interface */
+ 0x09, /* __u8 if_bLength; */
+ 0x04, /* __u8 if_bDescriptorType; Interface */
+ 0x00, /* __u8 if_bInterfaceNumber; */
+ 0x00, /* __u8 if_bAlternateSetting; */
+ 0x01, /* __u8 if_bNumEndpoints; */
+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 if_bInterfaceSubClass; */
+ 0x00, /* __u8 if_bInterfaceProtocol; */
+ 0x00, /* __u8 if_iInterface; */
+
+ /* endpoint */
+ 0x07, /* __u8 ep_bLength; */
+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
+ 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+ 0x00,
+ 0xff /* __u8 ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] =
+{
+ 0x04, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 0x09, /* __u8 lang ID */
+ 0x04, /* __u8 lang ID */
+};
+
+static unsigned char root_hub_str_index1[] =
+{
+ 28, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 'O', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'C', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'I', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'R', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 't', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'u', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'b', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+};
+
+/* Hub class-specific descriptor is constructed dynamically */
+
+
+/*-------------------------------------------------------------------------*/
+
+#define OK(x) len = (x); break
+#ifdef DEBUG
+#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
+#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
+#else
+#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status)
+#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
+#endif
+#define RD_RH_STAT roothub_status(&gohci)
+#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1)
+
+/* request to virtual root hub */
+
+int rh_check_port_status(ohci_t *controller)
+{
+ __u32 temp, ndp, i;
+ int res;
+
+ res = -1;
+ temp = roothub_a (controller);
+ ndp = (temp & RH_A_NDP);
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus (controller, i);
+ /* check for a device disconnect */
+ if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+ (RH_PS_PESC | RH_PS_CSC)) &&
+ ((temp & RH_PS_CCS) == 0)) {
+ res = i;
+ break;
+ }
+ }
+ return res;
+}
+
+static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len, struct devrequest *cmd)
+{
+ void * data = buffer;
+ int leni = transfer_len;
+ int len = 0;
+ int stat = 0;
+ __u32 datab[4];
+ __u8 *data_buf = (__u8 *)datab;
+ __u16 bmRType_bReq;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+
+#ifdef DEBUG
+urb_priv.actual_length = 0;
+pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
+#endif
+ if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+ info("Root-Hub submit IRQ: NOT implemented");
+ return 0;
+ }
+
+ bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+ wValue = m16_swap (cmd->value);
+ wIndex = m16_swap (cmd->index);
+ wLength = m16_swap (cmd->length);
+
+ info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
+ dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
+
+ switch (bmRType_bReq) {
+ /* Request Destination:
+ without flags: Device,
+ RH_INTERFACE: interface,
+ RH_ENDPOINT: endpoint,
+ RH_CLASS means HUB here,
+ RH_OTHER | RH_CLASS almost ever means HUB_PORT here
+ */
+
+ case RH_GET_STATUS:
+ *(__u16 *) data_buf = m16_swap (1); OK (2);
+ case RH_GET_STATUS | RH_INTERFACE:
+ *(__u16 *) data_buf = m16_swap (0); OK (2);
+ case RH_GET_STATUS | RH_ENDPOINT:
+ *(__u16 *) data_buf = m16_swap (0); OK (2);
+ case RH_GET_STATUS | RH_CLASS:
+ *(__u32 *) data_buf = m32_swap (
+ RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
+ OK (4);
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+ *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4);
+
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ switch (wValue) {
+ case (RH_ENDPOINT_STALL): OK (0);
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ switch (wValue) {
+ case RH_C_HUB_LOCAL_POWER:
+ OK(0);
+ case (RH_C_HUB_OVER_CURRENT):
+ WR_RH_STAT(RH_HS_OCIC); OK (0);
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case (RH_PORT_ENABLE):
+ WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
+ case (RH_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
+ case (RH_PORT_POWER):
+ WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
+ case (RH_C_PORT_CONNECTION):
+ WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
+ case (RH_C_PORT_ENABLE):
+ WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
+ case (RH_C_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
+ case (RH_C_PORT_OVER_CURRENT):
+ WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
+ case (RH_C_PORT_RESET):
+ WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
+ }
+ break;
+
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case (RH_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
+ case (RH_PORT_RESET): /* BUG IN HUP CODE *********/
+ if (RD_RH_PORTSTAT & RH_PS_CCS)
+ WR_RH_PORTSTAT (RH_PS_PRS);
+ OK (0);
+ case (RH_PORT_POWER):
+ WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
+ case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
+ if (RD_RH_PORTSTAT & RH_PS_CCS)
+ WR_RH_PORTSTAT (RH_PS_PES );
+ OK (0);
+ }
+ break;
+
+ case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);
+
+ case RH_GET_DESCRIPTOR:
+ switch ((wValue & 0xff00) >> 8) {
+ case (0x01): /* device descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_dev_des),
+ wLength));
+ data_buf = root_hub_dev_des; OK(len);
+ case (0x02): /* configuration descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_config_des),
+ wLength));
+ data_buf = root_hub_config_des; OK(len);
+ case (0x03): /* string descriptors */
+ if(wValue==0x0300) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_str_index0),
+ wLength));
+ data_buf = root_hub_str_index0;
+ OK(len);
+ }
+ if(wValue==0x0301) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_str_index1),
+ wLength));
+ data_buf = root_hub_str_index1;
+ OK(len);
+ }
+ default:
+ stat = USB_ST_STALLED;
+ }
+ break;
+
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ {
+ __u32 temp = roothub_a (&gohci);
+
+ data_buf [0] = 9; /* min length; */
+ data_buf [1] = 0x29;
+ data_buf [2] = temp & RH_A_NDP;
+ data_buf [3] = 0;
+ if (temp & RH_A_PSM) /* per-port power switching? */
+ data_buf [3] |= 0x1;
+ if (temp & RH_A_NOCP) /* no overcurrent reporting? */
+ data_buf [3] |= 0x10;
+ else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */
+ data_buf [3] |= 0x8;
+
+ /* corresponds to data_buf[4-7] */
+ datab [1] = 0;
+ data_buf [5] = (temp & RH_A_POTPGT) >> 24;
+ temp = roothub_b (&gohci);
+ data_buf [7] = temp & RH_B_DR;
+ if (data_buf [2] < 7) {
+ data_buf [8] = 0xff;
+ } else {
+ data_buf [0] += 2;
+ data_buf [8] = (temp & RH_B_DR) >> 8;
+ data_buf [10] = data_buf [9] = 0xff;
+ }
+
+ len = min_t(unsigned int, leni,
+ min_t(unsigned int, data_buf [0], wLength));
+ OK (len);
+ }
+
+ case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1);
+
+ case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0);
+
+ default:
+ dbg ("unsupported root hub command");
+ stat = USB_ST_STALLED;
+ }
+
+#ifdef DEBUG
+ ohci_dump_roothub (&gohci, 1);
+#endif
+
+ len = min_t(int, len, leni);
+ if (data != data_buf)
+ memcpy (data, data_buf, len);
+ dev->act_len = len;
+ dev->status = stat;
+
+#ifdef DEBUG
+ if (transfer_len)
+ urb_priv.actual_length = transfer_len;
+ pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
+#endif
+
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* common code for handling submit messages - used for all but root hub */
+/* accesses. */
+int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval)
+{
+ int stat = 0;
+ int maxsize = usb_maxpacket(dev, pipe);
+ int timeout;
+
+ /* device pulled? Shortcut the action. */
+ if (devgone == dev) {
+ dev->status = USB_ST_CRC_ERR;
+ return 0;
+ }
+
+#ifdef DEBUG
+ urb_priv.actual_length = 0;
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#endif
+ if (!maxsize) {
+ err("submit_common_message: pipesize for pipe %lx is zero",
+ pipe);
+ return -1;
+ }
+
+ if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) {
+ err("sohci_submit_job failed");
+ return -1;
+ }
+
+ /* allow more time for a BULK device to react - some are slow */
+#define BULK_TO 5000 /* timeout in milliseconds */
+ if (usb_pipetype (pipe) == PIPE_BULK)
+ timeout = BULK_TO;
+ else
+ timeout = 100;
+
+ /* wait for it to complete */
+ for (;;) {
+ /* check whether the controller is done */
+ stat = hc_interrupt();
+ if (stat < 0) {
+ stat = USB_ST_CRC_ERR;
+ break;
+ }
+ if (stat >= 0 && stat < 0xff) {
+ /* 0xff is returned for an SF-interrupt */
+ break;
+ }
+ if (--timeout) {
+ wait_ms(1);
+ } else {
+ err("CTL:TIMEOUT ");
+ stat = USB_ST_CRC_ERR;
+ break;
+ }
+ }
+ /* we got an Root Hub Status Change interrupt */
+ if (got_rhsc) {
+#ifdef DEBUG
+ ohci_dump_roothub (&gohci, 1);
+#endif
+ got_rhsc = 0;
+ /* abuse timeout */
+ timeout = rh_check_port_status(&gohci);
+ if (timeout >= 0) {
+#if 0 /* this does nothing useful, but leave it here in case that changes */
+ /* the called routine adds 1 to the passed value */
+ usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
+#endif
+ /*
+ * XXX
+ * This is potentially dangerous because it assumes
+ * that only one device is ever plugged in!
+ */
+ devgone = dev;
+ }
+ }
+
+ dev->status = stat;
+ dev->act_len = transfer_len;
+
+#ifdef DEBUG
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
+#endif
+
+ /* free TDs in urb_priv */
+ urb_free_priv (&urb_priv);
+ return 0;
+}
+
+/* submit routines called from usb.c */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len)
+{
+ info("submit_bulk_msg");
+ return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup)
+{
+ int maxsize = usb_maxpacket(dev, pipe);
+
+ info("submit_control_msg");
+#ifdef DEBUG
+ urb_priv.actual_length = 0;
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#endif
+ if (!maxsize) {
+ err("submit_control_message: pipesize for pipe %lx is zero",
+ pipe);
+ return -1;
+ }
+ if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
+ gohci.rh.dev = dev;
+ /* root hub - redirect */
+ return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
+ setup);
+ }
+
+ return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, int interval)
+{
+ info("submit_int_msg");
+ return -1;
+}
+
+/*-------------------------------------------------------------------------*
+ * HC functions
+ *-------------------------------------------------------------------------*/
+
+/* reset the HC and BUS */
+
+static int hc_reset (ohci_t *ohci)
+{
+ int timeout = 30;
+ int smm_timeout = 50; /* 0,5 sec */
+
+ if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
+ writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
+ info("USB HC TakeOver from SMM");
+ while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ wait_ms (10);
+ if (--smm_timeout == 0) {
+ err("USB HC TakeOver failed!");
+ return -1;
+ }
+ }
+ }
+
+ /* Disable HC interrupts */
+ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
+
+ dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;",
+ ohci->slot_name,
+ readl (&ohci->regs->control));
+
+ /* Reset USB (needed by some controllers) */
+ ohci->hc_control = 0;
+ writel (ohci->hc_control, &ohci->regs->control);
+
+ /* HC Reset requires max 10 us delay */
+ writel (OHCI_HCR, &ohci->regs->cmdstatus);
+ while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+ if (--timeout == 0) {
+ err("USB HC reset timed out!");
+ return -1;
+ }
+ udelay (1);
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Start an OHCI controller, set the BUS operational
+ * enable interrupts
+ * connect the virtual root hub */
+
+static int hc_start (ohci_t * ohci)
+{
+ __u32 mask;
+ unsigned int fminterval;
+
+ ohci->disabled = 1;
+
+ /* Tell the controller where the control and bulk lists are
+ * The lists are empty now. */
+
+ writel (0, &ohci->regs->ed_controlhead);
+ writel (0, &ohci->regs->ed_bulkhead);
+
+ writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */
+
+ fminterval = 0x2edf;
+ writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
+ fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
+ writel (fminterval, &ohci->regs->fminterval);
+ writel (0x628, &ohci->regs->lsthresh);
+
+ /* start controller operations */
+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ ohci->disabled = 0;
+ writel (ohci->hc_control, &ohci->regs->control);
+
+ /* disable all interrupts */
+ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
+ OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
+ OHCI_INTR_OC | OHCI_INTR_MIE);
+ writel (mask, &ohci->regs->intrdisable);
+ /* clear all interrupts */
+ mask &= ~OHCI_INTR_MIE;
+ writel (mask, &ohci->regs->intrstatus);
+ /* Choose the interrupts we care about now - but w/o MIE */
+ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+ writel (mask, &ohci->regs->intrenable);
+
+#ifdef OHCI_USE_NPS
+ /* required for AMD-756 and some Mac platforms */
+ writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
+ &ohci->regs->roothub.a);
+ writel (RH_HS_LPSC, &ohci->regs->roothub.status);
+#endif /* OHCI_USE_NPS */
+
+#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
+ /* POTPGT delay is bits 24-31, in 2 ms units. */
+ mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
+
+ /* connect the virtual root hub */
+ ohci->rh.devnum = 0;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* an interrupt happens */
+
+static int
+hc_interrupt (void)
+{
+ ohci_t *ohci = &gohci;
+ struct ohci_regs *regs = ohci->regs;
+ int ints;
+ int stat = -1;
+
+ if ((ohci->hcca->done_head != 0) && !(ohci_cpu_to_le32 (ohci->hcca->done_head) & 0x01)) {
+ ints = OHCI_INTR_WDH;
+ } else {
+ ints = readl (&regs->intrstatus);
+ }
+
+ /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
+
+ if (ints & OHCI_INTR_RHSC) {
+ got_rhsc = 1;
+ }
+
+ if (ints & OHCI_INTR_UE) {
+ ohci->disabled++;
+ err ("OHCI Unrecoverable Error, controller usb-%s disabled",
+ ohci->slot_name);
+ /* e.g. due to PCI Master/Target Abort */
+
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#endif
+ /* FIXME: be optimistic, hope that bug won't repeat often. */
+ /* Make some non-interrupt context restart the controller. */
+ /* Count and limit the retries though; either hardware or */
+ /* software errors can go forever... */
+ hc_reset (ohci);
+ return -1;
+ }
+
+ if (ints & OHCI_INTR_WDH) {
+ writel (OHCI_INTR_WDH, &regs->intrdisable);
+ stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
+ writel (OHCI_INTR_WDH, &regs->intrenable);
+ }
+
+ if (ints & OHCI_INTR_SO) {
+ dbg("USB Schedule overrun\n");
+ writel (OHCI_INTR_SO, &regs->intrenable);
+ stat = -1;
+ }
+
+ /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
+ if (ints & OHCI_INTR_SF) {
+ unsigned int frame = ohci_cpu_to_le16 (ohci->hcca->frame_no) & 1;
+ writel (OHCI_INTR_SF, &regs->intrdisable);
+ if (ohci->ed_rm_list[frame] != NULL)
+ writel (OHCI_INTR_SF, &regs->intrenable);
+ stat = 0xff;
+ }
+
+ writel (ints, &regs->intrstatus);
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+
+/* De-allocate all resources.. */
+
+static void hc_release_ohci (ohci_t *ohci)
+{
+ dbg ("USB HC release ohci usb-%s", ohci->slot_name);
+
+ if (!ohci->disabled)
+ hc_reset (ohci);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * low level initalisation routine, called from usb.c
+ */
+static char ohci_inited = 0;
+
+int usb_lowlevel_init(void)
+{
+
+ /* Set the USB Clock */
+ *(vu_long *)MPC5XXX_CDM_48_FDC = 0x0001bbbb;
+ *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00800000;
+ /* Activate USB port */
+ *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00001000;
+
+ memset (&gohci, 0, sizeof (ohci_t));
+ memset (&urb_priv, 0, sizeof (urb_priv_t));
+
+ /* align the storage */
+ if ((__u32)&ghcca[0] & 0xff) {
+ err("HCCA not aligned!!");
+ return -1;
+ }
+ phcca = &ghcca[0];
+ info("aligned ghcca %p", phcca);
+ memset(&ohci_dev, 0, sizeof(struct ohci_device));
+ if ((__u32)&ohci_dev.ed[0] & 0x7) {
+ err("EDs not aligned!!");
+ return -1;
+ }
+ memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
+ if ((__u32)gtd & 0x7) {
+ err("TDs not aligned!!");
+ return -1;
+ }
+ ptd = gtd;
+ gohci.hcca = phcca;
+ memset (phcca, 0, sizeof (struct ohci_hcca));
+
+ gohci.disabled = 1;
+ gohci.sleeping = 0;
+ gohci.irq = -1;
+ gohci.regs = (struct ohci_regs *)MPC5XXX_USB;
+
+ gohci.flags = 0;
+ gohci.slot_name = "mpc5200";
+
+ if (hc_reset (&gohci) < 0) {
+ hc_release_ohci (&gohci);
+ return -1;
+ }
+
+ if (hc_start (&gohci) < 0) {
+ err ("can't start usb-%s", gohci.slot_name);
+ hc_release_ohci (&gohci);
+ return -1;
+ }
+
+#ifdef DEBUG
+ ohci_dump (&gohci, 1);
+#endif
+ ohci_inited = 1;
+ return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+ /* this gets called really early - before the controller has */
+ /* even been initialized! */
+ if (!ohci_inited)
+ return 0;
+ /* TODO release any interrupts, etc. */
+ /* call hc_release_ohci() here ? */
+ hc_reset (&gohci);
+ return 0;
+}
+
+#endif /* CONFIG_USB_OHCI */
diff --git a/cpu/mpc5xxx/usb_ohci.h b/cpu/mpc5xxx/usb_ohci.h
new file mode 100644
index 0000000..11b361a
--- /dev/null
+++ b/cpu/mpc5xxx/usb_ohci.h
@@ -0,0 +1,424 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
+ *
+ * usb-ohci.h
+ */
+
+
+static int cc_to_error[16] = {
+
+/* mapping of the OHCI CC status to error codes */
+ /* No Error */ 0,
+ /* CRC Error */ USB_ST_CRC_ERR,
+ /* Bit Stuff */ USB_ST_BIT_ERR,
+ /* Data Togg */ USB_ST_CRC_ERR,
+ /* Stall */ USB_ST_STALLED,
+ /* DevNotResp */ -1,
+ /* PIDCheck */ USB_ST_BIT_ERR,
+ /* UnExpPID */ USB_ST_BIT_ERR,
+ /* DataOver */ USB_ST_BUF_ERR,
+ /* DataUnder */ USB_ST_BUF_ERR,
+ /* reservd */ -1,
+ /* reservd */ -1,
+ /* BufferOver */ USB_ST_BUF_ERR,
+ /* BuffUnder */ USB_ST_BUF_ERR,
+ /* Not Access */ -1,
+ /* Not Access */ -1
+};
+
+/* ED States */
+
+#define ED_NEW 0x00
+#define ED_UNLINK 0x01
+#define ED_OPER 0x02
+#define ED_DEL 0x04
+#define ED_URB_DEL 0x08
+
+/* usb_ohci_ed */
+struct ed {
+ __u32 hwINFO;
+ __u32 hwTailP;
+ __u32 hwHeadP;
+ __u32 hwNextED;
+
+ struct ed *ed_prev;
+ __u8 int_period;
+ __u8 int_branch;
+ __u8 int_load;
+ __u8 int_interval;
+ __u8 state;
+ __u8 type;
+ __u16 last_iso;
+ struct ed *ed_rm_list;
+
+ struct usb_device *usb_dev;
+ __u32 unused[3];
+} __attribute((aligned(16)));
+typedef struct ed ed_t;
+
+
+/* TD info field */
+#define TD_CC 0xf0000000
+#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
+#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
+#define TD_EC 0x0C000000
+#define TD_T 0x03000000
+#define TD_T_DATA0 0x02000000
+#define TD_T_DATA1 0x03000000
+#define TD_T_TOGGLE 0x00000000
+#define TD_R 0x00040000
+#define TD_DI 0x00E00000
+#define TD_DI_SET(X) (((X) & 0x07)<< 21)
+#define TD_DP 0x00180000
+#define TD_DP_SETUP 0x00000000
+#define TD_DP_IN 0x00100000
+#define TD_DP_OUT 0x00080000
+
+#define TD_ISO 0x00010000
+#define TD_DEL 0x00020000
+
+/* CC Codes */
+#define TD_CC_NOERROR 0x00
+#define TD_CC_CRC 0x01
+#define TD_CC_BITSTUFFING 0x02
+#define TD_CC_DATATOGGLEM 0x03
+#define TD_CC_STALL 0x04
+#define TD_DEVNOTRESP 0x05
+#define TD_PIDCHECKFAIL 0x06
+#define TD_UNEXPECTEDPID 0x07
+#define TD_DATAOVERRUN 0x08
+#define TD_DATAUNDERRUN 0x09
+#define TD_BUFFEROVERRUN 0x0C
+#define TD_BUFFERUNDERRUN 0x0D
+#define TD_NOTACCESSED 0x0F
+
+
+#define MAXPSW 1
+
+struct td {
+ __u32 hwINFO;
+ __u32 hwCBP; /* Current Buffer Pointer */
+ __u32 hwNextTD; /* Next TD Pointer */
+ __u32 hwBE; /* Memory Buffer End Pointer */
+
+ __u16 hwPSW[MAXPSW];
+ __u8 unused;
+ __u8 index;
+ struct ed *ed;
+ struct td *next_dl_td;
+ struct usb_device *usb_dev;
+ int transfer_len;
+ __u32 data;
+
+ __u32 unused2[2];
+} __attribute((aligned(32)));
+typedef struct td td_t;
+
+#define OHCI_ED_SKIP (1 << 14)
+
+/*
+ * The HCCA (Host Controller Communications Area) is a 256 byte
+ * structure defined in the OHCI spec. that the host controller is
+ * told the base address of. It must be 256-byte aligned.
+ */
+
+#define NUM_INTS 32 /* part of the OHCI standard */
+struct ohci_hcca {
+ __u32 int_table[NUM_INTS]; /* Interrupt ED table */
+#if defined(CONFIG_MPC5200)
+ __u16 pad1; /* set to 0 on each frame_no change */
+ __u16 frame_no; /* current frame number */
+#else
+ __u16 frame_no; /* current frame number */
+ __u16 pad1; /* set to 0 on each frame_no change */
+#endif
+ __u32 done_head; /* info returned for an interrupt */
+ u8 reserved_for_hc[116];
+} __attribute((aligned(256)));
+
+
+/*
+ * Maximum number of root hub ports.
+ */
+#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O
+ * region. This is Memory Mapped I/O. You must use the readl() and
+ * writel() macros defined in asm/io.h to access these!!
+ */
+struct ohci_regs {
+ /* control and status registers */
+ __u32 revision;
+ __u32 control;
+ __u32 cmdstatus;
+ __u32 intrstatus;
+ __u32 intrenable;
+ __u32 intrdisable;
+ /* memory pointers */
+ __u32 hcca;
+ __u32 ed_periodcurrent;
+ __u32 ed_controlhead;
+ __u32 ed_controlcurrent;
+ __u32 ed_bulkhead;
+ __u32 ed_bulkcurrent;
+ __u32 donehead;
+ /* frame counters */
+ __u32 fminterval;
+ __u32 fmremaining;
+ __u32 fmnumber;
+ __u32 periodicstart;
+ __u32 lsthresh;
+ /* Root hub ports */
+ struct ohci_roothub_regs {
+ __u32 a;
+ __u32 b;
+ __u32 status;
+ __u32 portstatus[MAX_ROOT_PORTS];
+ } roothub;
+} __attribute((aligned(32)));
+
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
+#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
+#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
+#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
+#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
+#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
+#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
+#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
+#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+# define OHCI_USB_RESET (0 << 6)
+# define OHCI_USB_RESUME (1 << 6)
+# define OHCI_USB_OPER (2 << 6)
+# define OHCI_USB_SUSPEND (3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR (1 << 0) /* host controller reset */
+#define OHCI_CLF (1 << 1) /* control list filled */
+#define OHCI_BLF (1 << 2) /* bulk list filled */
+#define OHCI_OCR (1 << 3) /* ownership change request */
+#define OHCI_SOC (3 << 16) /* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
+#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
+#define OHCI_INTR_SF (1 << 2) /* start frame */
+#define OHCI_INTR_RD (1 << 3) /* resume detect */
+#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
+#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
+#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
+#define OHCI_INTR_OC (1 << 30) /* ownership change */
+#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
+
+
+/* Virtual Root HUB */
+struct virt_root_hub {
+ int devnum; /* Address of Root Hub endpoint */
+ void *dev; /* was urb */
+ void *int_addr;
+ int send;
+ int interval;
+};
+
+/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
+
+/* destination of request */
+#define RH_INTERFACE 0x01
+#define RH_ENDPOINT 0x02
+#define RH_OTHER 0x03
+
+#define RH_CLASS 0x20
+#define RH_VENDOR 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS 0x0080
+#define RH_CLEAR_FEATURE 0x0100
+#define RH_SET_FEATURE 0x0300
+#define RH_SET_ADDRESS 0x0500
+#define RH_GET_DESCRIPTOR 0x0680
+#define RH_SET_DESCRIPTOR 0x0700
+#define RH_GET_CONFIGURATION 0x0880
+#define RH_SET_CONFIGURATION 0x0900
+#define RH_GET_STATE 0x0280
+#define RH_GET_INTERFACE 0x0A80
+#define RH_SET_INTERFACE 0x0B00
+#define RH_SYNC_FRAME 0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP 0x2000
+
+
+/* Hub port features */
+#define RH_PORT_CONNECTION 0x00
+#define RH_PORT_ENABLE 0x01
+#define RH_PORT_SUSPEND 0x02
+#define RH_PORT_OVER_CURRENT 0x03
+#define RH_PORT_RESET 0x04
+#define RH_PORT_POWER 0x08
+#define RH_PORT_LOW_SPEED 0x09
+
+#define RH_C_PORT_CONNECTION 0x10
+#define RH_C_PORT_ENABLE 0x11
+#define RH_C_PORT_SUSPEND 0x12
+#define RH_C_PORT_OVER_CURRENT 0x13
+#define RH_C_PORT_RESET 0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER 0x00
+#define RH_C_HUB_OVER_CURRENT 0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP 0x00
+#define RH_ENDPOINT_STALL 0x01
+
+#define RH_ACK 0x01
+#define RH_REQ_ERR -1
+#define RH_NACK 0x00
+
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS 0x00000001 /* current connect status */
+#define RH_PS_PES 0x00000002 /* port enable status*/
+#define RH_PS_PSS 0x00000004 /* port suspend status */
+#define RH_PS_POCI 0x00000008 /* port over current indicator */
+#define RH_PS_PRS 0x00000010 /* port reset status */
+#define RH_PS_PPS 0x00000100 /* port power status */
+#define RH_PS_LSDA 0x00000200 /* low speed device attached */
+#define RH_PS_CSC 0x00010000 /* connect status change */
+#define RH_PS_PESC 0x00020000 /* port enable status change */
+#define RH_PS_PSSC 0x00040000 /* port suspend status change */
+#define RH_PS_OCIC 0x00080000 /* over current indicator change */
+#define RH_PS_PRSC 0x00100000 /* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS 0x00000001 /* local power status */
+#define RH_HS_OCI 0x00000002 /* over current indicator */
+#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
+#define RH_HS_LPSC 0x00010000 /* local power status change */
+#define RH_HS_OCIC 0x00020000 /* over current indicator change */
+#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR 0x0000ffff /* device removable flags */
+#define RH_B_PPCM 0xffff0000 /* port power control mask */
+
+/* roothub.a masks */
+#define RH_A_NDP (0xff << 0) /* number of downstream ports */
+#define RH_A_PSM (1 << 8) /* power switching mode */
+#define RH_A_NPS (1 << 9) /* no power switching */
+#define RH_A_DT (1 << 10) /* device type (mbz) */
+#define RH_A_OCPM (1 << 11) /* over current protection mode */
+#define RH_A_NOCP (1 << 12) /* no over current protection */
+#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
+
+/* urb */
+#define N_URB_TD 48
+typedef struct
+{
+ ed_t *ed;
+ __u16 length; /* number of tds associated with this request */
+ __u16 td_cnt; /* number of tds already serviced */
+ int state;
+ unsigned long pipe;
+ int actual_length;
+ td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */
+} urb_priv_t;
+#define URB_DEL 1
+
+/*
+ * This is the full ohci controller description
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs. (Linus)
+ */
+
+
+typedef struct ohci {
+ struct ohci_hcca *hcca; /* hcca */
+ /*dma_addr_t hcca_dma;*/
+
+ int irq;
+ int disabled; /* e.g. got a UE, we're hung */
+ int sleeping;
+ unsigned long flags; /* for HC bugs */
+
+ struct ohci_regs *regs; /* OHCI controller's memory */
+
+ ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */
+ ed_t *ed_bulktail; /* last endpoint of bulk list */
+ ed_t *ed_controltail; /* last endpoint of control list */
+ int intrstatus;
+ __u32 hc_control; /* copy of the hc control reg */
+ struct usb_device *dev[32];
+ struct virt_root_hub rh;
+
+ const char *slot_name;
+} ohci_t;
+
+#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
+
+struct ohci_device {
+ ed_t ed[NUM_EDS];
+ int ed_cnt;
+};
+
+/* hcd */
+/* endpoint */
+static int ep_link(ohci_t * ohci, ed_t * ed);
+static int ep_unlink(ohci_t * ohci, ed_t * ed);
+static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe);
+
+/*-------------------------------------------------------------------------*/
+
+/* we need more TDs than EDs */
+#define NUM_TD 64
+
+/* +1 so we can align the storage */
+td_t gtd[NUM_TD+1];
+/* pointers to aligned storage */
+td_t *ptd;
+
+/* TDs ... */
+static inline struct td *
+td_alloc (struct usb_device *usb_dev)
+{
+ int i;
+ struct td *td;
+
+ td = NULL;
+ for (i = 0; i < NUM_TD; i++)
+ {
+ if (ptd[i].usb_dev == NULL)
+ {
+ td = &ptd[i];
+ td->usb_dev = usb_dev;
+ break;
+ }
+ }
+
+ return td;
+}
+
+static inline void
+ed_free (struct ed *ed)
+{
+ ed->usb_dev = NULL;
+}
diff --git a/doc/README.ns9750dev b/doc/README.ns9750dev
new file mode 100644
index 0000000..2991440
--- /dev/null
+++ b/doc/README.ns9750dev
@@ -0,0 +1,36 @@
+U-Boot Port to the NS9750 DevKit from NetSilicon
+
+1 Overview
+2 Board Configuration
+3 Installation
+
+
+1 Overview
+----------
+
+This port supports these NS9750 features.
+
+o one UART
+
+2 Board Configuration
+---------------------
+
+Switches:
+SW10: 4
+SW11: 6,7
+SW16: 6,7,8
+SW17-SW20: 1
+SW4: 3, 6
+SW 1: 1
+SW2: 4
+SW3: 3
+SW8: 3 (rotated by 180 degree!!!!)
+
+Serial Console is Port B (bottom right port)
+
+3 Installation
+--------------
+
+Have fun,
+--
+Markus Pietrek <mpietrek@fsforth.de>
diff --git a/drivers/ns9750_eth.c b/drivers/ns9750_eth.c
new file mode 100644
index 0000000..067ff8e
--- /dev/null
+++ b/drivers/ns9750_eth.c
@@ -0,0 +1,797 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_eth.c,v 1.2 2004/02/24 14:09:39 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Ethernet driver for the NS9750. Uses DMA Engine with polling
+ * interrupt status. But interrupts are not enabled.
+ * Only one tx buffer descriptor and the RXA buffer descriptor are used
+ * Currently no transmit lockup handling is included. eth_send has a 5s
+ * timeout for sending frames. No retransmits are performed when an
+ * error occurs.
+ * @References: [1] NS9750 Hardware Reference, December 2003
+ * [2] Intel LXT971 Datasheet #249414 Rev. 02
+ * [3] NS7520 Linux Ethernet Driver
+ *
+ * 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> /* NetSendPacket */
+
+#include "ns9750_eth.h" /* for Ethernet and PHY */
+
+#ifdef CONFIG_DRIVER_NS9750_ETHERNET
+
+/* some definition to make transistion to linux easier */
+
+#define NS9750_DRIVER_NAME "eth"
+#define KERN_WARNING "Warning:"
+#define KERN_ERR "Error:"
+#define KERN_INFO "Info:"
+
+#if 0
+# define DEBUG
+#endif
+
+#ifdef DEBUG
+# define printk printf
+
+# define DEBUG_INIT 0x0001
+# define DEBUG_MINOR 0x0002
+# define DEBUG_RX 0x0004
+# define DEBUG_TX 0x0008
+# define DEBUG_INT 0x0010
+# define DEBUG_POLL 0x0020
+# define DEBUG_LINK 0x0040
+# define DEBUG_MII 0x0100
+# define DEBUG_MII_LOW 0x0200
+# define DEBUG_MEM 0x0400
+# define DEBUG_ERROR 0x4000
+# define DEBUG_ERROR_CRIT 0x8000
+
+static int nDebugLvl = DEBUG_ERROR_CRIT;
+
+# define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
+ printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
+# define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
+ printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
+# define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
+ printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
+# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
+ printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
+# define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
+ printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
+# define ASSERT( expr, func ) if( !( expr ) ) { \
+ printf( "Assertion failed! %s:line %d %s\n", \
+ (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
+ func }
+#else /* DEBUG */
+# define printk(...)
+# define DEBUG_ARGS0( FLG, a0 )
+# define DEBUG_ARGS1( FLG, a0, a1 )
+# define DEBUG_ARGS2( FLG, a0, a1, a2 )
+# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
+# define DEBUG_FN( n )
+# define ASSERT(expr, func)
+#endif /* DEBUG */
+
+#define NS9750_MII_NEG_DELAY (5*CFG_HZ) /* in s */
+#define TX_TIMEOUT (5*CFG_HZ) /* in s */
+
+/* @TODO move it to eeprom.h */
+#define FS_EEPROM_AUTONEG_MASK 0x7
+#define FS_EEPROM_AUTONEG_SPEED_MASK 0x1
+#define FS_EEPROM_AUTONEG_SPEED_10 0x0
+#define FS_EEPROM_AUTONEG_SPEED_100 0x1
+#define FS_EEPROM_AUTONEG_DUPLEX_MASK 0x2
+#define FS_EEPROM_AUTONEG_DUPLEX_HALF 0x0
+#define FS_EEPROM_AUTONEG_DUPLEX_FULL 0x2
+#define FS_EEPROM_AUTONEG_ENABLE_MASK 0x4
+#define FS_EEPROM_AUTONEG_DISABLE 0x0
+#define FS_EEPROM_AUTONEG_ENABLE 0x4
+
+/* buffer descriptors taken from [1] p.306 */
+typedef struct
+{
+ unsigned int* punSrc;
+ unsigned int unLen; /* 11 bits */
+ unsigned int* punDest; /* unused */
+ union {
+ unsigned int unReg;
+ struct {
+ unsigned uStatus : 16;
+ unsigned uRes : 12;
+ unsigned uFull : 1;
+ unsigned uEnable : 1;
+ unsigned uInt : 1;
+ unsigned uWrap : 1;
+ } bits;
+ } s;
+} rx_buffer_desc_t;
+
+typedef struct
+{
+ unsigned int* punSrc;
+ unsigned int unLen; /* 10 bits */
+ unsigned int* punDest; /* unused */
+ union {
+ unsigned int unReg; /* only 32bit accesses may done to NS9750
+ * eth engine */
+ struct {
+ unsigned uStatus : 16;
+ unsigned uRes : 12;
+ unsigned uFull : 1;
+ unsigned uLast : 1;
+ unsigned uInt : 1;
+ unsigned uWrap : 1;
+ } bits;
+ } s;
+} tx_buffer_desc_t;
+
+static int ns9750_eth_reset( void );
+
+static void ns9750_link_force( void );
+static void ns9750_link_auto_negotiate( void );
+static void ns9750_link_update_egcr( void );
+static void ns9750_link_print_changed( void );
+
+/* the PHY stuff */
+
+static char ns9750_mii_identify_phy( void );
+static unsigned short ns9750_mii_read( unsigned short uiRegister );
+static void ns9750_mii_write( unsigned short uiRegister, unsigned short uiData );
+static unsigned int ns9750_mii_get_clock_divisor( unsigned int unMaxMDIOClk );
+static unsigned int ns9750_mii_poll_busy( void );
+
+static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
+static unsigned char ucLinkMode = FS_EEPROM_AUTONEG_ENABLE;
+static unsigned int uiLastLinkStatus;
+static PhyType phyDetected = PHY_NONE;
+
+/* we use only one tx buffer descriptor */
+static tx_buffer_desc_t* pTxBufferDesc =
+ (tx_buffer_desc_t*) get_eth_reg_addr( NS9750_ETH_TXBD );
+
+/* we use only one rx buffer descriptor of the 4 */
+static rx_buffer_desc_t aRxBufferDesc[ 4 ];
+
+/***********************************************************************
+ * @Function: eth_init
+ * @Return: -1 on failure otherwise 0
+ * @Descr: Initializes the ethernet engine and uses either FS Forth's default
+ * MAC addr or the one in environment
+ ***********************************************************************/
+
+int eth_init (bd_t * pbis)
+{
+ /* This default MAC Addr is reserved by FS Forth-Systeme for the case of
+ EEPROM failures */
+ unsigned char aucMACAddr[6] = { 0x00, 0x04, 0xf3, 0x00, 0x06, 0x35 };
+ char *pcTmp = getenv ("ethaddr");
+ char *pcEnd;
+ int i;
+
+ DEBUG_FN (DEBUG_INIT);
+
+ /* no need to check for hardware */
+
+ if (!ns9750_eth_reset ())
+ return -1;
+
+ if (pcTmp != NULL)
+ for (i = 0; i < 6; i++) {
+ aucMACAddr[i] =
+ pcTmp ? simple_strtoul (pcTmp, &pcEnd,
+ 16) : 0;
+ pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
+ }
+
+ /* configure ethernet address */
+
+ *get_eth_reg_addr (NS9750_ETH_SA1) =
+ aucMACAddr[5] << 8 | aucMACAddr[4];
+ *get_eth_reg_addr (NS9750_ETH_SA2) =
+ aucMACAddr[3] << 8 | aucMACAddr[2];
+ *get_eth_reg_addr (NS9750_ETH_SA3) =
+ aucMACAddr[1] << 8 | aucMACAddr[0];
+
+ /* enable hardware */
+
+ *get_eth_reg_addr (NS9750_ETH_MAC1) = NS9750_ETH_MAC1_RXEN;
+
+ /* the linux kernel may give packets < 60 bytes, for example arp */
+ *get_eth_reg_addr (NS9750_ETH_MAC2) = NS9750_ETH_MAC2_CRCEN |
+ NS9750_ETH_MAC2_PADEN | NS9750_ETH_MAC2_HUGE;
+
+ /* enable receive and transmit FIFO, use 10/100 Mbps MII */
+ *get_eth_reg_addr (NS9750_ETH_EGCR1) =
+ NS9750_ETH_EGCR1_ETXWM |
+ NS9750_ETH_EGCR1_ERX |
+ NS9750_ETH_EGCR1_ERXDMA |
+ NS9750_ETH_EGCR1_ETX |
+ NS9750_ETH_EGCR1_ETXDMA | NS9750_ETH_EGCR1_ITXA;
+
+ /* prepare DMA descriptors */
+ for (i = 0; i < 4; i++) {
+ aRxBufferDesc[i].punSrc = 0;
+ aRxBufferDesc[i].unLen = 0;
+ aRxBufferDesc[i].s.bits.uWrap = 1;
+ aRxBufferDesc[i].s.bits.uInt = 1;
+ aRxBufferDesc[i].s.bits.uEnable = 0;
+ aRxBufferDesc[i].s.bits.uFull = 0;
+ }
+
+ /* NetRxPackets[ 0 ] is initialized before eth_init is called and never
+ changes. NetRxPackets is 32bit aligned */
+ aRxBufferDesc[0].punSrc = (unsigned int *) NetRxPackets[0];
+ aRxBufferDesc[0].s.bits.uEnable = 1;
+ aRxBufferDesc[0].unLen = 1522; /* as stated in [1] p.307 */
+
+ *get_eth_reg_addr (NS9750_ETH_RXAPTR) =
+ (unsigned int) &aRxBufferDesc[0];
+
+ /* [1] Tab. 221 states less than 5us */
+ *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_ERXINIT;
+ while (!
+ (*get_eth_reg_addr (NS9750_ETH_EGSR) & NS9750_ETH_EGSR_RXINIT))
+ /* wait for finish */
+ udelay (1);
+
+ /* @TODO do we need to clear RXINIT? */
+ *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_ERXINIT;
+
+ *get_eth_reg_addr (NS9750_ETH_RXFREE) = 0x1;
+
+ return 0;
+}
+
+/***********************************************************************
+ * @Function: eth_send
+ * @Return: -1 on timeout otherwise 1
+ * @Descr: sends one frame by DMA
+ ***********************************************************************/
+
+int eth_send (volatile void *pPacket, int nLen)
+{
+ ulong ulTimeout;
+
+ DEBUG_FN (DEBUG_TX);
+
+ /* clear old status values */
+ *get_eth_reg_addr (NS9750_ETH_EINTR) &=
+ *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_TX_MA;
+
+ /* prepare Tx Descriptors */
+
+ pTxBufferDesc->punSrc = (unsigned int *) pPacket; /* pPacket is 32bit
+ * aligned */
+ pTxBufferDesc->unLen = nLen;
+ /* only 32bit accesses allowed. wrap, full, interrupt and enabled to 1 */
+ pTxBufferDesc->s.unReg = 0xf0000000;
+ /* pTxBufferDesc is the first possible buffer descriptor */
+ *get_eth_reg_addr (NS9750_ETH_TXPTR) = 0x0;
+
+ /* enable processor for next frame */
+
+ *get_eth_reg_addr (NS9750_ETH_EGCR2) &= ~NS9750_ETH_EGCR2_TCLER;
+ *get_eth_reg_addr (NS9750_ETH_EGCR2) |= NS9750_ETH_EGCR2_TCLER;
+
+ ulTimeout = get_timer (0);
+
+ DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR,
+ "Waiting for transmission to finish\n");
+ while (!
+ (*get_eth_reg_addr (NS9750_ETH_EINTR) &
+ (NS9750_ETH_EINTR_TXDONE | NS9750_ETH_EINTR_TXERR))) {
+ /* do nothing, wait for completion */
+ if (get_timer (0) - ulTimeout > TX_TIMEOUT) {
+ DEBUG_ARGS0 (DEBUG_TX, "Transmit Timed out\n");
+ return -1;
+ }
+ }
+ DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR, "transmitted...\n");
+
+ return 0;
+}
+
+/***********************************************************************
+ * @Function: eth_rx
+ * @Return: size of last frame in bytes or 0 if no frame available
+ * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
+ * to NetRxPackets[ 0 ].
+ ***********************************************************************/
+
+int eth_rx (void)
+{
+ int nLen = 0;
+ unsigned int unStatus;
+
+ unStatus =
+ *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_RX_MA;
+
+ if (!unStatus)
+ /* no packet available, return immediately */
+ return 0;
+
+ DEBUG_FN (DEBUG_RX);
+
+ /* unLen always < max(nLen) and discard checksum */
+ nLen = (int) aRxBufferDesc[0].unLen - 4;
+
+ /* acknowledge status register */
+ *get_eth_reg_addr (NS9750_ETH_EINTR) = unStatus;
+
+ aRxBufferDesc[0].unLen = 1522;
+ aRxBufferDesc[0].s.bits.uFull = 0;
+
+ /* Buffer A descriptor available again */
+ *get_eth_reg_addr (NS9750_ETH_RXFREE) |= 0x1;
+
+ /* NetReceive may call eth_send. Due to a possible bug of the NS9750 we
+ * have to acknowledge the received frame before sending a new one */
+ if (unStatus & NS9750_ETH_EINTR_RXDONEA)
+ NetReceive (NetRxPackets[0], nLen);
+
+ return nLen;
+}
+
+/***********************************************************************
+ * @Function: eth_halt
+ * @Return: n/a
+ * @Descr: stops the ethernet engine
+ ***********************************************************************/
+
+void eth_halt (void)
+{
+ DEBUG_FN (DEBUG_INIT);
+
+ *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_RXEN;
+ *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~(NS9750_ETH_EGCR1_ERX |
+ NS9750_ETH_EGCR1_ERXDMA |
+ NS9750_ETH_EGCR1_ETX |
+ NS9750_ETH_EGCR1_ETXDMA);
+}
+
+/***********************************************************************
+ * @Function: ns9750_eth_reset
+ * @Return: 0 on failure otherwise 1
+ * @Descr: resets the ethernet interface and the PHY,
+ * performs auto negotiation or fixed modes
+ ***********************************************************************/
+
+static int ns9750_eth_reset (void)
+{
+ DEBUG_FN (DEBUG_MINOR);
+
+ /* Reset MAC */
+ *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_MAC_HRST;
+ udelay (5); /* according to [1], p.322 */
+ *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_MAC_HRST;
+
+ /* reset and initialize PHY */
+
+ *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_SRST;
+
+ /* we don't support hot plugging of PHY, therefore we don't reset
+ phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
+ incorrect the first open
+ may detect the PHY correctly but succeding will fail
+ For reseting the PHY and identifying we have to use the standard
+ MDIO CLOCK value 2.5 MHz only after hardware reset
+ After having identified the PHY we will do faster */
+
+ *get_eth_reg_addr (NS9750_ETH_MCFG) =
+ ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
+
+ /* reset PHY */
+ ns9750_mii_write (PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET);
+ ns9750_mii_write (PHY_COMMON_CTRL, 0);
+
+ /* @TODO check time */
+ udelay (3000); /* [2] p.70 says at least 300us reset recovery time. But
+ go sure, it didn't worked stable at higher timer
+ frequencies under LxNETES-2.x */
+
+ /* MII clock has been setup to default, ns9750_mii_identify_phy should
+ work for all */
+
+ if (!ns9750_mii_identify_phy ()) {
+ printk (KERN_ERR NS9750_DRIVER_NAME
+ ": Unsupported PHY, aborting\n");
+ return 0;
+ }
+
+ /* now take the highest MDIO clock possible after detection */
+ *get_eth_reg_addr (NS9750_ETH_MCFG) =
+ ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
+
+
+ /* PHY has been detected, so there can be no abort reason and we can
+ finish initializing ethernet */
+
+ uiLastLinkStatus = 0xff; /* undefined */
+
+ if ((ucLinkMode & FS_EEPROM_AUTONEG_ENABLE_MASK) ==
+ FS_EEPROM_AUTONEG_DISABLE)
+ /* use parameters defined */
+ ns9750_link_force ();
+ else
+ ns9750_link_auto_negotiate ();
+
+ if (phyDetected == PHY_LXT971A)
+ /* set LED2 to link mode */
+ ns9750_mii_write (PHY_LXT971_LED_CFG,
+ PHY_LXT971_LED_CFG_LINK_ACT <<
+ PHY_LXT971_LED_CFG_SHIFT_LED2);
+
+ return 1;
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_force
+ * @Return: void
+ * @Descr: configures eth and MII to use the link mode defined in
+ * ucLinkMode
+ ***********************************************************************/
+
+static void ns9750_link_force (void)
+{
+ unsigned short uiControl;
+
+ DEBUG_FN (DEBUG_LINK);
+
+ uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
+ uiControl &= ~(PHY_COMMON_CTRL_SPD_MA |
+ PHY_COMMON_CTRL_AUTO_NEG | PHY_COMMON_CTRL_DUPLEX);
+
+ uiLastLinkStatus = 0;
+
+ if ((ucLinkMode & FS_EEPROM_AUTONEG_SPEED_MASK) ==
+ FS_EEPROM_AUTONEG_SPEED_100) {
+ uiControl |= PHY_COMMON_CTRL_SPD_100;
+ uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX;
+ } else
+ uiControl |= PHY_COMMON_CTRL_SPD_10;
+
+ if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) ==
+ FS_EEPROM_AUTONEG_DUPLEX_FULL) {
+ uiControl |= PHY_COMMON_CTRL_DUPLEX;
+ uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE;
+ }
+
+ ns9750_mii_write (PHY_COMMON_CTRL, uiControl);
+
+ ns9750_link_print_changed ();
+ ns9750_link_update_egcr ();
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_auto_negotiate
+ * @Return: void
+ * @Descr: performs auto-negotation of link.
+ ***********************************************************************/
+
+static void ns9750_link_auto_negotiate (void)
+{
+ unsigned long ulStartJiffies;
+ unsigned short uiStatus;
+
+ DEBUG_FN (DEBUG_LINK);
+
+ /* run auto-negotation */
+ /* define what we are capable of */
+ ns9750_mii_write (PHY_COMMON_AUTO_ADV,
+ PHY_COMMON_AUTO_ADV_100BTXFD |
+ PHY_COMMON_AUTO_ADV_100BTX |
+ PHY_COMMON_AUTO_ADV_10BTFD |
+ PHY_COMMON_AUTO_ADV_10BT |
+ PHY_COMMON_AUTO_ADV_802_3);
+ /* start auto-negotiation */
+ ns9750_mii_write (PHY_COMMON_CTRL,
+ PHY_COMMON_CTRL_AUTO_NEG |
+ PHY_COMMON_CTRL_RES_AUTO);
+
+ /* wait for completion */
+
+ ulStartJiffies = get_ticks ();
+ while (get_ticks () < ulStartJiffies + NS9750_MII_NEG_DELAY) {
+ uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
+ if ((uiStatus &
+ (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) ==
+ (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) {
+ /* lucky we are, auto-negotiation succeeded */
+ ns9750_link_print_changed ();
+ ns9750_link_update_egcr ();
+ return;
+ }
+ }
+
+ DEBUG_ARGS0 (DEBUG_LINK, "auto-negotiation timed out\n");
+ /* ignore invalid link settings */
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_update_egcr
+ * @Return: void
+ * @Descr: updates the EGCR and MAC2 link status after mode change or
+ * auto-negotation
+ ***********************************************************************/
+
+static void ns9750_link_update_egcr (void)
+{
+ unsigned int unEGCR;
+ unsigned int unMAC2;
+ unsigned int unIPGT;
+
+ DEBUG_FN (DEBUG_LINK);
+
+ unEGCR = *get_eth_reg_addr (NS9750_ETH_EGCR1);
+ unMAC2 = *get_eth_reg_addr (NS9750_ETH_MAC2);
+ unIPGT = *get_eth_reg_addr (NS9750_ETH_IPGT) & ~NS9750_ETH_IPGT_MA;
+
+ unMAC2 &= ~NS9750_ETH_MAC2_FULLD;
+ if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
+ == PHY_LXT971_STAT2_DUPLEX_MODE) {
+ unMAC2 |= NS9750_ETH_MAC2_FULLD;
+ unIPGT |= 0x15; /* see [1] p. 339 */
+ } else
+ unIPGT |= 0x12; /* see [1] p. 339 */
+
+ *get_eth_reg_addr (NS9750_ETH_MAC2) = unMAC2;
+ *get_eth_reg_addr (NS9750_ETH_EGCR1) = unEGCR;
+ *get_eth_reg_addr (NS9750_ETH_IPGT) = unIPGT;
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_print_changed
+ * @Return: void
+ * @Descr: checks whether the link status has changed and if so prints
+ * the new mode
+ ***********************************************************************/
+
+static void ns9750_link_print_changed (void)
+{
+ unsigned short uiStatus;
+ unsigned short uiControl;
+
+ DEBUG_FN (DEBUG_LINK);
+
+ uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
+
+ if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) ==
+ PHY_COMMON_CTRL_AUTO_NEG) {
+ /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */
+ uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
+
+ if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) {
+ printk (KERN_WARNING NS9750_DRIVER_NAME
+ ": link down\n");
+ /* @TODO Linux: carrier_off */
+ } else {
+ /* @TODO Linux: carrier_on */
+ if (phyDetected == PHY_LXT971A) {
+ uiStatus = ns9750_mii_read (PHY_LXT971_STAT2);
+ uiStatus &= (PHY_LXT971_STAT2_100BTX |
+ PHY_LXT971_STAT2_DUPLEX_MODE |
+ PHY_LXT971_STAT2_AUTO_NEG);
+
+ /* mask out all uninteresting parts */
+ }
+ /* other PHYs must store there link information in
+ uiStatus as PHY_LXT971 */
+ }
+ } else {
+ /* mode has been forced, so uiStatus should be the same as the
+ last link status, enforce printing */
+ uiStatus = uiLastLinkStatus;
+ uiLastLinkStatus = 0xff;
+ }
+
+ if (uiStatus != uiLastLinkStatus) {
+ /* save current link status */
+ uiLastLinkStatus = uiStatus;
+
+ /* print new link status */
+
+ printk (KERN_INFO NS9750_DRIVER_NAME
+ ": link mode %i Mbps %s duplex %s\n",
+ (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
+ (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
+ "half",
+ (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
+ "");
+ }
+}
+
+/***********************************************************************
+ * the MII low level stuff
+ ***********************************************************************/
+
+/***********************************************************************
+ * @Function: ns9750_mii_identify_phy
+ * @Return: 1 if supported PHY has been detected otherwise 0
+ * @Descr: checks for supported PHY and prints the IDs.
+ ***********************************************************************/
+
+static char ns9750_mii_identify_phy (void)
+{
+ unsigned short uiID1;
+ unsigned short uiID2;
+ unsigned char *szName;
+ char cRes = 0;
+
+ DEBUG_FN (DEBUG_MII);
+
+ phyDetected = (PhyType) uiID1 = ns9750_mii_read (PHY_COMMON_ID1);
+
+ switch (phyDetected) {
+ case PHY_LXT971A:
+ szName = "LXT971A";
+ uiID2 = ns9750_mii_read (PHY_COMMON_ID2);
+ nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
+ cRes = 1;
+ break;
+ case PHY_NONE:
+ default:
+ /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
+ address or reset sets the wrong NS9750_ETH_MCFG_CLKS */
+
+ uiID2 = 0;
+ szName = "unknown";
+ nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
+ phyDetected = PHY_NONE;
+ }
+
+ printk (KERN_INFO NS9750_DRIVER_NAME
+ ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
+
+ return cRes;
+}
+
+/***********************************************************************
+ * @Function: ns9750_mii_read
+ * @Return: the data read from PHY register uiRegister
+ * @Descr: the data read may be invalid if timed out. If so, a message
+ * is printed but the invalid data is returned.
+ * The fixed device address is being used.
+ ***********************************************************************/
+
+static unsigned short ns9750_mii_read (unsigned short uiRegister)
+{
+ DEBUG_FN (DEBUG_MII_LOW);
+
+ /* write MII register to be read */
+ *get_eth_reg_addr (NS9750_ETH_MADR) =
+ NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
+
+ *get_eth_reg_addr (NS9750_ETH_MCMD) = NS9750_ETH_MCMD_READ;
+
+ if (!ns9750_mii_poll_busy ())
+ printk (KERN_WARNING NS9750_DRIVER_NAME
+ ": MII still busy in read\n");
+ /* continue to read */
+
+ *get_eth_reg_addr (NS9750_ETH_MCMD) = 0;
+
+ return (unsigned short) (*get_eth_reg_addr (NS9750_ETH_MRDD));
+}
+
+
+/***********************************************************************
+ * @Function: ns9750_mii_write
+ * @Return: nothing
+ * @Descr: writes the data to the PHY register. In case of a timeout,
+ * no special handling is performed but a message printed
+ * The fixed device address is being used.
+ ***********************************************************************/
+
+static void ns9750_mii_write (unsigned short uiRegister,
+ unsigned short uiData)
+{
+ DEBUG_FN (DEBUG_MII_LOW);
+
+ /* write MII register to be written */
+ *get_eth_reg_addr (NS9750_ETH_MADR) =
+ NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
+
+ *get_eth_reg_addr (NS9750_ETH_MWTD) = uiData;
+
+ if (!ns9750_mii_poll_busy ()) {
+ printf (KERN_WARNING NS9750_DRIVER_NAME
+ ": MII still busy in write\n");
+ }
+}
+
+
+/***********************************************************************
+ * @Function: ns9750_mii_get_clock_divisor
+ * @Return: the clock divisor that should be used in NS9750_ETH_MCFG_CLKS
+ * @Descr: if no clock divisor can be calculated for the
+ * current SYSCLK and the maximum MDIO Clock, a warning is printed
+ * and the greatest divisor is taken
+ ***********************************************************************/
+
+static unsigned int ns9750_mii_get_clock_divisor (unsigned int unMaxMDIOClk)
+{
+ struct {
+ unsigned int unSysClkDivisor;
+ unsigned int unClks; /* field for NS9750_ETH_MCFG_CLKS */
+ } PHYClockDivisors[] = {
+ {
+ 4, NS9750_ETH_MCFG_CLKS_4}, {
+ 6, NS9750_ETH_MCFG_CLKS_6}, {
+ 8, NS9750_ETH_MCFG_CLKS_8}, {
+ 10, NS9750_ETH_MCFG_CLKS_10}, {
+ 20, NS9750_ETH_MCFG_CLKS_20}, {
+ 30, NS9750_ETH_MCFG_CLKS_30}, {
+ 40, NS9750_ETH_MCFG_CLKS_40}
+ };
+
+ int nIndexSysClkDiv;
+ int nArraySize =
+ sizeof (PHYClockDivisors) / sizeof (PHYClockDivisors[0]);
+ unsigned int unClks = NS9750_ETH_MCFG_CLKS_40; /* defaults to
+ greatest div */
+
+ DEBUG_FN (DEBUG_INIT);
+
+ for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
+ nIndexSysClkDiv++) {
+ /* find first sysclock divisor that isn't higher than 2.5 MHz
+ clock */
+ if (AHB_CLK_FREQ /
+ PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
+ unMaxMDIOClk) {
+ unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
+ break;
+ }
+ }
+
+ DEBUG_ARGS2 (DEBUG_INIT,
+ "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
+ unClks, unMaxMDIOClk);
+
+ /* return greatest divisor */
+ return unClks;
+}
+
+/***********************************************************************
+ * @Function: ns9750_mii_poll_busy
+ * @Return: 0 if timed out otherwise the remaing timeout
+ * @Descr: waits until the MII has completed a command or it times out
+ * code may be interrupted by hard interrupts.
+ * It is not checked what happens on multiple actions when
+ * the first is still being busy and we timeout.
+ ***********************************************************************/
+
+static unsigned int ns9750_mii_poll_busy (void)
+{
+ unsigned int unTimeout = 10000;
+
+ DEBUG_FN (DEBUG_MII_LOW);
+
+ while (((*get_eth_reg_addr (NS9750_ETH_MIND) & NS9750_ETH_MIND_BUSY)
+ == NS9750_ETH_MIND_BUSY) && unTimeout)
+ unTimeout--;
+
+ return unTimeout;
+}
+
+#endif /* CONFIG_DRIVER_NS9750_ETHERNET */
diff --git a/drivers/ns9750_serial.c b/drivers/ns9750_serial.c
new file mode 100644
index 0000000..aced3da
--- /dev/null
+++ b/drivers/ns9750_serial.c
@@ -0,0 +1,212 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_serial.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Serial driver for the NS9750. Only one UART is supported yet.
+ * @References: [1] NS9750 Hardware Reference/December 2003
+ * @TODO: Implement Character GAP Timer when chip is fixed for PLL bypass
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ***********************************************************************/
+
+#include <common.h>
+
+#ifdef CFG_NS9750_UART
+
+#include "ns9750_bbus.h" /* for GPIOs */
+#include "ns9750_ser.h" /* for serial configuration */
+
+#define CONSOLE CONFIG_CONS_INDEX
+
+static unsigned int calcBitrateRegister( void );
+static unsigned int calcRxCharGapRegister( void );
+
+static char cCharsAvailable; /* Numbers of chars in unCharCache */
+static unsigned int unCharCache; /* unCharCache is only valid if
+ * cCharsAvailable > 0 */
+
+/***********************************************************************
+ * @Function: serial_init
+ * @Return: 0
+ * @Descr: configures GPIOs and UART. Requires BBUS Master Reset turned off
+ ***********************************************************************/
+
+int serial_init( void )
+{
+ unsigned int aunGPIOTxD[] = { 0, 8, 40, 44 };
+ unsigned int aunGPIORxD[] = { 1, 9, 41, 45 };
+
+ cCharsAvailable = 0;
+
+ /* configure TxD and RxD pins for their special function */
+ set_gpio_cfg_reg_val( aunGPIOTxD[ CONSOLE ],
+ NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_OUTPUT );
+ set_gpio_cfg_reg_val( aunGPIORxD[ CONSOLE ],
+ NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_INPUT );
+
+ /* configure serial engine */
+ *get_ser_reg_addr_channel( NS9750_SER_CTRL_A, CONSOLE ) =
+ NS9750_SER_CTRL_A_CE |
+ NS9750_SER_CTRL_A_STOP |
+ NS9750_SER_CTRL_A_WLS_8;
+
+ serial_setbrg();
+
+ *get_ser_reg_addr_channel( NS9750_SER_CTRL_B, CONSOLE ) =
+ NS9750_SER_CTRL_B_RCGT;
+
+ return 0;
+}
+
+/***********************************************************************
+ * @Function: serial_putc
+ * @Return: n/a
+ * @Descr: writes one character to the FIFO. Blocks until FIFO is not full
+ ***********************************************************************/
+
+void serial_putc( const char c )
+{
+ if (c == '\n')
+ serial_putc( '\r' );
+
+ while (!(*get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE) &
+ NS9750_SER_STAT_A_TRDY ) ) {
+ /* do nothing, wait for characters in FIFO sent */
+ }
+
+ *(volatile char*) get_ser_reg_addr_channel( NS9750_SER_FIFO,
+ CONSOLE) = c;
+}
+
+/***********************************************************************
+ * @Function: serial_puts
+ * @Return: n/a
+ * @Descr: writes non-zero string to the FIFO.
+ ***********************************************************************/
+
+void serial_puts( const char *s )
+{
+ while (*s) {
+ serial_putc( *s++ );
+ }
+}
+
+/***********************************************************************
+ * @Function: serial_getc
+ * @Return: the character read
+ * @Descr: performs only 8bit accesses to the FIFO. No error handling
+ ***********************************************************************/
+
+int serial_getc( void )
+{
+ int i;
+
+ while (!serial_tstc() ) {
+ /* do nothing, wait for incoming characters */
+ }
+
+ /* at least one character in unCharCache */
+ i = (int) (unCharCache & 0xff);
+
+ unCharCache >>= 8;
+ cCharsAvailable--;
+
+ return i;
+}
+
+/***********************************************************************
+ * @Function: serial_tstc
+ * @Return: 0 if no input available, otherwise != 0
+ * @Descr: checks for incoming FIFO not empty. Stores the incoming chars in
+ * unCharCache and the numbers of characters in cCharsAvailable
+ ***********************************************************************/
+
+int serial_tstc( void )
+{
+ unsigned int unRegCache;
+
+ if ( cCharsAvailable )
+ return 1;
+
+ unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,CONSOLE );
+ if( unRegCache & NS9750_SER_STAT_A_RBC ) {
+ *get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE ) =
+ NS9750_SER_STAT_A_RBC;
+ unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,
+ CONSOLE );
+ }
+
+ if ( unRegCache & NS9750_SER_STAT_A_RRDY ) {
+ cCharsAvailable = (unRegCache & NS9750_SER_STAT_A_RXFDB_MA)>>20;
+ if ( !cCharsAvailable )
+ cCharsAvailable = 4;
+
+ unCharCache = *get_ser_reg_addr_channel( NS9750_SER_FIFO,
+ CONSOLE );
+ return 1;
+ }
+
+ /* no chars available */
+ return 0;
+}
+
+void serial_setbrg( void )
+{
+ *get_ser_reg_addr_channel( NS9750_SER_BITRATE, CONSOLE ) =
+ calcBitrateRegister();
+ *get_ser_reg_addr_channel( NS9750_SER_RX_CHAR_TIMER, CONSOLE ) =
+ calcRxCharGapRegister();
+}
+
+/***********************************************************************
+ * @Function: calcBitrateRegister
+ * @Return: value for the serial bitrate register
+ * @Descr: register value depends on clock frequency and baudrate
+ ***********************************************************************/
+
+static unsigned int calcBitrateRegister( void )
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ return ( NS9750_SER_BITRATE_EBIT |
+ NS9750_SER_BITRATE_CLKMUX_BCLK |
+ NS9750_SER_BITRATE_TMODE |
+ NS9750_SER_BITRATE_TCDR_16 |
+ NS9750_SER_BITRATE_RCDR_16 |
+ ( ( ( ( CONFIG_SYS_CLK_FREQ / 8 ) / /* BBUS clock,[1] Fig. 38 */
+ ( gd->baudrate * 16 ) ) - 1 ) &
+ NS9750_SER_BITRATE_N_MA ) );
+}
+
+/***********************************************************************
+ * @Function: calcRxCharGapRegister
+ * @Return: value for the character gap timer register
+ * @Descr: register value depends on clock frequency and baudrate. Currently 0
+ * is used as there is a bug with the gap timer in PLL bypass mode.
+ ***********************************************************************/
+
+static unsigned int calcRxCharGapRegister( void )
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ return NS9750_SER_RX_CHAR_TIMER_TRUN;
+}
+
+#endif /* CFG_NS9750_UART */
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index daa7034..6f1e57c 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -89,7 +89,8 @@ fat_register_device(block_dev_desc_t *dev_desc, int part_no)
part_offset=0;
}
else {
-#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)
+#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) || \
+ (CONFIG_COMMANDS & CFG_CMD_USB)
disk_partition_t info;
if(!get_partition_info(dev_desc, part_no, &info)) {
part_offset = info.start;
diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h
index 888b165..1dc9925 100644
--- a/include/configs/IceCube.h
+++ b/include/configs/IceCube.h
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2003
+ * (C) Copyright 2003-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -81,11 +81,22 @@
#endif
+/* USB */
+#if 1
+#define CONFIG_USB_OHCI
+#define ADD_USB_CMD CFG_CMD_USB | CFG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+#define CONFIG_USB_STORAGE
+#else
+#define ADD_USB_CMD 0
+#endif
+
/*
* Supported commands
*/
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | ADD_PCI_CMD | \
- CFG_CMD_I2C | CFG_CMD_EEPROM)
+ CFG_CMD_I2C | CFG_CMD_EEPROM | \
+ ADD_USB_CMD)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
diff --git a/include/configs/eXalion.h b/include/configs/eXalion.h
new file mode 100644
index 0000000..5ebc7a9
--- /dev/null
+++ b/include/configs/eXalion.h
@@ -0,0 +1,454 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+/* #define CONFIG_MPC8240 1 */
+#define CONFIG_MPC8245 1
+#define CONFIG_EXALION 1
+
+#if defined (CONFIG_MPC8240)
+ /* #warning ---------- eXalion with MPC8240 --------------- */
+#elif defined (CONFIG_MPC8245)
+ /* #warning ++++++++++ eXalion with MPC8245 +++++++++++++++ */
+#elif defined (CONFIG_MPC8245) && defined (CONFIG_MPC8245)
+#error #### Both types of MPC824x defined (CONFIG_8240 and CONFIG_8245)
+#else
+#error #### Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+/* older kernels need clock in MHz newer in Hz */
+ /* #define CONFIG_CLOCKS_IN_MHZ 1 *//* clocks passsed to Linux in MHz */
+#undef CONFIG_CLOCKS_IN_MHZ
+
+#define CONFIG_BOOTDELAY 10
+
+
+ /*#define CONFIG_DRAM_SPEED 66 *//* MHz */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_FLASH | \
+ CFG_CMD_SDRAM | \
+ CFG_CMD_I2C | \
+ CFG_CMD_IDE | \
+ CFG_CMD_FAT | \
+ CFG_CMD_ENV | \
+ CFG_CMD_PCI )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+/*-----------------------------------------------------------------------
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP 1 /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 8 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_MISC_INIT_R 1
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_MAX_RAM_SIZE 0x10000000 /* 1 GBytes - initdram() will */
+ /* return real value. */
+
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#undef CFG_RAMBOOT
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_MONITOR_BASE TEXT_BASE
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_DATA_SIZE 128
+
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
+
+#define CFG_GBL_DATA_SIZE 256 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+#if defined (CONFIG_MPC8240)
+#define CFG_FLASH_BASE 0xFFE00000
+#define CFG_FLASH_SIZE (2 * 1024 * 1024) /* onboard 2MByte flash */
+#elif defined (CONFIG_MPC8245)
+#define CFG_FLASH_BASE 0xFFC00000
+#define CFG_FLASH_SIZE (4 * 1024 * 1024) /* onboard 4MByte flash */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_SECT_SIZE 0x20000 /* Size of one Flash sector */
+#define CFG_ENV_SIZE CFG_ENV_SECT_SIZE /* Use one Flash sector for enviroment */
+#define CFG_ENV_ADDR 0xFFFC0000
+#define CFG_ENV_OFFSET 0 /* starting right at the beginning */
+
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+#define CFG_ALT_MEMTEST 1 /* use real memory test */
+#define CFG_MEMTEST_START 0x00004000 /* memtest works on */
+#define CFG_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+/* #define CFG_ISA_MEM 0xFD000000 */
+#define CFG_ISA_IO 0xFE000000
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* Max number of flash banks */
+#define CFG_MAX_FLASH_SECT 64 /* Max number of sectors per flash */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define FLASH_BASE0_PRELIM CFG_FLASH_BASE
+#define FLASH_BASE1_PRELIM 0
+
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+
+#define CFG_FLASH_CFI 1 /* Flash is CFI conformant */
+#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */
+#define CFG_MAX_FLASH_SECT 64 /* max number of sectors on one chip */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_FLASH_INCREMENT 0 /* there is only one bank */
+#define CFG_FLASH_PROTECTION 1 /* use hardware protection */
+#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */
+
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ */
+#define CONFIG_PCI 1 /* include pci support */
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI 1 /* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100 1
+
+#define PCI_ENET0_MEMADDR 0x80000000 /* Intel 82559ER */
+#define PCI_ENET0_IOADDR 0x80000000
+#define PCI_ENET1_MEMADDR 0x81000000 /* Intel 82559ER */
+#define PCI_ENET1_IOADDR 0x81000000
+#define PCI_ENET2_MEMADDR 0x82000000 /* Broadcom BCM569xx */
+#define PCI_ENET2_IOADDR 0x82000000
+#define PCI_ENET3_MEMADDR 0x83000000 /* Broadcom BCM56xx */
+#define PCI_ENET3_IOADDR 0x83000000
+
+/*-----------------------------------------------------------------------
+ * NS16550 Configuration
+ */
+#define CFG_NS16550 1
+#define CFG_NS16550_SERIAL 1
+
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 38400
+
+#define CFG_NS16550_REG_SIZE 1
+
+#if (CONFIG_CONS_INDEX == 1)
+#define CFG_NS16550_CLK 1843200 /* COM1 only ! */
+#else
+#define CFG_NS16550_CLK ({ extern ulong get_bus_freq (ulong); get_bus_freq (0); })
+#endif
+
+#define CFG_NS16550_COM1 (CFG_ISA_IO + 0x3F8)
+#define CFG_NS16550_COM2 (CFG_EUMB_ADDR + 0x4500)
+#define CFG_NS16550_COM3 (CFG_EUMB_ADDR + 0x4600)
+
+/*-----------------------------------------------------------------------
+ * select i2c support configuration
+ *
+ * Supported configurations are {none, software, hardware} drivers.
+ * If the software driver is chosen, there are some additional
+ * configuration items that the driver uses to drive the port pins.
+ */
+#define CONFIG_HARD_I2C 1 /* To enable I2C support */
+#undef CONFIG_SOFT_I2C /* I2C bit-banged */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+/*-----------------------------------------------------------------------
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+#define CFG_HZ 1000
+
+#define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER 2 /* for MPC8240 only */
+
+ /*#define CONFIG_133MHZ_DRAM 1 *//* For 133 MHZ DRAM only !!!!!!!!!!! */
+
+#if defined (CONFIG_MPC8245)
+/* Bit-field values for PMCR2. */
+#if defined (CONFIG_133MHZ_DRAM)
+#define CFG_DLL_EXTEND 0x80 /* use DLL extended range - 133MHz only */
+#define CFG_PCI_HOLD_DEL 0x20 /* delay and hold timing - 133MHz only */
+#endif
+
+/* Bit-field values for MIOCR1. */
+#if !defined (CONFIG_133MHZ_DRAM)
+#define CFG_DLL_MAX_DELAY 0x04 /* longer DLL delay line - 66MHz only */
+#endif
+/* Bit-field values for MIOCR2. */
+#define CFG_SDRAM_DSCD 0x20 /* SDRAM data in sample clock delay */
+ /* - note bottom 3 bits MUST be 0 */
+#endif
+
+/* Bit-field values for MCCR1. */
+#define CFG_ROMNAL 7 /*rom/flash next access time */
+#define CFG_ROMFAL 11 /*rom/flash access time */
+
+/* Bit-field values for MCCR2. */
+#define CFG_TSWAIT 0x5 /* Transaction Start Wait States timer */
+#if defined (CONFIG_133MHZ_DRAM)
+#define CFG_REFINT 1300 /* no of clock cycles between CBR */
+#else /* refresh cycles */
+#define CFG_REFINT 750
+#endif
+
+/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4. */
+#if defined (CONFIG_133MHZ_DRAM)
+#define CFG_BSTOPRE 1023
+#else
+#define CFG_BSTOPRE 250
+#endif
+
+/* Bit-field values for MCCR3. */
+/* the following are for SDRAM only */
+
+#if defined (CONFIG_133MHZ_DRAM)
+#define CFG_REFREC 9 /* Refresh to activate interval */
+#else
+#define CFG_REFREC 5 /* Refresh to activate interval */
+#endif
+#if defined (CONFIG_MPC8240)
+#define CFG_RDLAT 2 /* data latency from read command */
+#endif
+
+/* Bit-field values for MCCR4. */
+#if defined (CONFIG_133MHZ_DRAM)
+#define CFG_PRETOACT 3 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 7 /* Activate to Precharge interval */
+#define CFG_ACTORW 5 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latency */
+#else
+#if 0
+#define CFG_PRETOACT 2 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 3 /* Activate to Precharge interval */
+#define CFG_ACTORW 3 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 2 /* SDMODE CAS latency */
+#endif
+#define CFG_PRETOACT 2 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */
+#define CFG_ACTORW 3 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latency */
+#endif
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length 2=4, 3=8 */
+#define CFG_REGDIMM 0
+#if defined (CONFIG_MPC8240)
+#define CFG_REGISTERD_TYPE_BUFFER 0
+#elif defined (CONFIG_MPC8245)
+#define CFG_REGISTERD_TYPE_BUFFER 1
+#define CFG_EXTROM 0
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+
+/*-----------------------------------------------------------------------
+ memory bank settings
+ * only bits 20-29 are actually used from these vales to set the
+ * start/end address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x3ff00000
+#define CFG_BANK1_END 0x3fffffff
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x3ff00000
+#define CFG_BANK2_END 0x3fffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x3ff00000
+#define CFG_BANK3_END 0x3fffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x00000000
+#define CFG_BANK4_END 0x00000000
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x00000000
+#define CFG_BANK5_END 0x00000000
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x00000000
+#define CFG_BANK6_END 0x00000000
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x00000000
+#define CFG_BANK7_END 0x00000000
+#define CFG_BANK7_ENABLE 0
+
+/*-----------------------------------------------------------------------
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE 0x01
+
+#if defined (CONFIG_MPC8240)
+#define CFG_ODCR 0xDF /* configures line driver impedances, */
+ /* see 8240 book for bit definitions */
+#elif defined (CONFIG_MPC8245)
+#if defined (CONFIG_133MHZ_DRAM)
+#define CFG_ODCR 0xFE /* configures line driver impedances - 133MHz */
+#else
+#define CFG_ODCR 0xDE /* configures line driver impedances - 66MHz */
+#endif
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+#define CFG_PGMAX 0x32 /* how long the 8240 retains the */
+ /* currently accessed page in memory */
+ /* see 8240 book for details */
+
+/*-----------------------------------------------------------------------
+ * Block Address Translation (BAT) register settings.
+ */
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in DCACHE @ 1GB (no backing mem) */
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory */
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc */
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+/* values according to the manual */
+#define CONFIG_DRAM_50MHZ 1
+#define CONFIG_SDRAM_50MHZ
+
+#undef NR_8259_INTS
+#define NR_8259_INTS 1
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ */
+#define CFG_IDE_MAXBUS 1 /* max. 2 IDE busses */
+#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*1) /* max. 2 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR CFG_ISA_IO /* base address */
+#define CFG_ATA_IDE0_OFFSET 0x01F0 /* ide0 offste */
+#define CFG_ATA_IDE1_OFFSET 0x0170 /* ide1 offset */
+#define CFG_ATA_DATA_OFFSET 0 /* data reg offset */
+#define CFG_ATA_REG_OFFSET 0 /* reg offset */
+#define CFG_ATA_ALT_OFFSET 0x200 /* alternate register offset */
+
+#define CONFIG_ATAPI
+
+#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */
+#undef CONFIG_IDE_LED /* no led for ide supported */
+#undef CONFIG_IDE_RESET /* reset for ide supported... */
+#undef CONFIG_IDE_RESET_ROUTINE /* with a special reset function */
+
+/*-----------------------------------------------------------------------
+ * DISK Partition support
+ */
+#define CONFIG_DOS_PARTITION
+
+/*-----------------------------------------------------------------------
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/ns9750dev.h b/include/configs/ns9750dev.h
new file mode 100644
index 0000000..11d21b2
--- /dev/null
+++ b/include/configs/ns9750dev.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ * Markus Pietrek <mpietrek@fsforth.de>
+ *
+ * Configuation settings for the NetSilicon NS9750 DevBoard
+ *
+ * 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
+
+/*
+ * If we are developing, we might want to start armboot from ram
+ * so we MUST NOT initialize critical regs like mem-timing ...
+ */
+#define CONFIG_INIT_CRITICAL /* undef for developing */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARM926EJS 1 /* This is an ARM926EJS Core */
+#define CONFIG_NS9750 1 /* in an NetSilicon NS9750 SoC */
+#define CONFIG_NS9750DEV 1 /* on an NetSilicon NS9750 DevBoard */
+
+/* input clock of PLL */
+#define CONFIG_SYS_CLK_FREQ 324403200 /* Don't use PLL. SW11-4 off */
+
+#define CPU_CLK_FREQ (CONFIG_SYS_CLK_FREQ/2)
+#define AHB_CLK_FREQ (CONFIG_SYS_CLK_FREQ/4)
+#define BBUS_CLK_FREQ (CONFIG_SYS_CLK_FREQ/8)
+
+#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+/*@TODO #define CONFIG_STATUS_LED*/
+#define CONFIG_USE_IRQ
+
+/*
+ * Size of malloc() pool
+ */
+#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial
+ * data */
+
+/*
+ * Hardware drivers
+ */
+#define CFG_NS9750_UART 1 /* use on-chip UART */
+#define CONFIG_DRIVER_NS9750_ETHERNET 1 /* use on-chip ethernet */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_CONS_INDEX 1 /* Port B */
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE 38400
+
+/***********************************************************
+ * Command definition
+ ***********************************************************/
+#if 0 /* @TODO */
+#define CONFIG_COMMANDS \
+ (CONFIG_CMD_DFL | \
+ CFG_CMD_CACHE | \
+ /*CFG_CMD_NAND |*/ \
+ /*CFG_CMD_EEPROM |*/ \
+ /*CFG_CMD_I2C |*/ \
+ /*CFG_CMD_USB |*/ \
+ CFG_CMD_REGINFO | \
+ CFG_CMD_DATE | \
+ CFG_CMD_ELF)
+#else
+#define CONFIG_COMMANDS \
+ (CONFIG_CMD_BDI | \
+ CFG_CMD_NET | \
+ CFG_CMD_PING | \
+ CFG_CMD_CONSOLE | \
+ CFG_CMD_LOADB | \
+ CFG_CMD_LOADS | \
+ CFG_CMD_MEMORY)
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define CONFIG_BOOTDELAY 3
+/*#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,9600" */
+
+#define CONFIG_ETHADDR 00:04:f3:ff:ff:fb /*@TODO unset */
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_IPADDR 192.168.42.30
+#define CONFIG_SERVERIP 192.168.42.1
+
+/*#define CONFIG_BOOTFILE "elinos-lart" */
+/*#define CONFIG_BOOTCOMMAND "tftp; bootm" */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
+/* what's this ? it's not used anywhere */
+#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "NS9750DEV # " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x00000000 /* memtest works on */
+#define CFG_MEMTEST_END 0x00780000 /* 7,5 MB in DRAM */ /* @TODO */
+
+#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
+
+#define CFG_LOAD_ADDR 0x00600000 /* default load address */ /* @TODO */
+
+#define CFG_HZ (CPU_CLK_FREQ/64)
+
+/* valid baudrates */
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define NS9750_ETH_PHY_ADDRESS (0x0000)
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE (128*1024) /* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+/* TODO */
+#define CONFIG_NR_DRAM_BANKS 2 /* we have 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x00000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE 0x00800000 /* 8 MB */
+#define PHYS_SDRAM_2 0x10000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_2_SIZE 0x00800000 /* 8 MB */
+
+#define PHYS_FLASH_1 0x50000000 /* Flash Bank #1 */
+
+#define CFG_FLASH_BASE PHYS_FLASH_1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+
+/* @TODO*/
+#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
+#if 0
+#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
+#endif
+
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#ifdef CONFIG_AMD_LV800
+#define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
+#define CFG_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
+#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */
+#endif
+#ifdef CONFIG_AMD_LV400
+#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
+#define CFG_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
+#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x070000) /* addr of environment */
+#endif
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT (5*CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) /* Timeout for Flash Write */
+
+/* @TODO */
+/*#define CFG_ENV_IS_IN_FLASH 1*/
+#define CFG_ENV_IS_NOWHERE
+#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
+
+#ifdef CONFIG_STATUS_LED
+
+extern void __led_init(led_id_t mask, int state);
+extern void __led_toggle(led_id_t mask);
+extern void __led_set(led_id_t mask, int state);
+
+#endif /* CONFIG_STATUS_LED */
+
+#endif /* __CONFIG_H */
diff --git a/include/mpc5xxx.h b/include/mpc5xxx.h
index 49951f5..8d4013a 100644
--- a/include/mpc5xxx.h
+++ b/include/mpc5xxx.h
@@ -90,6 +90,7 @@
#define MPC5XXX_GPT (CFG_MBAR + 0x0600)
#define MPC5XXX_GPIO (CFG_MBAR + 0x0b00)
#define MPC5XXX_PCI (CFG_MBAR + 0x0d00)
+#define MPC5XXX_USB (CFG_MBAR + 0x1000)
#define MPC5XXX_SDMA (CFG_MBAR + 0x1200)
#define MPC5XXX_XLBARB (CFG_MBAR + 0x1f00)
@@ -132,6 +133,7 @@
#define MPC5XXX_CDM_JTAGID (MPC5XXX_CDM + 0x0000)
#define MPC5XXX_CDM_PORCFG (MPC5XXX_CDM + 0x0004)
#define MPC5XXX_CDM_CFG (MPC5XXX_CDM + 0x000c)
+#define MPC5XXX_CDM_48_FDC (MPC5XXX_CDM + 0x0010)
#define MPC5XXX_CDM_SRESET (MPC5XXX_CDM + 0x0020)
/* Local Plus Bus interface */
diff --git a/include/ns9750_bbus.h b/include/ns9750_bbus.h
new file mode 100644
index 0000000..0918931
--- /dev/null
+++ b/include/ns9750_bbus.h
@@ -0,0 +1,125 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_bbus.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Definitions for BBus usage
+ * @References: [1] NS9750 Hardware Reference Manual/December 2003 Chap. 10
+ *
+ * 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 FS_NS9750_BBUS_H
+#define FS_NS9750_BBUS_H
+
+#define NS9750_BBUS_MODULE_BASE (0x90600000)
+
+#define get_bbus_reg_addr(c) \
+ ((volatile unsigned int *)(NS9750_BBUS_MODULE_BASE+(unsigned int) (c)))
+
+/* We have support for 50 GPIO pins */
+
+#define get_gpio_cfg_reg_addr(pin) \
+ get_bbus_reg_addr( NS9750_BBUS_GPIO_CFG_BASE + (((pin) >> 3) * 4) )
+
+/* To Read/Modify/Write a pin configuration register, use it like
+ set_gpio_cfg_reg_val( 12, NS9750_GPIO_CFG_FUNC_GPIO|NS9750_GPIO_CFG_OUTPUT );
+ They should be wrapped by cli()/sti() */
+#define set_gpio_cfg_reg_val(pin,cfg) \
+ *get_gpio_cfg_reg_addr(pin)=(*get_gpio_cfg_reg_addr((pin)) & \
+ ~NS9750_GPIO_CFG_MASK((pin))) |\
+ NS9750_GPIO_CFG_VAL((pin),(cfg));
+
+#define NS9750_GPIO_CFG_MASK(pin) (NS9750_GPIO_CFG_VAL(pin, \
+ NS9750_GPIO_CFG_MA))
+#define NS9750_GPIO_CFG_VAL(pin,cfg) ((cfg) << (((pin) % 8) * 4))
+
+#define NS9750_GPIO_CFG_MA (0x0F)
+#define NS9750_GPIO_CFG_INPUT (0x00)
+#define NS9750_GPIO_CFG_OUTPUT (0x08)
+#define NS9750_GPIO_CFG_FUNC_GPIO (0x03)
+#define NS9750_GPIO_CFG_FUNC_2 (0x02)
+#define NS9750_GPIO_CFG_FUNC_1 (0x01)
+#define NS9750_GPIO_CFG_FUNC_0 (0x00)
+
+/* the register addresses */
+
+#define NS9750_BBUS_MASTER_RESET (0x00)
+#define NS9750_BBUS_GPIO_CFG_BASE (0x10)
+#define NS9750_BBUS_GPIO_CTRL_BASE (0x30)
+#define NS9750_BBUS_GPIO_STAT_BASE (0x40)
+#define NS9750_BBUS_MONITOR (0x50)
+#define NS9750_BBUS_DMA_INT_STAT (0x60)
+#define NS9750_BBUS_DMA_INT_ENABLE (0x64)
+#define NS9750_BBUS_USB_CFG (0x70)
+#define NS9750_BBUS_ENDIAN_CFG (0x80)
+#define NS9750_BBUS_ARM_WAKE_UP (0x90)
+
+/* register bit fields */
+
+#define NS9750_BBUS_MASTER_RESET_UTIL (0x00000100)
+#define NS9750_BBUS_MASTER_RESET_I2C (0x00000080)
+#define NS9750_BBUS_MASTER_RESET_1284 (0x00000040)
+#define NS9750_BBUS_MASTER_RESET_SER4 (0x00000020)
+#define NS9750_BBUS_MASTER_RESET_SER3 (0x00000010)
+#define NS9750_BBUS_MASTER_RESET_SER2 (0x00000008)
+#define NS9750_BBUS_MASTER_RESET_SER1 (0x00000004)
+#define NS9750_BBUS_MASTER_RESET_USB (0x00000002)
+#define NS9750_BBUS_MASTER_RESET_DMA (0x00000001)
+
+/* BS9750_BBUS_DMA_INT_BINT* are valid for *DMA_INT_STAT and *DMA_INT_ENABLE */
+
+#define NS9750_BBUS_DMA_INT_BINT16 (0x00010000)
+#define NS9750_BBUS_DMA_INT_BINT15 (0x00008000)
+#define NS9750_BBUS_DMA_INT_BINT14 (0x00004000)
+#define NS9750_BBUS_DMA_INT_BINT13 (0x00002000)
+#define NS9750_BBUS_DMA_INT_BINT12 (0x00001000)
+#define NS9750_BBUS_DMA_INT_BINT11 (0x00000800)
+#define NS9750_BBUS_DMA_INT_BINT10 (0x00000400)
+#define NS9750_BBUS_DMA_INT_BINT9 (0x00000200)
+#define NS9750_BBUS_DMA_INT_BINT8 (0x00000100)
+#define NS9750_BBUS_DMA_INT_BINT7 (0x00000080)
+#define NS9750_BBUS_DMA_INT_BINT6 (0x00000040)
+#define NS9750_BBUS_DMA_INT_BINT5 (0x00000020)
+#define NS9750_BBUS_DMA_INT_BINT4 (0x00000010)
+#define NS9750_BBUS_DMA_INT_BINT3 (0x00000008)
+#define NS9750_BBUS_DMA_INT_BINT2 (0x00000004)
+#define NS9750_BBUS_DMA_INT_BINT1 (0x00000002)
+#define NS9750_BBUS_DMA_INT_BINT0 (0x00000001)
+
+#define NS9750_BBUS_USB_CFG_OUTEN (0x00000008)
+#define NS9750_BBUS_USB_CFG_SPEED (0x00000004)
+#define NS9750_BBUS_USB_CFG_CFG_MA (0x00000003)
+#define NS9750_BBUS_USB_CFG_CFG_HOST_SOFT (0x00000003)
+#define NS9750_BBUS_USB_CFG_CFG_DEVICE (0x00000002)
+#define NS9750_BBUS_USB_CFG_CFG_HOST (0x00000001)
+#define NS9750_BBUS_USB_CFG_CFG_DIS (0x00000000)
+
+#define NS9750_BBUS_ENDIAN_CFG_AHBM (0x00001000)
+#define NS9750_BBUS_ENDIAN_CFG_I2C (0x00000080)
+#define NS9750_BBUS_ENDIAN_CFG_IEEE1284 (0x00000040)
+#define NS9750_BBUS_ENDIAN_CFG_SER4 (0x00000020)
+#define NS9750_BBUS_ENDIAN_CFG_SER3 (0x00000010)
+#define NS9750_BBUS_ENDIAN_CFG_SER2 (0x00000008)
+#define NS9750_BBUS_ENDIAN_CFG_SER1 (0x00000004)
+#define NS9750_BBUS_ENDIAN_CFG_USB (0x00000002)
+#define NS9750_BBUS_ENDIAN_CFG_DMA (0x00000001)
+
+#endif /* FS_NS9750_BBUS_H */
diff --git a/include/ns9750_eth.h b/include/ns9750_eth.h
new file mode 100644
index 0000000..ce0c841
--- /dev/null
+++ b/include/ns9750_eth.h
@@ -0,0 +1,526 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_eth.h,v 1.2 2004/02/24 13:25:39 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @References: [1] NS9750 Hardware Reference, December 2003
+ * [2] Intel LXT971 Datasheet #249414 Rev. 02
+ * [3] NS7520 Linux Ethernet Driver
+ *
+ * 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 FS_NS9750_ETH_H
+#define FS_NS9750_ETH_H
+
+#ifdef CONFIG_DRIVER_NS9750_ETHERNET
+
+#define NS9750_ETH_MODULE_BASE (0xA0600000)
+
+#define get_eth_reg_addr(c) \
+ ((volatile unsigned int*) ( NS9750_ETH_MODULE_BASE+(unsigned int) (c)))
+
+#define NS9750_ETH_EGCR1 (0x0000)
+#define NS9750_ETH_EGCR2 (0x0004)
+#define NS9750_ETH_EGSR (0x0008)
+#define NS9750_ETH_FIFORX (0x000C)
+#define NS9750_ETH_FIFOTX (0x0010)
+#define NS9750_ETH_FIFOTXS (0x0014)
+#define NS9750_ETH_ETSR (0x0018)
+#define NS9750_ETH_ERSR (0x001C)
+#define NS9750_ETH_MAC1 (0x0400)
+#define NS9750_ETH_MAC2 (0x0404)
+#define NS9750_ETH_IPGT (0x0408)
+#define NS9750_ETH_IPGR (0x040C)
+#define NS9750_ETH_CLRT (0x0410)
+#define NS9750_ETH_MAXF (0x0414)
+#define NS9750_ETH_SUPP (0x0418)
+#define NS9750_ETH_TEST (0x041C)
+#define NS9750_ETH_MCFG (0x0420)
+#define NS9750_ETH_MCMD (0x0424)
+#define NS9750_ETH_MADR (0x0428)
+#define NS9750_ETH_MWTD (0x042C)
+#define NS9750_ETH_MRDD (0x0430)
+#define NS9750_ETH_MIND (0x0434)
+#define NS9750_ETH_SA1 (0x0440)
+#define NS9750_ETH_SA2 (0x0444)
+#define NS9750_ETH_SA3 (0x0448)
+#define NS9750_ETH_SAFR (0x0500)
+#define NS9750_ETH_HT1 (0x0504)
+#define NS9750_ETH_HT2 (0x0508)
+#define NS9750_ETH_STAT_BASE (0x0680)
+#define NS9750_ETH_RXAPTR (0x0A00)
+#define NS9750_ETH_RXBPTR (0x0A04)
+#define NS9750_ETH_RXCPTR (0x0A08)
+#define NS9750_ETH_RXDPTR (0x0A0C)
+#define NS9750_ETH_EINTR (0x0A10)
+#define NS9750_ETH_EINTREN (0x0A14)
+#define NS9750_ETH_TXPTR (0x0A18)
+#define NS9750_ETH_TXRPTR (0x0A1C)
+#define NS9750_ETH_TXERBD (0x0A20)
+#define NS9750_ETH_TXSPTR (0x0A24)
+#define NS9750_ETH_RXAOFF (0x0A28)
+#define NS9750_ETH_RXBOFF (0x0A2C)
+#define NS9750_ETH_RXCOFF (0x0A30)
+#define NS9750_ETH_RXDOFF (0x0A34)
+#define NS9750_ETH_TXOFF (0x0A38)
+#define NS9750_ETH_RXFREE (0x0A3C)
+#define NS9750_ETH_TXBD (0x1000)
+
+/* register bit fields */
+
+#define NS9750_ETH_EGCR1_ERX (0x80000000)
+#define NS9750_ETH_EGCR1_ERXDMA (0x40000000)
+#define NS9750_ETH_EGCR1_ERXSHT (0x10000000)
+#define NS9750_ETH_EGCR1_ERXSIZ (0x08000000)
+#define NS9750_ETH_EGCR1_ETXSIZ (0x04000000)
+#define NS9750_ETH_EGCR1_ETXDIAG (0x02000000)
+#define NS9750_ETH_EGCR1_ERXBAD (0x01000000)
+#define NS9750_ETH_EGCR1_ETX (0x00800000)
+#define NS9750_ETH_EGCR1_ETXDMA (0x00400000)
+#define NS9750_ETH_EGCR1_ETXWM (0x00200000)
+#define NS9750_ETH_EGCR1_ERXADV (0x00100000)
+#define NS9750_ETH_EGCR1_ERXINIT (0x00080000)
+#define NS9750_ETH_EGCR1_PHY_MODE_MA (0x0000C000)
+#define NS9750_ETH_EGCR1_PHY_MODE_MII (0x00008000)
+#define NS9750_ETH_EGCR1_PHY_MODE_RMII (0x00004000)
+#define NS9750_ETH_EGCR1_RXCINV (0x00001000)
+#define NS9750_ETH_EGCR1_TXCINV (0x00000800)
+#define NS9750_ETH_EGCR1_RXALIGN (0x00000400)
+#define NS9750_ETH_EGCR1_MAC_HRST (0x00000200)
+#define NS9750_ETH_EGCR1_ITXA (0x00000100)
+
+#define NS9750_ETH_EGCR2_TPTV_MA (0xFFFF0000)
+#define NS9750_ETH_EGCR2_TPCF (0x00000040)
+#define NS9750_ETH_EGCR2_THPDF (0x00000020)
+#define NS9750_ETH_EGCR2_TCLER (0x00000008)
+#define NS9750_ETH_EGCR2_AUTOZ (0x00000004)
+#define NS9750_ETH_EGCR2_CLRCNT (0x00000002)
+#define NS9750_ETH_EGCR2_STEN (0x00000001)
+
+#define NS9750_ETH_EGSR_RXINIT (0x00100000)
+#define NS9750_ETH_EGSR_TXFIFONF (0x00080000)
+#define NS9750_ETH_EGSR_TXFIFOH (0x00040000)
+#define NS9750_ETH_EGSR_TXFIFOE (0x00010000)
+
+#define NS9750_ETH_FIFOTXS_ALL (0x00000055)
+#define NS9750_ETH_FIFOTXS_3 (0x000000d5)
+#define NS9750_ETH_FIFOTXS_2 (0x00000035)
+#define NS9750_ETH_FIFOTXS_1 (0x0000000D)
+#define NS9750_ETH_FIFOTXS_0 (0x00000003)
+
+#define NS9750_ETH_ETSR_TXOK (0x00008000)
+#define NS9750_ETH_ETSR_TXBR (0x00004000)
+#define NS9750_ETH_ETSR_TXMC (0x00002000)
+#define NS9750_ETH_ETSR_TXAL (0x00001000)
+#define NS9750_ETH_ETSR_TXAED (0x00000800)
+#define NS9750_ETH_ETSR_TXAEC (0x00000400)
+#define NS9750_ETH_ETSR_TXAUR (0x00000200)
+#define NS9750_ETH_ETSR_TXAJ (0x00000100)
+#define NS9750_ETH_ETSR_TXDEF (0x00000040)
+#define NS9750_ETH_ETSR_TXCRC (0x00000020)
+#define NS9750_ETH_ETSR_TXCOLC (0x0000000F)
+
+#define NS9750_ETH_ERSR_RXSIZE_MA (0x0FFF0000)
+#define NS9750_ETH_ERSR_RXCE (0x00008000)
+#define NS9750_ETH_ERSR_RXDV (0x00004000)
+#define NS9750_ETH_ERSR_RXOK (0x00002000)
+#define NS9750_ETH_ERSR_RXBR (0x00001000)
+#define NS9750_ETH_ERSR_RXMC (0x00000800)
+#define NS9750_ETH_ERSR_RXCRC (0x00000400)
+#define NS9750_ETH_ERSR_RXDR (0x00000200)
+#define NS9750_ETH_ERSR_RXCV (0x00000100)
+#define NS9750_ETH_ERSR_RXSHT (0x00000040)
+
+#define NS9750_ETH_MAC1_SRST (0x00008000)
+#define NS9750_ETH_MAC1_SIMMRST (0x00004000)
+#define NS9750_ETH_MAC1_RPEMCSR (0x00000800)
+#define NS9750_ETH_MAC1_RPERFUN (0x00000400)
+#define NS9750_ETH_MAC1_RPEMCST (0x00000200)
+#define NS9750_ETH_MAC1_RPETFUN (0x00000100)
+#define NS9750_ETH_MAC1_LOOPBK (0x00000010)
+#define NS9750_ETH_MAC1_TXFLOW (0x00000008)
+#define NS9750_ETH_MAC1_RXFLOW (0x00000004)
+#define NS9750_ETH_MAC1_PALLRX (0x00000002)
+#define NS9750_ETH_MAC1_RXEN (0x00000001)
+
+#define NS9750_ETH_MAC2_EDEFER (0x00004000)
+#define NS9750_ETH_MAC2_BACKP (0x00002000)
+#define NS9750_ETH_MAC2_NOBO (0x00001000)
+#define NS9750_ETH_MAC2_LONGP (0x00000200)
+#define NS9750_ETH_MAC2_PUREP (0x00000100)
+#define NS9750_ETH_MAC2_AUTOP (0x00000080)
+#define NS9750_ETH_MAC2_VLANP (0x00000040)
+#define NS9750_ETH_MAC2_PADEN (0x00000020)
+#define NS9750_ETH_MAC2_CRCEN (0x00000010)
+#define NS9750_ETH_MAC2_DELCRC (0x00000008)
+#define NS9750_ETH_MAC2_HUGE (0x00000004)
+#define NS9750_ETH_MAC2_FLENC (0x00000002)
+#define NS9750_ETH_MAC2_FULLD (0x00000001)
+
+#define NS9750_ETH_IPGT_MA (0x0000007F)
+
+#define NS9750_ETH_IPGR_IPGR1 (0x00007F00)
+#define NS9750_ETH_IPGR_IPGR2 (0x0000007F)
+
+#define NS9750_ETH_CLRT_CWIN (0x00003F00)
+#define NS9750_ETH_CLRT_RETX (0x0000000F)
+
+#define NS9750_ETH_MAXF_MAXF (0x0000FFFF)
+
+#define NS9750_ETH_SUPP_RPERMII (0x00008000)
+#define NS9750_ETH_SUPP_SPEED (0x00000080)
+
+#define NS9750_ETH_TEST_TBACK (0x00000004)
+#define NS9750_ETH_TEST_TPAUSE (0x00000002)
+#define NS9750_ETH_TEST_SPQ (0x00000001)
+
+#define NS9750_ETH_MCFG_RMIIM (0x00008000)
+#define NS9750_ETH_MCFG_CLKS_MA (0x0000001C)
+#define NS9750_ETH_MCFG_CLKS_4 (0x00000004)
+#define NS9750_ETH_MCFG_CLKS_6 (0x00000008)
+#define NS9750_ETH_MCFG_CLKS_8 (0x0000000C)
+#define NS9750_ETH_MCFG_CLKS_10 (0x00000010)
+#define NS9750_ETH_MCFG_CLKS_20 (0x00000014)
+#define NS9750_ETH_MCFG_CLKS_30 (0x00000018)
+#define NS9750_ETH_MCFG_CLKS_40 (0x0000001C)
+#define NS9750_ETH_MCFG_SPRE (0x00000002)
+#define NS9750_ETH_MCFG_SCANI (0x00000001)
+
+#define NS9750_ETH_MCMD_SCAN (0x00000002)
+#define NS9750_ETH_MCMD_READ (0x00000001)
+
+#define NS9750_ETH_MADR_DADR_MA (0x00001F00)
+#define NS9750_ETH_MADR_RADR_MA (0x0000001F)
+
+#define NS9750_ETH_MWTD_MA (0x0000FFFF)
+
+#define NS9750_ETH_MRRD_MA (0x0000FFFF)
+
+#define NS9750_ETH_MIND_MIILF (0x00000008)
+#define NS9750_ETH_MIND_NVALID (0x00000004)
+#define NS9750_ETH_MIND_SCAN (0x00000002)
+#define NS9750_ETH_MIND_BUSY (0x00000001)
+
+#define NS9750_ETH_SA1_OCTET1_MA (0x0000FF00)
+#define NS9750_ETH_SA1_OCTET2_MA (0x000000FF)
+
+#define NS9750_ETH_SA2_OCTET3_MA (0x0000FF00)
+#define NS9750_ETH_SA2_OCTET4_MA (0x000000FF)
+
+#define NS9750_ETH_SA3_OCTET5_MA (0x0000FF00)
+#define NS9750_ETH_SA3_OCTET6_MA (0x000000FF)
+
+#define NS9750_ETH_SAFR_PRO (0x00000008)
+#define NS9750_ETH_SAFR_PRM (0x00000004)
+#define NS9750_ETH_SAFR_PRA (0x00000002)
+#define NS9750_ETH_SAFR_BROAD (0x00000001)
+
+#define NS9750_ETH_HT1_MA (0x0000FFFF)
+
+#define NS9750_ETH_HT2_MA (0x0000FFFF)
+
+/* also valid for EINTREN */
+#define NS9750_ETH_EINTR_RXOVL_DATA (0x02000000)
+#define NS9750_ETH_EINTR_RXOVL_STAT (0x01000000)
+#define NS9750_ETH_EINTR_RXBUFC (0x00800000)
+#define NS9750_ETH_EINTR_RXDONEA (0x00400000)
+#define NS9750_ETH_EINTR_RXDONEB (0x00200000)
+#define NS9750_ETH_EINTR_RXDONEC (0x00100000)
+#define NS9750_ETH_EINTR_RXDONED (0x00080000)
+#define NS9750_ETH_EINTR_RXNOBUF (0x00040000)
+#define NS9750_ETH_EINTR_RXBUFFUL (0x00020000)
+#define NS9750_ETH_EINTR_RXBR (0x00010000)
+#define NS9750_ETH_EINTR_STOVFL (0x00000040)
+#define NS9750_ETH_EINTR_TXPAUSE (0x00000020)
+#define NS9750_ETH_EINTR_TXBUFC (0x00000010)
+#define NS9750_ETH_EINTR_TXBUFNR (0x00000008)
+#define NS9750_ETH_EINTR_TXDONE (0x00000004)
+#define NS9750_ETH_EINTR_TXERR (0x00000002)
+#define NS9750_ETH_EINTR_TXIDLE (0x00000001)
+#define NS9750_ETH_EINTR_RX_MA \
+ (NS9750_ETH_EINTR_RXOVL_DATA | \
+ NS9750_ETH_EINTR_RXOVL_STAT | \
+ NS9750_ETH_EINTR_RXBUFC | \
+ NS9750_ETH_EINTR_RXDONEA | \
+ NS9750_ETH_EINTR_RXDONEB | \
+ NS9750_ETH_EINTR_RXDONEC | \
+ NS9750_ETH_EINTR_RXDONED | \
+ NS9750_ETH_EINTR_RXNOBUF | \
+ NS9750_ETH_EINTR_RXBUFFUL | \
+ NS9750_ETH_EINTR_RXBR )
+#define NS9750_ETH_EINTR_TX_MA \
+ (NS9750_ETH_EINTR_TXPAUSE | \
+ NS9750_ETH_EINTR_TXBUFC | \
+ NS9750_ETH_EINTR_TXBUFNR | \
+ NS9750_ETH_EINTR_TXDONE | \
+ NS9750_ETH_EINTR_TXERR | \
+ NS9750_ETH_EINTR_TXIDLE)
+
+/* for TXPTR, TXRPTR, TXERBD and TXSPTR */
+#define NS9750_ETH_TXPTR_MA (0x000000FF)
+
+/* for RXAOFF, RXBOFF, RXCOFF and RXDOFF */
+#define NS9750_ETH_RXOFF_MA (0x000007FF)
+
+#define NS9750_ETH_TXOFF_MA (0x000003FF)
+
+#define NS9750_ETH_RXFREE_D (0x00000008)
+#define NS9750_ETH_RXFREE_C (0x00000004)
+#define NS9750_ETH_RXFREE_B (0x00000002)
+#define NS9750_ETH_RXFREE_A (0x00000001)
+
+/* PHY definitions (LXT971A) [2] */
+
+#define PHY_COMMON_CTRL (0x00)
+#define PHY_COMMON_STAT (0x01)
+#define PHY_COMMON_ID1 (0x02)
+#define PHY_COMMON_ID2 (0x03)
+#define PHY_COMMON_AUTO_ADV (0x04)
+#define PHY_COMMON_AUTO_LNKB (0x05)
+#define PHY_COMMON_AUTO_EXP (0x06)
+#define PHY_COMMON_AUTO_NEXT (0x07)
+#define PHY_COMMON_AUTO_LNKN (0x08)
+#define PHY_LXT971_PORT_CFG (0x10)
+#define PHY_LXT971_STAT2 (0x11)
+#define PHY_LXT971_INT_ENABLE (0x12)
+#define PHY_LXT971_INT_STATUS (0x13)
+#define PHY_LXT971_LED_CFG (0x14)
+#define PHY_LXT971_DIG_CFG (0x1A)
+#define PHY_LXT971_TX_CTRL (0x1E)
+
+/* CTRL PHY Control Register Bit Fields */
+
+#define PHY_COMMON_CTRL_RESET (0x8000)
+#define PHY_COMMON_CTRL_LOOPBACK (0x4000)
+#define PHY_COMMON_CTRL_SPD_MA (0x2040)
+#define PHY_COMMON_CTRL_SPD_10 (0x0000)
+#define PHY_COMMON_CTRL_SPD_100 (0x2000)
+#define PHY_COMMON_CTRL_SPD_1000 (0x0040)
+#define PHY_COMMON_CTRL_SPD_RES (0x2040)
+#define PHY_COMMON_CTRL_AUTO_NEG (0x1000)
+#define PHY_COMMON_CTRL_POWER_DN (0x0800)
+#define PHY_COMMON_CTRL_ISOLATE (0x0400)
+#define PHY_COMMON_CTRL_RES_AUTO (0x0200)
+#define PHY_COMMON_CTRL_DUPLEX (0x0100)
+#define PHY_COMMON_CTRL_COL_TEST (0x0080)
+#define PHY_COMMON_CTRL_RES1 (0x003F)
+
+/* STAT Status Register Bit Fields */
+
+#define PHY_COMMON_STAT_100BT4 (0x8000)
+#define PHY_COMMON_STAT_100BXFD (0x4000)
+#define PHY_COMMON_STAT_100BXHD (0x2000)
+#define PHY_COMMON_STAT_10BTFD (0x1000)
+#define PHY_COMMON_STAT_10BTHD (0x0800)
+#define PHY_COMMON_STAT_100BT2FD (0x0400)
+#define PHY_COMMON_STAT_100BT2HD (0x0200)
+#define PHY_COMMON_STAT_EXT_STAT (0x0100)
+#define PHY_COMMON_STAT_RES1 (0x0080)
+#define PHY_COMMON_STAT_MF_PSUP (0x0040)
+#define PHY_COMMON_STAT_AN_COMP (0x0020)
+#define PHY_COMMON_STAT_RMT_FLT (0x0010)
+#define PHY_COMMON_STAT_AN_CAP (0x0008)
+#define PHY_COMMON_STAT_LNK_STAT (0x0004)
+#define PHY_COMMON_STAT_JAB_DTCT (0x0002)
+#define PHY_COMMON_STAT_EXT_CAP (0x0001)
+
+
+/* AUTO_ADV Auto-neg Advert Register Bit Fields */
+
+#define PHY_COMMON_AUTO_ADV_NP (0x8000)
+#define PHY_COMMON_AUTO_ADV_RES1 (0x4000)
+#define PHY_COMMON_AUTO_ADV_RMT_FLT (0x2000)
+#define PHY_COMMON_AUTO_ADV_RES2 (0x1000)
+#define PHY_COMMON_AUTO_ADV_AS_PAUSE (0x0800)
+#define PHY_COMMON_AUTO_ADV_PAUSE (0x0400)
+#define PHY_COMMON_AUTO_ADV_100BT4 (0x0200)
+#define PHY_COMMON_AUTO_ADV_100BTXFD (0x0100)
+#define PHY_COMMON_AUTO_ADV_100BTX (0x0080)
+#define PHY_COMMON_AUTO_ADV_10BTFD (0x0040)
+#define PHY_COMMON_AUTO_ADV_10BT (0x0020)
+#define PHY_COMMON_AUTO_ADV_SEL_FLD_MA (0x001F)
+#define PHY_COMMON_AUTO_ADV_802_9 (0x0002)
+#define PHY_COMMON_AUTO_ADV_802_3 (0x0001)
+
+/* AUTO_LNKB Auto-neg Link Ability Register Bit Fields */
+
+#define PHY_COMMON_AUTO_LNKB_NP (0x8000)
+#define PHY_COMMON_AUTO_LNKB_ACK (0x4000)
+#define PHY_COMMON_AUTO_LNKB_RMT_FLT (0x2000)
+#define PHY_COMMON_AUTO_LNKB_RES2 (0x1000)
+#define PHY_COMMON_AUTO_LNKB_AS_PAUSE (0x0800)
+#define PHY_COMMON_AUTO_LNKB_PAUSE (0x0400)
+#define PHY_COMMON_AUTO_LNKB_100BT4 (0x0200)
+#define PHY_COMMON_AUTO_LNKB_100BTXFD (0x0100)
+#define PHY_COMMON_AUTO_LNKB_100BTX (0x0080)
+#define PHY_COMMON_AUTO_LNKB_10BTFD (0x0040)
+#define PHY_COMMON_AUTO_LNKB_10BT (0x0020)
+#define PHY_COMMON_AUTO_LNKB_SEL_FLD_MA (0x001F)
+#define PHY_COMMON_AUTO_LNKB_802_9 (0x0002)
+#define PHY_COMMON_AUTO_LNKB_802_3 (0x0001)
+
+/* AUTO_EXP Auto-neg Expansion Register Bit Fields */
+
+#define PHY_COMMON_AUTO_EXP_RES1 (0xFFC0)
+#define PHY_COMMON_AUTO_EXP_BASE_PAGE (0x0020)
+#define PHY_COMMON_AUTO_EXP_PAR_DT_FLT (0x0010)
+#define PHY_COMMON_AUTO_EXP_LNK_NP_CAP (0x0008)
+#define PHY_COMMON_AUTO_EXP_NP_CAP (0x0004)
+#define PHY_COMMON_AUTO_EXP_PAGE_REC (0x0002)
+#define PHY_COMMON_AUTO_EXP_LNK_AN_CAP (0x0001)
+
+/* AUTO_NEXT Aut-neg Next Page Tx Register Bit Fields */
+
+#define PHY_COMMON_AUTO_NEXT_NP (0x8000)
+#define PHY_COMMON_AUTO_NEXT_RES1 (0x4000)
+#define PHY_COMMON_AUTO_NEXT_MSG_PAGE (0x2000)
+#define PHY_COMMON_AUTO_NEXT_ACK_2 (0x1000)
+#define PHY_COMMON_AUTO_NEXT_TOGGLE (0x0800)
+#define PHY_COMMON_AUTO_NEXT_MSG (0x07FF)
+
+/* AUTO_LNKN Auto-neg Link Partner Rx Reg Bit Fields */
+
+#define PHY_COMMON_AUTO_LNKN_NP (0x8000)
+#define PHY_COMMON_AUTO_LNKN_ACK (0x4000)
+#define PHY_COMMON_AUTO_LNKN_MSG_PAGE (0x2000)
+#define PHY_COMMON_AUTO_LNKN_ACK_2 (0x1000)
+#define PHY_COMMON_AUTO_LNKN_TOGGLE (0x0800)
+#define PHY_COMMON_AUTO_LNKN_MSG (0x07FF)
+
+/* PORT_CFG Port Configuration Register Bit Fields */
+
+#define PHY_LXT971_PORT_CFG_RES1 (0x8000)
+#define PHY_LXT971_PORT_CFG_FORCE_LNK (0x4000)
+#define PHY_LXT971_PORT_CFG_TX_DISABLE (0x2000)
+#define PHY_LXT971_PORT_CFG_BYPASS_SCR (0x1000)
+#define PHY_LXT971_PORT_CFG_RES2 (0x0800)
+#define PHY_LXT971_PORT_CFG_JABBER (0x0400)
+#define PHY_LXT971_PORT_CFG_SQE (0x0200)
+#define PHY_LXT971_PORT_CFG_TP_LOOPBACK (0x0100)
+#define PHY_LXT971_PORT_CFG_CRS_SEL (0x0080)
+#define PHY_LXT971_PORT_CFG_SLEEP_MODE (0x0040)
+#define PHY_LXT971_PORT_CFG_PRE_EN (0x0020)
+#define PHY_LXT971_PORT_CFG_SLEEP_T_MA (0x0018)
+#define PHY_LXT971_PORT_CFG_SLEEP_T_104 (0x0010)
+#define PHY_LXT971_PORT_CFG_SLEEP_T_200 (0x0001)
+#define PHY_LXT971_PORT_CFG_SLEEP_T_304 (0x0000)
+#define PHY_LXT971_PORT_CFG_FLT_CODE_EN (0x0004)
+#define PHY_LXT971_PORT_CFG_ALT_NP (0x0002)
+#define PHY_LXT971_PORT_CFG_FIBER_SEL (0x0001)
+
+/* STAT2 Status Register #2 Bit Fields */
+
+#define PHY_LXT971_STAT2_RES1 (0x8000)
+#define PHY_LXT971_STAT2_100BTX (0x4000)
+#define PHY_LXT971_STAT2_TX_STATUS (0x2000)
+#define PHY_LXT971_STAT2_RX_STATUS (0x1000)
+#define PHY_LXT971_STAT2_COL_STATUS (0x0800)
+#define PHY_LXT971_STAT2_LINK (0x0400)
+#define PHY_LXT971_STAT2_DUPLEX_MODE (0x0200)
+#define PHY_LXT971_STAT2_AUTO_NEG (0x0100)
+#define PHY_LXT971_STAT2_AUTO_NEG_COMP (0x0080)
+#define PHY_LXT971_STAT2_RES2 (0x0040)
+#define PHY_LXT971_STAT2_POLARITY (0x0020)
+#define PHY_LXT971_STAT2_PAUSE (0x0010)
+#define PHY_LXT971_STAT2_ERROR (0x0008)
+#define PHY_LXT971_STAT2_RES3 (0x0007)
+
+/* INT_ENABLE Interrupt Enable Register Bit Fields */
+
+#define PHY_LXT971_INT_ENABLE_RES1 (0xFF00)
+#define PHY_LXT971_INT_ENABLE_ANMSK (0x0080)
+#define PHY_LXT971_INT_ENABLE_SPEEDMSK (0x0040)
+#define PHY_LXT971_INT_ENABLE_DUPLEXMSK (0x0020)
+#define PHY_LXT971_INT_ENABLE_LINKMSK (0x0010)
+#define PHY_LXT971_INT_ENABLE_RES2 (0x000C)
+#define PHY_LXT971_INT_ENABLE_INTEN (0x0002)
+#define PHY_LXT971_INT_ENABLE_TINT (0x0001)
+
+/* INT_STATUS Interrupt Status Register Bit Fields */
+
+#define PHY_LXT971_INT_STATUS_RES1 (0xFF00)
+#define PHY_LXT971_INT_STATUS_ANDONE (0x0080)
+#define PHY_LXT971_INT_STATUS_SPEEDCHG (0x0040)
+#define PHY_LXT971_INT_STATUS_DUPLEXCHG (0x0020)
+#define PHY_LXT971_INT_STATUS_LINKCHG (0x0010)
+#define PHY_LXT971_INT_STATUS_RES2 (0x0008)
+#define PHY_LXT971_INT_STATUS_MDINT (0x0004)
+#define PHY_LXT971_INT_STATUS_RES3 (0x0003)
+
+/* LED_CFG Interrupt LED Configuration Register Bit Fields */
+
+#define PHY_LXT971_LED_CFG_SHIFT_LED1 (0x000C)
+#define PHY_LXT971_LED_CFG_SHIFT_LED2 (0x0008)
+#define PHY_LXT971_LED_CFG_SHIFT_LED3 (0x0004)
+#define PHY_LXT971_LED_CFG_LEDFREQ_MA (0x000C)
+#define PHY_LXT971_LED_CFG_LEDFREQ_RES (0x000C)
+#define PHY_LXT971_LED_CFG_LEDFREQ_100 (0x0008)
+#define PHY_LXT971_LED_CFG_LEDFREQ_60 (0x0004)
+#define PHY_LXT971_LED_CFG_LEDFREQ_30 (0x0000)
+#define PHY_LXT971_LED_CFG_PULSE_STR (0x0002)
+#define PHY_LXT971_LED_CFG_RES1 (0x0001)
+
+/* only one of these values must be shifted for each SHIFT_LED? */
+
+#define PHY_LXT971_LED_CFG_UNUSED1 (0x000F)
+#define PHY_LXT971_LED_CFG_DUPLEX_COL (0x000E)
+#define PHY_LXT971_LED_CFG_LINK_ACT (0x000D)
+#define PHY_LXT971_LED_CFG_LINK_RX (0x000C)
+#define PHY_LXT971_LED_CFG_TEST_BLK_SLW (0x000B)
+#define PHY_LXT971_LED_CFG_TEST_BLK_FST (0x000A)
+#define PHY_LXT971_LED_CFG_TEST_OFF (0x0009)
+#define PHY_LXT971_LED_CFG_TEST_ON (0x0008)
+#define PHY_LXT971_LED_CFG_RX_OR_TX (0x0007)
+#define PHY_LXT971_LED_CFG_UNUSED2 (0x0006)
+#define PHY_LXT971_LED_CFG_DUPLEX (0x0005)
+#define PHY_LXT971_LED_CFG_LINK (0x0004)
+#define PHY_LXT971_LED_CFG_COLLISION (0x0003)
+#define PHY_LXT971_LED_CFG_RECEIVE (0x0002)
+#define PHY_LXT971_LED_CFG_TRANSMIT (0x0001)
+#define PHY_LXT971_LED_CFG_SPEED (0x0000)
+
+/* DIG_CFG Digitial Configuration Register Bit Fields */
+
+#define PHY_LXT971_DIG_CFG_RES1 (0xF000)
+#define PHY_LXT971_DIG_CFG_MII_DRIVE (0x0800)
+#define PHY_LXT971_DIG_CFG_RES2 (0x0400)
+#define PHY_LXT971_DIG_CFG_SHOW_SYMBOL (0x0200)
+#define PHY_LXT971_DIG_CFG_RES3 (0x01FF)
+
+#define PHY_LXT971_MDIO_MAX_CLK (8000000)
+
+/* TX_CTRL Transmit Control Register Bit Fields
+ documentation is buggy for this register, therefore setting not included */
+
+typedef enum
+{
+ PHY_NONE = 0x0000, /* no PHY detected yet */
+ PHY_LXT971A = 0x0013
+} PhyType;
+
+#define PHY_MDIO_MAX_CLK (2500000)
+
+#ifndef NS9750_ETH_PHY_ADDRESS
+# define NS9750_ETH_PHY_ADDRESS (0x0001) /* suitable for UNC20 */
+#endif /* NETARM_ETH_PHY_ADDRESS */
+
+#endif /* CONFIG_DRIVER_NS9750_ETHERNET */
+
+#endif /* FS_NS9750_ETH_H */
diff --git a/include/ns9750_mem.h b/include/ns9750_mem.h
new file mode 100644
index 0000000..44c8ddc
--- /dev/null
+++ b/include/ns9750_mem.h
@@ -0,0 +1,172 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_mem.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Definitions for Memory Control Module
+ * @References: [1] NS9750 Hardware Reference Manual/December 2003 Chap. 5
+ *
+ * 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 FS_NS9750_MEM_H
+#define FS_NS9750_SYS_H
+
+#define NS9750_MEM_MODULE_BASE (0xA0700000)
+
+#define get_mem_reg_addr(c) \
+ ((volatile unsigned int *)(NS9750_MEM_MODULE_BASE+(unsigned int) (c)))
+
+/* the register addresses */
+
+#define NS9750_MEM_CTRL (0x0000)
+#define NS9750_MEM_STATUS (0x0004)
+#define NS9750_MEM_CFG (0x0008)
+#define NS9750_MEM_DYN_CTRL (0x0020)
+#define NS9750_MEM_DYN_REFRESH (0x0024)
+#define NS9750_MEM_DYN_READ_CFG (0x0028)
+#define NS9750_MEM_DYN_TRP (0x0030)
+#define NS9750_MEM_DYN_TRAS (0x0034)
+#define NS9750_MEM_DYN_TSREX (0x0038)
+#define NS9750_MEM_DYN_TAPR (0x003C)
+#define NS9750_MEM_DYN_TDAL (0x0040)
+#define NS9750_MEM_DYN_TWR (0x0044)
+#define NS9750_MEM_DYN_TRC (0x0048)
+#define NS9750_MEM_DYN_TRFC (0x004C)
+#define NS9750_MEM_DYN_TXSR (0x0050)
+#define NS9750_MEM_DYN_TRRD (0x0054)
+#define NS9750_MEM_DYN_TMRD (0x0058)
+#define NS9750_MEM_STAT_EXT_WAIT (0x0080)
+#define NS9750_MEM_DYN_CFG_BASE (0x0100)
+#define NS9750_MEM_DYN_RAS_CAS_BASE (0x0104)
+#define NS9750_MEM_STAT_CFG_BASE (0x0200)
+#define NS9750_MEM_STAT_WAIT_WEN_BASE (0x0204)
+#define NS9750_MEM_STAT_WAIT_OEN_BASE (0x0208)
+#define NS9750_MEM_STAT_WAIT_RD_BASE (0x020C)
+#define NS9750_MEM_STAT_WAIT_PAGE_BASE (0x0210)
+#define NS9750_MEM_STAT_WAIR_WR_BASE (0x0214)
+#define NS9750_MEM_STAT_WAIT_TURN_BASE (0x0218)
+
+/* the vectored register addresses */
+
+#define NS9750_MEM_DYN_CFG(c) (NS9750_MEM_DYN_CFG_BASE + (c)*0x20)
+#define NS9750_MEM_DYN_RAS_CAS(c) (NS9750_MEM_DYN_RAS_CAS_BASE + (c)*0x20)
+#define NS9750_MEM_STAT_CFG(c) (NS9750_MEM_STAT_CFG_BASE + (c)*0x20)
+#define NS9750_MEM_STAT_WAIT_WEN(c) (NS9750_MEM_STAT_WAIT_WEN_BASE+(c)*0x20)
+#define NS9750_MEM_STAT_WAIT_OEN(c) (NS9750_MEM_STAT_WAIT_OEN_BASE+(c)*0x20)
+#define NS9750_MEM_STAT_RD(c) (NS9750_MEM_STAT_WAIT_RD_BASE+(c)*0x20)
+#define NS9750_MEM_STAT_PAGE(c) (NS9750_MEM_STAT_WAIT_PAGE_BASE+(c)*0x20)
+#define NS9750_MEM_STAT_WR(c) (NS9750_MEM_STAT_WAIT_WR_BASE+(c)*0x20)
+#define NS9750_MEM_STAT_TURN(c) (NS9750_MEM_STAT_WAIT_TURN_BASE+(c)*0x20)
+
+/* register bit fields */
+
+#define NS9750_MEM_CTRL_L (0x00000004)
+#define NS9750_MEM_CTRL_M (0x00000002)
+#define NS9750_MEM_CTRL_E (0x00000001)
+
+#define NS9750_MEM_STAT_SA (0x00000004)
+#define NS9750_MEM_STAT_S (0x00000002)
+#define NS9750_MEM_STAT_B (0x00000001)
+
+#define NS9750_MEM_CFG_CLK (0x00000010)
+#define NS9750_MEM_CFG_N (0x00000001)
+
+#define NS9750_MEM_DYN_CTRL_NRP (0x00004000)
+#define NS9750_MEM_DYN_CTRL_DP (0x00002000)
+#define NS9750_MEM_DYN_CTRL_I_MA (0x00000180)
+#define NS9750_MEM_DYN_CTRL_I_NORMAL (0x00000000)
+#define NS9750_MEM_DYN_CTRL_I_MODE (0x00000080)
+#define NS9750_MEM_DYN_CTRL_I_PALL (0x00000100)
+#define NS9750_MEM_DYN_CTRL_I_NOP (0x00000180)
+#define NS9750_MEM_DYN_CTRL_SR (0x00000002)
+#define NS9750_MEM_DYN_CTRL_CE (0x00000001)
+
+
+#define NS9750_MEM_DYN_REFRESH_MA (0x000007FF)
+
+#define NS9750_MEM_DYN_READ_CFG_MA (0x00000003)
+#define NS9750_MEM_DYN_READ_CFG_DELAY0 (0x00000001)
+#define NS9750_MEM_DYN_READ_CFG_DELAY1 (0x00000002)
+#define NS9750_MEM_DYN_READ_CFG_DELAY2 (0x00000003)
+
+#define NS9750_MEM_DYN_TRP_MA (0x0000000F)
+
+#define NS9750_MEM_DYN_TRAS_MA (0x0000000F)
+
+#define NS9750_MEM_DYN_TSREX_MA (0x0000000F)
+
+#define NS9750_MEM_DYN_TAPR_MA (0x0000000F)
+
+#define NS9750_MEM_DYN_TDAL_MA (0x0000000F)
+
+#define NS9750_MEM_DYN_TWR_MA (0x0000000F)
+
+#define NS9750_MEM_DYN_TRC_MA (0x0000001F)
+
+#define NS9750_MEM_DYN_TRFC_MA (0x0000001F)
+
+#define NS9750_MEM_DYN_TXSR_MA (0x0000001F)
+
+#define NS9750_MEM_DYN_TRRD_MA (0x0000000F)
+
+#define NS9750_MEM_DYN_TMRD_MA (0x0000000F)
+
+#define NS9750_MEM_STAT_EXTW_WAIT_MA (0x0000003F)
+
+#define NS9750_MEM_DYN_CFG_P (0x00100000)
+#define NS9750_MEM_DYN_CFG_BDMC (0x00080000)
+#define NS9750_MEM_DYN_CFG_AM (0x00004000)
+#define NS9750_MEM_DYN_CFG_AM_MA (0x00001F80)
+#define NS9750_MEM_DYN_CFG_MD (0x00000018)
+
+#define NS9750_MEM_DYN_RAS_CAS_CAS_MA (0x00000300)
+#define NS9750_MEM_DYN_RAS_CAS_CAS_1 (0x00000100)
+#define NS9750_MEM_DYN_RAS_CAS_CAS_2 (0x00000200)
+#define NS9750_MEM_DYN_RAS_CAS_CAS_3 (0x00000300)
+#define NS9750_MEM_DYN_RAS_CAS_RAS_MA (0x00000003)
+#define NS9750_MEM_DYN_RAS_CAS_RAS_1 (0x00000001)
+#define NS9750_MEM_DYN_RAS_CAS_RAS_2 (0x00000002)
+#define NS9750_MEM_DYN_RAS_CAS_RAS_3 (0x00000003)
+
+#define NS9750_MEM_STAT_CFG_PSMC (0x00100000)
+#define NS9750_MEM_STAT_CFG_BSMC (0x00080000)
+#define NS9750_MEM_STAT_CFG_EW (0x00000100)
+#define NS9750_MEM_STAT_CFG_PB (0x00000080)
+#define NS9750_MEM_STAT_CFG_PC (0x00000040)
+#define NS9750_MEM_STAT_CFG_PM (0x00000008)
+#define NS9750_MEM_STAT_CFG_MW_MA (0x00000003)
+#define NS9750_MEM_STAT_CFG_MW_8 (0x00000000)
+#define NS9750_MEM_STAT_CFG_MW_16 (0x00000001)
+#define NS9750_MEM_STAT_CFG_MW_32 (0x00000002)
+
+#define NS9750_MEM_STAT_WAIT_WEN_MA (0x0000000F)
+
+#define NS9750_MEM_STAT_WAIT_OEN_MA (0x0000000F)
+
+#define NS9750_MEM_STAT_WAIT_RD_MA (0x0000001F)
+
+#define NS9750_MEM_STAT_WAIT_PAGE_MA (0x0000001F)
+
+#define NS9750_MEM_STAT_WAIT_WR_MA (0x0000001F)
+
+#define NS9750_MEM_STAT_WAIT_TURN_MA (0x0000000F)
+
+
+#endif /* FS_NS9750_MEM_H */
diff --git a/include/ns9750_ser.h b/include/ns9750_ser.h
new file mode 100644
index 0000000..e6ff3e1
--- /dev/null
+++ b/include/ns9750_ser.h
@@ -0,0 +1,202 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_ser.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @References: [1] NS9750 Hardware Reference, December 2003
+ *
+ * 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 FS_NS9750_SER_H
+#define FS_NS9750_SER_H
+
+#define NS9750_SER_MODULE_BASE (0x90200000)
+
+#define get_ser_reg_addr(c) \
+ ((volatile unsigned int *)(NS9750_SER_MODULE_BASE+(unsigned int) (c)))
+
+#define get_ser_reg_addr_channel(reg,chan) \
+ get_ser_reg_addr((reg)+(((chan)<2)?0:0x00100000)+(((chan)&1)?0x40:0))
+
+/* the register addresses */
+
+#define NS9750_SER_CTRL_A (0x00)
+#define NS9750_SER_CTRL_B (0x04)
+#define NS9750_SER_STAT_A (0x08)
+#define NS9750_SER_BITRATE (0x0C)
+#define NS9750_SER_FIFO (0x10)
+#define NS9750_SER_RX_BUF_TIMER (0x14)
+#define NS9750_SER_RX_CHAR_TIMER (0x18)
+#define NS9750_SER_RX_MATCH (0x1C)
+#define NS9750_SER_RX_MATCH_MASK (0x20)
+#define NS9750_SER_FLOW_CTRL (0x34)
+#define NS9750_SER_FLOW_CTRL_FORCE (0x38)
+
+/* register bit fields */
+
+/* control A register */
+
+#define NS9750_SER_CTRL_A_CE (0x80000000)
+#define NS9750_SER_CTRL_A_BRK (0x40000000)
+#define NS9750_SER_CTRL_A_STICKP (0x20000000)
+#define NS9750_SER_CTRL_A_EPS (0x10000000)
+#define NS9750_SER_CTRL_A_PE (0x08000000)
+#define NS9750_SER_CTRL_A_STOP (0x04000000)
+#define NS9750_SER_CTRL_A_WLS_MA (0x03000000)
+#define NS9750_SER_CTRL_A_WLS_5 (0x00000000)
+#define NS9750_SER_CTRL_A_WLS_6 (0x01000000)
+#define NS9750_SER_CTRL_A_WLS_7 (0x02000000)
+#define NS9750_SER_CTRL_A_WLS_8 (0x03000000)
+#define NS9750_SER_CTRL_A_CTSTX (0x00800000)
+#define NS9750_SER_CTRL_A_RTSRX (0x00400000)
+#define NS9750_SER_CTRL_A_RL (0x00200000)
+#define NS9750_SER_CTRL_A_LL (0x00100000)
+#define NS9750_SER_CTRL_A_RES (0x000CF000)
+#define NS9750_SER_CTRL_A_DTR (0x00020000)
+#define NS9750_SER_CTRL_A_RTS (0x00010000)
+#define NS9750_SER_CTRL_A_RIE_MA (0x00000E00)
+#define NS9750_SER_CTRL_A_ERXDMA (0x00000100)
+#define NS9750_SER_CTRL_A_RIC_MA (0x000000E0)
+#define NS9750_SER_CTRL_A_TIC_MA (0x0000001E)
+#define NS9750_SER_CTRL_A_ETXDMA (0x00000001)
+
+/* control B register */
+
+#define NS9750_SER_CTRL_B_RDM1 (0x80000000)
+#define NS9750_SER_CTRL_B_RDM2 (0x40000000)
+#define NS9750_SER_CTRL_B_RDM3 (0x20000000)
+#define NS9750_SER_CTRL_B_RDM4 (0x10000000)
+#define NS9750_SER_CTRL_B_RBGT (0x08000000)
+#define NS9750_SER_CTRL_B_RCGT (0x04000000)
+#define NS9750_SER_CTRL_B_MODE_MA (0x00300000)
+#define NS9750_SER_CTRL_B_MODE_UART (0x00000000)
+#define NS9750_SER_CTRL_B_MODE_HDLC (0x00100000)
+#define NS9750_SER_CTRL_B_MODE_SPI_M (0x00200000)
+#define NS9750_SER_CTRL_B_MODE_SPI_S (0x00300000)
+#define NS9750_SER_CTRL_B_BITORDR (0x00080000)
+#define NS9750_SER_CTRL_B_RES (0x0007703F)
+#define NS9750_SER_CTRL_B_RTSTX (0x00008000)
+#define NS9750_SER_CTRL_B_ENDEC_MA (0x00000FC0)
+
+/* status A register */
+
+#define NS9750_SER_STAT_A_MATCH1 (0x80000000)
+#define NS9750_SER_STAT_A_MATCH2 (0x40000000)
+#define NS9750_SER_STAT_A_MATCH3 (0x20000000)
+#define NS9750_SER_STAT_A_MATCH4 (0x10000000)
+#define NS9750_SER_STAT_A_BGAP (0x08000000)
+#define NS9750_SER_STAT_A_CGAP (0x04000000)
+#define NS9750_SER_STAT_A_RXFDB_MA (0x00300000)
+#define NS9750_SER_STAT_A_RXFDB_FULL (0x00000000)
+#define NS9750_SER_STAT_A_RXFDB_1 (0x00100000)
+#define NS9750_SER_STAT_A_RXFDB_2 (0x00200000)
+#define NS9750_SER_STAT_A_RXFDB_3 (0x00300000)
+#define NS9750_SER_STAT_A_DCD (0x00080000)
+#define NS9750_SER_STAT_A_RI (0x00040000)
+#define NS9750_SER_STAT_A_DSR (0x00020000)
+#define NS9750_SER_STAT_A_CTS (0x00010000)
+#define NS9750_SER_STAT_A_RBRK (0x00008000)
+#define NS9750_SER_STAT_A_RFE (0x00004000)
+#define NS9750_SER_STAT_A_RPE (0x00002000)
+#define NS9750_SER_STAT_A_ROVER (0x00001000)
+#define NS9750_SER_STAT_A_RRDY (0x00000800)
+#define NS9750_SER_STAT_A_RHALF (0x00000400)
+#define NS9750_SER_STAT_A_RBC (0x00000200)
+#define NS9750_SER_STAT_A_RFULL (0x00000100)
+#define NS9750_SER_STAT_A_DCDI (0x00000080)
+#define NS9750_SER_STAT_A_RII (0x00000040)
+#define NS9750_SER_STAT_A_DSRI (0x00000020)
+#define NS9750_SER_STAT_A_CTSI (0x00000010)
+#define NS9750_SER_STAT_A_TRDY (0x00000008)
+#define NS9750_SER_STAT_A_THALF (0x00000004)
+#define NS9750_SER_STAT_A_TBC (0x00000002)
+#define NS9750_SER_STAT_A_TEMPTY (0x00000001)
+
+#define NS9750_SER_STAT_A_RX_COND_ERR ( NS9750_SER_STAT_A_RFE | \
+ NS9750_SER_STAT_A_ROVER | \
+ NS9750_SER_STAT_A_RPE )
+#define NS9750_SER_STAT_A_RX_COND_ALL ( NS9750_SER_STAT_A_RX_COND_ERR | \
+ NS9750_SER_STAT_A_RBRK | \
+ NS9750_SER_STAT_A_RRDY | \
+ NS9750_SER_STAT_A_RHALF | \
+ NS9750_SER_STAT_A_RBC | \
+ NS9750_SER_STAT_A_DCDI | \
+ NS9750_SER_STAT_A_RII | \
+ NS9750_SER_STAT_A_DSRI | \
+ NS9750_SER_STAT_A_CTSI )
+#define NS9750_SER_STAT_A_TX_COND_ALL ( NS9750_SER_STAT_A_TRDY | \
+ NS9750_SER_STAT_A_THALF | \
+ NS9750_SER_STAT_A_TBC | \
+ NS9750_SER_STAT_A_TEMPTY )
+/* bit rate register */
+
+#define NS9750_SER_BITRATE_EBIT (0x80000000)
+#define NS9750_SER_BITRATE_TMODE (0x40000000)
+#define NS9750_SER_BITRATE_RXSRC (0x20000000)
+#define NS9750_SER_BITRATE_TXSRC (0x10000000)
+#define NS9750_SER_BITRATE_RXEXT (0x08000000)
+#define NS9750_SER_BITRATE_TXEXT (0x04000000)
+#define NS9750_SER_BITRATE_CLKMUX_MA (0x03000000)
+#define NS9750_SER_BITRATE_CLKMUX_XTAL (0x00000000)
+#define NS9750_SER_BITRATE_CLKMUX_BCLK (0x01000000)
+#define NS9750_SER_BITRATE_CLKMUX_OUT1 (0x02000000)
+#define NS9750_SER_BITRATE_CLKMUX_OUT2 (0x03000000)
+#define NS9750_SER_BITRATE_TXCINV (0x00800000)
+#define NS9750_SER_BITRATE_RXCINV (0x00400000)
+#define NS9750_SER_BITRATE_TCDR_MA (0x00180000)
+#define NS9750_SER_BITRATE_TCDR_1 (0x00000000)
+#define NS9750_SER_BITRATE_TCDR_8 (0x00080000)
+#define NS9750_SER_BITRATE_TCDR_16 (0x00100000)
+#define NS9750_SER_BITRATE_TCDR_32 (0x00180000)
+#define NS9750_SER_BITRATE_RCDR_MA (0x00070000)
+#define NS9750_SER_BITRATE_RCDR_1 (0x00000000)
+#define NS9750_SER_BITRATE_RCDR_8 (0x00020000)
+#define NS9750_SER_BITRATE_RCDR_16 (0x00040000)
+#define NS9750_SER_BITRATE_RCDR_32 (0x00060000)
+#define NS9750_SER_BITRATE_TICS (0x00010000)
+#define NS9750_SER_BITRATE_RICS (0x00008000)
+#define NS9750_SER_BITRATE_N_MA (0x00007FFF)
+
+/* receive buffer gap timer */
+
+#define NS9750_SER_RX_BUF_TIMER_TRUN (0x80000000) /* UART and SPI */
+#define NS9750_SER_RX_BUF_TIMER_BT_MA (0x0000FFFF) /* UART and SPI */
+#define NS9750_SER_RX_BUF_TIMER_MAXLEN_MA (0x0000FFFF) /* HDLC only */
+
+/* receive character gap timer */
+
+#define NS9750_SER_RX_CHAR_TIMER_TRUN (0x80000000)
+#define NS9750_SER_RX_CHAR_TIMER_CT_MA (0x000FFFFF)
+
+/* receive match */
+
+#define NS9750_SER_RX_MATCH_RDMB1_MA (0xFF000000)
+#define NS9750_SER_RX_MATCH_RDMB2_MA (0x00FF0000)
+#define NS9750_SER_RX_MATCH_RDMB3_MA (0x0000FF00)
+#define NS9750_SER_RX_MATCH_RDMB4_MA (0x000000FF)
+
+/* receive match mask */
+
+#define NS9750_SER_RX_MATCH_MASK_RDMB1_MA (0xFF000000)
+#define NS9750_SER_RX_MATCH_MASK_RDMB2_MA (0x00FF0000)
+#define NS9750_SER_RX_MATCH_MASK_RDMB3_MA (0x0000FF00)
+#define NS9750_SER_RX_MATCH_MASK_RDMB4_MA (0x000000FF)
+
+#endif /* FS_NS9750_SER_H */
diff --git a/include/ns9750_sys.h b/include/ns9750_sys.h
new file mode 100644
index 0000000..c563cad
--- /dev/null
+++ b/include/ns9750_sys.h
@@ -0,0 +1,215 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_sys.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Definitions for SYS Control Module
+ * @References: [1] NS9750 Hardware Reference Manual/December 2003 Chap. 4
+ *
+ * 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 FS_NS9750_SYS_H
+#define FS_NS9750_SYS_H
+
+#define NS9750_SYS_MODULE_BASE (0xA0900000)
+
+#define get_sys_reg_addr(c) \
+ ((volatile unsigned int *)(NS9750_SYS_MODULE_BASE+(unsigned int) (c)))
+
+/* the register addresses */
+
+#define NS9750_SYS_AHB_GEN (0x0000)
+#define NS9750_SYS_BRC_BASE (0x0004)
+#define NS9750_SYS_AHB_TIMEOUT (0x0014)
+#define NS9750_SYS_AHB_ERROR1 (0x0018)
+#define NS9750_SYS_AHB_ERROR2 (0x001C)
+#define NS9750_SYS_AHB_MON (0x0020)
+#define NS9750_SYS_TIMER_COUNT_BASE (0x0044)
+#define NS9750_SYS_TIMER_READ_BASE (0x0084)
+#define NS9750_SYS_INT_VEC_ADR_BASE (0x00C4)
+#define NS9750_SYS_INT_CFG_BASE (0x0144)
+#define NS9750_SYS_ISRADDR (0x0164)
+#define NS9750_SYS_INT_STAT_ACTIVE (0x0168)
+#define NS9750_SYS_INT_STAT_RAW (0x016C)
+#define NS9750_SYS_TIMER_INT_STAT (0x0170)
+#define NS9750_SYS_SW_WDOG_CFG (0x0174)
+#define NS9750_SYS_SW_WDOG_TIMER (0x0178)
+#define NS9750_SYS_CLOCK (0x017C)
+#define NS9750_SYS_RESET (0x0180)
+#define NS9750_SYS_MISC (0x0184)
+#define NS9750_SYS_PLL (0x0188)
+#define NS9750_SYS_ACT_INT_STAT (0x018C)
+#define NS9750_SYS_TIMER_CTRL_BASE (0x0190)
+#define NS9750_SYS_CS_DYN_BASE_BASE (0x01D0)
+#define NS9750_SYS_CS_DYN_MASK_BASE (0x01D4)
+#define NS9750_SYS_CS_STATIC_BASE_BASE (0x01F0)
+#define NS9750_SYS_CS_STATIC_MASK_BASE (0x01F4)
+#define NS9750_SYS_GEN_ID (0x0210)
+#define NS9750_SYS_EXT_INT_CTRL_BASE (0x0214)
+
+/* the vectored register addresses */
+
+#define NS9750_SYS_TIMER_COUNT(c) (NS9750_SYS_TIMER_COUNT_BASE + (c))
+#define NS9750_SYS_TIMER_READ(c) (NS9750_SYS_TIMER_READ_BASE + (c))
+#define NS9750_SYS_INT_VEC_ADR(c) (NS9750_SYS_INT_VEC_ADR_BASE + (c))
+#define NS9750_SYS_TIMER_CTRL(c) (NS9750_SYS_TIMER_CTRL_BASE + (c))
+/* CS_DYN start with 4 */
+#define NS9750_SYS_CS_DYN_BASE(c) (NS9750_SYS_CS_DYN_BASE_BASE + ((c)-4)*2)
+#define NS9750_SYS_CS_DYN_MASK(c) (NS9750_SYS_CS_DYN_MASK_BASE + ((c)-4)*2)
+/* CS_STATIC start with 0 */
+#define NS9750_SYS_CS_STATIC_BASE(c) (NS9750_SYS_CS_STATIC_BASE_BASE + (c)*2)
+#define NS9750_SYS_CS_STATIC_MASK(c) (NS9750_SYS_CS_STATIC_MASK_BASE + (c)*2)
+#define NS9750_SYS_EXT_INT_CTRL(c) (NS9750_SYS_EXT_INT_CTRL + (c))
+
+/* register bit fields */
+
+#define NS9750_SYS_AHB_GEN_EXMAM (0x00000001)
+
+/* need to be n*8bit to BRC channel */
+#define NS9750_SYS_BRC_CEB (0x00000080)
+#define NS9750_SYS_BRC_BRF_MA (0x00000030)
+#define NS9750_SYS_BRC_BRF_100 (0x00000000)
+#define NS9750_SYS_BRC_BRF_75 (0x00000010)
+#define NS9750_SYS_BRC_BRF_50 (0x00000020)
+#define NS9750_SYS_BRC_BRF_25 (0x00000030)
+
+#define NS9750_SYS_AHB_TIMEOUT_BAT_MA (0xFFFF0000)
+#define NS9750_SYS_AHB_TIMEOUT_BMT_MA (0x0000FFFF)
+
+#define NS9750_SYS_AHB_ERROR2_ABL (0x00040000)
+#define NS9750_SYS_AHB_ERROR2_AER (0x00020000)
+#define NS9750_SYS_AHB_ERROR2_ABM (0x00010000)
+#define NS9750_SYS_AHB_ERROR2_ABA (0x00008000)
+#define NS9750_SYS_AHB_ERROR2_HWRT (0x00004000)
+#define NS9750_SYS_AHB_ERROR2_HMID_MA (0x00003C00)
+#define NS9750_SYS_AHB_ERROR2_HTPC_MA (0x000003C0)
+#define NS9750_SYS_AHB_ERROR2_HSZ_MA (0x00000038)
+#define NS9750_SYS_AHB_ERROR2_RR_MA (0x00000007)
+
+#define NS9750_SYS_AHB_MON_EIC (0x00800000)
+#define NS9750_SYS_AHB_MON_MBII (0x00400000)
+#define NS9750_SYS_AHB_MON_MBL_MA (0x003FFFC0)
+#define NS9750_SYS_AHB_MON_MBLDC (0x00000020)
+#define NS9750_SYS_AHB_MON_SERDC (0x00000010)
+#define NS9750_SYS_AHB_MON_BMTC_MA (0x0000000C)
+#define NS9750_SYS_AHB_MON_BMTC_RECORD (0x00000000)
+#define NS9750_SYS_AHB_MON_BMTC_GEN_IRQ (0x00000004)
+#define NS9750_SYS_AHB_MON_BMTC_GEN_RES (0x00000008)
+#define NS9750_SYS_AHB_MON_BATC_MA (0x00000003)
+#define NS9750_SYS_AHB_MON_BATC_RECORD (0x00000000)
+#define NS9750_SYS_AHB_MON_BATC_GEN_IRQ (0x00000001)
+#define NS9750_SYS_AHB_MON_BATC_GEN_RES (0x00000002)
+
+/* need to be n*8bit to Int Level */
+
+#define NS9750_SYS_INT_CFG_IE (0x00000080)
+#define NS9750_SYS_INT_CFG_IT (0x00000020)
+#define NS9750_SYS_INT_CFG_IAD_MA (0x0000001F)
+
+#define NS9750_SYS_TIMER_INT_STAT_MA (0x0000FFFF)
+
+#define NS9750_SYS_SW_WDOG_CFG_SWWE (0x00000080)
+#define NS9750_SYS_SW_WDOG_CFG_SWWI (0x00000020)
+#define NS9750_SYS_SW_WDOG_CFG_SWWIC (0x00000010)
+#define NS9750_SYS_SW_WDOG_CFG_SWTCS_MA (0x00000007)
+#define NS9750_SYS_SW_WDOG_CFG_SWTCS_2 (0x00000000)
+#define NS9750_SYS_SW_WDOG_CFG_SWTCS_4 (0x00000001)
+#define NS9750_SYS_SW_WDOG_CFG_SWTCS_8 (0x00000002)
+#define NS9750_SYS_SW_WDOG_CFG_SWTCS_16 (0x00000003)
+#define NS9750_SYS_SW_WDOG_CFG_SWTCS_32 (0x00000004)
+#define NS9750_SYS_SW_WDOG_CFG_SWTCS_64 (0x00000005)
+
+#define NS9750_SYS_CLOCK_LPCS_MA (0x00000380)
+#define NS9750_SYS_CLOCK_LPCS_1 (0x00000000)
+#define NS9750_SYS_CLOCK_LPCS_2 (0x00000080)
+#define NS9750_SYS_CLOCK_LPCS_4 (0x00000100)
+#define NS9750_SYS_CLOCK_LPCS_8 (0x00000180)
+#define NS9750_SYS_CLOCK_LPCS_EXT (0x00000200)
+#define NS9750_SYS_CLOCK_BBC (0x00000040)
+#define NS9750_SYS_CLOCK_LCC (0x00000020)
+#define NS9750_SYS_CLOCK_MCC (0x00000010)
+#define NS9750_SYS_CLOCK_PARBC (0x00000008)
+#define NS9750_SYS_CLOCK_PC (0x00000004)
+#define NS9750_SYS_CLOCK_MACC (0x00000001)
+
+#define NS9750_SYS_RESET_SR (0x80000000)
+#define NS9750_SYS_RESET_I2CW (0x00100000)
+#define NS9750_SYS_RESET_CSE (0x00080000)
+#define NS9750_SYS_RESET_SMWE (0x00040000)
+#define NS9750_SYS_RESET_EWE (0x00020000)
+#define NS9750_SYS_RESET_PI3WE (0x00010000)
+#define NS9750_SYS_RESET_BBT (0x00000040)
+#define NS9750_SYS_RESET_LCDC (0x00000020)
+#define NS9750_SYS_RESET_MEMC (0x00000010)
+#define NS9750_SYS_RESET_PCIAR (0x00000008)
+#define NS9750_SYS_RESET_PCIM (0x00000004)
+#define NS9750_SYS_RESET_MACM (0x00000001)
+
+#define NS9750_SYS_MISC_REV_MA (0xFF000000)
+#define NS9750_SYS_MISC_PCIA (0x00002000)
+#define NS9750_SYS_MISC_VDIS (0x00001000)
+#define NS9750_SYS_MISC_BMM (0x00000800)
+#define NS9750_SYS_MISC_CS1DB (0x00000400)
+#define NS9750_SYS_MISC_CS1DW_MA (0x00000300)
+#define NS9750_SYS_MISC_MCCM (0x00000080)
+#define NS9750_SYS_MISC_PMSS (0x00000040)
+#define NS9750_SYS_MISC_CS1P (0x00000020)
+#define NS9750_SYS_MISC_ENDM (0x00000008)
+#define NS9750_SYS_MISC_MBAR (0x00000004)
+#define NS9750_SYS_MISC_IRAM0 (0x00000001)
+
+#define NS9750_SYS_PLL_PLLBS (0x02000000)
+#define NS9750_SYS_PLL_PLLFS_MA (0x01800000)
+#define NS9750_SYS_PLL_PLLIS_MA (0x00600000)
+#define NS9750_SYS_PLL_PLLND_MA (0x001F0000)
+#define NS9750_SYS_PLL_PLLSW (0x00008000)
+#define NS9750_SYS_PLL_PLLBSSW (0x00000200)
+#define NS9750_SYS_PLL_FSEL_MA (0x00000180)
+#define NS9750_SYS_PLL_CPCC_MA (0x00000060)
+#define NS9750_SYS_PLL_NDSW_MA (0x0000001F)
+
+#define NS9750_SYS_ACT_INT_STAT_MA (0x0000FFFF)
+
+#define NS9750_SYS_TIMER_CTRL_TEN (0x00008000)
+#define NS9750_SYS_TIMER_CTRL_INTC (0x00000200)
+#define NS9750_SYS_TIMER_CTRL_TLCS_MA (0x000001C0)
+#define NS9750_SYS_TIMER_CTRL_TLCS_1 (0x00000000)
+#define NS9750_SYS_TIMER_CTRL_TLCS_2 (0x00000040)
+#define NS9750_SYS_TIMER_CTRL_TLCS_4 (0x00000080)
+#define NS9750_SYS_TIMER_CTRL_TLCS_8 (0x000000C0)
+#define NS9750_SYS_TIMER_CTRL_TLCS_16 (0x00000100)
+#define NS9750_SYS_TIMER_CTRL_TLCS_32 (0x00000140)
+#define NS9750_SYS_TIMER_CTRL_TLCS_64 (0x00000180)
+#define NS9750_SYS_TIMER_CTRL_TLCS_EXT (0x000001C0)
+#define NS9750_SYS_TIMER_CTRL_TM_MA (0x00000030)
+#define NS9750_SYS_TIMER_CTRL_TM_INT (0x00000000)
+#define NS9750_SYS_TIMER_CTRL_TM_LOW (0x00000010)
+#define NS9750_SYS_TIMER_CTRL_TM_HIGH (0x00000020)
+#define NS9750_SYS_TIMER_CTRL_INTS (0x00000008)
+#define NS9750_SYS_TIMER_CTRL_UDS (0x00000004)
+#define NS9750_SYS_TIMER_CTRL_TSZ (0x00000002)
+#define NS9750_SYS_TIMER_CTRL_REN (0x00000001)
+
+#define NS9750_SYS_EXT_INT_CTRL_STS (0x00000008)
+#define NS9750_SYS_EXT_INT_CTRL_CLR (0x00000004)
+#define NS9750_SYS_EXT_INT_CTRL_PLTY (0x00000002)
+#define NS9750_SYS_EXT_INT_CTRL_LVEDG (0x00000001)
+
+#endif /* FS_NS9750_SYS_H */