diff options
Diffstat (limited to 'cpu/mips/serial.c')
| -rw-r--r-- | cpu/mips/serial.c | 86 | 
1 files changed, 86 insertions, 0 deletions
| diff --git a/cpu/mips/serial.c b/cpu/mips/serial.c index ebda509b1..b26f41d0c 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); |