From db56ef367cd6dc9dab94076f4c8a3fa9d91bd1f2 Mon Sep 17 00:00:00 2001 From: Vijai Kumar K Date: Wed, 17 Jun 2020 19:25:16 +0530 Subject: platform: Add support for Shakti C-class SoC from IIT-M C-Class is a member of the SHAKTI family of processors from Indian Institute of Technology - Madras(IIT-M). It is an extremely configurable and commercial-grade 5-stage in-order core supporting the standard RV64GCSUN ISA extensions. https://gitlab.com/shaktiproject/cores/c-class/blob/master/README.md We add OpenSBI support for Shakti C-class SoC. Signed-off-by: Vijai Kumar K Reviewed-by: Anup Patel --- lib/utils/fdt/fdt_helper.c | 37 ++++++++++++++++++++++++++++++ lib/utils/serial/fdt_serial.c | 2 ++ lib/utils/serial/fdt_serial_shakti.c | 35 ++++++++++++++++++++++++++++ lib/utils/serial/objects.mk | 2 ++ lib/utils/serial/shakti-uart.c | 44 ++++++++++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+) create mode 100644 lib/utils/serial/fdt_serial_shakti.c create mode 100644 lib/utils/serial/shakti-uart.c (limited to 'lib/utils') diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c index 887d6ed..78077f7 100644 --- a/lib/utils/fdt/fdt_helper.c +++ b/lib/utils/fdt/fdt_helper.c @@ -26,6 +26,9 @@ #define DEFAULT_SIFIVE_UART_REG_SHIFT 0 #define DEFAULT_SIFIVE_UART_REG_IO_WIDTH 4 +#define DEFAULT_SHAKTI_UART_FREQ 50000000 +#define DEFAULT_SHAKTI_UART_BAUD 115200 + const struct fdt_match *fdt_match_node(void *fdt, int nodeoff, const struct fdt_match *match_table) { @@ -164,6 +167,40 @@ int fdt_parse_max_hart_id(void *fdt, u32 *max_hartid) return 0; } +int fdt_parse_shakti_uart_node(void *fdt, int nodeoffset, + struct platform_uart_data *uart) +{ + int len, rc; + const fdt32_t *val; + unsigned long reg_addr, reg_size; + + if (nodeoffset < 0 || !uart || !fdt) + return SBI_ENODEV; + + rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size); + if (rc < 0 || !reg_addr || !reg_size) + return SBI_ENODEV; + uart->addr = reg_addr; + + /** + * UART address is mandaotry. clock-frequency and current-speed + * may not be present. Don't return error. + */ + val = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "clock-frequency", &len); + if (len > 0 && val) + uart->freq = fdt32_to_cpu(*val); + else + uart->freq = DEFAULT_SHAKTI_UART_FREQ; + + val = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "current-speed", &len); + if (len > 0 && val) + uart->baud = fdt32_to_cpu(*val); + else + uart->baud = DEFAULT_SHAKTI_UART_BAUD; + + return 0; +} + int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset, struct platform_uart_data *uart) { diff --git a/lib/utils/serial/fdt_serial.c b/lib/utils/serial/fdt_serial.c index fa6c478..b9ce67e 100644 --- a/lib/utils/serial/fdt_serial.c +++ b/lib/utils/serial/fdt_serial.c @@ -15,11 +15,13 @@ extern struct fdt_serial fdt_serial_uart8250; extern struct fdt_serial fdt_serial_sifive; extern struct fdt_serial fdt_serial_htif; +extern struct fdt_serial fdt_serial_shakti; static struct fdt_serial *serial_drivers[] = { &fdt_serial_uart8250, &fdt_serial_sifive, &fdt_serial_htif, + &fdt_serial_shakti, }; static void dummy_putc(char ch) diff --git a/lib/utils/serial/fdt_serial_shakti.c b/lib/utils/serial/fdt_serial_shakti.c new file mode 100644 index 0000000..c6385a5 --- /dev/null +++ b/lib/utils/serial/fdt_serial_shakti.c @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Vijai Kumar K + * + */ + +#include +#include +#include + +static int serial_shakti_init(void *fdt, int nodeoff, + const struct fdt_match *match) +{ + int rc; + struct platform_uart_data uart; + + rc = fdt_parse_shakti_uart_node(fdt, nodeoff, &uart); + if (rc) + return rc; + + return shakti_uart_init(uart.addr, uart.freq, uart.baud); +} + +static const struct fdt_match serial_shakti_match[] = { + { .compatible = "shakti,uart0" }, + { }, +}; + +struct fdt_serial fdt_serial_shakti = { + .match_table = serial_shakti_match, + .init = serial_shakti_init, + .getc = shakti_uart_getc, + .putc = shakti_uart_putc +}; diff --git a/lib/utils/serial/objects.mk b/lib/utils/serial/objects.mk index d81663b..c0746f0 100644 --- a/lib/utils/serial/objects.mk +++ b/lib/utils/serial/objects.mk @@ -9,7 +9,9 @@ libsbiutils-objs-y += serial/fdt_serial.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_uart8250.o +libsbiutils-objs-y += serial/shakti-uart.o libsbiutils-objs-y += serial/sifive-uart.o libsbiutils-objs-y += serial/uart8250.o diff --git a/lib/utils/serial/shakti-uart.c b/lib/utils/serial/shakti-uart.c new file mode 100644 index 0000000..493edcf --- /dev/null +++ b/lib/utils/serial/shakti-uart.c @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Vijai Kumar K + */ + +#include +#include +#include + +#define REG_BAUD 0x00 +#define REG_TX 0x04 +#define REG_RX 0x08 +#define REG_STATUS 0x0C +#define REG_DELAY 0x10 +#define REG_CONTROL 0x14 +#define REG_INT_EN 0x18 +#define REG_IQ_CYCLES 0x1C +#define REG_RX_THRES 0x20 + +static volatile void *uart_base; + +void shakti_uart_putc(char ch) +{ + while((readw(uart_base + REG_STATUS) & 0x2) == 0); + writeb(ch, uart_base + REG_TX); +} + +int shakti_uart_getc(void) +{ + u16 status = readw(uart_base + REG_STATUS); + if (status & 0x8) + return readb(uart_base + REG_RX); + return -1; +} + +int shakti_uart_init(unsigned long base, u32 in_freq, u32 baudrate) +{ + uart_base = (volatile void *)base; + u16 baud = (u16)(in_freq/(16 * baudrate)); + writew(baud, uart_base + REG_BAUD); + + return 0; +} -- cgit v1.1