1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-21 12:27:27 +03:00

add u-boot sources for danube

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@11108 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
blogic
2008-05-11 14:13:15 +00:00
parent e43a5d11b5
commit 9a24ac5b8c
82 changed files with 23917 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
#
# (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
COBJS = asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
cpu.o interrupts.o incaip_clock.o ifx_asc.o ifx_clock.o
SOBJS = incaip_wdt.o cache.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
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
#########################################################################

View File

@@ -0,0 +1,371 @@
/*
* (INCA) ASC UART support
*/
#include <config.h>
#if defined(CONFIG_PURPLE) || defined(CONFIG_INCA_IP)
#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;
}
#endif /* CONFIG_PURPLE || CONFIG_INCA_IP */

View File

@@ -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 */

View File

@@ -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>
#ifdef CONFIG_AU1X00
#if defined(CFG_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_AU1000
/* Base address differ between cpu:s */
#define ETH0_BASE AU1000_ETH0_BASE
#define MAC0_ENABLE AU1000_MAC0_ENABLE
#else
#ifdef CONFIG_AU1100
#define ETH0_BASE AU1100_ETH0_BASE
#define MAC0_ENABLE AU1100_MAC0_ENABLE
#else
#ifdef CONFIG_AU1500
#define ETH0_BASE AU1500_ETH0_BASE
#define MAC0_ENABLE AU1500_MAC0_ENABLE
#else
#ifdef CONFIG_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 (CONFIG_COMMANDS & CFG_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
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){
}
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 0;
}
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 (CONFIG_COMMANDS & CFG_CMD_MII)
miiphy_register(dev->name,
au1x00_miiphy_read, au1x00_miiphy_write);
#endif
return 1;
}
#if (CONFIG_COMMANDS & CFG_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;
}
}
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 /* CONFIG_COMMANDS & CFG_CMD_MII */
#endif /* CONFIG_AU1X00 */

View File

@@ -0,0 +1,135 @@
/*
* 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>
#ifdef CONFIG_AU1X00
#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 = ((CFG_HZ/(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;
}
#endif /* CONFIG_SERIAL_AU1X00 */

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -0,0 +1,278 @@
/*
* Cache-handling routined for MIPS 4K 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 <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/cacheops.h>
#if defined(CONFIG_IFX_MIPS)
# include "ifx_cache.S"
#endif
/* 16KB is the maximum size of instruction and data caches on
* MIPS 4K.
*/
#define MIPS_MAX_CACHE_SIZE 0x4000
/*
* 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))
/*******************************************************************************
*
* 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
*
*/
.globl mips_cache_reset
.ent mips_cache_reset
mips_cache_reset:
li t2, CFG_ICACHE_SIZE
li t3, CFG_DCACHE_SIZE
li t4, CFG_CACHELINE_SIZE
move t5, t4
li v0, MIPS_MAX_CACHE_SIZE
/* Now clear that much memory starting from zero.
*/
li a0, KSEG1
addu a1, a0, v0
2: sw zero, 0(a0)
sw zero, 4(a0)
sw zero, 8(a0)
sw zero, 12(a0)
sw zero, 16(a0)
sw zero, 20(a0)
sw zero, 24(a0)
sw zero, 28(a0)
addu a0, 32
bltu a0, a1, 2b
/* Set invalid tag.
*/
mtc0 zero, CP0_TAGLO
#if defined(CONFIG_IFX_MIPS) && defined(IFX_CACHE_EXTRA_INVALID_TAG)
IFX_CACHE_EXTRA_INVALID_TAG
#endif
/*
* 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.
*/
li a0, K0BASE
move a2, t2 # icacheSize
move a3, t4 # icacheLineSize
move a1, a2
icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
#if defined(CONFIG_IFX_MIPS) && defined(IFX_CACHE_EXTRA_OPERATION)
IFX_CACHE_EXTRA_OPERATION
#else
/* To support Orion/R4600, we initialise the data cache in 3 passes.
*/
/* 1: initialise dcache tags.
*/
li a0, K0BASE
move a2, t3 # dcacheSize
move a3, t5 # dcacheLineSize
move a1, a2
icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
/* 2: fill dcache.
*/
li a0, K0BASE
move a2, t3 # dcacheSize
move a3, t5 # dcacheLineSize
move a1, a2
icacheopn(a0,a1,a2,a3,1lw,(dummy))
/* 3: clear dcache tags.
*/
li a0, K0BASE
move a2, t3 # dcacheSize
move a3, t5 # dcacheLineSize
move a1, a2
icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
#endif
j ra
.end mips_cache_reset
/*******************************************************************************
*
* dcache_status - get cache status
*
* RETURNS: 0 - cache disabled; 1 - cache enabled
*
*/
.globl dcache_status
.ent dcache_status
dcache_status:
mfc0 v0, CP0_CONFIG
andi v0, v0, 1
j ra
.end dcache_status
/*******************************************************************************
*
* dcache_disable - disable cache
*
* RETURNS: N/A
*
*/
.globl dcache_disable
.ent dcache_disable
dcache_disable:
mfc0 t0, CP0_CONFIG
li t1, -8
and t0, t0, t1
ori t0, t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
j ra
.end dcache_disable
/*******************************************************************************
*
* mips_cache_lock - lock RAM area pointed to by a0 in cache.
*
* RETURNS: N/A
*
*/
#if defined(CONFIG_PURPLE)
# define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
#else
# define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
#endif
.globl mips_cache_lock
.ent mips_cache_lock
mips_cache_lock:
li a1, K0BASE - CACHE_LOCK_SIZE
addu a0, a1
li a2, CACHE_LOCK_SIZE
li a3, CFG_CACHELINE_SIZE
move a1, a2
icacheop(a0,a1,a2,a3,0x1d)
j ra
.end mips_cache_lock

