summaryrefslogtreecommitdiff
path: root/lib/utils
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-04-24 14:30:37 +0300
committerAnup Patel <anup@brainfault.org>2020-05-01 07:32:39 +0300
commit76a89403c8efa58582fe35cf942e80be7f5f36f9 (patch)
tree6dfe764a67a13b485ed6d5538176d9e2241fb175 /lib/utils
parent75322a634bc8494fc5cf0f5290c81e1100789631 (diff)
downloadopensbi-76a89403c8efa58582fe35cf942e80be7f5f36f9.tar.xz
lib: utils: Add simple FDT serial framework
We add simple serial framework which will select and use serial driver based on details in FDT passed by previous booting stage. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/serial/fdt_serial.c109
-rw-r--r--lib/utils/serial/fdt_serial_htif.c24
-rw-r--r--lib/utils/serial/fdt_serial_sifive.c38
-rw-r--r--lib/utils/serial/fdt_serial_uart8250.c39
-rw-r--r--lib/utils/serial/objects.mk4
5 files changed, 214 insertions, 0 deletions
diff --git a/lib/utils/serial/fdt_serial.c b/lib/utils/serial/fdt_serial.c
new file mode 100644
index 0000000..ae1aeea
--- /dev/null
+++ b/lib/utils/serial/fdt_serial.c
@@ -0,0 +1,109 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/serial/fdt_serial.h>
+
+extern struct fdt_serial fdt_serial_uart8250;
+extern struct fdt_serial fdt_serial_sifive;
+extern struct fdt_serial fdt_serial_htif;
+
+static struct fdt_serial *serial_drivers[] = {
+ &fdt_serial_uart8250,
+ &fdt_serial_sifive,
+ &fdt_serial_htif,
+};
+
+static void dummy_putc(char ch)
+{
+}
+
+static int dummy_getc(void)
+{
+ return -1;
+}
+
+static struct fdt_serial dummy = {
+ .match_table = NULL,
+ .init = NULL,
+ .putc = dummy_putc,
+ .getc = dummy_getc,
+};
+
+static struct fdt_serial *current_driver = &dummy;
+
+void fdt_serial_putc(char ch)
+{
+ current_driver->putc(ch);
+}
+
+int fdt_serial_getc(void)
+{
+ return current_driver->getc();
+}
+
+int fdt_serial_init(void)
+{
+ const void *prop;
+ struct fdt_serial *drv;
+ const struct fdt_match *match;
+ int pos, noff = -1, len, coff, rc;
+ void *fdt = sbi_scratch_thishart_arg1_ptr();
+
+ /* Find offset of node pointed by stdout-path */
+ coff = fdt_path_offset(fdt, "/chosen");
+ if (-1 < coff) {
+ prop = fdt_getprop(fdt, coff, "stdout-path", &len);
+ if (prop && len)
+ noff = fdt_path_offset(fdt, prop);
+ }
+
+ /* First check DT node pointed by stdout-path */
+ for (pos = 0; pos < array_size(serial_drivers) && -1 < noff; pos++) {
+ drv = serial_drivers[pos];
+
+ match = fdt_match_node(fdt, noff, drv->match_table);
+ if (!match)
+ continue;
+
+ if (drv->init) {
+ rc = drv->init(fdt, noff, match);
+ if (rc)
+ return rc;
+ }
+ current_driver = drv;
+ break;
+ }
+
+ /* Check if we found desired driver */
+ if (current_driver != &dummy)
+ goto done;
+
+ /* Lastly check all DT nodes */
+ for (pos = 0; pos < array_size(serial_drivers); pos++) {
+ drv = serial_drivers[pos];
+
+ noff = fdt_find_match(fdt, drv->match_table, &match);
+ if (noff < 0)
+ continue;
+
+ if (drv->init) {
+ rc = drv->init(fdt, noff, match);
+ if (rc)
+ return rc;
+ }
+ current_driver = drv;
+ break;
+ }
+
+done:
+ return 0;
+}
diff --git a/lib/utils/serial/fdt_serial_htif.c b/lib/utils/serial/fdt_serial_htif.c
new file mode 100644
index 0000000..32d6953
--- /dev/null
+++ b/lib/utils/serial/fdt_serial_htif.c
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/serial/fdt_serial.h>
+#include <sbi_utils/sys/htif.h>
+
+static const struct fdt_match serial_htif_match[] = {
+ { .compatible = "ucb,htif0" },
+ { },
+};
+
+struct fdt_serial fdt_serial_htif = {
+ .match_table = serial_htif_match,
+ .init = NULL,
+ .getc = htif_getc,
+ .putc = htif_putc
+};
diff --git a/lib/utils/serial/fdt_serial_sifive.c b/lib/utils/serial/fdt_serial_sifive.c
new file mode 100644
index 0000000..9e487a2
--- /dev/null
+++ b/lib/utils/serial/fdt_serial_sifive.c
@@ -0,0 +1,38 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/serial/fdt_serial.h>
+#include <sbi_utils/serial/sifive-uart.h>
+
+static int serial_sifive_init(void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ int rc;
+ struct platform_uart_data uart;
+
+ rc = fdt_parse_sifive_uart_node(fdt, nodeoff, &uart);
+ if (rc)
+ return rc;
+
+ return sifive_uart_init(uart.addr, uart.freq, uart.baud);
+}
+
+static const struct fdt_match serial_sifive_match[] = {
+ { .compatible = "sifive,fu540-c000-uart" },
+ { .compatible = "sifive,uart0" },
+ { },
+};
+
+struct fdt_serial fdt_serial_sifive = {
+ .match_table = serial_sifive_match,
+ .init = serial_sifive_init,
+ .getc = sifive_uart_getc,
+ .putc = sifive_uart_putc
+};
diff --git a/lib/utils/serial/fdt_serial_uart8250.c b/lib/utils/serial/fdt_serial_uart8250.c
new file mode 100644
index 0000000..5030b82
--- /dev/null
+++ b/lib/utils/serial/fdt_serial_uart8250.c
@@ -0,0 +1,39 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/serial/fdt_serial.h>
+#include <sbi_utils/serial/uart8250.h>
+
+static int serial_uart8250_init(void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ int rc;
+ struct platform_uart_data uart;
+
+ rc = fdt_parse_uart8250_node(fdt, nodeoff, &uart);
+ if (rc)
+ return rc;
+
+ return uart8250_init(uart.addr, uart.freq, uart.baud,
+ uart.reg_shift, uart.reg_io_width);
+}
+
+static const struct fdt_match serial_uart8250_match[] = {
+ { .compatible = "ns16550" },
+ { .compatible = "ns16550a" },
+ { },
+};
+
+struct fdt_serial fdt_serial_uart8250 = {
+ .match_table = serial_uart8250_match,
+ .init = serial_uart8250_init,
+ .getc = uart8250_getc,
+ .putc = uart8250_putc
+};
diff --git a/lib/utils/serial/objects.mk b/lib/utils/serial/objects.mk
index 5b22031..d81663b 100644
--- a/lib/utils/serial/objects.mk
+++ b/lib/utils/serial/objects.mk
@@ -7,5 +7,9 @@
# Anup Patel <anup.patel@wdc.com>
#
+libsbiutils-objs-y += serial/fdt_serial.o
+libsbiutils-objs-y += serial/fdt_serial_htif.o
+libsbiutils-objs-y += serial/fdt_serial_sifive.o
+libsbiutils-objs-y += serial/fdt_serial_uart8250.o
libsbiutils-objs-y += serial/sifive-uart.o
libsbiutils-objs-y += serial/uart8250.o