u-boot/cpu/blackfin/serial.c
Mike Frysinger 9171fc8172 Blackfin: unify cpu and boot modes
All of the duplicated code for Blackfin processors and boot modes have been
unified.  After all, the core is the same for all processors, just the
peripheral set differs (which gets handled in the drivers).

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2008-03-30 15:50:19 -04:00

124 lines
2.7 KiB
C

/*
* U-boot - serial.c Blackfin Serial Driver
*
* Copyright (c) 2005-2008 Analog Devices Inc.
*
* Copyright (c) 2003 Bas Vermeulen <bas@buyways.nl>,
* BuyWays B.V. (www.buyways.nl)
*
* Based heavily on:
* blkfinserial.c: Serial driver for BlackFin DSP internal USRTs.
* Copyright(c) 2003 Metrowerks <mwaddel@metrowerks.com>
* Copyright(c) 2001 Tony Z. Kou <tonyko@arcturusnetworks.com>
* Copyright(c) 2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com>
*
* Based on code from 68328 version serial driver imlpementation which was:
* Copyright (C) 1995 David S. Miller <davem@caip.rutgers.edu>
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
* Copyright (C) 1998, 1999 D. Jeff Dionne <jeff@uclinux.org>
* Copyright (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>
*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Licensed under the GPL-2 or later.
*/
#include <common.h>
#include <watchdog.h>
#include <asm/blackfin.h>
#include <asm/mach-common/bits/uart.h>
#if defined(UART_LSR) && (CONFIG_UART_CONSOLE != 0)
# error CONFIG_UART_CONSOLE must be 0 on parts with only one UART
#endif
#include "serial.h"
/* Symbol for our assembly to call. */
void serial_set_baud(uint32_t baud)
{
serial_early_set_baud(baud);
}
/* Symbol for common u-boot code to call.
* Setup the baudrate (brg: baudrate generator).
*/
void serial_setbrg(void)
{
DECLARE_GLOBAL_DATA_PTR;
serial_set_baud(gd->baudrate);
}
/* Symbol for our assembly to call. */
void serial_initialize(void)
{
serial_early_init();
}
/* Symbol for common u-boot code to call. */
int serial_init(void)
{
serial_initialize();
serial_setbrg();
return 0;
}
void serial_putc(const char c)
{
/* send a \r for compatibility */
if (c == '\n')
serial_putc('\r');
WATCHDOG_RESET();
/* wait for the hardware fifo to clear up */
while (!(*pUART_LSR & THRE))
continue;
/* queue the character for transmission */
*pUART_THR = c;
SSYNC();
WATCHDOG_RESET();
/* wait for the byte to be shifted over the line */
while (!(*pUART_LSR & TEMT))
continue;
}
int serial_tstc(void)
{
WATCHDOG_RESET();
return (*pUART_LSR & DR) ? 1 : 0;
}
int serial_getc(void)
{
uint16_t uart_lsr_val, uart_rbr_val;
/* wait for data ! */
while (!serial_tstc())
continue;
/* clear the status and grab the new byte */
uart_lsr_val = *pUART_LSR;
uart_rbr_val = *pUART_RBR;
if (uart_lsr_val & (OE|PE|FE|BI)) {
/* Some parts are read-to-clear while others are
* write-to-clear. Just do the write for everyone
* since it cant hurt (other than code size).
*/
*pUART_LSR = (OE|PE|FE|BI);
return -1;
}
return uart_rbr_val & 0xFF;
}
void serial_puts(const char *s)
{
while (*s)
serial_putc(*s++);
}