View File

@@ -0,0 +1,53 @@
#
# (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 \
$(CROSS_COMPILE)as --version|grep "GNU assembler"|awk '{print $$3}'|awk -F . '{print $$2}')
ifndef PLATFORM_CPU
PLATFORM_CPU = mips32r2
endif
MIPSFLAGS=$(shell \
if [ "$v" -lt "14" ]; then \
echo "-mcpu=$(PLATFORM_CPU)"; \
else \
echo "-march=$(PLATFORM_CPU) -mtune=$(PLATFORM_CPU)"; \
fi)
ifeq ($(CROSS_COMPILE_UCLIBC),1)
ifneq (,$(findstring mipsel,$(CROSS_COMIPLE)))
ENDIANNESS = -el
else
ENDIANNESS = -eb
endif
else
ifneq (,$(findstring 4KCle,$(CROSS_COMPILE)))
ENDIANNESS = -EL
else
ENDIANNESS = -EB
endif
endif
MIPSFLAGS += $(ENDIANNESS) -mabicalls
PLATFORM_CPPFLAGS += $(MIPSFLAGS)

View File

@@ -0,0 +1,61 @@
/*
* (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>
#if defined(CONFIG_INCA_IP)
# include <asm/inca-ip.h>
#elif defined(CONFIG_IFX_MIPS)
# include <asm/danube.h>
# include "ifx_cpu.c"
#endif
#include <asm/mipsregs.h>
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#if defined(CONFIG_INCA_IP)
*INCA_IP_WDT_RST_REQ = 0x3f;
#elif defined(CONFIG_PURPLE) || defined(CONFIG_TB0229)
void (*f)(void) = (void *) 0xbfc00000;
f();
#elif defined(CONFIG_IFX_MIPS)
IFX_CPU_RESET;
#endif
fprintf(stderr, "*** reset failed ***\n");
return 0;
}
void flush_cache (ulong start_addr, ulong size)
{
}
void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 ){
write_32bit_cp0_register(CP0_ENTRYLO0, low0);
write_32bit_cp0_register(CP0_PAGEMASK, pagemask);
write_32bit_cp0_register(CP0_ENTRYLO1, low1);
write_32bit_cp0_register(CP0_ENTRYHI, hi);
write_32bit_cp0_register(CP0_INDEX, index);
tlb_write_indexed();
}

View File

@@ -0,0 +1,257 @@
/*****************************************************************************
* DANUBE BootROM
* Copyright (c) 2005, Infineon Technologies AG, All rights reserved
* IFAP DC COM SD
*****************************************************************************/
#include <config.h>
//#include <lib.h>
#include <asm/danube.h>
#include <asm/addrspace.h>
#include <asm/ifx_asc.h>
#define ASC_FIFO_PRESENT
#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);}
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef signed long s32;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef volatile unsigned short vuint;
void serial_setbrg (void);
/*TODO: undefine this !!!*/
#undef DEBUG_ASC_RAW
#ifdef DEBUG_ASC_RAW
#define DEBUG_ASC_RAW_RX_BUF 0xA0800000
#define DEBUG_ASC_RAW_TX_BUF 0xA0900000
#endif
static volatile DanubeAsc_t *pAsc = (DanubeAsc_t *)DANUBE_ASC1;
typedef struct{
u16 fdv; /* 0~511 fractional divider value*/
u16 reload; /* 13 bit reload value*/
} ifx_asc_baud_reg_t;
#ifdef ON_VENUS
/*9600 @1.25M rel 00.08*/
//#define FDV 503
//#define RELOAD 7
/*9600 @0.625M rel final00.01 & rtl_freeze*/
#define FDV 503
#define RELOAD 3
/* first index is DDR_SEL, second index is FPI_SEL */
#endif
static ifx_asc_baud_reg_t g_danube_asc_baud[4][2] =
{
#ifdef ON_VENUS
{{503,3},{503,3}}, /* 1152000 @ 166.67M and half*/
{{503,3},{503,3}}, /* 1152000 @ 133.3M and half*/
{{503,3},{503,3}}, /* 1152000 @ 111.11M and half*/
{{503.3},{503,3}} /* 1152000 @ 83.33M and half*/
#else
/* TAPEOUT table */
{{436,76},{419,36}}, /* 1152000 @ 166.67M and half*/
{{453,63},{453,31}}, /* 1152000 @ 133.3M and half*/
{{501,58},{510,29}}, /* 1152000 @ 111.11M and half*/
{{419.36},{453,19}} /* 1152000 @ 83.33M and half*/
#endif
};
/******************************************************************************
*
* asc_init - initialize a Danube ASC 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)
{
/* 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);
/* TXFIFO's filling level */
SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,
ASCTXFCON_TXFITLOFF, DANUBEASC_TXFIFO_FL);
/* enable TXFIFO */
SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);
/* RXFIFO's filling level */
SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,
ASCRXFCON_RXFITLOFF, DANUBEASC_RXFIFO_FL);
/* enable RXFIFO */
SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);
/* set baud rate */
serial_setbrg();
/* enable error signals & Receiver enable */
SET_BIT(pAsc->asc_whbstate, ASCWHBSTATE_SETREN|ASCCON_FEN|ASCCON_TOEN|ASCCON_ROEN);
return 0;
}
void serial_setbrg (void)
{
u32 uiReloadValue, fdv;
#if defined(ON_IKOS)
/*1200 @77K */
fdv=472;
uiReloadValue=5;
#else
/*venus & tapeout */
u32 ddr_sel,fpi_sel;
ddr_sel = (* DANUBE_CGU_SYS) & 0x3;
fpi_sel = ((* DANUBE_CGU_SYS) & 0x40)?1:0;
fdv= g_danube_asc_baud[ddr_sel][fpi_sel].fdv;
uiReloadValue=g_danube_asc_baud[ddr_sel][fpi_sel].reload;
#endif //ON_IKOS
/* Disable Baud Rate Generator; BG should only be written when R=0 */
CLEAR_BIT(pAsc->asc_con, ASCCON_R);
/* Enable Fractional Divider */
SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */
/* Set fractional divider value */
pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;
/* Set reload value in BG */
pAsc->asc_bg = uiReloadValue;
/* Enable Baud Rate Generator */
SET_BIT(pAsc->asc_con, ASCCON_R); /* R = 1 */
}
void serial_putc (const char c)
{
u32 txFl = 0;
#ifdef DEBUG_ASC_RAW
static u8 * debug = (u8 *) DEBUG_ASC_RAW_TX_BUF;
*debug++=c;
#endif
if (c == '\n')
serial_putc ('\r');
/* 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 == DANUBEASC_TXFIFO_FULL );
pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */
/* check for errors */
if ( pAsc->asc_state & ASCSTATE_TOE )
{
SET_BIT(pAsc->asc_whbstate, ASCWHBSTATE_CLRTOE);
return;
}
}
void serial_puts (const char *s)
{
while (*s)
{
serial_putc (*s++);
}
}
int asc_inb(int timeout)
{
u32 symbol_mask;
char c;
while ((pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 ) {
}
symbol_mask = ((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);
c = (char)(pAsc->asc_rbuf & symbol_mask);
return (c);
}
int serial_getc (void)
{
char c;
while ((pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 );
c = (char)(pAsc->asc_rbuf & 0xff);
#ifdef DEBUG_ASC_RAW
static u8* debug=(u8*)(DEBUG_ASC_RAW_RX_BUF);
*debug++=c;
#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
#if 0
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;
}
#endif
return res;
}
int serial_start(void)
{
return 1;
}
int serial_stop(void)
{
return 1;
}

View File

@@ -0,0 +1,60 @@
#define IFX_CACHE_EXTRA_INVALID_TAG \
mtc0 zero, CP0_TAGLO, 1; \
mtc0 zero, CP0_TAGLO, 2; \
mtc0 zero, CP0_TAGLO, 3; \
mtc0 zero, CP0_TAGLO, 4;
#define IFX_CACHE_EXTRA_OPERATION \
/* set WST bit */ \
mfc0 a0, CP0_ECC; \
li a1, ECCF_WST; \
or a0, a1; \
mtc0 a0, CP0_ECC; \
\
li a0, K0BASE; \
move a2, t2; /* icacheSize */ \
move a3, t4; /* icacheLineSize */ \
move a1, a2; \
icacheop(a0,a1,a2,a3,(Index_Store_Tag_I)); \
\
/* clear WST bit */ \
mfc0 a0, CP0_ECC; \
li a1, ~ECCF_WST; \
and a0, a1; \
mtc0 a0, CP0_ECC; \
\
/* 1: initialise dcache tags. */ \
\
/* cache line size */ \
li a2, CFG_CACHELINE_SIZE; \
/* kseg0 mem address */ \
li a1, 0; \
li a3, CFG_CACHE_SETS * CFG_CACHE_WAYS; \
1: \
/* store tag (invalid, not locked) */ \
cache 0x8, 0(a1); \
cache 0x9, 0(a1); \
\
add a3, -1; \
bne a3, zero, 1b; \
add a1, a2; \
\
/* set WST bit */ \
mfc0 a0, CP0_ECC; \
li a1, ECCF_WST; \
or a0, a1; \
mtc0 a0, CP0_ECC; \
\
li a0, K0BASE; \
move a2, t3; /* dcacheSize */ \
move a3, t5; /* dcacheLineSize */ \
move a1, a2; \
icacheop(a0,a1,a2,a3,(Index_Store_Tag_D)); \
\
/* clear WST bit */ \
mfc0 a0, CP0_ECC; \
li a1, ~ECCF_WST; \
and a0, a1; \
mtc0 a0, CP0_ECC;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
#ifndef __DANUBE_CGU_DEV_H__2005_07_20__14_26__
#define __DANUBE_CGU_DEV_H__2005_07_20__14_26__
/******************************************************************************
Copyright (c) 2002, Infineon Technologies. All rights reserved.
No Warranty
Because the program is licensed free of charge, there is no warranty for
the program, to the extent permitted by applicable law. Except when
otherwise stated in writing the copyright holders and/or other parties
provide the program "as is" without warranty of any kind, either
expressed or implied, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose. The
entire risk as to the quality and performance of the program is with
you. should the program prove defective, you assume the cost of all
necessary servicing, repair or correction.
In no event unless required by applicable law or agreed to in writing
will any copyright holder, or any other party who may modify and/or
redistribute the program as permitted above, be liable to you for
damages, including any general, special, incidental or consequential
damages arising out of the use or inability to use the program
(including but not limited to loss of data or data being rendered
inaccurate or losses sustained by you or third parties or a failure of
the program to operate with any other programs), even if such holder or
other party has been advised of the possibility of such damages.
******************************************************************************/
/*
* ####################################
* Definition
* ####################################
*/
/*
* ioctl Command
*/
#define CGU_IOC_MAGIC 'u'
#define CGU_GET_CLOCK_RATES _IOW(CGU_IOC_MAGIC, 0, struct cgu_clock_rates)
#define CGU_IOC_MAXNR 1
/*
* ####################################
* Data Type
* ####################################
*/
/*
* Data Type Used to Call ioctl(GET_CLOCK_RATES)
*/
struct cgu_clock_rates {
u32 mips0;
u32 mips1;
u32 cpu;
u32 io_region;
u32 fpi_bus1;
u32 fpi_bus2;
u32 pp32;
u32 pci;
u32 ethernet;
u32 usb;
u32 clockout0;
u32 clockout1;
u32 clockout2;
u32 clockout3;
};
/*
* ####################################
* Declaration
* ####################################
*/
#if defined(__KERNEL__)
extern u32 cgu_get_mips_clock(int);
extern u32 cgu_get_cpu_clock(void);
extern u32 cgu_get_io_region_clock(void);
extern u32 cgu_get_fpi_bus_clock(int);
extern u32 cgu_get_pp32_clock(void);
extern u32 cgu_get_pci_clock(void);
extern u32 cgu_get_ethernet_clock(void);
extern u32 cgu_get_usb_clock(void);
extern u32 cgu_get_clockout(int);
#endif // defined(__KERNEL__)
#endif // __DANUBE_CGU_DEV_H__2005_07_20__14_26__

View File

@@ -0,0 +1,91 @@
/*
* (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-mips/danube.h>
/*******************************************************************************
*
* get_cpuclk - returns the frequency of the CPU.
*
* NOTE:
* This functions should be used by the hardware driver to get the correct
* frequency of the CPU.
*/
unsigned int danube_get_ddr_hz(void)
{
switch((*DANUBE_CGU_SYS) & 0x3){
case 0:
return 166666667;
case 1:
return 133333333;
case 2:
return 111111111;
case 3:
return 83333333;
}
}
uint danube_get_cpuclk(void)
{
#ifdef CONFIG_USE_EMULATOR
return EMULATOR_CPU_SPEED;
#else //NOT CONFIG_USE_EMULATOR
unsigned int ddr_clock=danube_get_ddr_hz();
switch((*DANUBE_CGU_SYS) & 0xc){
case 0:
return 333333333;
case 4:
return ddr_clock;
case 8:
return ddr_clock << 1;
default:
break;
/*reserved*/
}
#endif
}
uint danube_get_fpiclk(void)
{
#ifdef CONFIG_USE_EMULATOR
unsigned int clkCPU;
clkCPU = danube_get_cpu_hz();
return clkCPU >> 2;
#else //NOT CONFIG_USE_EMULATOR
unsigned int ddr_clock=danube_get_ddr_hz();
if ((*DANUBE_CGU_SYS) & 0x40){
return ddr_clock >> 1;
}
return ddr_clock;
#endif
}

View File

@@ -0,0 +1,5 @@
#define IFX_CPU_RESET \
{ *DANUBE_RCU_RST_REQ |=1<<30; \
}

View File

@@ -0,0 +1,51 @@
/*
* IFX Platform Dependent CPU Initializations
* - for Danube
*/
#define IFX_EBU_BOOTCFG_DWORD \
.word INFINEON_EBU_BOOTCFG; /* EBU init code, fetched during booting */ \
.word 0x00000000; /* phases of the flash */
#define IFX_MORE_RESERVED_VECTORS \
XVECENT(romExcHandle,0x400); /* Int, CauseIV=1 */ \
RVECENT(romReserved,129); \
RVECENT(romReserved,130); \
RVECENT(romReserved,131); \
RVECENT(romReserved,132); \
RVECENT(romReserved,133); \
RVECENT(romReserved,134); \
RVECENT(romReserved,135); \
RVECENT(romReserved,136); \
RVECENT(romReserved,137); \
RVECENT(romReserved,138); \
RVECENT(romReserved,139); \
RVECENT(romReserved,140); \
RVECENT(romReserved,141); \
RVECENT(romReserved,142); \
RVECENT(romReserved,143); \
RVECENT(romExcHandle,0x480); /* EJTAG debug exception */
#define IFX_RESET_PRECHECK \
mfc0 k0, CP0_EBASE; \
and k0, EBASEF_CPUNUM; \
bne k0, zero, ifx_mips_handler_1; \
nop;
#define IFX_CPU_EXTRA_INIT \
mfc0 k0, CP0_CONFIG, 7; \
li k1, 0x04; \
or k0, k1; \
mtc0 k0, CP0_CONFIG, 7;
#define IFX_CACHE_OPER_MODE \
li t0, CONF_CM_CACHABLE_NO_WA;
/*
* Stop VCPU
*/
#define IFX_MIPS_HANDLER_1 \
wait; \
b ifx_mips_handler_1; \
nop;

View File

@@ -0,0 +1,120 @@
/*
* (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
*/
#ifdef CONFIG_INCA_IP
#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;
}
#endif /* CONFIG_INCA_IP */

View File

@@ -0,0 +1,75 @@
/*
* 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 <version.h>
#include <asm/regdef.h>
#ifdef CONFIG_INCA_IP
#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 */
j ra
nop
#endif /* CONFIG_INCA_IP */

View File

@@ -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;
}

