From bea6bf07dfd9b97ad81fb7433464a9f61ff02105 Mon Sep 17 00:00:00 2001 From: Kyösti Mälkki Date: Thu, 30 Jan 2014 15:45:16 +0200 Subject: uart8250: Move under drivers/uart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic65ffaaa092330ed68d891e4a09a8b86cdc04a3a Signed-off-by: Kyösti Mälkki Reviewed-on: http://review.coreboot.org/5236 Tested-by: build bot (Jenkins) --- src/drivers/uart/uart8250mem.c | 133 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/drivers/uart/uart8250mem.c (limited to 'src/drivers/uart/uart8250mem.c') diff --git a/src/drivers/uart/uart8250mem.c b/src/drivers/uart/uart8250mem.c new file mode 100644 index 0000000000..74929f5923 --- /dev/null +++ b/src/drivers/uart/uart8250mem.c @@ -0,0 +1,133 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2003 Eric Biederman + * Copyright (C) 2006-2010 coresystems GmbH + * + * 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; version 2 of the License. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include "uart8250reg.h" + +/* Should support 8250, 16450, 16550, 16550A type UARTs */ + +/* Expected character delay at 1200bps is 9ms for a working UART + * and no flow-control. Assume UART as stuck if shift register + * or FIFO takes more than 50ms per character to appear empty. + */ +#define SINGLE_CHAR_TIMEOUT (50 * 1000) +#define FIFO_TIMEOUT (16 * SINGLE_CHAR_TIMEOUT) + +static int uart8250_mem_can_tx_byte(unsigned base_port) +{ + return read8(base_port + UART_LSR) & UART_LSR_THRE; +} + +static void uart8250_mem_tx_byte(unsigned base_port, unsigned char data) +{ + unsigned long int i = SINGLE_CHAR_TIMEOUT; + while(i-- && !uart8250_mem_can_tx_byte(base_port)) + udelay(1); + write8(base_port + UART_TBR, data); +} + +static void uart8250_mem_tx_flush(unsigned base_port) +{ + unsigned long int i = FIFO_TIMEOUT; + while(i-- && !(read8(base_port + UART_LSR) & UART_LSR_TEMT)) + udelay(1); +} + +static int uart8250_mem_can_rx_byte(unsigned base_port) +{ + return read8(base_port + UART_LSR) & UART_LSR_DR; +} + +static unsigned char uart8250_mem_rx_byte(unsigned base_port) +{ + unsigned long int i = SINGLE_CHAR_TIMEOUT; + while(i-- && !uart8250_mem_can_rx_byte(base_port)) + udelay(1); + if (i) + return read8(base_port + UART_RBR); + else + return 0x0; +} + +static void uart8250_mem_init(unsigned base_port, unsigned divisor) +{ + /* Disable interrupts */ + write8(base_port + UART_IER, 0x0); + /* Enable FIFOs */ + write8(base_port + UART_FCR, UART_FCR_FIFO_EN); + + /* Assert DTR and RTS so the other end is happy */ + write8(base_port + UART_MCR, UART_MCR_DTR | UART_MCR_RTS); + + /* DLAB on */ + write8(base_port + UART_LCR, UART_LCR_DLAB | CONFIG_TTYS0_LCS); + + write8(base_port + UART_DLL, divisor & 0xFF); + write8(base_port + UART_DLM, (divisor >> 8) & 0xFF); + + /* Set to 3 for 8N1 */ + write8(base_port + UART_LCR, CONFIG_TTYS0_LCS); +} + +void uart_init(void) +{ + u32 base = uart_platform_base(0); + if (!base) + return; + + unsigned int div; + div = uart_baudrate_divisor(default_baudrate(), uart_platform_refclk(), 16); + uart8250_mem_init(base, div); +} + +void uart_tx_byte(unsigned char data) +{ + u32 base = uart_platform_base(0); + if (!base) + return; + uart8250_mem_tx_byte(base, data); +} + +unsigned char uart_rx_byte(void) +{ + u32 base = uart_platform_base(0); + if (!base) + return 0xff; + return uart8250_mem_rx_byte(base); +} + +int uart_can_rx_byte(void) +{ + u32 base = uart_platform_base(0); + if (!base) + return 0; + return uart8250_mem_can_rx_byte(base); +} + +void uart_tx_flush(void) +{ + u32 base = uart_platform_base(0); + if (!base) + return; + uart8250_mem_tx_flush(base); +} -- cgit v1.2.3