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:
@@ -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
|
||||
|
||||
#########################################################################
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
278
target/linux/ifxmips/image/u-boot/files/cpu/mips/danube/cache.S
Normal file
278
target/linux/ifxmips/image/u-boot/files/cpu/mips/danube/cache.S
Normal 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
|
||||
@@ -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)
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
1086
target/linux/ifxmips/image/u-boot/files/cpu/mips/danube/ifx_cgu.c
Normal file
1086
target/linux/ifxmips/image/u-boot/files/cpu/mips/danube/ifx_cgu.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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__
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
#define IFX_CPU_RESET \
|
||||
{ *DANUBE_RCU_RST_REQ |=1<<30; \
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
442
target/linux/ifxmips/image/u-boot/files/cpu/mips/danube/start.S
Normal file
442
target/linux/ifxmips/image/u-boot/files/cpu/mips/danube/start.S
Normal 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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user