View File

@@ -0,0 +1,442 @@
/*
* 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 <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#if defined(CONFIG_IFX_MIPS)
#include "ifx_start.S"
#endif
#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_IFX_MIPS) && defined(IFX_EBU_BOOTCFG_DWORD)
IFX_EBU_BOOTCFG_DWORD
#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
*/
#if defined(CONFIG_IFX_MIPS) && defined(IFX_MORE_RESERVED_VECTORS)
IFX_MORE_RESERVED_VECTORS
#else
#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 */
#endif /* CONFIG_IFX_MIPS */
.align 4
reset:
#if defined(CONFIG_IFX_MIPS) && defined(IFX_RESET_PRECHECK)
IFX_RESET_PRECHECK
#endif
/* Clear watch registers.
*/
mtc0 zero, CP0_WATCHLO
mtc0 zero, CP0_WATCHHI
/* STATUS register */
#ifdef CONFIG_TB0229
li k0, ST0_CU0
#else
mfc0 k0, CP0_STATUS
#endif
li k1, ~ST0_IE
and k0, k1
mtc0 k0, CP0_STATUS
/* CAUSE register */
mtc0 zero, CP0_CAUSE
#if defined(CONFIG_IFX_MIPS) && defined(IFX_CPU_EXTRA_INIT)
IFX_CPU_EXTRA_INIT
#endif
/* Init Timer */
mtc0 zero, CP0_COUNT
mtc0 zero, CP0_COMPARE
/* CONFIG0 register */
li t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
/* Initialize GOT pointer.
*/
bal 1f
nop
.word _GLOBAL_OFFSET_TABLE_
1:
move gp, ra
lw t1, 0(ra)
move gp, t1
#ifdef CONFIG_INCA_IP
/* Disable INCA-IP Watchdog.
*/
la t9, disable_incaip_wdt
jalr t9
nop
#endif
/* Initialize any external memory.
*/
la t9, lowlevel_init
jalr t9
nop
/* Initialize caches...
*/
la t9, mips_cache_reset
jalr t9
nop
/* ... and enable them.
*/
#if defined(CONFIG_IFX_MIPS) && defined(IFX_CACHE_OPER_MODE)
IFX_CACHE_OPER_MODE
#else
li t0, CONF_CM_CACHABLE_NONCOHERENT
#endif
mtc0 t0, CP0_CONFIG
/* Set up temporary stack.
*/
li a0, CFG_INIT_SP_OFFSET
la t9, mips_cache_lock
jalr t9
nop
li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
la sp, 0(t0)
la t9, board_init_f
j t9
nop
#ifdef CFG_HEAD_CODE
/*
* void jump_unconditional (addr)
* This function simply jumps to the location pointed by a0.
* a0 = target_location
*
*/
.globl jump_unconditional
.ent jump_unconditional
jump_unconditional:
move t9, a0
j t9
nop
.end jump_unconditional
#endif
/*
* 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 */
#ifdef CFG_HEAD_CODE
li t0, CFG_HEAD_BASE
#else
li t0, CFG_MONITOR_BASE
#endif
la t3, in_ram
lw t2, -12(t3) /* t2 <-- uboot_end_data */
move t1, a2
/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
*/
move t6, gp
#ifdef CFG_HEAD_CODE
sub gp, CFG_HEAD_BASE
#else
sub gp, CFG_MONITOR_BASE
#endif
add gp, a2 /* gp now adjusted */
sub t6, gp, t6 /* t6 <-- relocation offset */
/*
* t0 = source address
* t1 = target address
* t2 = source end address
*/
/* 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.
*/
/* Jump to where we've relocated ourselves.
*/
addi t0, a2, in_ram - _start
j t0
nop
.word uboot_end_data
.word uboot_end
.word num_got_entries
in_ram:
/* Now we want to update GOT.
*/
lw t3, -4(t0) /* t3 <-- num_got_entries */
addi t4, gp, 8 /* Skipping first two entries. */
li t2, 2
1:
lw t1, 0(t4)
beqz t1, 2f
add t1, t6
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, t6 /* adjust pointers */
add t2, t6
sub t1, 4
1: addi t1, 4
bltl t1, t2, 1b
sw zero, 0(t1) /* delay slot */
move a0, a1
la t9, board_init_r
j t9
move a1, a2 /* delay slot */
.end relocate_code
/* Exception handlers.
*/
romReserved:
b romReserved
romExcHandle:
b romExcHandle
/* Additional handlers.
*/
#if defined(CONFIG_IFX_MIPS)
#if defined(IFX_MIPS_HANDLER_1)
ifx_mips_handler_1:
IFX_MIPS_HANDLER_1
#endif
#endif

