From f64111b4865d611821950b25dc1ea235d8d9ca79 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Fri, 13 Dec 2013 20:44:48 -0600 Subject: cpu: Add initial support for Allwinner A10 SoC Add minimal support needed to get a bootblock capable of initialising a serial console. Change-Id: I50dd85544549baf9c5ea0aa3b4296972136c02a4 Signed-off-by: Alexandru Gagniuc Reviewed-on: http://review.coreboot.org/4549 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks Reviewed-by: Stefan Reinauer --- src/cpu/allwinner/a10/uart.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/cpu/allwinner/a10/uart.c (limited to 'src/cpu/allwinner/a10/uart.c') diff --git a/src/cpu/allwinner/a10/uart.c b/src/cpu/allwinner/a10/uart.c new file mode 100644 index 0000000000..dc98bffbdf --- /dev/null +++ b/src/cpu/allwinner/a10/uart.c @@ -0,0 +1,98 @@ +/* + * Uart setup helpers for Allwinner SoCs + * + * Copyright (C) 2013 Alexandru Gagniuc + * Subject to the GNU GPL v2, or (at your option) any later version. + */ + +#include "uart.h" +#include + +/* Give me my 8250 UART definitions!!!! */ +/* TODO: Clean this up when uart8250mem works on ARM */ +#undef CONFIG_CONSOLE_SERIAL8250MEM +#define CONFIG_CONSOLE_SERIAL8250MEM 1 +#include + +/** + * \brief Configure line control settings for UART + */ +void a10_uart_configure(void *uart_base, u32 baud_rate, u8 data_bits, + enum uart_parity parity, u8 stop_bits) +{ + u32 reg32; + u16 div; + struct a10_uart *uart = uart_base; + + /* Enable access to Divisor Latch register */ + write32(UART_LCR_DLAB, &uart->lcr); + /* Set baudrate */ + /* FIXME: We assume clock is 24MHz, which may not be the case */ + div = 24000000 / 16 / baud_rate; + write32((div >> 8) & 0xff, &uart->dlh); + write32(div & 0xff, &uart->dll); + /* Set line control */ + reg32 = (data_bits - 5) & UART_LCR_WLS_MSK; + switch (parity) { + case UART_PARITY_ODD: + reg32 |= UART_LCR_PEN; + break; + case UART_PARITY_EVEN: + reg32 |= UART_LCR_PEN; + reg32 |= UART_LCR_EPS; + break; + case UART_PARITY_NONE: /* Fall through */ + default: + break; + } + write32(reg32, &uart->lcr); +} + +void a10_uart_enable_fifos(void *uart_base) +{ + struct a10_uart *uart = uart_base; + + write32(UART_FCR_FIFO_EN, &uart->fcr); +} + +static int tx_fifo_full(struct a10_uart *uart) +{ + /* This may be a misnomer, or a typo in the datasheet. THRE indicates + * that the TX register is empty, not that the FIFO is not full, but + * this may be due to a datasheet typo. Keep the current name to signal + * intent. */ + return !(read32(&uart->lsr) & UART_LSR_THRE); +} + +static int rx_fifo_empty(struct a10_uart *uart) +{ + return !(read32(&uart->lsr) & UART_LSR_DR); +} + +/** + * \brief Read a single byte from the UART. + * + * Blocks until at least a byte is available. + */ +u8 a10_uart_rx_blocking(void *uart_base) +{ + struct a10_uart *uart = uart_base; + + while (rx_fifo_empty(uart)) ; + + return read32(&uart->rbr); +} + +/** + * \brief Write a single byte to the UART. + * + * Blocks until there is space in the FIFO. + */ +void a10_uart_tx_blocking(void *uart_base, u8 data) +{ + struct a10_uart *uart = uart_base; + + while (tx_fifo_full(uart)) ; + + return write32(data, &uart->thr); +} -- cgit v1.2.3