From c2610a4a186c6e5a05f6518c2c7a734fde8f6cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Mon, 24 Feb 2014 20:51:30 +0200 Subject: uart: Prepare to support multiple base addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepare low-level register access to take UART base address as a parameter. This is done to support a list of base addresses defined in the platform. Change-Id: Ie630e55f2562f099b0ba9eb94b08c92d26dfdf2e Signed-off-by: Kyösti Mälkki Reviewed-on: http://review.coreboot.org/5309 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc --- src/cpu/samsung/exynos5250/uart.c | 50 ++++++++++++++++++--------------------- src/cpu/samsung/exynos5420/uart.c | 44 ++++++++++++++++------------------ src/cpu/ti/am335x/uart.c | 30 +++++++++++------------ 3 files changed, 59 insertions(+), 65 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/samsung/exynos5250/uart.c b/src/cpu/samsung/exynos5250/uart.c index 14d140c4dc..860d020a92 100644 --- a/src/cpu/samsung/exynos5250/uart.c +++ b/src/cpu/samsung/exynos5250/uart.c @@ -28,9 +28,6 @@ #define RX_FIFO_FULL_MASK (1 << 8) #define TX_FIFO_FULL_MASK (1 << 24) -/* FIXME(dhendrix): exynos5 has 4 UARTs and its functions in u-boot take a - base_port argument. However console_driver functions do not. */ -static uint32_t base_port = CONFIG_CONSOLE_SERIAL_UART_ADDRESS; /* * The coefficient, used to calculate the baudrate on S5P UARTs is @@ -58,9 +55,8 @@ static const int udivslot[] = { 0xffdf, }; -static void serial_setbrg_dev(void) +static void serial_setbrg_dev(struct s5p_uart *uart) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; u32 uclk; u32 val; @@ -87,10 +83,8 @@ static void serial_setbrg_dev(void) * Initialise the serial port with the given baudrate. The settings * are always 8 data bits, no parity, 1 stop bit, no start bits. */ -static void exynos5_init_dev(void) +static void exynos5_init_dev(struct s5p_uart *uart) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; - // TODO initialize with correct peripheral id by base_port. exynos_pinmux_uart3(); @@ -102,12 +96,11 @@ static void exynos5_init_dev(void) /* No interrupts, no DMA, pure polling */ writel(0x245, &uart->ucon); - serial_setbrg_dev(); + serial_setbrg_dev(uart); } -static int exynos5_uart_err_check(int op) +static int exynos5_uart_err_check(struct s5p_uart *uart, int op) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; unsigned int mask; /* @@ -130,14 +123,12 @@ static int exynos5_uart_err_check(int op) * otherwise. When the function is successful, the character read is * written into its argument c. */ -static unsigned char exynos5_uart_rx_byte(void) +static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; - /* wait for character to arrive */ while (!(readl(&uart->ufstat) & (RX_FIFO_COUNT_MASK | RX_FIFO_FULL_MASK))) { - if (exynos5_uart_err_check(0)) + if (exynos5_uart_err_check(uart, 0)) return 0; } @@ -147,49 +138,54 @@ static unsigned char exynos5_uart_rx_byte(void) /* * Output a single byte to the serial port. */ -static void exynos5_uart_tx_byte(unsigned char data) +static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; - /* wait for room in the tx FIFO */ while ((readl(&uart->ufstat) & TX_FIFO_FULL_MASK)) { - if (exynos5_uart_err_check(1)) + if (exynos5_uart_err_check(uart, 1)) return; } writeb(data, &uart->utxh); } -static void exynos5_uart_tx_flush(void) +static void exynos5_uart_tx_flush(struct s5p_uart *uart) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; - while (readl(&uart->ufstat) & 0x1ff0000); } +unsigned int uart_platform_base(int idx) +{ + return CONFIG_CONSOLE_SERIAL_UART_ADDRESS; +} + #if !defined(__PRE_RAM__) uint32_t uartmem_getbaseaddr(void) { - return base_port; + return uart_platform_base(0); } #endif void uart_init(void) { - exynos5_init_dev(); + struct s5p_uart *uart = uart_platform_baseptr(0); + exynos5_init_dev(uart); } unsigned char uart_rx_byte(void) { - return exynos5_uart_rx_byte(); + struct s5p_uart *uart = uart_platform_baseptr(0); + return exynos5_uart_rx_byte(uart); } void uart_tx_byte(unsigned char data) { - exynos5_uart_tx_byte(data); + struct s5p_uart *uart = uart_platform_baseptr(0); + exynos5_uart_tx_byte(uart, data); } void uart_tx_flush(void) { - exynos5_uart_tx_flush(); + struct s5p_uart *uart = uart_platform_baseptr(0); + exynos5_uart_tx_flush(uart); } diff --git a/src/cpu/samsung/exynos5420/uart.c b/src/cpu/samsung/exynos5420/uart.c index d05adcd903..82b1265972 100644 --- a/src/cpu/samsung/exynos5420/uart.c +++ b/src/cpu/samsung/exynos5420/uart.c @@ -28,9 +28,6 @@ #define RX_FIFO_FULL_MASK (1 << 8) #define TX_FIFO_FULL_MASK (1 << 24) -/* FIXME(dhendrix): exynos5 has 4 UARTs and its functions in u-boot take a - base_port argument. However console_driver functions do not. */ -static uint32_t base_port = CONFIG_CONSOLE_SERIAL_UART_ADDRESS; /* * The coefficient, used to calculate the baudrate on S5P UARTs is @@ -58,9 +55,8 @@ static const int udivslot[] = { 0xffdf, }; -static void serial_setbrg_dev(void) +static void serial_setbrg_dev(struct s5p_uart *uart) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; u32 uclk; u32 val; @@ -87,10 +83,8 @@ static void serial_setbrg_dev(void) * Initialise the serial port with the given baudrate. The settings * are always 8 data bits, no parity, 1 stop bit, no start bits. */ -static void exynos5_init_dev(void) +static void exynos5_init_dev(struct s5p_uart *uart) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; - /* enable FIFOs */ writel(0x1, &uart->ufcon); writel(0, &uart->umcon); @@ -99,12 +93,11 @@ static void exynos5_init_dev(void) /* No interrupts, no DMA, pure polling */ writel(0x245, &uart->ucon); - serial_setbrg_dev(); + serial_setbrg_dev(uart); } -static int exynos5_uart_err_check(int op) +static int exynos5_uart_err_check(struct s5p_uart *uart, int op) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; unsigned int mask; /* @@ -127,14 +120,12 @@ static int exynos5_uart_err_check(int op) * otherwise. When the function is succesfull, the character read is * written into its argument c. */ -static unsigned char exynos5_uart_rx_byte(void) +static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; - /* wait for character to arrive */ while (!(readl(&uart->ufstat) & (RX_FIFO_COUNT_MASK | RX_FIFO_FULL_MASK))) { - if (exynos5_uart_err_check(0)) + if (exynos5_uart_err_check(uart, 0)) return 0; } @@ -144,41 +135,48 @@ static unsigned char exynos5_uart_rx_byte(void) /* * Output a single byte to the serial port. */ -static void exynos5_uart_tx_byte(unsigned char data) +static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data) { - struct s5p_uart *uart = (struct s5p_uart *)base_port; - /* wait for room in the tx FIFO */ while ((readl(&uart->ufstat) & TX_FIFO_FULL_MASK)) { - if (exynos5_uart_err_check(1)) + if (exynos5_uart_err_check(uart, 1)) return; } writeb(data, &uart->utxh); } +unsigned int uart_platform_base(int idx) +{ + return CONFIG_CONSOLE_SERIAL_UART_ADDRESS; +} + #if !defined(__PRE_RAM__) uint32_t uartmem_getbaseaddr(void) { - return base_port; + return uart_platform_base(0); } #endif void uart_init(void) { - exynos5_init_dev(); + struct s5p_uart *uart = uart_platform_baseptr(0); + exynos5_init_dev(uart); } unsigned char uart_rx_byte(void) { - return exynos5_uart_rx_byte(); + struct s5p_uart *uart = uart_platform_baseptr(0); + return exynos5_uart_rx_byte(uart); } void uart_tx_byte(unsigned char data) { - exynos5_uart_tx_byte(data); + struct s5p_uart *uart = uart_platform_baseptr(0); + exynos5_uart_tx_byte(uart, data); } void uart_tx_flush(void) { + /* Exynos5250 implements this too. */ } diff --git a/src/cpu/ti/am335x/uart.c b/src/cpu/ti/am335x/uart.c index 27051ea2cc..09bb96ece3 100644 --- a/src/cpu/ti/am335x/uart.c +++ b/src/cpu/ti/am335x/uart.c @@ -35,10 +35,8 @@ * Initialise the serial port with the given baudrate divisor. The settings * are always 8 data bits, no parity, 1 stop bit, no start bits. */ -static void am335x_uart_init(uint16_t div) +static void am335x_uart_init(struct am335x_uart *uart, uint16_t div) { - struct am335x_uart *uart = (struct am335x_uart *) - CONFIG_CONSOLE_SERIAL_UART_ADDRESS; uint16_t lcr_orig, efr_orig, mcr_orig; /* reset the UART */ @@ -131,11 +129,8 @@ static void am335x_uart_init(uint16_t div) * otherwise. When the function is successful, the character read is * written into its argument c. */ -static unsigned char am335x_uart_rx_byte(void) +static unsigned char am335x_uart_rx_byte(struct am335x_uart *uart) { - struct am335x_uart *uart = - (struct am335x_uart *)CONFIG_CONSOLE_SERIAL_UART_ADDRESS; - while (!(read16(&uart->lsr) & LSR_RXFIFOE)); return read8(&uart->rhr); @@ -144,11 +139,8 @@ static unsigned char am335x_uart_rx_byte(void) /* * Output a single byte to the serial port. */ -static void am335x_uart_tx_byte(unsigned char data) +static void am335x_uart_tx_byte(struct am335x_uart *uart, unsigned char data) { - struct am335x_uart *uart = - (struct am335x_uart *)CONFIG_CONSOLE_SERIAL_UART_ADDRESS; - while (!(read16(&uart->lsr) & LSR_TXFIFOE)); return write8(data, &uart->thr); @@ -159,28 +151,36 @@ unsigned int uart_platform_refclk(void) return 48000000; } +unsigned int uart_platform_base(int idx) +{ + return CONFIG_CONSOLE_SERIAL_UART_ADDRESS; +} + #if !defined(__PRE_RAM__) uint32_t uartmem_getbaseaddr(void) { - return CONFIG_CONSOLE_SERIAL_UART_ADDRESS; + return uart_platform_base(0); } #endif void uart_init(void) { + struct am335x_uart *uart = uart_platform_baseptr(0); uint16_t div = (uint16_t) uart_baudrate_divisor( default_baudrate(), uart_platform_refclk(), 16); - am335x_uart_init(div); + am335x_uart_init(uart, div); } unsigned char uart_rx_byte(void) { - return am335x_uart_rx_byte(); + struct am335x_uart *uart = uart_platform_baseptr(0); + return am335x_uart_rx_byte(uart); } void uart_tx_byte(unsigned char data) { - am335x_uart_tx_byte(data); + struct am335x_uart *uart = uart_platform_baseptr(0); + am335x_uart_tx_byte(uart, data); } void uart_tx_flush(void) -- cgit v1.2.3