/*
 * (C) Copyright 2000
 * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
 *
 * (C) Copyright 2004
 * ARM Ltd.
 * Philippe Robin, <philippe.robin@arm.com>
 *
 * 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
 */

/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */
/* Should be fairly simple to make it work with the PL010 as well */

#include <common.h>

#ifdef CFG_PL010_SERIAL

#include "serial_pl011.h"

#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
#define IO_READ(addr) (*(volatile unsigned int *)(addr))

/* Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 */
#define NUM_PORTS 2
#define CONSOLE_PORT CONFIG_CONS_INDEX
#define baudRate CONFIG_BAUDRATE
static volatile unsigned char * const port[NUM_PORTS] = {(void*)(CFG_SERIAL0),
                                                         (void*)(CFG_SERIAL1)};


static void pl010_putc(int portnum, char c);
static int pl010_getc(int portnum);
static int pl010_tstc(int portnum);


int serial_init (void)
{
    unsigned int temp;
    unsigned int divisor;

    /*
    ** First, disable everything.
    */
    IO_WRITE(port[CONSOLE_PORT] + UART_PL010_CR, 0x0);

    /*
    ** Set baud rate
    **
    */
    switch (baudRate) {
    case 9600:
      divisor = UART_PL010_BAUD_9600;
      break;

    case 19200:
      divisor = UART_PL010_BAUD_9600;
      break;

    case 38400:
      divisor = UART_PL010_BAUD_38400;
      break;

    case 57600:
      divisor = UART_PL010_BAUD_57600;
      break;

    case 115200:
      divisor = UART_PL010_BAUD_115200;
      break;

    default:
      divisor = UART_PL010_BAUD_38400;
    }
 
    IO_WRITE(port[CONSOLE_PORT] + UART_PL010_LCRM, ((divisor & 0xf00) >> 8));
    IO_WRITE(port[CONSOLE_PORT] + UART_PL010_LCRL, (divisor & 0xff));

    /*
    ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
    */
    IO_WRITE(port[CONSOLE_PORT] + UART_PL010_LCRH,
        (UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN));

    /*
    ** Finally, enable the UART
    */
    IO_WRITE(port[CONSOLE_PORT] + UART_PL010_CR, (UART_PL010_CR_UARTEN));

    return (0);
}

void
serial_putc(const char c)
{
	if (c == '\n')
		pl010_putc(CONSOLE_PORT, '\r');

	pl010_putc(CONSOLE_PORT, c);
}

void
serial_puts (const char *s)
{
	while (*s) {
		serial_putc (*s++);
	}
}

int
serial_getc(void)
{
	return pl010_getc(CONSOLE_PORT);
}

int
serial_tstc(void)
{
	return pl010_tstc(CONSOLE_PORT);
}

void
serial_setbrg (void)
{
}

static void pl010_putc(int portnum, char c)
{
    /* Wait until there is space in the FIFO */
    while (IO_READ(port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF);
    
    /* Send the character */
    IO_WRITE(port[portnum] + UART_PL01x_DR, c);
}

static int pl010_getc(int portnum)
{
    unsigned int data;

    /* Wait until there is data in the FIFO */
    while (IO_READ(port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE);
    
    data = IO_READ(port[portnum] + UART_PL01x_DR);
    
    /* Check for an error flag */
    if (data & 0xFFFFFF00)
    {
        /* Clear the error */
        IO_WRITE(port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF);
        return -1;
    }
    
    return (int)data;
}

static int pl010_tstc(int portnum)
{
    return !(IO_READ(port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE);
}

#endif
