| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 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 char *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 char *)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;
}
 |