]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
* Patch by Markus Pietrek, 24 Feb 2004:
authorwdenk <wdenk>
Thu, 26 Feb 2004 23:46:20 +0000 (23:46 +0000)
committerwdenk <wdenk>
Thu, 26 Feb 2004 23:46:20 +0000 (23:46 +0000)
  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)

37 files changed:
CHANGELOG
CREDITS
MAINTAINERS
MAKEALL
Makefile
board/eXalion/Makefile [new file with mode: 0644]
board/eXalion/config.mk [new file with mode: 0644]
board/eXalion/eXalion.c [new file with mode: 0644]
board/eXalion/eXalion.h [new file with mode: 0644]
board/eXalion/piix_pci.h [new file with mode: 0644]
board/eXalion/u-boot.lds [new file with mode: 0644]
board/ns9750dev/Makefile [new file with mode: 0644]
board/ns9750dev/config.mk [new file with mode: 0644]
board/ns9750dev/flash.c [new file with mode: 0644]
board/ns9750dev/led.c [new file with mode: 0644]
board/ns9750dev/ns9750dev.c [new file with mode: 0644]
board/ns9750dev/platform.S [new file with mode: 0644]
board/ns9750dev/u-boot.lds [new file with mode: 0644]
board/omap1610inn/platform.S
common/cmd_mii.c
common/usb_storage.c
cpu/mpc5xxx/Makefile
cpu/mpc5xxx/usb_ohci.c [new file with mode: 0644]
cpu/mpc5xxx/usb_ohci.h [new file with mode: 0644]
doc/README.ns9750dev [new file with mode: 0644]
drivers/ns9750_eth.c [new file with mode: 0644]
drivers/ns9750_serial.c [new file with mode: 0644]
fs/fat/fat.c
include/configs/IceCube.h
include/configs/eXalion.h [new file with mode: 0644]
include/configs/ns9750dev.h [new file with mode: 0644]
include/mpc5xxx.h
include/ns9750_bbus.h [new file with mode: 0644]
include/ns9750_eth.h [new file with mode: 0644]
include/ns9750_mem.h [new file with mode: 0644]
include/ns9750_ser.h [new file with mode: 0644]
include/ns9750_sys.h [new file with mode: 0644]

index 85394aaf895ffb35898806a8732d17fc974b3a3a..64277b1af599ed647493b793331b5ffe3af70459 100644 (file)
--- 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 047240df0401856040ae86f2d991d984ed182edb..c6ebb4a9a177f6441f8293df66697d50b64cb259 100644 (file)
--- 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
index f23d9e2f6de0bae6157aa8dc8be1b8ba3b18f7dc..b692c19bc8eb89196e44de7ecffe7f97d72de92d 100644 (file)
@@ -49,6 +49,10 @@ K
 
        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 a099980868e0a919a4194c6eede911115ece88a9..dec6f53608db9c09bc96bfaaf904212cb2b9c7f2 100644 (file)
--- 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                         \
 "
 
 #########################################################################
index 6dab719304a9cf0a50ea265dc6cc7d594ca37f53..8c822c6defa1670c52bf8f4fa1db4e4ba6a099d5 100644 (file)
--- 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 (file)
index 0000000..110d09d
--- /dev/null
@@ -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 (file)
index 0000000..b3f65eb
--- /dev/null
@@ -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 (file)
index 0000000..2e3f519
--- /dev/null
@@ -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 (file)
index 0000000..8dccabb
--- /dev/null
@@ -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 (file)
index 0000000..b3c9c16
--- /dev/null
@@ -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 (file)
index 0000000..98584dc
--- /dev/null
@@ -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 (file)
index 0000000..d2718cc
--- /dev/null
@@ -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 (file)
index 0000000..6a22cee
--- /dev/null
@@ -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 (file)
index 0000000..e7d6515
--- /dev/null
@@ -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 (file)
index 0000000..ab27f7b
--- /dev/null
@@ -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 (file)
index 0000000..0ea89a5
--- /dev/null
@@ -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 (file)
index 0000000..11f9aef
--- /dev/null
@@ -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 (file)
index 0000000..8a05892
--- /dev/null
@@ -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 = . ;
+
+}
index 2fa4378b62790656534829182757f5e7518ad64e..441edc28aedf51d3818f4ac571ba3c85ebf44f0a 100644 (file)
@@ -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)                   *
         *------------------------------------------------------*/
index f8ebef6af512abcadc2ee6044e94eccfba1ccff3..abbdaa2be3b0cdb5a2e9c0171426e59ba9bc339b 100644 (file)
@@ -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;
 }
index d99f25963a0da7e64aec3cc2c830290184eaa322..dbe9cd9b8e7d0ad1d02edbc6dec0b6dac1d47ab8 100644 (file)
@@ -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
 
 #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;
        }
index a65bc2232eb82680e86022147a307204d3f79bca..5b5a33bc74c18777146693e1314411a33017b36a 100644 (file)
@@ -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 (file)
index 0000000..5b5eac2
--- /dev/null
@@ -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 (file)
index 0000000..11b361a
--- /dev/null
@@ -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 (file)
index 0000000..2991440
--- /dev/null
@@ -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 (file)
index 0000000..067ff8e
--- /dev/null
@@ -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 (file)
index 0000000..aced3da
--- /dev/null
@@ -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 */
index daa70349d27a786f23140e67808f51f95ce5155a..6f1e57cbc9af8a4cf8bb4694408263c802aba511 100644 (file)
@@ -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;
index 888b1652306f84fff4249ce04c16dea8470cf485..1dc992598c83e23f7ae59fbfe4bdab1ff3aa25d2 100644 (file)
@@ -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
 
 #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 (file)
index 0000000..5ebc7a9
--- /dev/null
@@ -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 (file)
index 0000000..11d21b2
--- /dev/null
@@ -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 */
index 49951f5972e938a4952910f9235416dce47a1244..8d4013a16fa4c71274289030ba69cee3c57aba3e 100644 (file)
@@ -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)
 
 #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 (file)
index 0000000..0918931
--- /dev/null
@@ -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 (file)
index 0000000..ce0c841
--- /dev/null
@@ -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 (file)
index 0000000..44c8ddc
--- /dev/null
@@ -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 (file)
index 0000000..e6ff3e1
--- /dev/null
@@ -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 (file)
index 0000000..c563cad
--- /dev/null
@@ -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 */