summaryrefslogtreecommitdiff
path: root/cpu/mips
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/mips')
-rw-r--r--cpu/mips/cache.S4
-rw-r--r--cpu/mips/cpu.c6
-rw-r--r--cpu/mips/serial.c86
-rw-r--r--cpu/mips/start.S38
4 files changed, 128 insertions, 6 deletions
diff --git a/cpu/mips/cache.S b/cpu/mips/cache.S
index aeb04b3..2715b9b 100644
--- a/cpu/mips/cache.S
+++ b/cpu/mips/cache.S
@@ -253,9 +253,9 @@ dcache_disable:
.globl mips_cache_lock
.ent mips_cache_lock
mips_cache_lock:
- li a1, K0BASE - CFG_DCACHE_SIZE
+ li a1, K0BASE - CFG_DCACHE_SIZE/2
addu a0, a1
- li a2, CFG_DCACHE_SIZE
+ li a2, CFG_DCACHE_SIZE/2
li a3, CFG_CACHELINE_SIZE
move a1, a2
icacheop(a0,a1,a2,a3,0x1d)
diff --git a/cpu/mips/cpu.c b/cpu/mips/cpu.c
index 3fc3916..e9676c1 100644
--- a/cpu/mips/cpu.c
+++ b/cpu/mips/cpu.c
@@ -27,8 +27,12 @@
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
-#ifdef CONFIG_INCA_IP
+#if defined(CONFIG_INCA_IP)
*INCA_IP_WDT_RST_REQ = 0x3f;
+#elif defined(CONFIG_PURPLE)
+ void (*f)(void) = (void *) 0xbfc00000;
+
+ f();
#endif
fprintf(stderr, "*** reset failed ***\n");
return 0;
diff --git a/cpu/mips/serial.c b/cpu/mips/serial.c
index ebda509..b26f41d 100644
--- a/cpu/mips/serial.c
+++ b/cpu/mips/serial.c
@@ -2,10 +2,49 @@
* (INCA) ASC UART support
*/
+#include <config.h>
+
+#ifdef CONFIG_PURPLE
+#define serial_init asc_serial_init
+#define serial_putc asc_serial_putc
+#define serial_puts asc_serial_puts
+#define serial_getc asc_serial_getc
+#define serial_tstc asc_serial_tstc
+#define serial_setbrg asc_serial_setbrg
+#endif
+
#include <common.h>
#include <asm/inca-ip.h>
#include "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)
@@ -32,8 +71,10 @@ static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC;
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);
@@ -45,6 +86,7 @@ int serial_init (void)
/* 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);
@@ -56,20 +98,25 @@ int serial_init (void)
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();
@@ -85,7 +132,11 @@ 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;
@@ -210,10 +261,15 @@ static int serial_setopt (void)
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
@@ -221,8 +277,25 @@ void serial_putc (const char c)
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 )
{
@@ -251,6 +324,10 @@ int serial_getc (void)
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;
}
@@ -258,10 +335,19 @@ 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);
diff --git a/cpu/mips/start.S b/cpu/mips/start.S
index bf11655..86a8407 100644
--- a/cpu/mips/start.S
+++ b/cpu/mips/start.S
@@ -42,9 +42,12 @@
_start:
RVECENT(reset,0) /* U-boot entry point */
RVECENT(reset,1) /* software reboot */
-#ifdef CONFIG_INCA_IP
- .word 0x000020C4 /* EBU init code, fetched during booting */
- .word 0x00000000 /* phase of the flash */
+#if defined(CONFIG_INCA_IP)
+ .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+ .word 0x00000000 /* phase of the flash */
+#elif defined(CONFIG_PURPLE)
+ .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+ .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
#else
RVECENT(romReserved,2)
#endif
@@ -178,6 +181,30 @@ _start:
* 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:
@@ -283,12 +310,17 @@ relocate_code:
* 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.
*/