diff options
author | Gabriel Somlo <gsomlo@gmail.com> | 2021-11-16 14:17:04 -0500 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2021-11-18 13:22:02 +0530 |
commit | 52af6e4b52d0ea1d687121bfba0954c2621d2629 (patch) | |
tree | 4e075754ccc1d9271fcf38988dec820a06de0c61 | |
parent | d335a178d8cfdf2ed13af70fe385f7e38162e171 (diff) | |
download | opensbi-52af6e4b52d0ea1d687121bfba0954c2621d2629.zip opensbi-52af6e4b52d0ea1d687121bfba0954c2621d2629.tar.gz opensbi-52af6e4b52d0ea1d687121bfba0954c2621d2629.tar.bz2 |
lib: utils: Add LiteX UART support
Add support for the UART provided by the LiteX SoC
framework (https://github.com/enjoy-digital/litex),
based on its FDT info (described in the Linux tree at
Documentation/devicetree/bindings/serial/litex,liteuart.yaml).
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
-rw-r--r-- | include/sbi_utils/serial/litex-uart.h | 17 | ||||
-rw-r--r-- | lib/utils/serial/fdt_serial.c | 2 | ||||
-rw-r--r-- | lib/utils/serial/fdt_serial_litex.c | 39 | ||||
-rw-r--r-- | lib/utils/serial/litex-uart.c | 63 | ||||
-rw-r--r-- | lib/utils/serial/objects.mk | 2 |
5 files changed, 123 insertions, 0 deletions
diff --git a/include/sbi_utils/serial/litex-uart.h b/include/sbi_utils/serial/litex-uart.h new file mode 100644 index 0000000..91ab644 --- /dev/null +++ b/include/sbi_utils/serial/litex-uart.h @@ -0,0 +1,17 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Gabriel Somlo + * + * Authors: + * Gabriel Somlo <gsomlo@gmail.com> + */ + +#ifndef __SERIAL_LITEX_UART_H__ +#define __SERIAL_LITEX_UART_H__ + +#include <sbi/sbi_types.h> + +int litex_uart_init(unsigned long base); + +#endif diff --git a/lib/utils/serial/fdt_serial.c b/lib/utils/serial/fdt_serial.c index cedda04..f73d26a 100644 --- a/lib/utils/serial/fdt_serial.c +++ b/lib/utils/serial/fdt_serial.c @@ -15,6 +15,7 @@ extern struct fdt_serial fdt_serial_uart8250; extern struct fdt_serial fdt_serial_sifive; +extern struct fdt_serial fdt_serial_litex; extern struct fdt_serial fdt_serial_htif; extern struct fdt_serial fdt_serial_shakti; extern struct fdt_serial fdt_serial_gaisler; @@ -22,6 +23,7 @@ extern struct fdt_serial fdt_serial_gaisler; static struct fdt_serial *serial_drivers[] = { &fdt_serial_uart8250, &fdt_serial_sifive, + &fdt_serial_litex, &fdt_serial_htif, &fdt_serial_shakti, &fdt_serial_gaisler diff --git a/lib/utils/serial/fdt_serial_litex.c b/lib/utils/serial/fdt_serial_litex.c new file mode 100644 index 0000000..3b3b306 --- /dev/null +++ b/lib/utils/serial/fdt_serial_litex.c @@ -0,0 +1,39 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Gabriel Somlo + * + * Authors: + * Gabriel Somlo <gsomlo@gmail.com> + */ + +#include <sbi/sbi_error.h> +#include <sbi_utils/fdt/fdt_helper.h> +#include <sbi_utils/serial/fdt_serial.h> +#include <sbi_utils/serial/litex-uart.h> + +static int serial_litex_init(void *fdt, int nodeoff, + const struct fdt_match *match) +{ + uint64_t reg_addr, reg_size; + int rc; + + if (nodeoff < 0 || !fdt) + return SBI_ENODEV; + + rc = fdt_get_node_addr_size(fdt, nodeoff, 0, ®_addr, ®_size); + if (rc < 0 || !reg_addr || !reg_size) + return SBI_ENODEV; + + return litex_uart_init(reg_addr); +} + +static const struct fdt_match serial_litex_match[] = { + { .compatible = "litex,liteuart" }, + { }, +}; + +struct fdt_serial fdt_serial_litex = { + .match_table = serial_litex_match, + .init = serial_litex_init +}; diff --git a/lib/utils/serial/litex-uart.c b/lib/utils/serial/litex-uart.c new file mode 100644 index 0000000..f843bf3 --- /dev/null +++ b/lib/utils/serial/litex-uart.c @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Gabriel Somlo + * + * Authors: + * Gabriel Somlo <gsomlo@gmail.com> + */ + +#include <sbi/riscv_io.h> +#include <sbi/sbi_console.h> +#include <sbi_utils/serial/litex-uart.h> + +/* clang-format off */ + +#define UART_REG_RXTX 0 +#define UART_REG_TXFULL 1 +#define UART_REG_RXEMPTY 2 +#define UART_REG_EV_STATUS 3 +#define UART_REG_EV_PENDING 4 +#define UART_REG_EV_ENABLE 5 + +/* clang-format on */ + +static volatile u32 *uart_base; + +static u8 get_reg(u8 reg) +{ + return readb(uart_base + reg); +} + +static void set_reg(u8 reg, u8 val) +{ + writeb(val, uart_base + reg); +} + +static void litex_uart_putc(char ch) +{ + while (get_reg(UART_REG_TXFULL)); + set_reg(UART_REG_RXTX, ch); +} + +static int litex_uart_getc(void) +{ + if (get_reg(UART_REG_RXEMPTY)) + return -1; + else + return get_reg(UART_REG_RXTX); +} + +static struct sbi_console_device litex_console = { + .name = "litex_uart", + .console_putc = litex_uart_putc, + .console_getc = litex_uart_getc +}; + +int litex_uart_init(unsigned long base) +{ + uart_base = (volatile u32 *)base; + set_reg(UART_REG_EV_ENABLE, 0); /* UART in polling mode: disable IRQ */ + sbi_console_set_device(&litex_console); + return 0; +} diff --git a/lib/utils/serial/objects.mk b/lib/utils/serial/objects.mk index 9fb0902..4f751ba 100644 --- a/lib/utils/serial/objects.mk +++ b/lib/utils/serial/objects.mk @@ -12,8 +12,10 @@ libsbiutils-objs-y += serial/fdt_serial_gaisler.o libsbiutils-objs-y += serial/fdt_serial_htif.o libsbiutils-objs-y += serial/fdt_serial_shakti.o libsbiutils-objs-y += serial/fdt_serial_sifive.o +libsbiutils-objs-y += serial/fdt_serial_litex.o libsbiutils-objs-y += serial/fdt_serial_uart8250.o libsbiutils-objs-y += serial/gaisler-uart.o libsbiutils-objs-y += serial/shakti-uart.o libsbiutils-objs-y += serial/sifive-uart.o +libsbiutils-objs-y += serial/litex-uart.o libsbiutils-objs-y += serial/uart8250.o |