forked from Mirrors/opensbi
lib: utils/serial: Add support for Gaisler APBUART
This patch adds support for the UART used by the NOEL-V processor. Cobham Gaisler's NOEL-V RISC-V processor IP is available under GPL and commercial license and is described in more detail at https://www.gaisler.com/noelv. Signed-off-by: Daniel Cederman <cederman@gaisler.com> Reviewed-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:

committed by
Anup Patel

parent
632e27bb91
commit
117fb6dcb1
86
lib/utils/serial/gaisler-uart.c
Normal file
86
lib/utils/serial/gaisler-uart.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021 Cobham Gaisler AB.
|
||||
*
|
||||
* Authors:
|
||||
* Daniel Cederman <cederman@gaisler.com>
|
||||
*/
|
||||
|
||||
#include <sbi/riscv_io.h>
|
||||
#include <sbi/sbi_console.h>
|
||||
#include <sbi_utils/serial/gaisler-uart.h>
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define UART_REG_DATA 0
|
||||
#define UART_REG_STATUS 1
|
||||
#define UART_REG_CTRL 2
|
||||
#define UART_REG_SCALER 3
|
||||
|
||||
#define UART_DATA_DATA 0x000000ff
|
||||
#define UART_STATUS_FIFOFULL 0x00000200
|
||||
#define UART_STATUS_DATAREADY 0x00000001
|
||||
|
||||
#define UART_CTRL_DB (1<<11)
|
||||
#define UART_CTRL_FL (1<<6)
|
||||
#define UART_CTRL_TE (1<<1)
|
||||
#define UART_CTRL_RE (1<<0)
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
static volatile void *uart_base;
|
||||
|
||||
static u32 get_reg(u32 num)
|
||||
{
|
||||
return readl(uart_base + (num * 0x4));
|
||||
}
|
||||
|
||||
static void set_reg(u32 num, u32 val)
|
||||
{
|
||||
writel(val, uart_base + (num * 0x4));
|
||||
}
|
||||
|
||||
static void gaisler_uart_putc(char ch)
|
||||
{
|
||||
while (get_reg(UART_REG_STATUS) & UART_STATUS_FIFOFULL)
|
||||
;
|
||||
|
||||
set_reg(UART_REG_DATA, ch);
|
||||
}
|
||||
|
||||
static int gaisler_uart_getc(void)
|
||||
{
|
||||
u32 ret = get_reg(UART_REG_STATUS);
|
||||
if (!(ret & UART_STATUS_DATAREADY))
|
||||
return -1;
|
||||
return get_reg(UART_REG_DATA) & UART_DATA_DATA;
|
||||
}
|
||||
|
||||
static struct sbi_console_device gaisler_console = {
|
||||
.name = "gaisler_uart",
|
||||
.console_putc = gaisler_uart_putc,
|
||||
.console_getc = gaisler_uart_getc
|
||||
};
|
||||
|
||||
int gaisler_uart_init(unsigned long base, u32 in_freq, u32 baudrate)
|
||||
{
|
||||
u32 ctrl;
|
||||
|
||||
uart_base = (volatile void *)base;
|
||||
|
||||
/* Configure baudrate */
|
||||
if (in_freq)
|
||||
set_reg(UART_REG_SCALER, in_freq / (baudrate * 8 + 7));
|
||||
|
||||
ctrl = get_reg(UART_REG_CTRL);
|
||||
/* Preserve debug mode and flow control */
|
||||
ctrl &= (UART_CTRL_DB | UART_CTRL_FL);
|
||||
/* Enable TX and RX */
|
||||
ctrl |= UART_CTRL_TE | UART_CTRL_RE;
|
||||
set_reg(UART_REG_CTRL, ctrl);
|
||||
|
||||
sbi_console_set_device(&gaisler_console);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user