View File

@@ -0,0 +1,428 @@
/*
* 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 <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#define RVECENT(f,n) \
b f; nop
#define XVECENT(f,bev) \
b f ; \
li k0,bev
.set noreorder
.globl _start_bootstrap
.text
_start_bootstrap:
RVECENT(reset,0) /* U-boot entry point */
RVECENT(reset,1) /* software reboot */
#if defined(CONFIG_INCA_IP) || defined(CONFIG_INCA_IP2)
.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 */
#elif defined(CONFIG_DANUBE)
.org 0x10
.word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
.word 0x00000000 /* phase of the flash */
.org 0x18
.word 0x312E3000 /* version x.x */
.word 0x00000000 /* phase of the flash */
#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:
#ifdef CONFIG_INCA_IP2
/* Check for Host or Voice CPU */
mfc0 k0, CP0_EBASE
and k0, EBASEF_CPUNUM
srl k0, EBASEB_CPUNUM
subu k0, EBASE_CPU_HOST
bne k0, zero, voice_reset_handler
nop
#endif
/* Clear watch registers.
*/
mtc0 zero, CP0_WATCHLO
mtc0 zero, CP0_WATCHHI
/* STATUS register */
#ifdef CONFIG_TB0229
li k0, ST0_CU0
#else
mfc0 k0, CP0_STATUS
#endif
li k1, ~ST0_IE
and k0, k1
mtc0 k0, CP0_STATUS
/* CAUSE register */
mtc0 zero, CP0_CAUSE
#ifdef CONFIG_INCA_IP2
/* CONFIG7 register */
mfc0 k0, CP0_CONFIG, 7
li k1, 4 /* Disable RPS due to E83 bug of 24KEC */
or k0, k1
mtc0 k0, CP0_CONFIG, 7
#endif
/* Init Timer */
mtc0 zero, CP0_COUNT
mtc0 zero, CP0_COMPARE
/* CONFIG0 register */
li t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
/* Initialize GOT pointer.
*/
bal 1f
nop
.word _GLOBAL_OFFSET_TABLE_
1:
move gp, ra
lw t1, 0(ra)
move gp, t1
#ifdef CONFIG_INCA_IP
/* Disable INCA-IP Watchdog.
*/
la t9, disable_incaip_wdt
jalr t9
nop
#endif
/* Initialize any external memory.
*/
la t9, lowlevel_init
jalr t9
nop
/* Initialize caches...
*/
la t9, mips_cache_reset
jalr t9
nop
/* ... and enable them.
*/
#ifdef CONFIG_MIPS_FORCE_CACHE_WRITE_THROUGH
li t0, CONF_CM_CACHABLE_NO_WA
#else
li t0, CONF_CM_CACHABLE_NONCOHERENT
#endif
mtc0 t0, CP0_CONFIG
/* Set up temporary stack.
*/
li a0, CFG_INIT_SP_OFFSET
la t9, mips_cache_lock
jalr t9
nop
li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
la sp, 0(t0)
la t9, bootstrap_board_init_f
j t9
nop
/*
* void bootstrap_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 bootstrap_relocate_code
.ent bootstrap_relocate_code
bootstrap_relocate_code:
move sp, a0 /* Set new stack pointer */
li t0, BOOTSTRAP_CFG_MONITOR_BASE
la t3, in_ram
lw t2, -12(t3) /* t2 <-- uboot_end_data_bootsrap */
move t1, a2
/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - BOOTSTRAP_CFG_MONITOR_BASE) + Destination Address
*/
move t6, gp
sub gp, BOOTSTRAP_CFG_MONITOR_BASE
add gp, a2 /* gp now adjusted */
sub t6, gp, t6 /* t6 <-- relocation offset */
/*
* t0 = source address
* t1 = target address
* t2 = source end address
*/
/* 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.
*/
/* Jump to where we've relocated ourselves.
*/
addi t0, a2, in_ram - _start_bootstrap
j t0
nop
.word uboot_end_data_bootstrap
.word uboot_end_bootstrap
.word num_got_entries
in_ram:
/* Now we want to update GOT.
*/
lw t3, -4(t0) /* t3 <-- num_got_entries */
addi t4, gp, 8 /* Skipping first two entries. */
li t2, 2
1:
lw t1, 0(t4)
beqz t1, 2f
add t1, t6
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_bootstrap */
lw t2, -8(t0) /* t2 <-- uboot_end_bootstrap */
add t1, t6 /* adjust pointers */
add t2, t6
sub t1, 4
1: addi t1, 4
bltl t1, t2, 1b
sw zero, 0(t1) /* delay slot */
move a0, a1
la t9, bootstrap_board_init_r
j t9
move a1, a2 /* delay slot */
.end bootstrap_relocate_code
/* Exception handlers.
*/
romReserved:
b romReserved
romExcHandle:
b romExcHandle
#ifdef CONFIG_INCA_IP2
voice_reset_handler:
wait
b voice_reset_handler
nop
#endif