summaryrefslogtreecommitdiff
path: root/cpu/mips/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/mips/serial.c')
-rw-r--r--cpu/mips/serial.c86
1 files changed, 86 insertions, 0 deletions
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);