]> git.sur5r.net Git - u-boot/commitdiff
mips: Move cpu/mips/* to arch/mips/cpu/*
authorPeter Tyser <ptyser@xes-inc.com>
Tue, 13 Apr 2010 03:28:14 +0000 (22:28 -0500)
committerWolfgang Denk <wd@denx.de>
Tue, 13 Apr 2010 07:13:25 +0000 (09:13 +0200)
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
33 files changed:
arch/mips/cpu/Makefile [new file with mode: 0644]
arch/mips/cpu/asc_serial.c [new file with mode: 0644]
arch/mips/cpu/asc_serial.h [new file with mode: 0644]
arch/mips/cpu/au1x00_eth.c [new file with mode: 0644]
arch/mips/cpu/au1x00_serial.c [new file with mode: 0644]
arch/mips/cpu/au1x00_usb_ohci.c [new file with mode: 0644]
arch/mips/cpu/au1x00_usb_ohci.h [new file with mode: 0644]
arch/mips/cpu/cache.S [new file with mode: 0644]
arch/mips/cpu/config.mk [new file with mode: 0644]
arch/mips/cpu/cpu.c [new file with mode: 0644]
arch/mips/cpu/incaip_clock.c [new file with mode: 0644]
arch/mips/cpu/incaip_wdt.S [new file with mode: 0644]
arch/mips/cpu/interrupts.c [new file with mode: 0644]
arch/mips/cpu/start.S [new file with mode: 0644]
board/dbau1x00/dbau1x00.c
board/gth2/gth2.c
board/pb1x00/pb1x00.c
board/purple/u-boot.lds
cpu/mips/Makefile [deleted file]
cpu/mips/asc_serial.c [deleted file]
cpu/mips/asc_serial.h [deleted file]
cpu/mips/au1x00_eth.c [deleted file]
cpu/mips/au1x00_serial.c [deleted file]
cpu/mips/au1x00_usb_ohci.c [deleted file]
cpu/mips/au1x00_usb_ohci.h [deleted file]
cpu/mips/cache.S [deleted file]
cpu/mips/config.mk [deleted file]
cpu/mips/cpu.c [deleted file]
cpu/mips/incaip_clock.c [deleted file]
cpu/mips/incaip_wdt.S [deleted file]
cpu/mips/interrupts.c [deleted file]
cpu/mips/start.S [deleted file]
drivers/usb/host/isp116x-hcd.c

diff --git a/arch/mips/cpu/Makefile b/arch/mips/cpu/Makefile
new file mode 100644 (file)
index 0000000..28a1cbb
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# (C) Copyright 2003-2006
+# 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    = $(obj)lib$(CPU).a
+
+START  = start.o
+SOBJS-y        = cache.o
+COBJS-y        = cpu.o interrupts.o
+
+SOBJS-$(CONFIG_INCA_IP)        += incaip_wdt.o
+COBJS-$(CONFIG_INCA_IP)        += asc_serial.o incaip_clock.o
+COBJS-$(CONFIG_PURPLE) += asc_serial.o
+COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o
+
+SRCS   := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS   := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+START  := $(addprefix $(obj),$(START))
+
+all:   $(obj).depend $(START) $(LIB)
+
+$(LIB):        $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/mips/cpu/asc_serial.c b/arch/mips/cpu/asc_serial.c
new file mode 100644 (file)
index 0000000..be686c2
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * (INCA) ASC UART support
+ */
+
+#include <config.h>
+
+#ifdef CONFIG_PURPLE
+#define        serial_init     asc_serial_init
+#define        serial_putc     asc_serial_putc
+#define        serial_puts     asc_serial_puts
+#define        serial_getc     asc_serial_getc
+#define        serial_tstc     asc_serial_tstc
+#define        serial_setbrg   asc_serial_setbrg
+#endif
+
+#include <common.h>
+#include <asm/inca-ip.h>
+#include "asc_serial.h"
+
+#ifdef CONFIG_PURPLE
+
+#undef ASC_FIFO_PRESENT
+#define TOUT_LOOP      100000
+
+/* Set base address for second FPI interrupt control register bank */
+#define SFPI_INTCON_BASEADDR   0xBF0F0000
+
+/* Register offset from base address */
+#define FBS_ISR                0x00000000      /* Interrupt status register */
+#define FBS_IMR                0x00000008      /* Interrupt mask register */
+#define FBS_IDIS       0x00000010      /* Interrupt disable register */
+
+/* Interrupt status register bits */
+#define FBS_ISR_AT     0x00000040      /* ASC transmit interrupt */
+#define FBS_ISR_AR     0x00000020      /* ASC receive interrupt */
+#define FBS_ISR_AE     0x00000010      /* ASC error interrupt */
+#define FBS_ISR_AB     0x00000008      /* ASC transmit buffer interrupt */
+#define FBS_ISR_AS      0x00000004     /* ASC start of autobaud detection interrupt */
+#define FBS_ISR_AF     0x00000002      /* ASC end of autobaud detection interrupt */
+
+#else
+
+#define ASC_FIFO_PRESENT
+
+#endif
+
+
+#define SET_BIT(reg, mask)                  reg |= (mask)
+#define CLEAR_BIT(reg, mask)                reg &= (~mask)
+#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)
+#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}
+
+extern uint incaip_get_fpiclk(void);
+
+static int serial_setopt (void);
+
+/* pointer to ASC register base address */
+static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC;
+
+/******************************************************************************
+*
+* serial_init - initialize a INCAASC channel
+*
+* This routine initializes the number of data bits, parity
+* and set the selected baud rate. Interrupts are disabled.
+* Set the modem control signals if the option is selected.
+*
+* RETURNS: N/A
+*/
+
+int serial_init (void)
+{
+#ifdef CONFIG_INCA_IP
+    /* we have to set PMU.EN13 bit to enable an ASC device*/
+    INCAASC_PMU_ENABLE(13);
+#endif
+
+    /* and we have to set CLC register*/
+    CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS);
+    SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001);
+
+    /* initialy we are in async mode */
+    pAsc->asc_con = ASCCON_M_8ASYNC;
+
+    /* select input port */
+    pAsc->asc_pisel = (CONSOLE_TTY & 0x1);
+
+#ifdef ASC_FIFO_PRESENT
+    /* TXFIFO's filling level */
+    SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,
+                   ASCTXFCON_TXFITLOFF, INCAASC_TXFIFO_FL);
+    /* enable TXFIFO */
+    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);
+
+    /* RXFIFO's filling level */
+    SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,
+                   ASCRXFCON_RXFITLOFF, INCAASC_RXFIFO_FL);
+    /* enable RXFIFO */
+    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);
+#endif
+
+    /* enable error signals */
+    SET_BIT(pAsc->asc_con, ASCCON_FEN);
+    SET_BIT(pAsc->asc_con, ASCCON_OEN);
+
+#ifdef CONFIG_INCA_IP
+    /* acknowledge ASC interrupts */
+    ASC_INTERRUPTS_CLEAR(INCAASC_IRQ_LINE_ALL);
+
+    /* disable ASC interrupts */
+    ASC_INTERRUPTS_DISABLE(INCAASC_IRQ_LINE_ALL);
+#endif
+
+#ifdef ASC_FIFO_PRESENT
+    /* set FIFOs into the transparent mode */
+    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXTMEN);
+    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXTMEN);
+#endif
+
+    /* set baud rate */
+    serial_setbrg();
+
+    /* set the options */
+    serial_setopt();
+
+    return 0;
+}
+
+void serial_setbrg (void)
+{
+    ulong      uiReloadValue, fdv;
+    ulong      f_ASC;
+
+#ifdef CONFIG_INCA_IP
+    f_ASC = incaip_get_fpiclk();
+#else
+    f_ASC = ASC_CLOCK_RATE;
+#endif
+
+#ifndef INCAASC_USE_FDV
+    fdv = 2;
+    uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
+#else
+    fdv = INCAASC_FDV_HIGH_BAUDRATE;
+    uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
+#endif /* INCAASC_USE_FDV */
+
+    if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
+    {
+#ifndef INCAASC_USE_FDV
+       fdv = 3;
+       uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
+#else
+       fdv = INCAASC_FDV_LOW_BAUDRATE;
+       uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
+#endif /* INCAASC_USE_FDV */
+
+       if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
+       {
+           return;    /* can't impossibly generate that baud rate */
+       }
+    }
+
+    /* Disable Baud Rate Generator; BG should only be written when R=0 */
+    CLEAR_BIT(pAsc->asc_con, ASCCON_R);
+
+#ifndef INCAASC_USE_FDV
+    /*
+     * Disable Fractional Divider (FDE)
+     * Divide clock by reload-value + constant (BRS)
+     */
+    /* FDE = 0 */
+    CLEAR_BIT(pAsc->asc_con, ASCCON_FDE);
+
+    if ( fdv == 2 )
+       CLEAR_BIT(pAsc->asc_con, ASCCON_BRS);   /* BRS = 0 */
+    else
+       SET_BIT(pAsc->asc_con, ASCCON_BRS); /* BRS = 1 */
+
+#else /* INCAASC_USE_FDV */
+
+    /* Enable Fractional Divider */
+    SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */
+
+    /* Set fractional divider value */
+    pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;
+
+#endif /* INCAASC_USE_FDV */
+
+    /* Set reload value in BG */
+    pAsc->asc_bg = uiReloadValue;
+
+    /* Enable Baud Rate Generator */
+    SET_BIT(pAsc->asc_con, ASCCON_R);           /* R = 1 */
+}
+
+/*******************************************************************************
+*
+* serial_setopt - set the serial options
+*
+* Set the channel operating mode to that specified. Following options
+* are supported: CREAD, CSIZE, PARENB, and PARODD.
+*
+* Note, this routine disables the transmitter.  The calling routine
+* may have to re-enable it.
+*
+* RETURNS:
+* Returns 0 to indicate success, otherwise -1 is returned
+*/
+
+static int serial_setopt (void)
+{
+    ulong  con;
+
+    switch ( ASC_OPTIONS & ASCOPT_CSIZE )
+    {
+    /* 7-bit-data */
+    case ASCOPT_CS7:
+       con = ASCCON_M_7ASYNCPAR;   /* 7-bit-data and parity bit */
+       break;
+
+    /* 8-bit-data */
+    case ASCOPT_CS8:
+       if ( ASC_OPTIONS & ASCOPT_PARENB )
+           con = ASCCON_M_8ASYNCPAR;   /* 8-bit-data and parity bit */
+       else
+           con = ASCCON_M_8ASYNC;      /* 8-bit-data no parity */
+       break;
+
+    /*
+     *  only 7 and 8-bit frames are supported
+     *  if we don't use IOCTL extensions
+     */
+    default:
+       return -1;
+    }
+
+    if ( ASC_OPTIONS & ASCOPT_STOPB )
+       SET_BIT(con, ASCCON_STP);       /* 2 stop bits */
+    else
+       CLEAR_BIT(con, ASCCON_STP);     /* 1 stop bit */
+
+    if ( ASC_OPTIONS & ASCOPT_PARENB )
+       SET_BIT(con, ASCCON_PEN);           /* enable parity checking */
+    else
+       CLEAR_BIT(con, ASCCON_PEN);         /* disable parity checking */
+
+    if ( ASC_OPTIONS & ASCOPT_PARODD )
+       SET_BIT(con, ASCCON_ODD);       /* odd parity */
+    else
+       CLEAR_BIT(con, ASCCON_ODD);     /* even parity */
+
+    if ( ASC_OPTIONS & ASCOPT_CREAD )
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_SETREN); /* Receiver enable */
+
+    pAsc->asc_con |= con;
+
+    return 0;
+}
+
+void serial_putc (const char c)
+{
+#ifdef ASC_FIFO_PRESENT
+    uint txFl = 0;
+#else
+    uint timeout = 0;
+#endif
+
+    if (c == '\n') serial_putc ('\r');
+
+#ifdef ASC_FIFO_PRESENT
+    /* check do we have a free space in the TX FIFO */
+    /* get current filling level */
+    do
+    {
+       txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF;
+    }
+    while ( txFl == INCAASC_TXFIFO_FULL );
+#else
+
+    while(!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &
+                          FBS_ISR_AB))
+    {
+           if (timeout++ > TOUT_LOOP)
+           {
+                   break;
+           }
+    }
+#endif
+
+    pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */
+
+#ifndef ASC_FIFO_PRESENT
+    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AB |
+                                                                FBS_ISR_AT;
+#endif
+
+    /* check for errors */
+    if ( pAsc->asc_con & ASCCON_OE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
+       return;
+    }
+}
+
+void serial_puts (const char *s)
+{
+    while (*s)
+    {
+       serial_putc (*s++);
+    }
+}
+
+int serial_getc (void)
+{
+    ulong symbol_mask;
+    char c;
+
+    while (!serial_tstc());
+
+    symbol_mask =
+       ((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);
+
+    c = (char)(pAsc->asc_rbuf & symbol_mask);
+
+#ifndef ASC_FIFO_PRESENT
+    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AR;
+#endif
+
+    return c;
+}
+
+int serial_tstc (void)
+{
+    int res = 1;
+
+#ifdef ASC_FIFO_PRESENT
+    if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 )
+    {
+       res = 0;
+    }
+#else
+    if (!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &
+                                                               FBS_ISR_AR))
+
+    {
+       res = 0;
+    }
+#endif
+    else if ( pAsc->asc_con & ASCCON_FE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE);
+       res = 0;
+    }
+    else if ( pAsc->asc_con & ASCCON_PE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE);
+       res = 0;
+    }
+    else if ( pAsc->asc_con & ASCCON_OE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
+       res = 0;
+    }
+
+    return res;
+}
diff --git a/arch/mips/cpu/asc_serial.h b/arch/mips/cpu/asc_serial.h
new file mode 100644 (file)
index 0000000..7ffdcfa
--- /dev/null
@@ -0,0 +1,177 @@
+/* incaAscSio.h - (INCA) ASC UART tty driver header */
+
+#ifndef __INCincaAscSioh
+#define __INCincaAscSioh
+
+#include <asm/inca-ip.h>
+
+/* channel operating modes */
+#define        ASCOPT_CSIZE    0x00000003
+#define        ASCOPT_CS7      0x00000001
+#define        ASCOPT_CS8      0x00000002
+#define        ASCOPT_PARENB   0x00000004
+#define        ASCOPT_STOPB    0x00000008
+#define        ASCOPT_PARODD   0x00000010
+#define        ASCOPT_CREAD    0x00000020
+
+#define ASC_OPTIONS            (ASCOPT_CREAD | ASCOPT_CS8)
+
+/* ASC input select (0 or 1) */
+#define CONSOLE_TTY    0
+
+/* use fractional divider for baudrate settings */
+#define INCAASC_USE_FDV
+
+#ifdef INCAASC_USE_FDV
+   #define INCAASC_FDV_LOW_BAUDRATE        71
+   #define INCAASC_FDV_HIGH_BAUDRATE       453
+#endif /*INCAASC_USE_FDV*/
+
+
+#define INCAASC_TXFIFO_FL       1
+#define INCAASC_RXFIFO_FL       1
+#define INCAASC_TXFIFO_FULL     16
+
+/* interrupt lines masks for the ASC device interrupts*/
+/* change these macroses if it's necessary */
+#define INCAASC_IRQ_LINE_ALL        0x000F0000  /* all IRQs */
+
+#define INCAASC_IRQ_LINE_TIR            0x00010000      /* TIR - Tx */
+#define INCAASC_IRQ_LINE_RIR            0x00020000      /* RIR - Rx */
+#define INCAASC_IRQ_LINE_EIR            0x00040000      /* EIR - Err */
+#define INCAASC_IRQ_LINE_TBIR           0x00080000      /* TBIR - Tx Buf*/
+
+/* interrupt controller access macros */
+#define ASC_INTERRUPTS_ENABLE(X)  \
+   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) |= X;
+#define ASC_INTERRUPTS_DISABLE(X) \
+   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) &= ~X;
+#define ASC_INTERRUPTS_CLEAR(X)   \
+   *((volatile unsigned int*) INCA_IP_ICU_IM2_ISR) = X;
+
+/* CLC register's bits and bitfields */
+#define ASCCLC_DISR        0x00000001
+#define ASCCLC_DISS        0x00000002
+#define ASCCLC_RMCMASK     0x0000FF00
+#define ASCCLC_RMCOFFSET   8
+
+/* CON register's bits and bitfields */
+#define ASCCON_MODEMASK 0x0007
+    #define ASCCON_M_8SYNC          0x0
+    #define ASCCON_M_8ASYNC         0x1
+    #define ASCCON_M_8IRDAASYNC     0x2
+    #define ASCCON_M_7ASYNCPAR      0x3
+    #define ASCCON_M_9ASYNC         0x4
+    #define ASCCON_M_8WAKEUPASYNC   0x5
+    #define ASCCON_M_8ASYNCPAR      0x7
+#define ASCCON_STP      0x0008
+#define ASCCON_REN      0x0010
+#define ASCCON_PEN      0x0020
+#define ASCCON_FEN      0x0040
+#define ASCCON_OEN      0x0080
+#define ASCCON_PE       0x0100
+#define ASCCON_FE       0x0200
+#define ASCCON_OE       0x0400
+#define ASCCON_FDE      0x0800
+#define ASCCON_ODD      0x1000
+#define ASCCON_BRS      0x2000
+#define ASCCON_LB       0x4000
+#define ASCCON_R        0x8000
+
+/* WHBCON register's bits and bitfields */
+#define ASCWHBCON_CLRREN    0x0010
+#define ASCWHBCON_SETREN    0x0020
+#define ASCWHBCON_CLRPE     0x0100
+#define ASCWHBCON_CLRFE     0x0200
+#define ASCWHBCON_CLROE     0x0400
+#define ASCWHBCON_SETPE     0x0800
+#define ASCWHBCON_SETFE     0x1000
+#define ASCWHBCON_SETOE     0x2000
+
+/* ABCON register's bits and bitfields */
+#define ASCABCON_ABEN       0x0001
+#define ASCABCON_AUREN      0x0002
+#define ASCABCON_ABSTEN     0x0004
+#define ASCABCON_ABDETEN    0x0008
+#define ASCABCON_FCDETEN    0x0010
+#define ASCABCON_EMMASK     0x0300
+    #define ASCABCON_EMOFF          8
+       #define ASCABCON_EM_DISAB       0x0
+       #define ASCABCON_EM_DURAB       0x1
+       #define ASCABCON_EM_ALWAYS      0x2
+#define ASCABCON_TXINV      0x0400
+#define ASCABCON_RXINV      0x0800
+
+/* FDV register mask, offset and bitfields*/
+#define ASCFDV_VALUE_MASK     0x000001FF
+
+/* WHBABCON register's bits and bitfields */
+#define ASCWHBABCON_SETABEN     0x0001
+#define ASCWHBABCON_CLRABEN     0x0002
+
+/* ABSTAT register's bits and bitfields */
+#define ASCABSTAT_FCSDET    0x0001
+#define ASCABSTAT_FCCDET    0x0002
+#define ASCABSTAT_SCSDET    0x0004
+#define ASCABSTAT_SCCDET    0x0008
+#define ASCABSTAT_DETWAIT   0x0010
+
+/* WHBABSTAT register's bits and bitfields */
+#define ASCWHBABSTAT_CLRFCSDET  0x0001
+#define ASCWHBABSTAT_SETFCSDET  0x0002
+#define ASCWHBABSTAT_CLRFCCDET  0x0004
+#define ASCWHBABSTAT_SETFCCDET  0x0008
+#define ASCWHBABSTAT_CLRSCSDET  0x0010
+#define ASCWHBABSTAT_SETSCSDET  0x0020
+#define ASCWHBABSTAT_SETSCCDET  0x0040
+#define ASCWHBABSTAT_CLRSCCDET  0x0080
+#define ASCWHBABSTAT_CLRDETWAIT 0x0100
+#define ASCWHBABSTAT_SETDETWAIT 0x0200
+
+/* TXFCON register's bits and bitfields */
+#define ASCTXFCON_TXFEN         0x0001
+#define ASCTXFCON_TXFFLU        0x0002
+#define ASCTXFCON_TXTMEN        0x0004
+#define ASCTXFCON_TXFITLMASK    0x3F00
+#define ASCTXFCON_TXFITLOFF     8
+
+/* RXFCON register's bits and bitfields */
+#define ASCRXFCON_RXFEN         0x0001
+#define ASCRXFCON_RXFFLU        0x0002
+#define ASCRXFCON_RXTMEN        0x0004
+#define ASCRXFCON_RXFITLMASK    0x3F00
+#define ASCRXFCON_RXFITLOFF     8
+
+/* FSTAT register's bits and bitfields */
+#define ASCFSTAT_RXFFLMASK      0x003F
+#define ASCFSTAT_TXFFLMASK      0x3F00
+#define ASCFSTAT_TXFFLOFF       8
+
+#define INCAASC_PMU_ENABLE(BIT) *((volatile ulong*)0xBF102000) |= (0x1 << BIT);
+
+typedef  struct         /* incaAsc_t */
+{
+    volatile unsigned long  asc_clc;                            /*0x0000*/
+    volatile unsigned long  asc_pisel;                          /*0x0004*/
+    volatile unsigned long  asc_rsvd1[2];   /* for mapping */   /*0x0008*/
+    volatile unsigned long  asc_con;                            /*0x0010*/
+    volatile unsigned long  asc_bg;                             /*0x0014*/
+    volatile unsigned long  asc_fdv;                            /*0x0018*/
+    volatile unsigned long  asc_pmw;        /* not used */      /*0x001C*/
+    volatile unsigned long  asc_tbuf;                           /*0x0020*/
+    volatile unsigned long  asc_rbuf;                           /*0x0024*/
+    volatile unsigned long  asc_rsvd2[2];   /* for mapping */   /*0x0028*/
+    volatile unsigned long  asc_abcon;                          /*0x0030*/
+    volatile unsigned long  asc_abstat;     /* not used */      /*0x0034*/
+    volatile unsigned long  asc_rsvd3[2];   /* for mapping */   /*0x0038*/
+    volatile unsigned long  asc_rxfcon;                         /*0x0040*/
+    volatile unsigned long  asc_txfcon;                         /*0x0044*/
+    volatile unsigned long  asc_fstat;                          /*0x0048*/
+    volatile unsigned long  asc_rsvd4;      /* for mapping */   /*0x004C*/
+    volatile unsigned long  asc_whbcon;                         /*0x0050*/
+    volatile unsigned long  asc_whbabcon;                       /*0x0054*/
+    volatile unsigned long  asc_whbabstat;  /* not used */      /*0x0058*/
+
+} incaAsc_t;
+
+#endif /* __INCincaAscSioh */
diff --git a/arch/mips/cpu/au1x00_eth.c b/arch/mips/cpu/au1x00_eth.c
new file mode 100644 (file)
index 0000000..5074997
--- /dev/null
@@ -0,0 +1,311 @@
+/* Only eth0 supported for now
+ *
+ * (C) Copyright 2003
+ * Thomas.Lange@corelatus.se
+ *
+ * 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>
+
+#if defined(CONFIG_SYS_DISCOVER_PHY)
+#error "PHY not supported yet"
+/* We just assume that we are running 100FD for now */
+/* We all use switches, right? ;-) */
+#endif
+
+/* I assume ethernet behaves like au1000 */
+
+#ifdef CONFIG_SOC_AU1000
+/* Base address differ between cpu:s */
+#define ETH0_BASE AU1000_ETH0_BASE
+#define MAC0_ENABLE AU1000_MAC0_ENABLE
+#else
+#ifdef CONFIG_SOC_AU1100
+#define ETH0_BASE AU1100_ETH0_BASE
+#define MAC0_ENABLE AU1100_MAC0_ENABLE
+#else
+#ifdef CONFIG_SOC_AU1500
+#define ETH0_BASE AU1500_ETH0_BASE
+#define MAC0_ENABLE AU1500_MAC0_ENABLE
+#else
+#ifdef CONFIG_SOC_AU1550
+#define ETH0_BASE AU1550_ETH0_BASE
+#define MAC0_ENABLE AU1550_MAC0_ENABLE
+#else
+#error "No valid cpu set"
+#endif
+#endif
+#endif
+#endif
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+#include <asm/io.h>
+#include <asm/au1x00.h>
+
+#if defined(CONFIG_CMD_MII)
+#include <miiphy.h>
+#endif
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH  1520
+#define PKT_MAXBUF_SIZE                1518
+
+static char txbuf[DBUF_LENGTH];
+
+static int next_tx;
+static int next_rx;
+
+/* 4 rx and 4 tx fifos */
+#define NO_OF_FIFOS 4
+
+typedef struct{
+       u32 status;
+       u32 addr;
+       u32 len; /* Only used for tx */
+       u32 not_used;
+} mac_fifo_t;
+
+mac_fifo_t mac_fifo[NO_OF_FIFOS];
+
+#define MAX_WAIT 1000
+
+#if defined(CONFIG_CMD_MII)
+int  au1x00_miiphy_read(char *devname, unsigned char addr,
+               unsigned char reg, unsigned short * value)
+{
+       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
+       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
+       u32 mii_control;
+       unsigned int timedout = 20;
+
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
+                       return -1;
+               }
+       }
+
+       mii_control = MAC_SET_MII_SELECT_REG(reg) |
+               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_READ;
+
+       *mii_control_reg = mii_control;
+
+       timedout = 20;
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
+                       return -1;
+               }
+       }
+       *value = *mii_data_reg;
+       return 0;
+}
+
+int  au1x00_miiphy_write(char *devname, unsigned char addr,
+               unsigned char reg, unsigned short value)
+{
+       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
+       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
+       u32 mii_control;
+       unsigned int timedout = 20;
+
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_write busy timeout!!\n");
+                       return -1;
+               }
+       }
+
+       mii_control = MAC_SET_MII_SELECT_REG(reg) |
+               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_WRITE;
+
+       *mii_data_reg = value;
+       *mii_control_reg = mii_control;
+       return 0;
+}
+#endif
+
+static int au1x00_send(struct eth_device* dev, volatile void *packet, int length){
+       volatile mac_fifo_t *fifo_tx =
+               (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS);
+       int i;
+       int res;
+
+       /* tx fifo should always be idle */
+       fifo_tx[next_tx].len = length;
+       fifo_tx[next_tx].addr = (virt_to_phys(packet))|TX_DMA_ENABLE;
+       au_sync();
+
+       udelay(1);
+       i=0;
+       while(!(fifo_tx[next_tx].addr&TX_T_DONE)){
+               if(i>MAX_WAIT){
+                       printf("TX timeout\n");
+                       break;
+               }
+               udelay(1);
+               i++;
+       }
+
+       /* Clear done bit */
+       fifo_tx[next_tx].addr = 0;
+       fifo_tx[next_tx].len = 0;
+       au_sync();
+
+       res = fifo_tx[next_tx].status;
+
+       next_tx++;
+       if(next_tx>=NO_OF_FIFOS){
+               next_tx=0;
+       }
+       return(res);
+}
+
+static int au1x00_recv(struct eth_device* dev){
+       volatile mac_fifo_t *fifo_rx =
+               (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS);
+
+       int length;
+       u32 status;
+
+       for(;;){
+               if(!(fifo_rx[next_rx].addr&RX_T_DONE)){
+                       /* Nothing has been received */
+                       return(-1);
+               }
+
+               status = fifo_rx[next_rx].status;
+
+               length = status&0x3FFF;
+
+               if(status&RX_ERROR){
+                       printf("Rx error 0x%x\n", status);
+               }
+               else{
+                       /* Pass the packet up to the protocol layers. */
+                       NetReceive(NetRxPackets[next_rx], length - 4);
+               }
+
+               fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE;
+
+               next_rx++;
+               if(next_rx>=NO_OF_FIFOS){
+                       next_rx=0;
+               }
+       } /* for */
+
+       return(0); /* Does anyone use this? */
+}
+
+static int au1x00_init(struct eth_device* dev, bd_t * bd){
+
+       volatile u32 *macen = (volatile u32*)MAC0_ENABLE;
+       volatile u32 *mac_ctrl = (volatile u32*)(ETH0_BASE+MAC_CONTROL);
+       volatile u32 *mac_addr_high = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_HIGH);
+       volatile u32 *mac_addr_low = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_LOW);
+       volatile u32 *mac_mcast_high = (volatile u32*)(ETH0_BASE+MAC_MCAST_HIGH);
+       volatile u32 *mac_mcast_low = (volatile u32*)(ETH0_BASE+MAC_MCAST_LOW);
+       volatile mac_fifo_t *fifo_tx =
+               (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS);
+       volatile mac_fifo_t *fifo_rx =
+               (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS);
+       int i;
+
+       next_tx = TX_GET_DMA_BUFFER(fifo_tx[0].addr);
+       next_rx = RX_GET_DMA_BUFFER(fifo_rx[0].addr);
+
+       /* We have to enable clocks before releasing reset */
+       *macen = MAC_EN_CLOCK_ENABLE;
+       udelay(10);
+
+       /* Enable MAC0 */
+       /* We have to release reset before accessing registers */
+       *macen = MAC_EN_CLOCK_ENABLE|MAC_EN_RESET0|
+               MAC_EN_RESET1|MAC_EN_RESET2;
+       udelay(10);
+
+       for(i=0;i<NO_OF_FIFOS;i++){
+               fifo_tx[i].len = 0;
+               fifo_tx[i].addr = virt_to_phys(&txbuf[0]);
+               fifo_rx[i].addr = (virt_to_phys(NetRxPackets[i]))|RX_DMA_ENABLE;
+       }
+
+       /* Put mac addr in little endian */
+#define ea eth_get_dev()->enetaddr
+       *mac_addr_high  =       (ea[5] <<  8) | (ea[4]      ) ;
+       *mac_addr_low   =       (ea[3] << 24) | (ea[2] << 16) |
+               (ea[1] <<  8) | (ea[0]      ) ;
+#undef ea
+       *mac_mcast_low = 0;
+       *mac_mcast_high = 0;
+
+       /* Make sure the MAC buffer is in the correct endian mode */
+#ifdef __LITTLE_ENDIAN
+       *mac_ctrl = MAC_FULL_DUPLEX;
+       udelay(1);
+       *mac_ctrl = MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE;
+#else
+       *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX;
+       udelay(1);
+       *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE;
+#endif
+
+       return(1);
+}
+
+static void au1x00_halt(struct eth_device* dev){
+       volatile u32 *macen = (volatile u32*)MAC0_ENABLE;
+
+       /* Put MAC0 in reset */
+       *macen = 0;
+}
+
+int au1x00_enet_initialize(bd_t *bis){
+       struct eth_device* dev;
+
+       if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) {
+               puts ("malloc failed\n");
+               return -1;
+       }
+
+       memset(dev, 0, sizeof *dev);
+
+       sprintf(dev->name, "Au1X00 ethernet");
+       dev->iobase = 0;
+       dev->priv   = 0;
+       dev->init   = au1x00_init;
+       dev->halt   = au1x00_halt;
+       dev->send   = au1x00_send;
+       dev->recv   = au1x00_recv;
+
+       eth_register(dev);
+
+#if defined(CONFIG_CMD_MII)
+       miiphy_register(dev->name,
+               au1x00_miiphy_read, au1x00_miiphy_write);
+#endif
+
+       return 1;
+}
diff --git a/arch/mips/cpu/au1x00_serial.c b/arch/mips/cpu/au1x00_serial.c
new file mode 100644 (file)
index 0000000..c25ba5a
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * AU1X00 UART support
+ *
+ * Hardcoded to UART 0 for now
+ * Speed and options also hardcoded to 115200 8N1
+ *
+ *  Copyright (c) 2003 Thomas.Lange@corelatus.se
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/au1x00.h>
+
+/******************************************************************************
+*
+* serial_init - initialize a channel
+*
+* This routine initializes the number of data bits, parity
+* and set the selected baud rate. Interrupts are disabled.
+* Set the modem control signals if the option is selected.
+*
+* RETURNS: N/A
+*/
+
+int serial_init (void)
+{
+       volatile u32 *uart_fifoctl = (volatile u32*)(UART0_ADDR+UART_FCR);
+       volatile u32 *uart_enable = (volatile u32*)(UART0_ADDR+UART_ENABLE);
+
+       /* Enable clocks first */
+       *uart_enable = UART_EN_CE;
+
+       /* Then release reset */
+       /* Must release reset before setting other regs */
+       *uart_enable = UART_EN_CE|UART_EN_E;
+
+       /* Activate fifos, reset tx and rx */
+       /* Set tx trigger level to 12 */
+       *uart_fifoctl = UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|
+               UART_FCR_CLEAR_XMIT|UART_FCR_T_TRIGGER_12;
+
+       serial_setbrg();
+
+       return 0;
+}
+
+
+void serial_setbrg (void)
+{
+       volatile u32 *uart_clk = (volatile u32*)(UART0_ADDR+UART_CLK);
+       volatile u32 *uart_lcr = (volatile u32*)(UART0_ADDR+UART_LCR);
+       volatile u32 *sys_powerctrl = (u32 *)SYS_POWERCTRL;
+       int sd;
+       int divisorx2;
+
+       /* sd is system clock divisor                   */
+       /* see section 10.4.5 in au1550 datasheet       */
+       sd = (*sys_powerctrl & 0x03) + 2;
+
+       /* calulate 2x baudrate and round */
+       divisorx2 = ((CONFIG_SYS_MIPS_TIMER_FREQ/(sd * 16 * CONFIG_BAUDRATE)));
+
+       if (divisorx2 & 0x01)
+               divisorx2 = divisorx2 + 1;
+
+       *uart_clk = divisorx2 / 2;
+
+       /* Set parity, stop bits and word length to 8N1 */
+       *uart_lcr = UART_LCR_WLEN8;
+}
+
+void serial_putc (const char c)
+{
+       volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR);
+       volatile u32 *uart_tx = (volatile u32*)(UART0_ADDR+UART_TX);
+
+       if (c == '\n') serial_putc ('\r');
+
+       /* Wait for fifo to shift out some bytes */
+       while((*uart_lsr&UART_LSR_THRE)==0);
+
+       *uart_tx = (u32)c;
+}
+
+void serial_puts (const char *s)
+{
+       while (*s)
+       {
+               serial_putc (*s++);
+       }
+}
+
+int serial_getc (void)
+{
+       volatile u32 *uart_rx = (volatile u32*)(UART0_ADDR+UART_RX);
+       char c;
+
+       while (!serial_tstc());
+
+       c = (*uart_rx&0xFF);
+       return c;
+}
+
+int serial_tstc (void)
+{
+       volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR);
+
+       if(*uart_lsr&UART_LSR_DR){
+               /* Data in rfifo */
+               return(1);
+       }
+       return 0;
+}
diff --git a/arch/mips/cpu/au1x00_usb_ohci.c b/arch/mips/cpu/au1x00_usb_ohci.c
new file mode 100644 (file)
index 0000000..0bc2305
--- /dev/null
@@ -0,0 +1,1726 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.
+ *
+ * (C) Copyright 2003
+ * Gary Jennejohn, DENX Software Engineering <garyj@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
+ *
+ * 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 <config.h>
+
+#ifdef CONFIG_USB_OHCI
+
+/* #include <pci.h> no PCI on the AU1x00 */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/au1x00.h>
+#include <usb.h>
+#include "au1x00_usb_ohci.h"
+
+#define OHCI_USE_NPS           /* force NoPowerSwitching mode */
+#define OHCI_VERBOSE_DEBUG     /* not always helpful */
+#define OHCI_FILL_TRACE
+
+#define USBH_ENABLE_BE (1<<0)
+#define USBH_ENABLE_C  (1<<1)
+#define USBH_ENABLE_E  (1<<2)
+#define USBH_ENABLE_CE (1<<3)
+#define USBH_ENABLE_RD (1<<4)
+
+#ifdef __LITTLE_ENDIAN
+#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
+#else
+#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE)
+#endif
+
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#undef readl
+#undef writel
+
+#define readl(a)     au_readl((long)(a))
+#define writel(v,a)  au_writel((v),(int)(a))
+
+#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#define DEBUG
+#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)
+#define SHOW_INFO
+#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)
+
+/* 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 *)m32_swap(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 m16_swap (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 ((long)ed, &ohci->regs->ed_controlhead);
+               } else {
+                       ohci->ed_controltail->hwNextED = m32_swap (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 ((long)ed, &ohci->regs->ed_bulkhead);
+               } else {
+                       ohci->ed_bulktail->hwNextED = m32_swap (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 *ed)
+{
+       ed->hwINFO |= m32_swap (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 (m32_swap (*((__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 *)m32_swap (*((__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 (m32_swap (*((__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 *)m32_swap (*((__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 = m32_swap (OHCI_ED_SKIP); /* skip ed */
+               /* dummy td; end of td list for ed */
+               td = td_alloc (usb_dev);
+               ed->hwTailP = m32_swap (td);
+               ed->hwHeadP = ed->hwTailP;
+               ed->state = ED_UNLINK;
+               ed->type = usb_pipetype (pipe);
+               ohci_dev.ed_cnt++;
+       }
+
+       ed->hwINFO = m32_swap (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 *)(m32_swap (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 (1 || (usb_pipebulk(urb_priv->pipe) &&
+                               usb_pipeout(urb_priv->pipe))) {
+               for (i = 0; i < len; i++)
+               printf("td->data[%d] %#2x\n",i, ((unsigned char *)(td->data+0x80000000))[i]);
+       }
+#endif
+       if (!len)
+               data = 0;
+
+       td->hwINFO = m32_swap (info);
+       td->hwCBP = m32_swap (data);
+       if (data)
+               td->hwBE = m32_swap (data + len - 1);
+       else
+               td->hwBE = 0;
+       td->hwNextTD = m32_swap (td_pt);
+       td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000);
+
+       /* append to queue */
+       td->ed->hwTailP = td->hwNextTD;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* prepare all TDs of a transfer */
+
+#define kseg_to_phys(x)          ((void *)((__u32)(x) - 0x80000000))
+
+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 = kseg_to_phys(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, kseg_to_phys(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 = m32_swap (td->hwINFO);
+       tdBE   = m32_swap (td->hwBE);
+       tdCBP  = m32_swap (td->hwCBP);
+
+
+       if (!(usb_pipecontrol(lurb_priv->pipe) &&
+           ((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 = m32_swap (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 (m32_swap (td_list->hwINFO))) {
+                       lurb_priv = &urb_priv;
+                       dbg(" USB-error/status: %x : %p",
+                                       TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
+                       if (td_list->ed->hwHeadP & m32_swap (0x1)) {
+                               if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
+                                       td_list->ed->hwHeadP =
+                                               (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |
+                                                                       (td_list->ed->hwHeadP & m32_swap (0x2));
+                                       lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
+                               } else
+                                       td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
+                       }
+               }
+
+               td_list->next_dl_td = td_rev;
+               td_rev = td_list;
+               td_list_hc = m32_swap (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 = 0;
+       /* 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 = m32_swap (td_list->hwINFO);
+
+               ed = td_list->ed;
+
+               dl_transfer_length(td_list);
+
+               /* error code of transfer */
+               cc = TD_CC_GET (tdINFO);
+               if (cc != 0) {
+                       dbg("ConditionCode %#x", cc);
+                       stat = cc_to_error[cc];
+               }
+
+               if (ed->state != ED_NEW) {
+                       edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
+                       edTailP = m32_swap (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));
+#else
+       wait_ms(1);
+#endif
+       if (usb_pipeint(pipe)) {
+               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);
+#else
+       wait_ms(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)*/);
+#else
+       wait_ms(1);
+#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));
+#else
+       wait_ms(1);
+#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;
+       }
+
+       wait_ms(10);
+       /* ohci_dump_status(&gohci); */
+
+       /* allow more time for a BULK device to react - some are slow */
+#define BULK_TO         5000   /* timeout in milliseconds */
+       if (usb_pipebulk(pipe))
+               timeout = BULK_TO;
+       else
+               timeout = 100;
+
+       timeout *= 4;
+       /* 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) {
+                       udelay(250); /* 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));
+#else
+       wait_ms(1);
+#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));
+#else
+       wait_ms(1);
+#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) */
+       writel (0, &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) && !(m32_swap (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);
+#else
+       wait_ms(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) {
+               wait_ms(1);
+               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 = m16_swap (ohci->hcca->frame_no) & 1;
+               wait_ms(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);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#define __read_32bit_c0_register(source, sel)                          \
+({ int __res;                                                          \
+       if (sel == 0)                                                   \
+               __asm__ __volatile__(                                   \
+                       "mfc0\t%0, " #source "\n\t"                     \
+                       : "=r" (__res));                                \
+       else                                                            \
+               __asm__ __volatile__(                                   \
+                       ".set\tmips32\n\t"                              \
+                       "mfc0\t%0, " #source ", " #sel "\n\t"           \
+                       ".set\tmips0\n\t"                               \
+                       : "=r" (__res));                                \
+       __res;                                                          \
+})
+
+#define read_c0_prid()         __read_32bit_c0_register($15, 0)
+
+/*
+ * low level initalisation routine, called from usb.c
+ */
+static char ohci_inited = 0;
+
+int usb_lowlevel_init(void)
+{
+       u32 pin_func;
+       u32 sys_freqctrl, sys_clksrc;
+       u32 prid = read_c0_prid();
+
+       dbg("in usb_lowlevel_init\n");
+
+       /* zero and disable FREQ2 */
+       sys_freqctrl = au_readl(SYS_FREQCTRL0);
+       sys_freqctrl &= ~0xFFF00000;
+       au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+       /* zero and disable USBH/USBD clocks */
+       sys_clksrc = au_readl(SYS_CLKSRC);
+       sys_clksrc &= ~0x00007FE0;
+       au_writel(sys_clksrc, SYS_CLKSRC);
+
+       sys_freqctrl = au_readl(SYS_FREQCTRL0);
+       sys_freqctrl &= ~0xFFF00000;
+
+       sys_clksrc = au_readl(SYS_CLKSRC);
+       sys_clksrc &= ~0x00007FE0;
+
+       switch (prid & 0x000000FF) {
+       case 0x00: /* DA */
+       case 0x01: /* HA */
+       case 0x02: /* HB */
+               /* CPU core freq to 48MHz to slow it way down... */
+               au_writel(4, SYS_CPUPLL);
+
+               /*
+                * Setup 48MHz FREQ2 from CPUPLL for USB Host
+                */
+               /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
+               sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
+               au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+               /* CPU core freq to 384MHz */
+               au_writel(0x20, SYS_CPUPLL);
+
+               printf("Au1000: 48MHz OHCI workaround enabled\n");
+               break;
+
+       default:  /* HC and newer */
+               /* FREQ2 = aux/2 = 48 MHz */
+               sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+               au_writel(sys_freqctrl, SYS_FREQCTRL0);
+               break;
+       }
+
+       /*
+        * Route 48MHz FREQ2 into USB Host and/or Device
+        */
+       sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+       au_writel(sys_clksrc, SYS_CLKSRC);
+
+       /* configure pins GPIO[14:9] as GPIO */
+       pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
+
+       au_writel(pin_func, SYS_PINFUNC);
+       au_writel(0x2800, SYS_TRIOUTCLR);
+       au_writel(0x0030, SYS_OUTPUTCLR);
+
+       dbg("OHCI board setup complete\n");
+
+       /* enable host controller */
+       au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
+       udelay(1000);
+       au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
+       udelay(1000);
+
+       /* wait for reset complete (read register twice; see au1500 errata) */
+       while (au_readl(USB_HOST_CONFIG),
+              !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
+               udelay(1000);
+
+       dbg("OHCI clock running\n");
+
+       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 *)(USB_OHCI_BASE | 0xA0000000);
+
+       gohci.flags = 0;
+       gohci.slot_name = "au1x00";
+
+       dbg("OHCI revision: 0x%08x\n"
+              "  RH: a: 0x%08x b: 0x%08x\n",
+              readl(&gohci.regs->revision),
+              readl(&gohci.regs->roothub.a), readl(&gohci.regs->roothub.b));
+
+       if (hc_reset (&gohci) < 0)
+               goto errout;
+
+       /* FIXME this is a second HC reset; why?? */
+       writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
+       wait_ms (10);
+
+       if (hc_start (&gohci) < 0)
+               goto errout;
+
+#ifdef DEBUG
+       ohci_dump (&gohci, 1);
+#else
+       wait_ms(1);
+#endif
+       ohci_inited = 1;
+       return 0;
+
+  errout:
+       err("OHCI initialization error\n");
+       hc_release_ohci (&gohci);
+       /* Initialization failed */
+       au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
+       return -1;
+}
+
+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);
+       /* may not want to do this */
+       /* Disable clock */
+       au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
+       return 0;
+}
+
+#endif /* CONFIG_USB_OHCI */
diff --git a/arch/mips/cpu/au1x00_usb_ohci.h b/arch/mips/cpu/au1x00_usb_ohci.h
new file mode 100644 (file)
index 0000000..bb9f351
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * 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 */
+       __u16   frame_no;               /* current frame number */
+       __u16   pad1;                   /* set to 0 on each frame_no change */
+       __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/arch/mips/cpu/cache.S b/arch/mips/cpu/cache.S
new file mode 100644 (file)
index 0000000..ff4f11c
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ *  Cache-handling routined for MIPS CPUs
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <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 <config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+
+#define RA             t8
+
+/*
+ * 16kB is the maximum size of instruction and data caches on MIPS 4K,
+ * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
+ *
+ * Note that the above size is the maximum size of primary cache. U-Boot
+ * doesn't have L2 cache support for now.
+ */
+#define MIPS_MAX_CACHE_SIZE    0x10000
+
+#define INDEX_BASE     CKSEG0
+
+       .macro  cache_op op addr
+       .set    push
+       .set    noreorder
+       .set    mips3
+       cache   \op, 0(\addr)
+       .set    pop
+       .endm
+
+/*
+ * cacheop macro to automate cache operations
+ * first some helpers...
+ */
+#define _mincache(size, maxsize) \
+   bltu  size,maxsize,9f ; \
+   move  size,maxsize ;    \
+9:
+
+#define _align(minaddr, maxaddr, linesize) \
+   .set noat ; \
+   subu  AT,linesize,1 ;   \
+   not   AT ;        \
+   and   minaddr,AT ;      \
+   addu  maxaddr,-1 ;      \
+   and   maxaddr,AT ;      \
+   .set at
+
+/* general operations */
+#define doop1(op1) \
+   cache op1,0(a0)
+#define doop2(op1, op2) \
+   cache op1,0(a0) ;    \
+   nop ;          \
+   cache op2,0(a0)
+
+/* specials for cache initialisation */
+#define doop1lw(op1) \
+   lw zero,0(a0)
+#define doop1lw1(op1) \
+   cache op1,0(a0) ;    \
+   lw zero,0(a0) ;      \
+   cache op1,0(a0)
+#define doop121(op1,op2) \
+   cache op1,0(a0) ;    \
+   nop;           \
+   cache op2,0(a0) ;    \
+   nop;           \
+   cache op1,0(a0)
+
+#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
+   .set  noreorder ;    \
+10:   doop##tag##ops ;  \
+   bne     minaddr,maxaddr,10b ; \
+   add      minaddr,linesize ;   \
+   .set  reorder
+
+/* finally the cache operation macros */
+#define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
+   blez  n,11f ;        \
+   addu  n,kva ;        \
+   _align(kva, n, cacheLineSize) ; \
+   _oploopn(kva, n, cacheLineSize, tag, ops) ; \
+11:
+
+#define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
+   _mincache(n, cacheSize);   \
+   blez  n,11f ;        \
+   addu  n,kva ;        \
+   _align(kva, n, cacheLineSize) ; \
+   _oploopn(kva, n, cacheLineSize, tag, ops) ; \
+11:
+
+#define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
+   vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
+
+#define icacheop(kva, n, cacheSize, cacheLineSize, op) \
+   icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
+
+       .macro  f_fill64 dst, offset, val
+       LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  2 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  3 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  4 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  5 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  6 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  7 * LONGSIZE)(\dst)
+#if LONGSIZE == 4
+       LONG_S  \val, (\offset +  8 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset +  9 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset + 10 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset + 11 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset + 12 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset + 13 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset + 14 * LONGSIZE)(\dst)
+       LONG_S  \val, (\offset + 15 * LONGSIZE)(\dst)
+#endif
+       .endm
+
+/*
+ * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
+ */
+LEAF(mips_init_icache)
+       blez    a1, 9f
+       mtc0    zero, CP0_TAGLO
+       /* clear tag to invalidate */
+       PTR_LI          t0, INDEX_BASE
+       PTR_ADDU        t1, t0, a1
+1:     cache_op        Index_Store_Tag_I t0
+       PTR_ADDU        t0, a2
+       bne             t0, t1, 1b
+       /* fill once, so data field parity is correct */
+       PTR_LI          t0, INDEX_BASE
+2:     cache_op        Fill t0
+       PTR_ADDU        t0, a2
+       bne             t0, t1, 2b
+       /* invalidate again - prudent but not strictly neccessary */
+       PTR_LI          t0, INDEX_BASE
+1:     cache_op        Index_Store_Tag_I t0
+       PTR_ADDU        t0, a2
+       bne             t0, t1, 1b
+9:     jr      ra
+       END(mips_init_icache)
+
+/*
+ * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
+ */
+LEAF(mips_init_dcache)
+       blez    a1, 9f
+       mtc0    zero, CP0_TAGLO
+       /* clear all tags */
+       PTR_LI          t0, INDEX_BASE
+       PTR_ADDU        t1, t0, a1
+1:     cache_op        Index_Store_Tag_D t0
+       PTR_ADDU        t0, a2
+       bne             t0, t1, 1b
+       /* load from each line (in cached space) */
+       PTR_LI          t0, INDEX_BASE
+2:     LONG_L          zero, 0(t0)
+       PTR_ADDU        t0, a2
+       bne             t0, t1, 2b
+       /* clear all tags */
+       PTR_LI          t0, INDEX_BASE
+1:     cache_op        Index_Store_Tag_D t0
+       PTR_ADDU        t0, a2
+       bne             t0, t1, 1b
+9:     jr      ra
+       END(mips_init_dcache)
+
+/*******************************************************************************
+*
+* mips_cache_reset - low level initialisation of the primary caches
+*
+* This routine initialises the primary caches to ensure that they
+* have good parity.  It must be called by the ROM before any cached locations
+* are used to prevent the possibility of data with bad parity being written to
+* memory.
+* To initialise the instruction cache it is essential that a source of data
+* with good parity is available. This routine
+* will initialise an area of memory starting at location zero to be used as
+* a source of parity.
+*
+* RETURNS: N/A
+*
+*/
+NESTED(mips_cache_reset, 0, ra)
+       move    RA, ra
+       li      t2, CONFIG_SYS_ICACHE_SIZE
+       li      t3, CONFIG_SYS_DCACHE_SIZE
+       li      t4, CONFIG_SYS_CACHELINE_SIZE
+       move    t5, t4
+
+       li      v0, MIPS_MAX_CACHE_SIZE
+
+       /*
+        * Now clear that much memory starting from zero.
+        */
+       PTR_LI          a0, CKSEG1
+       PTR_ADDU        a1, a0, v0
+2:     PTR_ADDIU       a0, 64
+       f_fill64        a0, -64, zero
+       bne             a0, a1, 2b
+
+       /*
+        * The caches are probably in an indeterminate state,
+        * so we force good parity into them by doing an
+        * invalidate, load/fill, invalidate for each line.
+        */
+
+       /*
+        * Assume bottom of RAM will generate good parity for the cache.
+        */
+
+       /*
+        * Initialize the I-cache first,
+        */
+       move    a1, t2
+       move    a2, t4
+       PTR_LA  t7, mips_init_icache
+       jalr    t7
+
+       /*
+        * then initialize D-cache.
+        */
+       move    a1, t3
+       move    a2, t5
+       PTR_LA  t7, mips_init_dcache
+       jalr    t7
+
+       jr      RA
+       END(mips_cache_reset)
+
+/*******************************************************************************
+*
+* dcache_status - get cache status
+*
+* RETURNS: 0 - cache disabled; 1 - cache enabled
+*
+*/
+LEAF(dcache_status)
+       mfc0    t0, CP0_CONFIG
+       li      t1, CONF_CM_UNCACHED
+       andi    t0, t0, CONF_CM_CMASK
+       move    v0, zero
+       beq     t0, t1, 2f
+       li      v0, 1
+2:     jr      ra
+       END(dcache_status)
+
+/*******************************************************************************
+*
+* dcache_disable - disable cache
+*
+* RETURNS: N/A
+*
+*/
+LEAF(dcache_disable)
+       mfc0    t0, CP0_CONFIG
+       li      t1, -8
+       and     t0, t0, t1
+       ori     t0, t0, CONF_CM_UNCACHED
+       mtc0    t0, CP0_CONFIG
+       jr      ra
+       END(dcache_disable)
+
+/*******************************************************************************
+*
+* dcache_enable - enable cache
+*
+* RETURNS: N/A
+*
+*/
+LEAF(dcache_enable)
+       mfc0    t0, CP0_CONFIG
+       ori     t0, CONF_CM_CMASK
+       xori    t0, CONF_CM_CMASK
+       ori     t0, CONF_CM_CACHABLE_NONCOHERENT
+       mtc0    t0, CP0_CONFIG
+       jr      ra
+       END(dcache_enable)
+
+#ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS
+/*******************************************************************************
+*
+* mips_cache_lock - lock RAM area pointed to by a0 in cache.
+*
+* RETURNS: N/A
+*
+*/
+#if defined(CONFIG_PURPLE)
+# define       CACHE_LOCK_SIZE (CONFIG_SYS_DCACHE_SIZE/2)
+#else
+# define       CACHE_LOCK_SIZE (CONFIG_SYS_DCACHE_SIZE)
+#endif
+       .globl  mips_cache_lock
+       .ent    mips_cache_lock
+mips_cache_lock:
+       li      a1, CKSEG0 - CACHE_LOCK_SIZE
+       addu    a0, a1
+       li      a2, CACHE_LOCK_SIZE
+       li      a3, CONFIG_SYS_CACHELINE_SIZE
+       move    a1, a2
+       icacheop(a0,a1,a2,a3,0x1d)
+
+       jr      ra
+
+       .end    mips_cache_lock
+#endif /* CONFIG_SYS_INIT_RAM_LOCK_MIPS */
diff --git a/arch/mips/cpu/config.mk b/arch/mips/cpu/config.mk
new file mode 100644 (file)
index 0000000..a173c54
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# (C) Copyright 2003
+# 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
+#
+v=$(shell $(AS) --version | grep 'GNU assembler' | egrep -o '2\.[0-9\.]+' | cut -d. -f2)
+MIPSFLAGS:=$(shell \
+if [ "$v" -lt "14" ]; then \
+       echo "-mcpu=4kc"; \
+else \
+       echo "-march=4kc -mtune=4kc"; \
+fi)
+
+ifneq (,$(findstring 4KCle,$(CROSS_COMPILE)))
+ENDIANNESS = -EL
+else
+ENDIANNESS = -EB
+endif
+
+MIPSFLAGS += $(ENDIANNESS)
+
+PLATFORM_CPPFLAGS += $(MIPSFLAGS)
diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c
new file mode 100644 (file)
index 0000000..d5a1604
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * (C) Copyright 2003
+ * 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 <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheops.h>
+#include <asm/reboot.h>
+
+#define cache_op(op,addr)                                              \
+       __asm__ __volatile__(                                           \
+       "       .set    push                                    \n"     \
+       "       .set    noreorder                               \n"     \
+       "       .set    mips3\n\t                               \n"     \
+       "       cache   %0, %1                                  \n"     \
+       "       .set    pop                                     \n"     \
+       :                                                               \
+       : "i" (op), "R" (*(unsigned char *)(addr)))
+
+void __attribute__((weak)) _machine_restart(void)
+{
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       _machine_restart();
+
+       fprintf(stderr, "*** reset failed ***\n");
+       return 0;
+}
+
+void flush_cache(ulong start_addr, ulong size)
+{
+       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+       unsigned long addr = start_addr & ~(lsize - 1);
+       unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
+
+       while (1) {
+               cache_op(Hit_Writeback_Inv_D, addr);
+               cache_op(Hit_Invalidate_I, addr);
+               if (addr == aend)
+                       break;
+               addr += lsize;
+       }
+}
+
+void flush_dcache_range(ulong start_addr, ulong stop)
+{
+       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+       unsigned long addr = start_addr & ~(lsize - 1);
+       unsigned long aend = (stop - 1) & ~(lsize - 1);
+
+       while (1) {
+               cache_op(Hit_Writeback_Inv_D, addr);
+               if (addr == aend)
+                       break;
+               addr += lsize;
+       }
+}
+
+void invalidate_dcache_range(ulong start_addr, ulong stop)
+{
+       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+       unsigned long addr = start_addr & ~(lsize - 1);
+       unsigned long aend = (stop - 1) & ~(lsize - 1);
+
+       while (1) {
+               cache_op(Hit_Invalidate_D, addr);
+               if (addr == aend)
+                       break;
+               addr += lsize;
+       }
+}
+
+void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
+{
+       write_c0_entrylo0(low0);
+       write_c0_pagemask(pagemask);
+       write_c0_entrylo1(low1);
+       write_c0_entryhi(hi);
+       write_c0_index(index);
+       tlb_write_indexed();
+}
+
+int cpu_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_SOC_AU1X00
+       au1x00_enet_initialize(bis);
+#endif
+       return 0;
+}
diff --git a/arch/mips/cpu/incaip_clock.c b/arch/mips/cpu/incaip_clock.c
new file mode 100644 (file)
index 0000000..fc2c621
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * (C) Copyright 2003
+ * 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 <common.h>
+#include <asm/inca-ip.h>
+
+
+/*******************************************************************************
+*
+* get_cpuclk - returns the frequency of the CPU.
+*
+* Gets the value directly from the INCA-IP hardware.
+*
+* RETURNS:
+*          150.000.000 for 150 MHz
+*          133.333.333 for 133 MHz (= 400MHz/3)
+*          100.000.000 for 100 MHz (= 400MHz/4)
+* NOTE:
+*   This functions should be used by the hardware driver to get the correct
+*   frequency of the CPU. Don't use the macros, which are set to init the CPU
+*   frequency in the ROM code.
+*/
+uint incaip_get_cpuclk (void)
+{
+       /*-------------------------------------------------------------------------*/
+       /* CPU Clock Input Multiplexer (MUX I)                                     */
+       /* Multiplexer MUX I selects the maximum input clock to the CPU.           */
+       /*-------------------------------------------------------------------------*/
+       if (*((volatile ulong *) INCA_IP_CGU_CGU_MUXCR) &
+           INCA_IP_CGU_CGU_MUXCR_MUXI) {
+               /* MUX I set to 150 MHz clock */
+               return 150000000;
+       } else {
+               /* MUX I set to 100/133 MHz clock */
+               if (*((volatile ulong *) INCA_IP_CGU_CGU_DIVCR) & 0x40) {
+                       /* Division value is 1/3, maximum CPU operating */
+                       /* frequency is 133.3 MHz                       */
+                       return 133333333;
+               } else {
+                       /* Division value is 1/4, maximum CPU operating */
+                       /* frequency is 100 MHz                         */
+                       return 100000000;
+               }
+       }
+}
+
+/*******************************************************************************
+*
+* get_fpiclk - returns the frequency of the FPI bus.
+*
+* Gets the value directly from the INCA-IP hardware.
+*
+* RETURNS: Frquency in Hz
+*
+* NOTE:
+*   This functions should be used by the hardware driver to get the correct
+*   frequency of the CPU. Don't use the macros, which are set to init the CPU
+*   frequency in the ROM code.
+*   The calculation for the
+*/
+uint incaip_get_fpiclk (void)
+{
+       uint clkCPU;
+
+       clkCPU = incaip_get_cpuclk ();
+
+       switch (*((volatile ulong *) INCA_IP_CGU_CGU_DIVCR) & 0xC) {
+       case 0x4:
+               return clkCPU >> 1;     /* devided by 2 */
+               break;
+       case 0x8:
+               return clkCPU >> 2;     /* devided by 4 */
+               break;
+       default:
+               return clkCPU;
+               break;
+       }
+}
+
+int incaip_set_cpuclk (void)
+{
+       extern void ebu_init(long);
+       extern void cgu_init(long);
+       extern void sdram_init(long);
+       char tmp[64];
+       ulong cpuclk;
+
+       if (getenv_r ("cpuclk", tmp, sizeof (tmp)) > 0) {
+               cpuclk = simple_strtoul (tmp, NULL, 10) * 1000000;
+               cgu_init (cpuclk);
+               ebu_init (cpuclk);
+               sdram_init (cpuclk);
+       }
+
+       return 0;
+}
diff --git a/arch/mips/cpu/incaip_wdt.S b/arch/mips/cpu/incaip_wdt.S
new file mode 100644 (file)
index 0000000..3ade3cd
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  INCA-IP Watchdog timer management code.
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <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 <config.h>
+#include <asm/regdef.h>
+
+
+#define WD_BASE            0xb8000000
+#define WD_CON0(value)     0x0020(value)
+#define WD_CON1(value)     0x0024(value)
+#define WD_DISABLE         0x00000008
+#define WD_ENABLE          0x00000000
+#define WD_WRITE_PW        0xFFFC00F8
+#define WD_WRITE_ENDINIT   0xFFFC00F3
+#define WD_WRITE_INIT      0xFFFC00F2
+
+
+       .globl  disable_incaip_wdt
+disable_incaip_wdt:
+       li      t0, WD_BASE
+
+       /* Calculate password.
+        */
+       lw      t2, WD_CON1(t0)
+       and     t2, 0xC
+
+       lw      t3, WD_CON0(t0)
+       and     t3, 0xFFFFFF01
+
+       or      t3, t2
+       or      t3, 0xF0
+
+       sw      t3, WD_CON0(t0)         /* write password */
+
+       /* Clear ENDINIT.
+        */
+       li      t1, WD_WRITE_INIT
+       sw      t1, WD_CON0(t0)
+
+
+       li      t1, WD_DISABLE
+       sw      t1, WD_CON1(t0)         /* disable watchdog */
+       li      t1, WD_WRITE_PW
+       sw      t1, WD_CON0(t0)         /* write password */
+       li      t1, WD_WRITE_ENDINIT
+       sw      t1, WD_CON0(t0)         /* end command */
+
+       jr      ra
+       nop
diff --git a/arch/mips/cpu/interrupts.c b/arch/mips/cpu/interrupts.c
new file mode 100644 (file)
index 0000000..87f7a9f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2003
+ * 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 <common.h>
+
+void enable_interrupts(void)
+{
+}
+
+int disable_interrupts(void)
+{
+       return 0;
+}
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S
new file mode 100644 (file)
index 0000000..57db589
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ *  Startup Code for MIPS32 CPU-core
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <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 <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+       /*
+        * For the moment disable interrupts, mark the kernel mode and
+        * set ST0_KX so that the CPU does not spit fire when using
+        * 64-bit addresses.
+        */
+       .macro  setup_c0_status set clr
+       .set    push
+       mfc0    t0, CP0_STATUS
+       or      t0, ST0_CU0 | \set | 0x1f | \clr
+       xor     t0, 0x1f | \clr
+       mtc0    t0, CP0_STATUS
+       .set    noreorder
+       sll     zero, 3                         # ehb
+       .set    pop
+       .endm
+
+       .macro  setup_c0_status_reset
+#ifdef CONFIG_64BIT
+       setup_c0_status ST0_KX 0
+#else
+       setup_c0_status 0 0
+#endif
+       .endm
+
+#define RVECENT(f,n) \
+   b f; nop
+#define XVECENT(f,bev) \
+   b f     ;           \
+   li k0,bev
+
+       .set noreorder
+
+       .globl _start
+       .text
+_start:
+       RVECENT(reset,0)        /* U-boot entry point */
+       RVECENT(reset,1)        /* software reboot */
+#if defined(CONFIG_INCA_IP)
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+       .word 0x00000000           /* phase of the flash                    */
+#elif defined(CONFIG_PURPLE)
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+#else
+       RVECENT(romReserved,2)
+#endif
+       RVECENT(romReserved,3)
+       RVECENT(romReserved,4)
+       RVECENT(romReserved,5)
+       RVECENT(romReserved,6)
+       RVECENT(romReserved,7)
+       RVECENT(romReserved,8)
+       RVECENT(romReserved,9)
+       RVECENT(romReserved,10)
+       RVECENT(romReserved,11)
+       RVECENT(romReserved,12)
+       RVECENT(romReserved,13)
+       RVECENT(romReserved,14)
+       RVECENT(romReserved,15)
+       RVECENT(romReserved,16)
+       RVECENT(romReserved,17)
+       RVECENT(romReserved,18)
+       RVECENT(romReserved,19)
+       RVECENT(romReserved,20)
+       RVECENT(romReserved,21)
+       RVECENT(romReserved,22)
+       RVECENT(romReserved,23)
+       RVECENT(romReserved,24)
+       RVECENT(romReserved,25)
+       RVECENT(romReserved,26)
+       RVECENT(romReserved,27)
+       RVECENT(romReserved,28)
+       RVECENT(romReserved,29)
+       RVECENT(romReserved,30)
+       RVECENT(romReserved,31)
+       RVECENT(romReserved,32)
+       RVECENT(romReserved,33)
+       RVECENT(romReserved,34)
+       RVECENT(romReserved,35)
+       RVECENT(romReserved,36)
+       RVECENT(romReserved,37)
+       RVECENT(romReserved,38)
+       RVECENT(romReserved,39)
+       RVECENT(romReserved,40)
+       RVECENT(romReserved,41)
+       RVECENT(romReserved,42)
+       RVECENT(romReserved,43)
+       RVECENT(romReserved,44)
+       RVECENT(romReserved,45)
+       RVECENT(romReserved,46)
+       RVECENT(romReserved,47)
+       RVECENT(romReserved,48)
+       RVECENT(romReserved,49)
+       RVECENT(romReserved,50)
+       RVECENT(romReserved,51)
+       RVECENT(romReserved,52)
+       RVECENT(romReserved,53)
+       RVECENT(romReserved,54)
+       RVECENT(romReserved,55)
+       RVECENT(romReserved,56)
+       RVECENT(romReserved,57)
+       RVECENT(romReserved,58)
+       RVECENT(romReserved,59)
+       RVECENT(romReserved,60)
+       RVECENT(romReserved,61)
+       RVECENT(romReserved,62)
+       RVECENT(romReserved,63)
+       XVECENT(romExcHandle,0x200)     /* bfc00200: R4000 tlbmiss vector */
+       RVECENT(romReserved,65)
+       RVECENT(romReserved,66)
+       RVECENT(romReserved,67)
+       RVECENT(romReserved,68)
+       RVECENT(romReserved,69)
+       RVECENT(romReserved,70)
+       RVECENT(romReserved,71)
+       RVECENT(romReserved,72)
+       RVECENT(romReserved,73)
+       RVECENT(romReserved,74)
+       RVECENT(romReserved,75)
+       RVECENT(romReserved,76)
+       RVECENT(romReserved,77)
+       RVECENT(romReserved,78)
+       RVECENT(romReserved,79)
+       XVECENT(romExcHandle,0x280)     /* bfc00280: R4000 xtlbmiss vector */
+       RVECENT(romReserved,81)
+       RVECENT(romReserved,82)
+       RVECENT(romReserved,83)
+       RVECENT(romReserved,84)
+       RVECENT(romReserved,85)
+       RVECENT(romReserved,86)
+       RVECENT(romReserved,87)
+       RVECENT(romReserved,88)
+       RVECENT(romReserved,89)
+       RVECENT(romReserved,90)
+       RVECENT(romReserved,91)
+       RVECENT(romReserved,92)
+       RVECENT(romReserved,93)
+       RVECENT(romReserved,94)
+       RVECENT(romReserved,95)
+       XVECENT(romExcHandle,0x300)     /* bfc00300: R4000 cache vector */
+       RVECENT(romReserved,97)
+       RVECENT(romReserved,98)
+       RVECENT(romReserved,99)
+       RVECENT(romReserved,100)
+       RVECENT(romReserved,101)
+       RVECENT(romReserved,102)
+       RVECENT(romReserved,103)
+       RVECENT(romReserved,104)
+       RVECENT(romReserved,105)
+       RVECENT(romReserved,106)
+       RVECENT(romReserved,107)
+       RVECENT(romReserved,108)
+       RVECENT(romReserved,109)
+       RVECENT(romReserved,110)
+       RVECENT(romReserved,111)
+       XVECENT(romExcHandle,0x380)     /* bfc00380: R4000 general vector */
+       RVECENT(romReserved,113)
+       RVECENT(romReserved,114)
+       RVECENT(romReserved,115)
+       RVECENT(romReserved,116)
+       RVECENT(romReserved,116)
+       RVECENT(romReserved,118)
+       RVECENT(romReserved,119)
+       RVECENT(romReserved,120)
+       RVECENT(romReserved,121)
+       RVECENT(romReserved,122)
+       RVECENT(romReserved,123)
+       RVECENT(romReserved,124)
+       RVECENT(romReserved,125)
+       RVECENT(romReserved,126)
+       RVECENT(romReserved,127)
+
+       /* We hope there are no more reserved vectors!
+        * 128 * 8 == 1024 == 0x400
+        * so this is address R_VEC+0x400 == 0xbfc00400
+        */
+#ifdef CONFIG_PURPLE
+/* 0xbfc00400 */
+       .word   0xdc870000
+       .word   0xfca70000
+       .word   0x20840008
+       .word   0x20a50008
+       .word   0x20c6ffff
+       .word   0x14c0fffa
+       .word   0x00000000
+       .word   0x03e00008
+       .word   0x00000000
+       .word   0x00000000
+/* 0xbfc00428 */
+       .word   0xdc870000
+       .word   0xfca70000
+       .word   0x20840008
+       .word   0x20a50008
+       .word   0x20c6ffff
+       .word   0x14c0fffa
+       .word   0x00000000
+       .word   0x03e00008
+       .word   0x00000000
+       .word   0x00000000
+#endif /* CONFIG_PURPLE */
+       .align 4
+reset:
+
+       /* Clear watch registers.
+        */
+       mtc0    zero, CP0_WATCHLO
+       mtc0    zero, CP0_WATCHHI
+
+       /* WP(Watch Pending), SW0/1 should be cleared. */
+       mtc0    zero, CP0_CAUSE
+
+       setup_c0_status_reset
+
+       /* Init Timer */
+       mtc0    zero, CP0_COUNT
+       mtc0    zero, CP0_COMPARE
+
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT)
+       /* CONFIG0 register */
+       li      t0, CONF_CM_UNCACHED
+       mtc0    t0, CP0_CONFIG
+#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
+
+       /* Initialize $gp.
+        */
+       bal     1f
+       nop
+       .word   _gp
+1:
+       lw      gp, 0(ra)
+
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT)
+       /* Initialize any external memory.
+        */
+       la      t9, lowlevel_init
+       jalr    t9
+       nop
+
+       /* Initialize caches...
+        */
+       la      t9, mips_cache_reset
+       jalr    t9
+       nop
+
+       /* ... and enable them.
+        */
+       li      t0, CONF_CM_CACHABLE_NONCOHERENT
+       mtc0    t0, CP0_CONFIG
+#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
+
+       /* Set up temporary stack.
+        */
+#ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS
+       li      a0, CONFIG_SYS_INIT_SP_OFFSET
+       la      t9, mips_cache_lock
+       jalr    t9
+       nop
+#endif
+
+       li      t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
+       la      sp, 0(t0)
+
+       la      t9, board_init_f
+       jr      t9
+       nop
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * a0 = addr_sp
+ * a1 = gd
+ * a2 = destination address
+ */
+       .globl  relocate_code
+       .ent    relocate_code
+relocate_code:
+       move    sp, a0          /* Set new stack pointer        */
+
+       li      t0, CONFIG_SYS_MONITOR_BASE
+       la      t3, in_ram
+       lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
+       move    t1, a2
+       move    s2, a2          /* s2 <-- destination address   */
+
+       /*
+        * Fix $gp:
+        *
+        * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address
+        */
+       move    t6, gp
+       sub     gp, CONFIG_SYS_MONITOR_BASE
+       add     gp, a2          /* gp now adjusted              */
+       sub     s1, gp, t6      /* s1 <-- relocation offset     */
+
+       /*
+        * t0 = source address
+        * t1 = target address
+        * t2 = source end address
+        */
+
+       /*
+        * Save destination address and size for later usage in flush_cache()
+        */
+       move    s0, a1          /* save gd in s0                */
+       move    a0, t1          /* a0 <-- destination addr      */
+       sub     a1, t2, t0      /* a1 <-- size                  */
+
+       /* On the purple board we copy the code earlier in a special way
+        * in order to solve flash problems
+        */
+#ifndef CONFIG_PURPLE
+1:
+       lw      t3, 0(t0)
+       sw      t3, 0(t1)
+       addu    t0, 4
+       ble     t0, t2, 1b
+       addu    t1, 4           /* delay slot                   */
+#endif
+
+       /* If caches were enabled, we would have to flush them here.
+        */
+
+       /* a0 & a1 are already set up for flush_cache(start, size) */
+       la      t9, flush_cache
+       jalr    t9
+       nop
+
+       /* Jump to where we've relocated ourselves.
+        */
+       addi    t0, s2, in_ram - _start
+       jr      t0
+       nop
+
+       .word   _gp
+       .word   _GLOBAL_OFFSET_TABLE_
+       .word   uboot_end_data
+       .word   uboot_end
+       .word   num_got_entries
+
+in_ram:
+       /*
+        * Now we want to update GOT.
+        *
+        * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
+        * generated by GNU ld. Skip these reserved entries from relocation.
+        */
+       lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
+       lw      t4, -16(t0)     /* t4 <-- _GLOBAL_OFFSET_TABLE_ */
+       lw      t5, -20(t0)     /* t5 <-- _gp   */
+       sub     t4, t5          /* compute offset*/
+       add     t4, t4, gp      /* t4 now holds relocated _GLOBAL_OFFSET_TABLE_ */
+       addi    t4, t4, 8       /* Skipping first two entries.  */
+       li      t2, 2
+1:
+       lw      t1, 0(t4)
+       beqz    t1, 2f
+       add     t1, s1
+       sw      t1, 0(t4)
+2:
+       addi    t2, 1
+       blt     t2, t3, 1b
+       addi    t4, 4           /* delay slot                   */
+
+       /* Clear BSS.
+        */
+       lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
+       lw      t2, -8(t0)      /* t2 <-- uboot_end             */
+       add     t1, s1          /* adjust pointers              */
+       add     t2, s1
+
+       sub     t1, 4
+1:
+       addi    t1, 4
+       bltl    t1, t2, 1b
+       sw      zero, 0(t1)     /* delay slot                   */
+
+       move    a0, s0          /* a0 <-- gd                    */
+       la      t9, board_init_r
+       jr      t9
+       move    a1, s2          /* delay slot                   */
+
+       .end    relocate_code
+
+       /* Exception handlers.
+        */
+romReserved:
+       b       romReserved
+
+romExcHandle:
+       b       romExcHandle
index 42756f5b822e7be307f247558bf2f6ada992c91c..b3c6d512e70fd4a3f298e6410700254b00757b3d 100644 (file)
@@ -37,7 +37,7 @@ phys_size_t initdram(int board_type)
 #define BCSR_PCMCIA_PC0DRVEN           0x0010
 #define BCSR_PCMCIA_PC0RST             0x0080
 
-/* In cpu/mips/cpu.c */
+/* In arch/mips/cpu/cpu.c */
 void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
 
 int checkboard (void)
index 59873d5ef6a80d7b0e108d20069bb729bd94726f..8c3b55af42909fa18b83c15d143a6ba19b0000e3 100644 (file)
@@ -93,7 +93,7 @@ phys_size_t initdram(int board_type)
        return (SDRAM_SIZE);
 }
 
-/* In cpu/mips/cpu.c */
+/* In arch/mips/cpu/cpu.c */
 void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
 
 void set_ledcard(u32 value){
index 773e446c0c72e494536e16b9f2e45898a07df2fb..2510ddfd69ddb9394420b6a23596c9a225778355 100644 (file)
@@ -37,7 +37,7 @@ phys_size_t initdram(int board_type)
 #define BCSR_PCMCIA_PC0DRVEN           0x0010
 #define BCSR_PCMCIA_PC0RST             0x0080
 
-/* In cpu/mips/cpu.c */
+/* In arch/mips/cpu/cpu.c */
 void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
 
 int checkboard (void)
index 236ece478c6a7dfbffe297032239143b6e049635..1881e651c018fdd1f6b1259427330825d12060b8 100644 (file)
@@ -34,9 +34,9 @@ SECTIONS
        . = ALIGN(4);
        .text       :
        {
-         cpu/mips/start.o              (.text)
+         arch/mips/cpu/start.o         (.text)
          board/purple/lowlevel_init.o  (.text)
-         cpu/mips/cache.o              (.text)
+         arch/mips/cpu/cache.o         (.text)
          common/main.o                 (.text)
          common/dlmalloc.o             (.text)
          common/cmd_boot.o             (.text)
diff --git a/cpu/mips/Makefile b/cpu/mips/Makefile
deleted file mode 100644 (file)
index 28a1cbb..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# (C) Copyright 2003-2006
-# 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    = $(obj)lib$(CPU).a
-
-START  = start.o
-SOBJS-y        = cache.o
-COBJS-y        = cpu.o interrupts.o
-
-SOBJS-$(CONFIG_INCA_IP)        += incaip_wdt.o
-COBJS-$(CONFIG_INCA_IP)        += asc_serial.o incaip_clock.o
-COBJS-$(CONFIG_PURPLE) += asc_serial.o
-COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o
-
-SRCS   := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
-OBJS   := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
-START  := $(addprefix $(obj),$(START))
-
-all:   $(obj).depend $(START) $(LIB)
-
-$(LIB):        $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/cpu/mips/asc_serial.c b/cpu/mips/asc_serial.c
deleted file mode 100644 (file)
index be686c2..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * (INCA) ASC UART support
- */
-
-#include <config.h>
-
-#ifdef CONFIG_PURPLE
-#define        serial_init     asc_serial_init
-#define        serial_putc     asc_serial_putc
-#define        serial_puts     asc_serial_puts
-#define        serial_getc     asc_serial_getc
-#define        serial_tstc     asc_serial_tstc
-#define        serial_setbrg   asc_serial_setbrg
-#endif
-
-#include <common.h>
-#include <asm/inca-ip.h>
-#include "asc_serial.h"
-
-#ifdef CONFIG_PURPLE
-
-#undef ASC_FIFO_PRESENT
-#define TOUT_LOOP      100000
-
-/* Set base address for second FPI interrupt control register bank */
-#define SFPI_INTCON_BASEADDR   0xBF0F0000
-
-/* Register offset from base address */
-#define FBS_ISR                0x00000000      /* Interrupt status register */
-#define FBS_IMR                0x00000008      /* Interrupt mask register */
-#define FBS_IDIS       0x00000010      /* Interrupt disable register */
-
-/* Interrupt status register bits */
-#define FBS_ISR_AT     0x00000040      /* ASC transmit interrupt */
-#define FBS_ISR_AR     0x00000020      /* ASC receive interrupt */
-#define FBS_ISR_AE     0x00000010      /* ASC error interrupt */
-#define FBS_ISR_AB     0x00000008      /* ASC transmit buffer interrupt */
-#define FBS_ISR_AS      0x00000004     /* ASC start of autobaud detection interrupt */
-#define FBS_ISR_AF     0x00000002      /* ASC end of autobaud detection interrupt */
-
-#else
-
-#define ASC_FIFO_PRESENT
-
-#endif
-
-
-#define SET_BIT(reg, mask)                  reg |= (mask)
-#define CLEAR_BIT(reg, mask)                reg &= (~mask)
-#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)
-#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)
-#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}
-
-extern uint incaip_get_fpiclk(void);
-
-static int serial_setopt (void);
-
-/* pointer to ASC register base address */
-static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC;
-
-/******************************************************************************
-*
-* serial_init - initialize a INCAASC channel
-*
-* This routine initializes the number of data bits, parity
-* and set the selected baud rate. Interrupts are disabled.
-* Set the modem control signals if the option is selected.
-*
-* RETURNS: N/A
-*/
-
-int serial_init (void)
-{
-#ifdef CONFIG_INCA_IP
-    /* we have to set PMU.EN13 bit to enable an ASC device*/
-    INCAASC_PMU_ENABLE(13);
-#endif
-
-    /* and we have to set CLC register*/
-    CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS);
-    SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001);
-
-    /* initialy we are in async mode */
-    pAsc->asc_con = ASCCON_M_8ASYNC;
-
-    /* select input port */
-    pAsc->asc_pisel = (CONSOLE_TTY & 0x1);
-
-#ifdef ASC_FIFO_PRESENT
-    /* TXFIFO's filling level */
-    SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,
-                   ASCTXFCON_TXFITLOFF, INCAASC_TXFIFO_FL);
-    /* enable TXFIFO */
-    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);
-
-    /* RXFIFO's filling level */
-    SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,
-                   ASCRXFCON_RXFITLOFF, INCAASC_RXFIFO_FL);
-    /* enable RXFIFO */
-    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);
-#endif
-
-    /* enable error signals */
-    SET_BIT(pAsc->asc_con, ASCCON_FEN);
-    SET_BIT(pAsc->asc_con, ASCCON_OEN);
-
-#ifdef CONFIG_INCA_IP
-    /* acknowledge ASC interrupts */
-    ASC_INTERRUPTS_CLEAR(INCAASC_IRQ_LINE_ALL);
-
-    /* disable ASC interrupts */
-    ASC_INTERRUPTS_DISABLE(INCAASC_IRQ_LINE_ALL);
-#endif
-
-#ifdef ASC_FIFO_PRESENT
-    /* set FIFOs into the transparent mode */
-    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXTMEN);
-    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXTMEN);
-#endif
-
-    /* set baud rate */
-    serial_setbrg();
-
-    /* set the options */
-    serial_setopt();
-
-    return 0;
-}
-
-void serial_setbrg (void)
-{
-    ulong      uiReloadValue, fdv;
-    ulong      f_ASC;
-
-#ifdef CONFIG_INCA_IP
-    f_ASC = incaip_get_fpiclk();
-#else
-    f_ASC = ASC_CLOCK_RATE;
-#endif
-
-#ifndef INCAASC_USE_FDV
-    fdv = 2;
-    uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
-#else
-    fdv = INCAASC_FDV_HIGH_BAUDRATE;
-    uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
-#endif /* INCAASC_USE_FDV */
-
-    if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
-    {
-#ifndef INCAASC_USE_FDV
-       fdv = 3;
-       uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
-#else
-       fdv = INCAASC_FDV_LOW_BAUDRATE;
-       uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
-#endif /* INCAASC_USE_FDV */
-
-       if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
-       {
-           return;    /* can't impossibly generate that baud rate */
-       }
-    }
-
-    /* Disable Baud Rate Generator; BG should only be written when R=0 */
-    CLEAR_BIT(pAsc->asc_con, ASCCON_R);
-
-#ifndef INCAASC_USE_FDV
-    /*
-     * Disable Fractional Divider (FDE)
-     * Divide clock by reload-value + constant (BRS)
-     */
-    /* FDE = 0 */
-    CLEAR_BIT(pAsc->asc_con, ASCCON_FDE);
-
-    if ( fdv == 2 )
-       CLEAR_BIT(pAsc->asc_con, ASCCON_BRS);   /* BRS = 0 */
-    else
-       SET_BIT(pAsc->asc_con, ASCCON_BRS); /* BRS = 1 */
-
-#else /* INCAASC_USE_FDV */
-
-    /* Enable Fractional Divider */
-    SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */
-
-    /* Set fractional divider value */
-    pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;
-
-#endif /* INCAASC_USE_FDV */
-
-    /* Set reload value in BG */
-    pAsc->asc_bg = uiReloadValue;
-
-    /* Enable Baud Rate Generator */
-    SET_BIT(pAsc->asc_con, ASCCON_R);           /* R = 1 */
-}
-
-/*******************************************************************************
-*
-* serial_setopt - set the serial options
-*
-* Set the channel operating mode to that specified. Following options
-* are supported: CREAD, CSIZE, PARENB, and PARODD.
-*
-* Note, this routine disables the transmitter.  The calling routine
-* may have to re-enable it.
-*
-* RETURNS:
-* Returns 0 to indicate success, otherwise -1 is returned
-*/
-
-static int serial_setopt (void)
-{
-    ulong  con;
-
-    switch ( ASC_OPTIONS & ASCOPT_CSIZE )
-    {
-    /* 7-bit-data */
-    case ASCOPT_CS7:
-       con = ASCCON_M_7ASYNCPAR;   /* 7-bit-data and parity bit */
-       break;
-
-    /* 8-bit-data */
-    case ASCOPT_CS8:
-       if ( ASC_OPTIONS & ASCOPT_PARENB )
-           con = ASCCON_M_8ASYNCPAR;   /* 8-bit-data and parity bit */
-       else
-           con = ASCCON_M_8ASYNC;      /* 8-bit-data no parity */
-       break;
-
-    /*
-     *  only 7 and 8-bit frames are supported
-     *  if we don't use IOCTL extensions
-     */
-    default:
-       return -1;
-    }
-
-    if ( ASC_OPTIONS & ASCOPT_STOPB )
-       SET_BIT(con, ASCCON_STP);       /* 2 stop bits */
-    else
-       CLEAR_BIT(con, ASCCON_STP);     /* 1 stop bit */
-
-    if ( ASC_OPTIONS & ASCOPT_PARENB )
-       SET_BIT(con, ASCCON_PEN);           /* enable parity checking */
-    else
-       CLEAR_BIT(con, ASCCON_PEN);         /* disable parity checking */
-
-    if ( ASC_OPTIONS & ASCOPT_PARODD )
-       SET_BIT(con, ASCCON_ODD);       /* odd parity */
-    else
-       CLEAR_BIT(con, ASCCON_ODD);     /* even parity */
-
-    if ( ASC_OPTIONS & ASCOPT_CREAD )
-       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_SETREN); /* Receiver enable */
-
-    pAsc->asc_con |= con;
-
-    return 0;
-}
-
-void serial_putc (const char c)
-{
-#ifdef ASC_FIFO_PRESENT
-    uint txFl = 0;
-#else
-    uint timeout = 0;
-#endif
-
-    if (c == '\n') serial_putc ('\r');
-
-#ifdef ASC_FIFO_PRESENT
-    /* check do we have a free space in the TX FIFO */
-    /* get current filling level */
-    do
-    {
-       txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF;
-    }
-    while ( txFl == INCAASC_TXFIFO_FULL );
-#else
-
-    while(!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &
-                          FBS_ISR_AB))
-    {
-           if (timeout++ > TOUT_LOOP)
-           {
-                   break;
-           }
-    }
-#endif
-
-    pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */
-
-#ifndef ASC_FIFO_PRESENT
-    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AB |
-                                                                FBS_ISR_AT;
-#endif
-
-    /* check for errors */
-    if ( pAsc->asc_con & ASCCON_OE )
-    {
-       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
-       return;
-    }
-}
-
-void serial_puts (const char *s)
-{
-    while (*s)
-    {
-       serial_putc (*s++);
-    }
-}
-
-int serial_getc (void)
-{
-    ulong symbol_mask;
-    char c;
-
-    while (!serial_tstc());
-
-    symbol_mask =
-       ((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);
-
-    c = (char)(pAsc->asc_rbuf & symbol_mask);
-
-#ifndef ASC_FIFO_PRESENT
-    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AR;
-#endif
-
-    return c;
-}
-
-int serial_tstc (void)
-{
-    int res = 1;
-
-#ifdef ASC_FIFO_PRESENT
-    if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 )
-    {
-       res = 0;
-    }
-#else
-    if (!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &
-                                                               FBS_ISR_AR))
-
-    {
-       res = 0;
-    }
-#endif
-    else if ( pAsc->asc_con & ASCCON_FE )
-    {
-       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE);
-       res = 0;
-    }
-    else if ( pAsc->asc_con & ASCCON_PE )
-    {
-       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE);
-       res = 0;
-    }
-    else if ( pAsc->asc_con & ASCCON_OE )
-    {
-       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
-       res = 0;
-    }
-
-    return res;
-}
diff --git a/cpu/mips/asc_serial.h b/cpu/mips/asc_serial.h
deleted file mode 100644 (file)
index 7ffdcfa..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/* incaAscSio.h - (INCA) ASC UART tty driver header */
-
-#ifndef __INCincaAscSioh
-#define __INCincaAscSioh
-
-#include <asm/inca-ip.h>
-
-/* channel operating modes */
-#define        ASCOPT_CSIZE    0x00000003
-#define        ASCOPT_CS7      0x00000001
-#define        ASCOPT_CS8      0x00000002
-#define        ASCOPT_PARENB   0x00000004
-#define        ASCOPT_STOPB    0x00000008
-#define        ASCOPT_PARODD   0x00000010
-#define        ASCOPT_CREAD    0x00000020
-
-#define ASC_OPTIONS            (ASCOPT_CREAD | ASCOPT_CS8)
-
-/* ASC input select (0 or 1) */
-#define CONSOLE_TTY    0
-
-/* use fractional divider for baudrate settings */
-#define INCAASC_USE_FDV
-
-#ifdef INCAASC_USE_FDV
-   #define INCAASC_FDV_LOW_BAUDRATE        71
-   #define INCAASC_FDV_HIGH_BAUDRATE       453
-#endif /*INCAASC_USE_FDV*/
-
-
-#define INCAASC_TXFIFO_FL       1
-#define INCAASC_RXFIFO_FL       1
-#define INCAASC_TXFIFO_FULL     16
-
-/* interrupt lines masks for the ASC device interrupts*/
-/* change these macroses if it's necessary */
-#define INCAASC_IRQ_LINE_ALL        0x000F0000  /* all IRQs */
-
-#define INCAASC_IRQ_LINE_TIR            0x00010000      /* TIR - Tx */
-#define INCAASC_IRQ_LINE_RIR            0x00020000      /* RIR - Rx */
-#define INCAASC_IRQ_LINE_EIR            0x00040000      /* EIR - Err */
-#define INCAASC_IRQ_LINE_TBIR           0x00080000      /* TBIR - Tx Buf*/
-
-/* interrupt controller access macros */
-#define ASC_INTERRUPTS_ENABLE(X)  \
-   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) |= X;
-#define ASC_INTERRUPTS_DISABLE(X) \
-   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) &= ~X;
-#define ASC_INTERRUPTS_CLEAR(X)   \
-   *((volatile unsigned int*) INCA_IP_ICU_IM2_ISR) = X;
-
-/* CLC register's bits and bitfields */
-#define ASCCLC_DISR        0x00000001
-#define ASCCLC_DISS        0x00000002
-#define ASCCLC_RMCMASK     0x0000FF00
-#define ASCCLC_RMCOFFSET   8
-
-/* CON register's bits and bitfields */
-#define ASCCON_MODEMASK 0x0007
-    #define ASCCON_M_8SYNC          0x0
-    #define ASCCON_M_8ASYNC         0x1
-    #define ASCCON_M_8IRDAASYNC     0x2
-    #define ASCCON_M_7ASYNCPAR      0x3
-    #define ASCCON_M_9ASYNC         0x4
-    #define ASCCON_M_8WAKEUPASYNC   0x5
-    #define ASCCON_M_8ASYNCPAR      0x7
-#define ASCCON_STP      0x0008
-#define ASCCON_REN      0x0010
-#define ASCCON_PEN      0x0020
-#define ASCCON_FEN      0x0040
-#define ASCCON_OEN      0x0080
-#define ASCCON_PE       0x0100
-#define ASCCON_FE       0x0200
-#define ASCCON_OE       0x0400
-#define ASCCON_FDE      0x0800
-#define ASCCON_ODD      0x1000
-#define ASCCON_BRS      0x2000
-#define ASCCON_LB       0x4000
-#define ASCCON_R        0x8000
-
-/* WHBCON register's bits and bitfields */
-#define ASCWHBCON_CLRREN    0x0010
-#define ASCWHBCON_SETREN    0x0020
-#define ASCWHBCON_CLRPE     0x0100
-#define ASCWHBCON_CLRFE     0x0200
-#define ASCWHBCON_CLROE     0x0400
-#define ASCWHBCON_SETPE     0x0800
-#define ASCWHBCON_SETFE     0x1000
-#define ASCWHBCON_SETOE     0x2000
-
-/* ABCON register's bits and bitfields */
-#define ASCABCON_ABEN       0x0001
-#define ASCABCON_AUREN      0x0002
-#define ASCABCON_ABSTEN     0x0004
-#define ASCABCON_ABDETEN    0x0008
-#define ASCABCON_FCDETEN    0x0010
-#define ASCABCON_EMMASK     0x0300
-    #define ASCABCON_EMOFF          8
-       #define ASCABCON_EM_DISAB       0x0
-       #define ASCABCON_EM_DURAB       0x1
-       #define ASCABCON_EM_ALWAYS      0x2
-#define ASCABCON_TXINV      0x0400
-#define ASCABCON_RXINV      0x0800
-
-/* FDV register mask, offset and bitfields*/
-#define ASCFDV_VALUE_MASK     0x000001FF
-
-/* WHBABCON register's bits and bitfields */
-#define ASCWHBABCON_SETABEN     0x0001
-#define ASCWHBABCON_CLRABEN     0x0002
-
-/* ABSTAT register's bits and bitfields */
-#define ASCABSTAT_FCSDET    0x0001
-#define ASCABSTAT_FCCDET    0x0002
-#define ASCABSTAT_SCSDET    0x0004
-#define ASCABSTAT_SCCDET    0x0008
-#define ASCABSTAT_DETWAIT   0x0010
-
-/* WHBABSTAT register's bits and bitfields */
-#define ASCWHBABSTAT_CLRFCSDET  0x0001
-#define ASCWHBABSTAT_SETFCSDET  0x0002
-#define ASCWHBABSTAT_CLRFCCDET  0x0004
-#define ASCWHBABSTAT_SETFCCDET  0x0008
-#define ASCWHBABSTAT_CLRSCSDET  0x0010
-#define ASCWHBABSTAT_SETSCSDET  0x0020
-#define ASCWHBABSTAT_SETSCCDET  0x0040
-#define ASCWHBABSTAT_CLRSCCDET  0x0080
-#define ASCWHBABSTAT_CLRDETWAIT 0x0100
-#define ASCWHBABSTAT_SETDETWAIT 0x0200
-
-/* TXFCON register's bits and bitfields */
-#define ASCTXFCON_TXFEN         0x0001
-#define ASCTXFCON_TXFFLU        0x0002
-#define ASCTXFCON_TXTMEN        0x0004
-#define ASCTXFCON_TXFITLMASK    0x3F00
-#define ASCTXFCON_TXFITLOFF     8
-
-/* RXFCON register's bits and bitfields */
-#define ASCRXFCON_RXFEN         0x0001
-#define ASCRXFCON_RXFFLU        0x0002
-#define ASCRXFCON_RXTMEN        0x0004
-#define ASCRXFCON_RXFITLMASK    0x3F00
-#define ASCRXFCON_RXFITLOFF     8
-
-/* FSTAT register's bits and bitfields */
-#define ASCFSTAT_RXFFLMASK      0x003F
-#define ASCFSTAT_TXFFLMASK      0x3F00
-#define ASCFSTAT_TXFFLOFF       8
-
-#define INCAASC_PMU_ENABLE(BIT) *((volatile ulong*)0xBF102000) |= (0x1 << BIT);
-
-typedef  struct         /* incaAsc_t */
-{
-    volatile unsigned long  asc_clc;                            /*0x0000*/
-    volatile unsigned long  asc_pisel;                          /*0x0004*/
-    volatile unsigned long  asc_rsvd1[2];   /* for mapping */   /*0x0008*/
-    volatile unsigned long  asc_con;                            /*0x0010*/
-    volatile unsigned long  asc_bg;                             /*0x0014*/
-    volatile unsigned long  asc_fdv;                            /*0x0018*/
-    volatile unsigned long  asc_pmw;        /* not used */      /*0x001C*/
-    volatile unsigned long  asc_tbuf;                           /*0x0020*/
-    volatile unsigned long  asc_rbuf;                           /*0x0024*/
-    volatile unsigned long  asc_rsvd2[2];   /* for mapping */   /*0x0028*/
-    volatile unsigned long  asc_abcon;                          /*0x0030*/
-    volatile unsigned long  asc_abstat;     /* not used */      /*0x0034*/
-    volatile unsigned long  asc_rsvd3[2];   /* for mapping */   /*0x0038*/
-    volatile unsigned long  asc_rxfcon;                         /*0x0040*/
-    volatile unsigned long  asc_txfcon;                         /*0x0044*/
-    volatile unsigned long  asc_fstat;                          /*0x0048*/
-    volatile unsigned long  asc_rsvd4;      /* for mapping */   /*0x004C*/
-    volatile unsigned long  asc_whbcon;                         /*0x0050*/
-    volatile unsigned long  asc_whbabcon;                       /*0x0054*/
-    volatile unsigned long  asc_whbabstat;  /* not used */      /*0x0058*/
-
-} incaAsc_t;
-
-#endif /* __INCincaAscSioh */
diff --git a/cpu/mips/au1x00_eth.c b/cpu/mips/au1x00_eth.c
deleted file mode 100644 (file)
index 5074997..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* Only eth0 supported for now
- *
- * (C) Copyright 2003
- * Thomas.Lange@corelatus.se
- *
- * 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>
-
-#if defined(CONFIG_SYS_DISCOVER_PHY)
-#error "PHY not supported yet"
-/* We just assume that we are running 100FD for now */
-/* We all use switches, right? ;-) */
-#endif
-
-/* I assume ethernet behaves like au1000 */
-
-#ifdef CONFIG_SOC_AU1000
-/* Base address differ between cpu:s */
-#define ETH0_BASE AU1000_ETH0_BASE
-#define MAC0_ENABLE AU1000_MAC0_ENABLE
-#else
-#ifdef CONFIG_SOC_AU1100
-#define ETH0_BASE AU1100_ETH0_BASE
-#define MAC0_ENABLE AU1100_MAC0_ENABLE
-#else
-#ifdef CONFIG_SOC_AU1500
-#define ETH0_BASE AU1500_ETH0_BASE
-#define MAC0_ENABLE AU1500_MAC0_ENABLE
-#else
-#ifdef CONFIG_SOC_AU1550
-#define ETH0_BASE AU1550_ETH0_BASE
-#define MAC0_ENABLE AU1550_MAC0_ENABLE
-#else
-#error "No valid cpu set"
-#endif
-#endif
-#endif
-#endif
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <command.h>
-#include <asm/io.h>
-#include <asm/au1x00.h>
-
-#if defined(CONFIG_CMD_MII)
-#include <miiphy.h>
-#endif
-
-/* Ethernet Transmit and Receive Buffers */
-#define DBUF_LENGTH  1520
-#define PKT_MAXBUF_SIZE                1518
-
-static char txbuf[DBUF_LENGTH];
-
-static int next_tx;
-static int next_rx;
-
-/* 4 rx and 4 tx fifos */
-#define NO_OF_FIFOS 4
-
-typedef struct{
-       u32 status;
-       u32 addr;
-       u32 len; /* Only used for tx */
-       u32 not_used;
-} mac_fifo_t;
-
-mac_fifo_t mac_fifo[NO_OF_FIFOS];
-
-#define MAX_WAIT 1000
-
-#if defined(CONFIG_CMD_MII)
-int  au1x00_miiphy_read(char *devname, unsigned char addr,
-               unsigned char reg, unsigned short * value)
-{
-       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
-       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
-       u32 mii_control;
-       unsigned int timedout = 20;
-
-       while (*mii_control_reg & MAC_MII_BUSY) {
-               udelay(1000);
-               if (--timedout == 0) {
-                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
-                       return -1;
-               }
-       }
-
-       mii_control = MAC_SET_MII_SELECT_REG(reg) |
-               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_READ;
-
-       *mii_control_reg = mii_control;
-
-       timedout = 20;
-       while (*mii_control_reg & MAC_MII_BUSY) {
-               udelay(1000);
-               if (--timedout == 0) {
-                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
-                       return -1;
-               }
-       }
-       *value = *mii_data_reg;
-       return 0;
-}
-
-int  au1x00_miiphy_write(char *devname, unsigned char addr,
-               unsigned char reg, unsigned short value)
-{
-       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
-       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
-       u32 mii_control;
-       unsigned int timedout = 20;
-
-       while (*mii_control_reg & MAC_MII_BUSY) {
-               udelay(1000);
-               if (--timedout == 0) {
-                       printf("au1x00_eth: miiphy_write busy timeout!!\n");
-                       return -1;
-               }
-       }
-
-       mii_control = MAC_SET_MII_SELECT_REG(reg) |
-               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_WRITE;
-
-       *mii_data_reg = value;
-       *mii_control_reg = mii_control;
-       return 0;
-}
-#endif
-
-static int au1x00_send(struct eth_device* dev, volatile void *packet, int length){
-       volatile mac_fifo_t *fifo_tx =
-               (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS);
-       int i;
-       int res;
-
-       /* tx fifo should always be idle */
-       fifo_tx[next_tx].len = length;
-       fifo_tx[next_tx].addr = (virt_to_phys(packet))|TX_DMA_ENABLE;
-       au_sync();
-
-       udelay(1);
-       i=0;
-       while(!(fifo_tx[next_tx].addr&TX_T_DONE)){
-               if(i>MAX_WAIT){
-                       printf("TX timeout\n");
-                       break;
-               }
-               udelay(1);
-               i++;
-       }
-
-       /* Clear done bit */
-       fifo_tx[next_tx].addr = 0;
-       fifo_tx[next_tx].len = 0;
-       au_sync();
-
-       res = fifo_tx[next_tx].status;
-
-       next_tx++;
-       if(next_tx>=NO_OF_FIFOS){
-               next_tx=0;
-       }
-       return(res);
-}
-
-static int au1x00_recv(struct eth_device* dev){
-       volatile mac_fifo_t *fifo_rx =
-               (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS);
-
-       int length;
-       u32 status;
-
-       for(;;){
-               if(!(fifo_rx[next_rx].addr&RX_T_DONE)){
-                       /* Nothing has been received */
-                       return(-1);
-               }
-
-               status = fifo_rx[next_rx].status;
-
-               length = status&0x3FFF;
-
-               if(status&RX_ERROR){
-                       printf("Rx error 0x%x\n", status);
-               }
-               else{
-                       /* Pass the packet up to the protocol layers. */
-                       NetReceive(NetRxPackets[next_rx], length - 4);
-               }
-
-               fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE;
-
-               next_rx++;
-               if(next_rx>=NO_OF_FIFOS){
-                       next_rx=0;
-               }
-       } /* for */
-
-       return(0); /* Does anyone use this? */
-}
-
-static int au1x00_init(struct eth_device* dev, bd_t * bd){
-
-       volatile u32 *macen = (volatile u32*)MAC0_ENABLE;
-       volatile u32 *mac_ctrl = (volatile u32*)(ETH0_BASE+MAC_CONTROL);
-       volatile u32 *mac_addr_high = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_HIGH);
-       volatile u32 *mac_addr_low = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_LOW);
-       volatile u32 *mac_mcast_high = (volatile u32*)(ETH0_BASE+MAC_MCAST_HIGH);
-       volatile u32 *mac_mcast_low = (volatile u32*)(ETH0_BASE+MAC_MCAST_LOW);
-       volatile mac_fifo_t *fifo_tx =
-               (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS);
-       volatile mac_fifo_t *fifo_rx =
-               (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS);
-       int i;
-
-       next_tx = TX_GET_DMA_BUFFER(fifo_tx[0].addr);
-       next_rx = RX_GET_DMA_BUFFER(fifo_rx[0].addr);
-
-       /* We have to enable clocks before releasing reset */
-       *macen = MAC_EN_CLOCK_ENABLE;
-       udelay(10);
-
-       /* Enable MAC0 */
-       /* We have to release reset before accessing registers */
-       *macen = MAC_EN_CLOCK_ENABLE|MAC_EN_RESET0|
-               MAC_EN_RESET1|MAC_EN_RESET2;
-       udelay(10);
-
-       for(i=0;i<NO_OF_FIFOS;i++){
-               fifo_tx[i].len = 0;
-               fifo_tx[i].addr = virt_to_phys(&txbuf[0]);
-               fifo_rx[i].addr = (virt_to_phys(NetRxPackets[i]))|RX_DMA_ENABLE;
-       }
-
-       /* Put mac addr in little endian */
-#define ea eth_get_dev()->enetaddr
-       *mac_addr_high  =       (ea[5] <<  8) | (ea[4]      ) ;
-       *mac_addr_low   =       (ea[3] << 24) | (ea[2] << 16) |
-               (ea[1] <<  8) | (ea[0]      ) ;
-#undef ea
-       *mac_mcast_low = 0;
-       *mac_mcast_high = 0;
-
-       /* Make sure the MAC buffer is in the correct endian mode */
-#ifdef __LITTLE_ENDIAN
-       *mac_ctrl = MAC_FULL_DUPLEX;
-       udelay(1);
-       *mac_ctrl = MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE;
-#else
-       *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX;
-       udelay(1);
-       *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE;
-#endif
-
-       return(1);
-}
-
-static void au1x00_halt(struct eth_device* dev){
-       volatile u32 *macen = (volatile u32*)MAC0_ENABLE;
-
-       /* Put MAC0 in reset */
-       *macen = 0;
-}
-
-int au1x00_enet_initialize(bd_t *bis){
-       struct eth_device* dev;
-
-       if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) {
-               puts ("malloc failed\n");
-               return -1;
-       }
-
-       memset(dev, 0, sizeof *dev);
-
-       sprintf(dev->name, "Au1X00 ethernet");
-       dev->iobase = 0;
-       dev->priv   = 0;
-       dev->init   = au1x00_init;
-       dev->halt   = au1x00_halt;
-       dev->send   = au1x00_send;
-       dev->recv   = au1x00_recv;
-
-       eth_register(dev);
-
-#if defined(CONFIG_CMD_MII)
-       miiphy_register(dev->name,
-               au1x00_miiphy_read, au1x00_miiphy_write);
-#endif
-
-       return 1;
-}
diff --git a/cpu/mips/au1x00_serial.c b/cpu/mips/au1x00_serial.c
deleted file mode 100644 (file)
index c25ba5a..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * AU1X00 UART support
- *
- * Hardcoded to UART 0 for now
- * Speed and options also hardcoded to 115200 8N1
- *
- *  Copyright (c) 2003 Thomas.Lange@corelatus.se
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <config.h>
-#include <common.h>
-#include <asm/au1x00.h>
-
-/******************************************************************************
-*
-* serial_init - initialize a channel
-*
-* This routine initializes the number of data bits, parity
-* and set the selected baud rate. Interrupts are disabled.
-* Set the modem control signals if the option is selected.
-*
-* RETURNS: N/A
-*/
-
-int serial_init (void)
-{
-       volatile u32 *uart_fifoctl = (volatile u32*)(UART0_ADDR+UART_FCR);
-       volatile u32 *uart_enable = (volatile u32*)(UART0_ADDR+UART_ENABLE);
-
-       /* Enable clocks first */
-       *uart_enable = UART_EN_CE;
-
-       /* Then release reset */
-       /* Must release reset before setting other regs */
-       *uart_enable = UART_EN_CE|UART_EN_E;
-
-       /* Activate fifos, reset tx and rx */
-       /* Set tx trigger level to 12 */
-       *uart_fifoctl = UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|
-               UART_FCR_CLEAR_XMIT|UART_FCR_T_TRIGGER_12;
-
-       serial_setbrg();
-
-       return 0;
-}
-
-
-void serial_setbrg (void)
-{
-       volatile u32 *uart_clk = (volatile u32*)(UART0_ADDR+UART_CLK);
-       volatile u32 *uart_lcr = (volatile u32*)(UART0_ADDR+UART_LCR);
-       volatile u32 *sys_powerctrl = (u32 *)SYS_POWERCTRL;
-       int sd;
-       int divisorx2;
-
-       /* sd is system clock divisor                   */
-       /* see section 10.4.5 in au1550 datasheet       */
-       sd = (*sys_powerctrl & 0x03) + 2;
-
-       /* calulate 2x baudrate and round */
-       divisorx2 = ((CONFIG_SYS_MIPS_TIMER_FREQ/(sd * 16 * CONFIG_BAUDRATE)));
-
-       if (divisorx2 & 0x01)
-               divisorx2 = divisorx2 + 1;
-
-       *uart_clk = divisorx2 / 2;
-
-       /* Set parity, stop bits and word length to 8N1 */
-       *uart_lcr = UART_LCR_WLEN8;
-}
-
-void serial_putc (const char c)
-{
-       volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR);
-       volatile u32 *uart_tx = (volatile u32*)(UART0_ADDR+UART_TX);
-
-       if (c == '\n') serial_putc ('\r');
-
-       /* Wait for fifo to shift out some bytes */
-       while((*uart_lsr&UART_LSR_THRE)==0);
-
-       *uart_tx = (u32)c;
-}
-
-void serial_puts (const char *s)
-{
-       while (*s)
-       {
-               serial_putc (*s++);
-       }
-}
-
-int serial_getc (void)
-{
-       volatile u32 *uart_rx = (volatile u32*)(UART0_ADDR+UART_RX);
-       char c;
-
-       while (!serial_tstc());
-
-       c = (*uart_rx&0xFF);
-       return c;
-}
-
-int serial_tstc (void)
-{
-       volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR);
-
-       if(*uart_lsr&UART_LSR_DR){
-               /* Data in rfifo */
-               return(1);
-       }
-       return 0;
-}
diff --git a/cpu/mips/au1x00_usb_ohci.c b/cpu/mips/au1x00_usb_ohci.c
deleted file mode 100644 (file)
index 0bc2305..0000000
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.
- *
- * (C) Copyright 2003
- * Gary Jennejohn, DENX Software Engineering <garyj@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
- *
- * 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 <config.h>
-
-#ifdef CONFIG_USB_OHCI
-
-/* #include <pci.h> no PCI on the AU1x00 */
-
-#include <common.h>
-#include <malloc.h>
-#include <asm/io.h>
-#include <asm/au1x00.h>
-#include <usb.h>
-#include "au1x00_usb_ohci.h"
-
-#define OHCI_USE_NPS           /* force NoPowerSwitching mode */
-#define OHCI_VERBOSE_DEBUG     /* not always helpful */
-#define OHCI_FILL_TRACE
-
-#define USBH_ENABLE_BE (1<<0)
-#define USBH_ENABLE_C  (1<<1)
-#define USBH_ENABLE_E  (1<<2)
-#define USBH_ENABLE_CE (1<<3)
-#define USBH_ENABLE_RD (1<<4)
-
-#ifdef __LITTLE_ENDIAN
-#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
-#else
-#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE)
-#endif
-
-
-/* For initializing controller (mask in an HCFS mode too) */
-#define OHCI_CONTROL_INIT \
-       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-
-#undef readl
-#undef writel
-
-#define readl(a)     au_readl((long)(a))
-#define writel(v,a)  au_writel((v),(int)(a))
-
-#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
-
-#define DEBUG
-#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)
-#define SHOW_INFO
-#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)
-
-/* 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 *)m32_swap(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 m16_swap (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 ((long)ed, &ohci->regs->ed_controlhead);
-               } else {
-                       ohci->ed_controltail->hwNextED = m32_swap (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 ((long)ed, &ohci->regs->ed_bulkhead);
-               } else {
-                       ohci->ed_bulktail->hwNextED = m32_swap (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 *ed)
-{
-       ed->hwINFO |= m32_swap (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 (m32_swap (*((__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 *)m32_swap (*((__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 (m32_swap (*((__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 *)m32_swap (*((__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 = m32_swap (OHCI_ED_SKIP); /* skip ed */
-               /* dummy td; end of td list for ed */
-               td = td_alloc (usb_dev);
-               ed->hwTailP = m32_swap (td);
-               ed->hwHeadP = ed->hwTailP;
-               ed->state = ED_UNLINK;
-               ed->type = usb_pipetype (pipe);
-               ohci_dev.ed_cnt++;
-       }
-
-       ed->hwINFO = m32_swap (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 *)(m32_swap (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 (1 || (usb_pipebulk(urb_priv->pipe) &&
-                               usb_pipeout(urb_priv->pipe))) {
-               for (i = 0; i < len; i++)
-               printf("td->data[%d] %#2x\n",i, ((unsigned char *)(td->data+0x80000000))[i]);
-       }
-#endif
-       if (!len)
-               data = 0;
-
-       td->hwINFO = m32_swap (info);
-       td->hwCBP = m32_swap (data);
-       if (data)
-               td->hwBE = m32_swap (data + len - 1);
-       else
-               td->hwBE = 0;
-       td->hwNextTD = m32_swap (td_pt);
-       td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000);
-
-       /* append to queue */
-       td->ed->hwTailP = td->hwNextTD;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* prepare all TDs of a transfer */
-
-#define kseg_to_phys(x)          ((void *)((__u32)(x) - 0x80000000))
-
-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 = kseg_to_phys(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, kseg_to_phys(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 = m32_swap (td->hwINFO);
-       tdBE   = m32_swap (td->hwBE);
-       tdCBP  = m32_swap (td->hwCBP);
-
-
-       if (!(usb_pipecontrol(lurb_priv->pipe) &&
-           ((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 = m32_swap (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 (m32_swap (td_list->hwINFO))) {
-                       lurb_priv = &urb_priv;
-                       dbg(" USB-error/status: %x : %p",
-                                       TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
-                       if (td_list->ed->hwHeadP & m32_swap (0x1)) {
-                               if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
-                                       td_list->ed->hwHeadP =
-                                               (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |
-                                                                       (td_list->ed->hwHeadP & m32_swap (0x2));
-                                       lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
-                               } else
-                                       td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
-                       }
-               }
-
-               td_list->next_dl_td = td_rev;
-               td_rev = td_list;
-               td_list_hc = m32_swap (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 = 0;
-       /* 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 = m32_swap (td_list->hwINFO);
-
-               ed = td_list->ed;
-
-               dl_transfer_length(td_list);
-
-               /* error code of transfer */
-               cc = TD_CC_GET (tdINFO);
-               if (cc != 0) {
-                       dbg("ConditionCode %#x", cc);
-                       stat = cc_to_error[cc];
-               }
-
-               if (ed->state != ED_NEW) {
-                       edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
-                       edTailP = m32_swap (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));
-#else
-       wait_ms(1);
-#endif
-       if (usb_pipeint(pipe)) {
-               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);
-#else
-       wait_ms(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)*/);
-#else
-       wait_ms(1);
-#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));
-#else
-       wait_ms(1);
-#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;
-       }
-
-       wait_ms(10);
-       /* ohci_dump_status(&gohci); */
-
-       /* allow more time for a BULK device to react - some are slow */
-#define BULK_TO         5000   /* timeout in milliseconds */
-       if (usb_pipebulk(pipe))
-               timeout = BULK_TO;
-       else
-               timeout = 100;
-
-       timeout *= 4;
-       /* 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) {
-                       udelay(250); /* 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));
-#else
-       wait_ms(1);
-#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));
-#else
-       wait_ms(1);
-#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) */
-       writel (0, &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) && !(m32_swap (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);
-#else
-       wait_ms(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) {
-               wait_ms(1);
-               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 = m16_swap (ohci->hcca->frame_no) & 1;
-               wait_ms(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);
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define __read_32bit_c0_register(source, sel)                          \
-({ int __res;                                                          \
-       if (sel == 0)                                                   \
-               __asm__ __volatile__(                                   \
-                       "mfc0\t%0, " #source "\n\t"                     \
-                       : "=r" (__res));                                \
-       else                                                            \
-               __asm__ __volatile__(                                   \
-                       ".set\tmips32\n\t"                              \
-                       "mfc0\t%0, " #source ", " #sel "\n\t"           \
-                       ".set\tmips0\n\t"                               \
-                       : "=r" (__res));                                \
-       __res;                                                          \
-})
-
-#define read_c0_prid()         __read_32bit_c0_register($15, 0)
-
-/*
- * low level initalisation routine, called from usb.c
- */
-static char ohci_inited = 0;
-
-int usb_lowlevel_init(void)
-{
-       u32 pin_func;
-       u32 sys_freqctrl, sys_clksrc;
-       u32 prid = read_c0_prid();
-
-       dbg("in usb_lowlevel_init\n");
-
-       /* zero and disable FREQ2 */
-       sys_freqctrl = au_readl(SYS_FREQCTRL0);
-       sys_freqctrl &= ~0xFFF00000;
-       au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
-       /* zero and disable USBH/USBD clocks */
-       sys_clksrc = au_readl(SYS_CLKSRC);
-       sys_clksrc &= ~0x00007FE0;
-       au_writel(sys_clksrc, SYS_CLKSRC);
-
-       sys_freqctrl = au_readl(SYS_FREQCTRL0);
-       sys_freqctrl &= ~0xFFF00000;
-
-       sys_clksrc = au_readl(SYS_CLKSRC);
-       sys_clksrc &= ~0x00007FE0;
-
-       switch (prid & 0x000000FF) {
-       case 0x00: /* DA */
-       case 0x01: /* HA */
-       case 0x02: /* HB */
-               /* CPU core freq to 48MHz to slow it way down... */
-               au_writel(4, SYS_CPUPLL);
-
-               /*
-                * Setup 48MHz FREQ2 from CPUPLL for USB Host
-                */
-               /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
-               sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
-               au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
-               /* CPU core freq to 384MHz */
-               au_writel(0x20, SYS_CPUPLL);
-
-               printf("Au1000: 48MHz OHCI workaround enabled\n");
-               break;
-
-       default:  /* HC and newer */
-               /* FREQ2 = aux/2 = 48 MHz */
-               sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-               au_writel(sys_freqctrl, SYS_FREQCTRL0);
-               break;
-       }
-
-       /*
-        * Route 48MHz FREQ2 into USB Host and/or Device
-        */
-       sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
-       au_writel(sys_clksrc, SYS_CLKSRC);
-
-       /* configure pins GPIO[14:9] as GPIO */
-       pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
-
-       au_writel(pin_func, SYS_PINFUNC);
-       au_writel(0x2800, SYS_TRIOUTCLR);
-       au_writel(0x0030, SYS_OUTPUTCLR);
-
-       dbg("OHCI board setup complete\n");
-
-       /* enable host controller */
-       au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
-       udelay(1000);
-       au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
-       udelay(1000);
-
-       /* wait for reset complete (read register twice; see au1500 errata) */
-       while (au_readl(USB_HOST_CONFIG),
-              !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
-               udelay(1000);
-
-       dbg("OHCI clock running\n");
-
-       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 *)(USB_OHCI_BASE | 0xA0000000);
-
-       gohci.flags = 0;
-       gohci.slot_name = "au1x00";
-
-       dbg("OHCI revision: 0x%08x\n"
-              "  RH: a: 0x%08x b: 0x%08x\n",
-              readl(&gohci.regs->revision),
-              readl(&gohci.regs->roothub.a), readl(&gohci.regs->roothub.b));
-
-       if (hc_reset (&gohci) < 0)
-               goto errout;
-
-       /* FIXME this is a second HC reset; why?? */
-       writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
-       wait_ms (10);
-
-       if (hc_start (&gohci) < 0)
-               goto errout;
-
-#ifdef DEBUG
-       ohci_dump (&gohci, 1);
-#else
-       wait_ms(1);
-#endif
-       ohci_inited = 1;
-       return 0;
-
-  errout:
-       err("OHCI initialization error\n");
-       hc_release_ohci (&gohci);
-       /* Initialization failed */
-       au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
-       return -1;
-}
-
-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);
-       /* may not want to do this */
-       /* Disable clock */
-       au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
-       return 0;
-}
-
-#endif /* CONFIG_USB_OHCI */
diff --git a/cpu/mips/au1x00_usb_ohci.h b/cpu/mips/au1x00_usb_ohci.h
deleted file mode 100644 (file)
index bb9f351..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * 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 */
-       __u16   frame_no;               /* current frame number */
-       __u16   pad1;                   /* set to 0 on each frame_no change */
-       __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/cpu/mips/cache.S b/cpu/mips/cache.S
deleted file mode 100644 (file)
index ff4f11c..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- *  Cache-handling routined for MIPS CPUs
- *
- *  Copyright (c) 2003 Wolfgang Denk <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 <config.h>
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/cacheops.h>
-
-#define RA             t8
-
-/*
- * 16kB is the maximum size of instruction and data caches on MIPS 4K,
- * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
- *
- * Note that the above size is the maximum size of primary cache. U-Boot
- * doesn't have L2 cache support for now.
- */
-#define MIPS_MAX_CACHE_SIZE    0x10000
-
-#define INDEX_BASE     CKSEG0
-
-       .macro  cache_op op addr
-       .set    push
-       .set    noreorder
-       .set    mips3
-       cache   \op, 0(\addr)
-       .set    pop
-       .endm
-
-/*
- * cacheop macro to automate cache operations
- * first some helpers...
- */
-#define _mincache(size, maxsize) \
-   bltu  size,maxsize,9f ; \
-   move  size,maxsize ;    \
-9:
-
-#define _align(minaddr, maxaddr, linesize) \
-   .set noat ; \
-   subu  AT,linesize,1 ;   \
-   not   AT ;        \
-   and   minaddr,AT ;      \
-   addu  maxaddr,-1 ;      \
-   and   maxaddr,AT ;      \
-   .set at
-
-/* general operations */
-#define doop1(op1) \
-   cache op1,0(a0)
-#define doop2(op1, op2) \
-   cache op1,0(a0) ;    \
-   nop ;          \
-   cache op2,0(a0)
-
-/* specials for cache initialisation */
-#define doop1lw(op1) \
-   lw zero,0(a0)
-#define doop1lw1(op1) \
-   cache op1,0(a0) ;    \
-   lw zero,0(a0) ;      \
-   cache op1,0(a0)
-#define doop121(op1,op2) \
-   cache op1,0(a0) ;    \
-   nop;           \
-   cache op2,0(a0) ;    \
-   nop;           \
-   cache op1,0(a0)
-
-#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
-   .set  noreorder ;    \
-10:   doop##tag##ops ;  \
-   bne     minaddr,maxaddr,10b ; \
-   add      minaddr,linesize ;   \
-   .set  reorder
-
-/* finally the cache operation macros */
-#define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
-   blez  n,11f ;        \
-   addu  n,kva ;        \
-   _align(kva, n, cacheLineSize) ; \
-   _oploopn(kva, n, cacheLineSize, tag, ops) ; \
-11:
-
-#define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
-   _mincache(n, cacheSize);   \
-   blez  n,11f ;        \
-   addu  n,kva ;        \
-   _align(kva, n, cacheLineSize) ; \
-   _oploopn(kva, n, cacheLineSize, tag, ops) ; \
-11:
-
-#define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
-   vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
-
-#define icacheop(kva, n, cacheSize, cacheLineSize, op) \
-   icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
-
-       .macro  f_fill64 dst, offset, val
-       LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  2 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  3 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  4 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  5 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  6 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  7 * LONGSIZE)(\dst)
-#if LONGSIZE == 4
-       LONG_S  \val, (\offset +  8 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  9 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 10 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 11 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 12 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 13 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 14 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 15 * LONGSIZE)(\dst)
-#endif
-       .endm
-
-/*
- * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
- */
-LEAF(mips_init_icache)
-       blez    a1, 9f
-       mtc0    zero, CP0_TAGLO
-       /* clear tag to invalidate */
-       PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, a1
-1:     cache_op        Index_Store_Tag_I t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-       /* fill once, so data field parity is correct */
-       PTR_LI          t0, INDEX_BASE
-2:     cache_op        Fill t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 2b
-       /* invalidate again - prudent but not strictly neccessary */
-       PTR_LI          t0, INDEX_BASE
-1:     cache_op        Index_Store_Tag_I t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-9:     jr      ra
-       END(mips_init_icache)
-
-/*
- * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
- */
-LEAF(mips_init_dcache)
-       blez    a1, 9f
-       mtc0    zero, CP0_TAGLO
-       /* clear all tags */
-       PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, a1
-1:     cache_op        Index_Store_Tag_D t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-       /* load from each line (in cached space) */
-       PTR_LI          t0, INDEX_BASE
-2:     LONG_L          zero, 0(t0)
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 2b
-       /* clear all tags */
-       PTR_LI          t0, INDEX_BASE
-1:     cache_op        Index_Store_Tag_D t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-9:     jr      ra
-       END(mips_init_dcache)
-
-/*******************************************************************************
-*
-* mips_cache_reset - low level initialisation of the primary caches
-*
-* This routine initialises the primary caches to ensure that they
-* have good parity.  It must be called by the ROM before any cached locations
-* are used to prevent the possibility of data with bad parity being written to
-* memory.
-* To initialise the instruction cache it is essential that a source of data
-* with good parity is available. This routine
-* will initialise an area of memory starting at location zero to be used as
-* a source of parity.
-*
-* RETURNS: N/A
-*
-*/
-NESTED(mips_cache_reset, 0, ra)
-       move    RA, ra
-       li      t2, CONFIG_SYS_ICACHE_SIZE
-       li      t3, CONFIG_SYS_DCACHE_SIZE
-       li      t4, CONFIG_SYS_CACHELINE_SIZE
-       move    t5, t4
-
-       li      v0, MIPS_MAX_CACHE_SIZE
-
-       /*
-        * Now clear that much memory starting from zero.
-        */
-       PTR_LI          a0, CKSEG1
-       PTR_ADDU        a1, a0, v0
-2:     PTR_ADDIU       a0, 64
-       f_fill64        a0, -64, zero
-       bne             a0, a1, 2b
-
-       /*
-        * The caches are probably in an indeterminate state,
-        * so we force good parity into them by doing an
-        * invalidate, load/fill, invalidate for each line.
-        */
-
-       /*
-        * Assume bottom of RAM will generate good parity for the cache.
-        */
-
-       /*
-        * Initialize the I-cache first,
-        */
-       move    a1, t2
-       move    a2, t4
-       PTR_LA  t7, mips_init_icache
-       jalr    t7
-
-       /*
-        * then initialize D-cache.
-        */
-       move    a1, t3
-       move    a2, t5
-       PTR_LA  t7, mips_init_dcache
-       jalr    t7
-
-       jr      RA
-       END(mips_cache_reset)
-
-/*******************************************************************************
-*
-* dcache_status - get cache status
-*
-* RETURNS: 0 - cache disabled; 1 - cache enabled
-*
-*/
-LEAF(dcache_status)
-       mfc0    t0, CP0_CONFIG
-       li      t1, CONF_CM_UNCACHED
-       andi    t0, t0, CONF_CM_CMASK
-       move    v0, zero
-       beq     t0, t1, 2f
-       li      v0, 1
-2:     jr      ra
-       END(dcache_status)
-
-/*******************************************************************************
-*
-* dcache_disable - disable cache
-*
-* RETURNS: N/A
-*
-*/
-LEAF(dcache_disable)
-       mfc0    t0, CP0_CONFIG
-       li      t1, -8
-       and     t0, t0, t1
-       ori     t0, t0, CONF_CM_UNCACHED
-       mtc0    t0, CP0_CONFIG
-       jr      ra
-       END(dcache_disable)
-
-/*******************************************************************************
-*
-* dcache_enable - enable cache
-*
-* RETURNS: N/A
-*
-*/
-LEAF(dcache_enable)
-       mfc0    t0, CP0_CONFIG
-       ori     t0, CONF_CM_CMASK
-       xori    t0, CONF_CM_CMASK
-       ori     t0, CONF_CM_CACHABLE_NONCOHERENT
-       mtc0    t0, CP0_CONFIG
-       jr      ra
-       END(dcache_enable)
-
-#ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS
-/*******************************************************************************
-*
-* mips_cache_lock - lock RAM area pointed to by a0 in cache.
-*
-* RETURNS: N/A
-*
-*/
-#if defined(CONFIG_PURPLE)
-# define       CACHE_LOCK_SIZE (CONFIG_SYS_DCACHE_SIZE/2)
-#else
-# define       CACHE_LOCK_SIZE (CONFIG_SYS_DCACHE_SIZE)
-#endif
-       .globl  mips_cache_lock
-       .ent    mips_cache_lock
-mips_cache_lock:
-       li      a1, CKSEG0 - CACHE_LOCK_SIZE
-       addu    a0, a1
-       li      a2, CACHE_LOCK_SIZE
-       li      a3, CONFIG_SYS_CACHELINE_SIZE
-       move    a1, a2
-       icacheop(a0,a1,a2,a3,0x1d)
-
-       jr      ra
-
-       .end    mips_cache_lock
-#endif /* CONFIG_SYS_INIT_RAM_LOCK_MIPS */
diff --git a/cpu/mips/config.mk b/cpu/mips/config.mk
deleted file mode 100644 (file)
index a173c54..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# (C) Copyright 2003
-# 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
-#
-v=$(shell $(AS) --version | grep 'GNU assembler' | egrep -o '2\.[0-9\.]+' | cut -d. -f2)
-MIPSFLAGS:=$(shell \
-if [ "$v" -lt "14" ]; then \
-       echo "-mcpu=4kc"; \
-else \
-       echo "-march=4kc -mtune=4kc"; \
-fi)
-
-ifneq (,$(findstring 4KCle,$(CROSS_COMPILE)))
-ENDIANNESS = -EL
-else
-ENDIANNESS = -EB
-endif
-
-MIPSFLAGS += $(ENDIANNESS)
-
-PLATFORM_CPPFLAGS += $(MIPSFLAGS)
diff --git a/cpu/mips/cpu.c b/cpu/mips/cpu.c
deleted file mode 100644 (file)
index d5a1604..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * (C) Copyright 2003
- * 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 <common.h>
-#include <command.h>
-#include <netdev.h>
-#include <asm/mipsregs.h>
-#include <asm/cacheops.h>
-#include <asm/reboot.h>
-
-#define cache_op(op,addr)                                              \
-       __asm__ __volatile__(                                           \
-       "       .set    push                                    \n"     \
-       "       .set    noreorder                               \n"     \
-       "       .set    mips3\n\t                               \n"     \
-       "       cache   %0, %1                                  \n"     \
-       "       .set    pop                                     \n"     \
-       :                                                               \
-       : "i" (op), "R" (*(unsigned char *)(addr)))
-
-void __attribute__((weak)) _machine_restart(void)
-{
-}
-
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
-       _machine_restart();
-
-       fprintf(stderr, "*** reset failed ***\n");
-       return 0;
-}
-
-void flush_cache(ulong start_addr, ulong size)
-{
-       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
-
-       while (1) {
-               cache_op(Hit_Writeback_Inv_D, addr);
-               cache_op(Hit_Invalidate_I, addr);
-               if (addr == aend)
-                       break;
-               addr += lsize;
-       }
-}
-
-void flush_dcache_range(ulong start_addr, ulong stop)
-{
-       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (stop - 1) & ~(lsize - 1);
-
-       while (1) {
-               cache_op(Hit_Writeback_Inv_D, addr);
-               if (addr == aend)
-                       break;
-               addr += lsize;
-       }
-}
-
-void invalidate_dcache_range(ulong start_addr, ulong stop)
-{
-       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (stop - 1) & ~(lsize - 1);
-
-       while (1) {
-               cache_op(Hit_Invalidate_D, addr);
-               if (addr == aend)
-                       break;
-               addr += lsize;
-       }
-}
-
-void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
-{
-       write_c0_entrylo0(low0);
-       write_c0_pagemask(pagemask);
-       write_c0_entrylo1(low1);
-       write_c0_entryhi(hi);
-       write_c0_index(index);
-       tlb_write_indexed();
-}
-
-int cpu_eth_init(bd_t *bis)
-{
-#ifdef CONFIG_SOC_AU1X00
-       au1x00_enet_initialize(bis);
-#endif
-       return 0;
-}
diff --git a/cpu/mips/incaip_clock.c b/cpu/mips/incaip_clock.c
deleted file mode 100644 (file)
index fc2c621..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * (C) Copyright 2003
- * 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 <common.h>
-#include <asm/inca-ip.h>
-
-
-/*******************************************************************************
-*
-* get_cpuclk - returns the frequency of the CPU.
-*
-* Gets the value directly from the INCA-IP hardware.
-*
-* RETURNS:
-*          150.000.000 for 150 MHz
-*          133.333.333 for 133 MHz (= 400MHz/3)
-*          100.000.000 for 100 MHz (= 400MHz/4)
-* NOTE:
-*   This functions should be used by the hardware driver to get the correct
-*   frequency of the CPU. Don't use the macros, which are set to init the CPU
-*   frequency in the ROM code.
-*/
-uint incaip_get_cpuclk (void)
-{
-       /*-------------------------------------------------------------------------*/
-       /* CPU Clock Input Multiplexer (MUX I)                                     */
-       /* Multiplexer MUX I selects the maximum input clock to the CPU.           */
-       /*-------------------------------------------------------------------------*/
-       if (*((volatile ulong *) INCA_IP_CGU_CGU_MUXCR) &
-           INCA_IP_CGU_CGU_MUXCR_MUXI) {
-               /* MUX I set to 150 MHz clock */
-               return 150000000;
-       } else {
-               /* MUX I set to 100/133 MHz clock */
-               if (*((volatile ulong *) INCA_IP_CGU_CGU_DIVCR) & 0x40) {
-                       /* Division value is 1/3, maximum CPU operating */
-                       /* frequency is 133.3 MHz                       */
-                       return 133333333;
-               } else {
-                       /* Division value is 1/4, maximum CPU operating */
-                       /* frequency is 100 MHz                         */
-                       return 100000000;
-               }
-       }
-}
-
-/*******************************************************************************
-*
-* get_fpiclk - returns the frequency of the FPI bus.
-*
-* Gets the value directly from the INCA-IP hardware.
-*
-* RETURNS: Frquency in Hz
-*
-* NOTE:
-*   This functions should be used by the hardware driver to get the correct
-*   frequency of the CPU. Don't use the macros, which are set to init the CPU
-*   frequency in the ROM code.
-*   The calculation for the
-*/
-uint incaip_get_fpiclk (void)
-{
-       uint clkCPU;
-
-       clkCPU = incaip_get_cpuclk ();
-
-       switch (*((volatile ulong *) INCA_IP_CGU_CGU_DIVCR) & 0xC) {
-       case 0x4:
-               return clkCPU >> 1;     /* devided by 2 */
-               break;
-       case 0x8:
-               return clkCPU >> 2;     /* devided by 4 */
-               break;
-       default:
-               return clkCPU;
-               break;
-       }
-}
-
-int incaip_set_cpuclk (void)
-{
-       extern void ebu_init(long);
-       extern void cgu_init(long);
-       extern void sdram_init(long);
-       char tmp[64];
-       ulong cpuclk;
-
-       if (getenv_r ("cpuclk", tmp, sizeof (tmp)) > 0) {
-               cpuclk = simple_strtoul (tmp, NULL, 10) * 1000000;
-               cgu_init (cpuclk);
-               ebu_init (cpuclk);
-               sdram_init (cpuclk);
-       }
-
-       return 0;
-}
diff --git a/cpu/mips/incaip_wdt.S b/cpu/mips/incaip_wdt.S
deleted file mode 100644 (file)
index 3ade3cd..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  INCA-IP Watchdog timer management code.
- *
- *  Copyright (c) 2003 Wolfgang Denk <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 <config.h>
-#include <asm/regdef.h>
-
-
-#define WD_BASE            0xb8000000
-#define WD_CON0(value)     0x0020(value)
-#define WD_CON1(value)     0x0024(value)
-#define WD_DISABLE         0x00000008
-#define WD_ENABLE          0x00000000
-#define WD_WRITE_PW        0xFFFC00F8
-#define WD_WRITE_ENDINIT   0xFFFC00F3
-#define WD_WRITE_INIT      0xFFFC00F2
-
-
-       .globl  disable_incaip_wdt
-disable_incaip_wdt:
-       li      t0, WD_BASE
-
-       /* Calculate password.
-        */
-       lw      t2, WD_CON1(t0)
-       and     t2, 0xC
-
-       lw      t3, WD_CON0(t0)
-       and     t3, 0xFFFFFF01
-
-       or      t3, t2
-       or      t3, 0xF0
-
-       sw      t3, WD_CON0(t0)         /* write password */
-
-       /* Clear ENDINIT.
-        */
-       li      t1, WD_WRITE_INIT
-       sw      t1, WD_CON0(t0)
-
-
-       li      t1, WD_DISABLE
-       sw      t1, WD_CON1(t0)         /* disable watchdog */
-       li      t1, WD_WRITE_PW
-       sw      t1, WD_CON0(t0)         /* write password */
-       li      t1, WD_WRITE_ENDINIT
-       sw      t1, WD_CON0(t0)         /* end command */
-
-       jr      ra
-       nop
diff --git a/cpu/mips/interrupts.c b/cpu/mips/interrupts.c
deleted file mode 100644 (file)
index 87f7a9f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * (C) Copyright 2003
- * 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 <common.h>
-
-void enable_interrupts(void)
-{
-}
-
-int disable_interrupts(void)
-{
-       return 0;
-}
diff --git a/cpu/mips/start.S b/cpu/mips/start.S
deleted file mode 100644 (file)
index 57db589..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- *  Startup Code for MIPS32 CPU-core
- *
- *  Copyright (c) 2003 Wolfgang Denk <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 <config.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-
-       /*
-        * For the moment disable interrupts, mark the kernel mode and
-        * set ST0_KX so that the CPU does not spit fire when using
-        * 64-bit addresses.
-        */
-       .macro  setup_c0_status set clr
-       .set    push
-       mfc0    t0, CP0_STATUS
-       or      t0, ST0_CU0 | \set | 0x1f | \clr
-       xor     t0, 0x1f | \clr
-       mtc0    t0, CP0_STATUS
-       .set    noreorder
-       sll     zero, 3                         # ehb
-       .set    pop
-       .endm
-
-       .macro  setup_c0_status_reset
-#ifdef CONFIG_64BIT
-       setup_c0_status ST0_KX 0
-#else
-       setup_c0_status 0 0
-#endif
-       .endm
-
-#define RVECENT(f,n) \
-   b f; nop
-#define XVECENT(f,bev) \
-   b f     ;           \
-   li k0,bev
-
-       .set noreorder
-
-       .globl _start
-       .text
-_start:
-       RVECENT(reset,0)        /* U-boot entry point */
-       RVECENT(reset,1)        /* software reboot */
-#if defined(CONFIG_INCA_IP)
-       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
-       .word 0x00000000           /* phase of the flash                    */
-#elif defined(CONFIG_PURPLE)
-       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
-       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
-#else
-       RVECENT(romReserved,2)
-#endif
-       RVECENT(romReserved,3)
-       RVECENT(romReserved,4)
-       RVECENT(romReserved,5)
-       RVECENT(romReserved,6)
-       RVECENT(romReserved,7)
-       RVECENT(romReserved,8)
-       RVECENT(romReserved,9)
-       RVECENT(romReserved,10)
-       RVECENT(romReserved,11)
-       RVECENT(romReserved,12)
-       RVECENT(romReserved,13)
-       RVECENT(romReserved,14)
-       RVECENT(romReserved,15)
-       RVECENT(romReserved,16)
-       RVECENT(romReserved,17)
-       RVECENT(romReserved,18)
-       RVECENT(romReserved,19)
-       RVECENT(romReserved,20)
-       RVECENT(romReserved,21)
-       RVECENT(romReserved,22)
-       RVECENT(romReserved,23)
-       RVECENT(romReserved,24)
-       RVECENT(romReserved,25)
-       RVECENT(romReserved,26)
-       RVECENT(romReserved,27)
-       RVECENT(romReserved,28)
-       RVECENT(romReserved,29)
-       RVECENT(romReserved,30)
-       RVECENT(romReserved,31)
-       RVECENT(romReserved,32)
-       RVECENT(romReserved,33)
-       RVECENT(romReserved,34)
-       RVECENT(romReserved,35)
-       RVECENT(romReserved,36)
-       RVECENT(romReserved,37)
-       RVECENT(romReserved,38)
-       RVECENT(romReserved,39)
-       RVECENT(romReserved,40)
-       RVECENT(romReserved,41)
-       RVECENT(romReserved,42)
-       RVECENT(romReserved,43)
-       RVECENT(romReserved,44)
-       RVECENT(romReserved,45)
-       RVECENT(romReserved,46)
-       RVECENT(romReserved,47)
-       RVECENT(romReserved,48)
-       RVECENT(romReserved,49)
-       RVECENT(romReserved,50)
-       RVECENT(romReserved,51)
-       RVECENT(romReserved,52)
-       RVECENT(romReserved,53)
-       RVECENT(romReserved,54)
-       RVECENT(romReserved,55)
-       RVECENT(romReserved,56)
-       RVECENT(romReserved,57)
-       RVECENT(romReserved,58)
-       RVECENT(romReserved,59)
-       RVECENT(romReserved,60)
-       RVECENT(romReserved,61)
-       RVECENT(romReserved,62)
-       RVECENT(romReserved,63)
-       XVECENT(romExcHandle,0x200)     /* bfc00200: R4000 tlbmiss vector */
-       RVECENT(romReserved,65)
-       RVECENT(romReserved,66)
-       RVECENT(romReserved,67)
-       RVECENT(romReserved,68)
-       RVECENT(romReserved,69)
-       RVECENT(romReserved,70)
-       RVECENT(romReserved,71)
-       RVECENT(romReserved,72)
-       RVECENT(romReserved,73)
-       RVECENT(romReserved,74)
-       RVECENT(romReserved,75)
-       RVECENT(romReserved,76)
-       RVECENT(romReserved,77)
-       RVECENT(romReserved,78)
-       RVECENT(romReserved,79)
-       XVECENT(romExcHandle,0x280)     /* bfc00280: R4000 xtlbmiss vector */
-       RVECENT(romReserved,81)
-       RVECENT(romReserved,82)
-       RVECENT(romReserved,83)
-       RVECENT(romReserved,84)
-       RVECENT(romReserved,85)
-       RVECENT(romReserved,86)
-       RVECENT(romReserved,87)
-       RVECENT(romReserved,88)
-       RVECENT(romReserved,89)
-       RVECENT(romReserved,90)
-       RVECENT(romReserved,91)
-       RVECENT(romReserved,92)
-       RVECENT(romReserved,93)
-       RVECENT(romReserved,94)
-       RVECENT(romReserved,95)
-       XVECENT(romExcHandle,0x300)     /* bfc00300: R4000 cache vector */
-       RVECENT(romReserved,97)
-       RVECENT(romReserved,98)
-       RVECENT(romReserved,99)
-       RVECENT(romReserved,100)
-       RVECENT(romReserved,101)
-       RVECENT(romReserved,102)
-       RVECENT(romReserved,103)
-       RVECENT(romReserved,104)
-       RVECENT(romReserved,105)
-       RVECENT(romReserved,106)
-       RVECENT(romReserved,107)
-       RVECENT(romReserved,108)
-       RVECENT(romReserved,109)
-       RVECENT(romReserved,110)
-       RVECENT(romReserved,111)
-       XVECENT(romExcHandle,0x380)     /* bfc00380: R4000 general vector */
-       RVECENT(romReserved,113)
-       RVECENT(romReserved,114)
-       RVECENT(romReserved,115)
-       RVECENT(romReserved,116)
-       RVECENT(romReserved,116)
-       RVECENT(romReserved,118)
-       RVECENT(romReserved,119)
-       RVECENT(romReserved,120)
-       RVECENT(romReserved,121)
-       RVECENT(romReserved,122)
-       RVECENT(romReserved,123)
-       RVECENT(romReserved,124)
-       RVECENT(romReserved,125)
-       RVECENT(romReserved,126)
-       RVECENT(romReserved,127)
-
-       /* We hope there are no more reserved vectors!
-        * 128 * 8 == 1024 == 0x400
-        * so this is address R_VEC+0x400 == 0xbfc00400
-        */
-#ifdef CONFIG_PURPLE
-/* 0xbfc00400 */
-       .word   0xdc870000
-       .word   0xfca70000
-       .word   0x20840008
-       .word   0x20a50008
-       .word   0x20c6ffff
-       .word   0x14c0fffa
-       .word   0x00000000
-       .word   0x03e00008
-       .word   0x00000000
-       .word   0x00000000
-/* 0xbfc00428 */
-       .word   0xdc870000
-       .word   0xfca70000
-       .word   0x20840008
-       .word   0x20a50008
-       .word   0x20c6ffff
-       .word   0x14c0fffa
-       .word   0x00000000
-       .word   0x03e00008
-       .word   0x00000000
-       .word   0x00000000
-#endif /* CONFIG_PURPLE */
-       .align 4
-reset:
-
-       /* Clear watch registers.
-        */
-       mtc0    zero, CP0_WATCHLO
-       mtc0    zero, CP0_WATCHHI
-
-       /* WP(Watch Pending), SW0/1 should be cleared. */
-       mtc0    zero, CP0_CAUSE
-
-       setup_c0_status_reset
-
-       /* Init Timer */
-       mtc0    zero, CP0_COUNT
-       mtc0    zero, CP0_COMPARE
-
-#if !defined(CONFIG_SKIP_LOWLEVEL_INIT)
-       /* CONFIG0 register */
-       li      t0, CONF_CM_UNCACHED
-       mtc0    t0, CP0_CONFIG
-#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
-
-       /* Initialize $gp.
-        */
-       bal     1f
-       nop
-       .word   _gp
-1:
-       lw      gp, 0(ra)
-
-#if !defined(CONFIG_SKIP_LOWLEVEL_INIT)
-       /* Initialize any external memory.
-        */
-       la      t9, lowlevel_init
-       jalr    t9
-       nop
-
-       /* Initialize caches...
-        */
-       la      t9, mips_cache_reset
-       jalr    t9
-       nop
-
-       /* ... and enable them.
-        */
-       li      t0, CONF_CM_CACHABLE_NONCOHERENT
-       mtc0    t0, CP0_CONFIG
-#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
-
-       /* Set up temporary stack.
-        */
-#ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS
-       li      a0, CONFIG_SYS_INIT_SP_OFFSET
-       la      t9, mips_cache_lock
-       jalr    t9
-       nop
-#endif
-
-       li      t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
-       la      sp, 0(t0)
-
-       la      t9, board_init_f
-       jr      t9
-       nop
-
-/*
- * void relocate_code (addr_sp, gd, addr_moni)
- *
- * This "function" does not return, instead it continues in RAM
- * after relocating the monitor code.
- *
- * a0 = addr_sp
- * a1 = gd
- * a2 = destination address
- */
-       .globl  relocate_code
-       .ent    relocate_code
-relocate_code:
-       move    sp, a0          /* Set new stack pointer        */
-
-       li      t0, CONFIG_SYS_MONITOR_BASE
-       la      t3, in_ram
-       lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
-       move    t1, a2
-       move    s2, a2          /* s2 <-- destination address   */
-
-       /*
-        * Fix $gp:
-        *
-        * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address
-        */
-       move    t6, gp
-       sub     gp, CONFIG_SYS_MONITOR_BASE
-       add     gp, a2          /* gp now adjusted              */
-       sub     s1, gp, t6      /* s1 <-- relocation offset     */
-
-       /*
-        * t0 = source address
-        * t1 = target address
-        * t2 = source end address
-        */
-
-       /*
-        * Save destination address and size for later usage in flush_cache()
-        */
-       move    s0, a1          /* save gd in s0                */
-       move    a0, t1          /* a0 <-- destination addr      */
-       sub     a1, t2, t0      /* a1 <-- size                  */
-
-       /* On the purple board we copy the code earlier in a special way
-        * in order to solve flash problems
-        */
-#ifndef CONFIG_PURPLE
-1:
-       lw      t3, 0(t0)
-       sw      t3, 0(t1)
-       addu    t0, 4
-       ble     t0, t2, 1b
-       addu    t1, 4           /* delay slot                   */
-#endif
-
-       /* If caches were enabled, we would have to flush them here.
-        */
-
-       /* a0 & a1 are already set up for flush_cache(start, size) */
-       la      t9, flush_cache
-       jalr    t9
-       nop
-
-       /* Jump to where we've relocated ourselves.
-        */
-       addi    t0, s2, in_ram - _start
-       jr      t0
-       nop
-
-       .word   _gp
-       .word   _GLOBAL_OFFSET_TABLE_
-       .word   uboot_end_data
-       .word   uboot_end
-       .word   num_got_entries
-
-in_ram:
-       /*
-        * Now we want to update GOT.
-        *
-        * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
-        * generated by GNU ld. Skip these reserved entries from relocation.
-        */
-       lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
-       lw      t4, -16(t0)     /* t4 <-- _GLOBAL_OFFSET_TABLE_ */
-       lw      t5, -20(t0)     /* t5 <-- _gp   */
-       sub     t4, t5          /* compute offset*/
-       add     t4, t4, gp      /* t4 now holds relocated _GLOBAL_OFFSET_TABLE_ */
-       addi    t4, t4, 8       /* Skipping first two entries.  */
-       li      t2, 2
-1:
-       lw      t1, 0(t4)
-       beqz    t1, 2f
-       add     t1, s1
-       sw      t1, 0(t4)
-2:
-       addi    t2, 1
-       blt     t2, t3, 1b
-       addi    t4, 4           /* delay slot                   */
-
-       /* Clear BSS.
-        */
-       lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
-       lw      t2, -8(t0)      /* t2 <-- uboot_end             */
-       add     t1, s1          /* adjust pointers              */
-       add     t2, s1
-
-       sub     t1, 4
-1:
-       addi    t1, 4
-       bltl    t1, t2, 1b
-       sw      zero, 0(t1)     /* delay slot                   */
-
-       move    a0, s0          /* a0 <-- gd                    */
-       la      t9, board_init_r
-       jr      t9
-       move    a1, s2          /* delay slot                   */
-
-       .end    relocate_code
-
-       /* Exception handlers.
-        */
-romReserved:
-       b       romReserved
-
-romExcHandle:
-       b       romExcHandle
index 7aff54bce172c3423a667e87068b1eb68fbdfcb9..abdcbb4b22533a1aacf34c76a9962a07f36139d5 100644 (file)
@@ -42,7 +42,7 @@
  *
  *    [[GNU/GPL disclaimer]]
  *
- * and in part from AU1x00 OHCI HCD driver "u-boot/cpu/mips/au1x00_usb_ohci.c"
+ * and in part from AU1x00 OHCI HCD driver "u-boot/arch/mips/cpu/au1x00_usb_ohci.c"
  * (original copyright message follows):
  *
  *    URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.