[coreboot-gerrit] New patch to review for coreboot: Exynos7: Add UART initialization

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Thu May 19 20:38:47 CEST 2016


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14910

-gerrit

commit d6c3db1cb2e0745a020a440c420cc72df640e8cf
Author: Akshay Saraswat <akshay.s at samsung.com>
Date:   Thu Aug 7 15:34:50 2014 +0530

    Exynos7: Add UART initialization
    
    This patch adds UART setup for Exynos7. It also enables UART-2 as
    default serial port.
    
    BUG=None
    BRANCH=None
    TEST=Built and booted Coreboot Over Jazz. Saw prints over console.
    
    Change-Id: Id5f3f69d6d3aef9efa888259534d3ad93cfed8ba
    Signed-off-by: Akshay Saraswat <akshay.s at samsung.com>
---
 src/soc/samsung/exynos7/Makefile.inc       |   7 ++
 src/soc/samsung/exynos7/include/soc/uart.h |  43 ++++++++
 src/soc/samsung/exynos7/uart.c             | 158 +++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+)

diff --git a/src/soc/samsung/exynos7/Makefile.inc b/src/soc/samsung/exynos7/Makefile.inc
index 6cc3680..6b521a5 100644
--- a/src/soc/samsung/exynos7/Makefile.inc
+++ b/src/soc/samsung/exynos7/Makefile.inc
@@ -32,6 +32,9 @@ bootblock-y += monotonic_timer.c
 bootblock-y += pinmux.c
 bootblock-y += power.c
 bootblock-y += timer.c
+ifeq ($(CONFIG_CONSOLE_SERIAL_UART),y)
+bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c
+endif
 
 # ROMSTAGE : Run primitive tests and remaining basic stuff
 romstage-y += clock.c
@@ -41,6 +44,9 @@ romstage-y += monotonic_timer.c
 romstage-y += pinmux.c
 romstage-y += power.c
 romstage-y += timer.c
+ifeq ($(CONFIG_CONSOLE_SERIAL_UART),y)
+romstage-$(CONFIG_EARLY_CONSOLE) += uart.c
+endif
 
 # RAMSTAGE : Prepare and load payload
 ramstage-y += clock.c
@@ -51,6 +57,7 @@ ramstage-y += monotonic_timer.c
 ramstage-y += pinmux.c
 ramstage-y += power.c
 ramstage-y += timer.c
+ramstage-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c
 
 $(objcbfs)/bootblock.raw.elf: $(objcbfs)/bootblock.elf
 	cp $< $@
diff --git a/src/soc/samsung/exynos7/include/soc/uart.h b/src/soc/samsung/exynos7/include/soc/uart.h
new file mode 100644
index 0000000..a8bfefb
--- /dev/null
+++ b/src/soc/samsung/exynos7/include/soc/uart.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ *
+ * 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
+ */
+
+#ifndef _CPU_SAMSUNG_EXYNOS7_UART_H_
+#define _CPU_SAMSUNG_EXYNOS7_UART_H_
+
+#include <stddef.h>
+
+struct exynos_uart {
+	unsigned int	ulcon;
+	unsigned int	ucon;
+	unsigned int	ufcon;
+	unsigned int	umcon;
+	unsigned int	utrstat;
+	unsigned int	uerstat;
+	unsigned int	ufstat;
+	unsigned int	umstat;
+	unsigned char	utxh;
+	unsigned char	res1[3];
+	unsigned char	urxh;
+	unsigned char	res2[3];
+	unsigned int	ubrdiv;
+	unsigned char	res3[0xffd0];
+};
+check_member(exynos_uart, ubrdiv, 0x28);
+
+#endif /* _CPU_SAMSUNG_EXYNOS7_UART_H_ */
diff --git a/src/soc/samsung/exynos7/uart.c b/src/soc/samsung/exynos7/uart.c
new file mode 100644
index 0000000..810b9c0
--- /dev/null
+++ b/src/soc/samsung/exynos7/uart.c
@@ -0,0 +1,158 @@
+/*c
+ ic This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ *
+ * 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 <types.h>
+#include <uart.h>
+#include <arch/io.h>
+#include <console/console.h>	/* for __console definition */
+#include <soc/clock.h>
+#include <soc/cpu.h>
+#include <soc/periph.h>
+#include <soc/uart.h>
+
+#define RX_FIFO_COUNT_MASK	0xff
+#define RX_FIFO_FULL_MASK	(1 << 8)
+#define TX_FIFO_FULL_MASK	(1 << 24)
+
+static struct exynos_uart * base_port =
+		(struct exynos_uart *)CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
+
+static void serial_setbrg_dev(void)
+{
+	struct exynos_uart *uart = base_port;
+	u32 uclk;
+	u32 baudrate = CONFIG_TTYS0_BAUD;
+	u32 val;
+
+	/* All UARTs share the same clock */
+	uclk = get_uart_clk(PERIPH_ID_UART2);
+	val = uclk / baudrate;
+
+	writel(val / 16 - 1, &uart->ubrdiv);
+}
+
+/*
+ * 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 exynos7_init_dev(void)
+{
+	struct exynos_uart *uart = base_port;
+
+	/* enable FIFOs */
+	writel(0x1, &uart->ufcon);
+	writel(0, &uart->umcon);
+	/* 8N1 */
+	writel(0x3, &uart->ulcon);
+	/* No interrupts, no DMA, pure polling */
+	writel(0x245, &uart->ucon);
+
+	serial_setbrg_dev();
+}
+
+static int exynos7_uart_err_check(int op)
+{
+	struct exynos_uart *uart = base_port;
+	unsigned int mask;
+
+	/*
+	 * UERSTAT
+	 * Break Detect	[3]
+	 * Frame Err	[2] : receive operation
+	 * Parity Err	[1] : receive operation
+	 * Overrun Err	[0] : receive operation
+	 */
+	if (op)
+		mask = 0x8;
+	else
+		mask = 0xf;
+
+	return readl(&uart->uerstat) & mask;
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+static unsigned char exynos7_uart_rx_byte(void)
+{
+	struct exynos_uart *uart = base_port;
+
+	/* wait for character to arrive */
+	while (!(readl(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
+					 RX_FIFO_FULL_MASK))) {
+		if (exynos7_uart_err_check(0))
+			return 0;
+	}
+
+	return readb(&uart->urxh) & 0xff;
+}
+
+/*
+ * Output a single byte to the serial port.
+ */
+static void exynos7_uart_tx_byte(unsigned char data)
+{
+	struct exynos_uart *uart = base_port;
+
+	/* wait for room in the tx FIFO */
+	while ((readl(&uart->ufstat) & TX_FIFO_FULL_MASK)) {
+		if (exynos7_uart_err_check(1))
+			return;
+	}
+
+	writeb(data, &uart->utxh);
+}
+
+#if !defined(__PRE_RAM__)
+
+static const struct console_driver exynos7_uart_console __console = {
+	.init     = exynos7_init_dev,
+	.tx_byte  = exynos7_uart_tx_byte,
+	.rx_byte  = exynos7_uart_rx_byte,
+};
+
+uint32_t uartmem_getbaseaddr(void)
+{
+	return ((uint32_t) (uintptr_t) base_port);
+}
+
+#else
+
+void uart_init(void)
+{
+	exynos7_init_dev();
+}
+
+unsigned char uart_rx_byte(void)
+{
+	return exynos7_uart_rx_byte();
+}
+
+void uart_tx_byte(unsigned char data)
+{
+	exynos7_uart_tx_byte(data);
+}
+
+void uart_tx_flush(void)
+{
+}
+
+#endif



More information about the coreboot-gerrit mailing list