[coreboot-gerrit] Patch set updated for coreboot: 32da062 uart: Prepare to support multiple base addresses

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Mon Apr 7 09:31:21 CEST 2014


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5309

-gerrit

commit 32da062b514d68670bf51635bbb1ce54c68f21e7
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Mon Feb 24 20:51:30 2014 +0200

    uart: Prepare to support multiple base addresses
    
    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 <kyosti.malkki at gmail.com>
---
 src/cpu/samsung/exynos5250/uart.c | 50 ++++++++++++++++++---------------------
 src/cpu/samsung/exynos5420/uart.c | 44 ++++++++++++++++------------------
 src/cpu/ti/am335x/uart.c          | 30 +++++++++++------------
 src/drivers/uart/pl011.c          | 13 ++++++----
 src/include/console/uart.h        |  7 ++++++
 5 files changed, 74 insertions(+), 70 deletions(-)

diff --git a/src/cpu/samsung/exynos5250/uart.c b/src/cpu/samsung/exynos5250/uart.c
index 14d140c..860d020 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 d05adcd..82b1265 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 27051ea..09bb96e 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)
diff --git a/src/drivers/uart/pl011.c b/src/drivers/uart/pl011.c
index 2202de7..e4bfdc6 100644
--- a/src/drivers/uart/pl011.c
+++ b/src/drivers/uart/pl011.c
@@ -15,12 +15,14 @@
 
 #include <console/uart.h>
 
-static void pl011_uart_tx_byte(unsigned char data)
+static void pl011_uart_tx_byte(unsigned int *uart_base, unsigned char data)
 {
-	static volatile unsigned int *uart0_address =
-		(unsigned int *) CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
+	*uart_base = (unsigned int)data;
+}
 
-	*uart0_address = (unsigned int)data;
+unsigned int uart_platform_base(int idx)
+{
+	return CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
 }
 
 #if !defined(__PRE_RAM__)
@@ -36,7 +38,8 @@ void uart_init(void)
 
 void uart_tx_byte(unsigned char data)
 {
-	pl011_uart_tx_byte(data);
+	unsigned int *uart_base = uart_platform_baseptr(0);
+	pl011_uart_tx_byte(uart_base, data);
 }
 
 void uart_tx_flush(void)
diff --git a/src/include/console/uart.h b/src/include/console/uart.h
index f0371a2..6a1251e 100644
--- a/src/include/console/uart.h
+++ b/src/include/console/uart.h
@@ -48,6 +48,13 @@ int uart_can_rx_byte(void);
 unsigned int uart_platform_base(int idx);
 uint32_t uartmem_getbaseaddr(void);
 
+#if !defined(__ROMCC__)
+static inline void *uart_platform_baseptr(int idx)
+{
+	return (void *)uart_platform_base(idx);
+}
+#endif
+
 void oxford_init(void);
 void oxford_remap(unsigned int new_base);
 



More information about the coreboot-gerrit mailing list