summaryrefslogtreecommitdiff
path: root/lib/utils/serial/altr-juart.c
blob: a230a561f2abff2bbbf7dcf4225ea1a23af602d4 (plain)
1
2
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
/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2025 ISCAS
 *
 * Authors:
 *   Icenowy Zheng <[email protected]>
 */

#include <sbi/riscv_io.h>
#include <sbi/sbi_console.h>
#include <sbi_utils/serial/altr-juart.h>

/* clang-format off */

#define JUART_DATA_OFFSET		0x00
# define JUART_DATA_DATA_MASK		0x000000ff
# define JUART_DATA_RVALID		(1 << 15)
# define JUART_DATA_RAVAIL_MASK		0xffff0000
# define JUART_DATA_RAVAIL_SHIFT	16
#define JUART_CTRL_OFFSET		0x04
# define JUART_CTRL_RE			(1 << 0)
# define JUART_CTRL_WE			(1 << 1)
# define JUART_CTRL_RI			(1 << 8)
# define JUART_CTRL_WI			(1 << 9)
# define JUART_CTRL_AC			(1 << 10)
# define JUART_CTRL_WSPACE_MASK		0xffff0000
# define JUART_CTRL_WSPACE_SHIFT	16

/* clang-format on */

static volatile char *altr_juart_base;

static u32 get_reg(u32 offset)
{
	return readl(altr_juart_base + offset);
}

static void set_reg(u32 offset, u32 val)
{
	writel(val, altr_juart_base + offset);
}

static void altr_juart_putc(char ch)
{
	while(!(get_reg(JUART_CTRL_OFFSET) & JUART_CTRL_WSPACE_MASK))
		;

	set_reg(JUART_DATA_OFFSET, (unsigned char)ch);
}

static int altr_juart_getc(void)
{
	u32 reg = get_reg(JUART_DATA_OFFSET);
	if (reg & JUART_DATA_RVALID)
		return reg & JUART_DATA_DATA_MASK;

	return -1;
}

static struct sbi_console_device altr_juart_console = {
	.name = "altr-juart",
	.console_putc = altr_juart_putc,
	.console_getc = altr_juart_getc
};

int altr_juart_init(unsigned long base)
{
	altr_juart_base = (volatile char *)base;

	sbi_console_set_device(&altr_juart_console);

	return 0;
}