[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