forked from Mirrors/opensbi
		
	lib: utils: serial: Initial commit of xlnx-uartlite
Initial commit of the xlnx-uartlite device and FDT support. This was tested by running OpenSBI on a modified QEMU virt machine using the xlnx-uartlite for serial. Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Xiang W <wxjstz@126.com> Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
		
				
					committed by
					
						
						Anup Patel
					
				
			
			
				
	
			
			
			
						parent
						
							f3f4604c19
						
					
				
				
					commit
					4998a712b2
				
			@@ -467,6 +467,24 @@ int fdt_parse_uart8250(void *fdt, struct platform_uart_data *uart,
 | 
			
		||||
	return fdt_parse_uart8250_node(fdt, nodeoffset, uart);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_parse_xlnx_uartlite_node(void *fdt, int nodeoffset,
 | 
			
		||||
			       struct platform_uart_data *uart)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
	uint64_t reg_addr, reg_size;
 | 
			
		||||
 | 
			
		||||
	if (nodeoffset < 0 || !uart || !fdt)
 | 
			
		||||
		return SBI_ENODEV;
 | 
			
		||||
 | 
			
		||||
	rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
 | 
			
		||||
				    ®_addr, ®_size);
 | 
			
		||||
	if (rc < 0 || !reg_addr || !reg_size)
 | 
			
		||||
		return SBI_ENODEV;
 | 
			
		||||
	uart->addr = reg_addr;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_parse_aplic_node(void *fdt, int nodeoff, struct aplic_data *aplic)
 | 
			
		||||
{
 | 
			
		||||
	bool child_found;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ 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;
 | 
			
		||||
extern struct fdt_serial fdt_serial_xlnx_uartlite;
 | 
			
		||||
 | 
			
		||||
static struct fdt_serial *serial_drivers[] = {
 | 
			
		||||
	&fdt_serial_uart8250,
 | 
			
		||||
@@ -26,7 +27,8 @@ static struct fdt_serial *serial_drivers[] = {
 | 
			
		||||
	&fdt_serial_litex,
 | 
			
		||||
	&fdt_serial_htif,
 | 
			
		||||
	&fdt_serial_shakti,
 | 
			
		||||
	&fdt_serial_gaisler
 | 
			
		||||
	&fdt_serial_gaisler,
 | 
			
		||||
	&fdt_serial_xlnx_uartlite,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct fdt_serial dummy = {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								lib/utils/serial/fdt_serial_xlnx_uartlite.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								lib/utils/serial/fdt_serial_xlnx_uartlite.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2022 Western Digital Corporation or its affiliates.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *   Alistair Francis <alistair.francis@wdc.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sbi_utils/fdt/fdt_helper.h>
 | 
			
		||||
#include <sbi_utils/serial/fdt_serial.h>
 | 
			
		||||
#include <sbi_utils/serial/xlnx_uartlite.h>
 | 
			
		||||
 | 
			
		||||
static int serial_xlnx_uartlite_init(void *fdt, int nodeoff,
 | 
			
		||||
				const struct fdt_match *match)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
	struct platform_uart_data uart;
 | 
			
		||||
 | 
			
		||||
	rc = fdt_parse_xlnx_uartlite_node(fdt, nodeoff, &uart);
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	return xlnx_uartlite_init(uart.addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct fdt_match serial_xlnx_uartlite_match[] = {
 | 
			
		||||
	{ .compatible = "xlnx,xps-uartlite-1.00.a" },
 | 
			
		||||
	{ },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct fdt_serial fdt_serial_xlnx_uartlite = {
 | 
			
		||||
	.match_table = serial_xlnx_uartlite_match,
 | 
			
		||||
	.init = serial_xlnx_uartlite_init,
 | 
			
		||||
};
 | 
			
		||||
@@ -14,8 +14,10 @@ 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/fdt_serial_xlnx_uartlite.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
 | 
			
		||||
libsbiutils-objs-y += serial/xlnx-uartlite.o
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								lib/utils/serial/xlnx-uartlite.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								lib/utils/serial/xlnx-uartlite.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2022 Western Digital Corporation or its affiliates.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *   Alistair Francis <alistair.francis@wdc.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sbi/riscv_io.h>
 | 
			
		||||
#include <sbi/sbi_console.h>
 | 
			
		||||
#include <sbi_utils/serial/xlnx_uartlite.h>
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
 | 
			
		||||
#define UART_RX_OFFSET		0x00
 | 
			
		||||
#define UART_TX_OFFSET		0x04
 | 
			
		||||
#define UART_STATUS_OFFSET	0x08
 | 
			
		||||
# define UART_STATUS_RXVALID	0x01
 | 
			
		||||
# define UART_STATUS_RXFULL	0x02
 | 
			
		||||
# define UART_STATUS_TXEMPTY	0x04
 | 
			
		||||
# define UART_STATUS_TXFULL	0x08
 | 
			
		||||
# define UART_STATUS_IE	0x10
 | 
			
		||||
# define UART_STATUS_OVERRUN	0x20
 | 
			
		||||
# define UART_STATUS_FRAME	0x40
 | 
			
		||||
# define UART_STATUS_PARITY	0x80
 | 
			
		||||
#define UART_CTRL_OFFSET	0x0C
 | 
			
		||||
# define UART_CTRL_RST_TX	0x01
 | 
			
		||||
# define UART_CTRL_RST_RX	0x02
 | 
			
		||||
# define UART_CTRL_IE		0x10
 | 
			
		||||
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
static volatile char *xlnx_uartlite_base;
 | 
			
		||||
 | 
			
		||||
static void xlnx_uartlite_putc(char ch)
 | 
			
		||||
{
 | 
			
		||||
	while((readb(xlnx_uartlite_base + UART_STATUS_OFFSET) & UART_STATUS_TXFULL))
 | 
			
		||||
		;
 | 
			
		||||
 | 
			
		||||
	writeb(ch, xlnx_uartlite_base + UART_TX_OFFSET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int xlnx_uartlite_getc(void)
 | 
			
		||||
{
 | 
			
		||||
	u16 status = readb(xlnx_uartlite_base + UART_STATUS_OFFSET);
 | 
			
		||||
 | 
			
		||||
	if (status & UART_STATUS_RXVALID)
 | 
			
		||||
		return readb(xlnx_uartlite_base + UART_RX_OFFSET);
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct sbi_console_device xlnx_uartlite_console = {
 | 
			
		||||
	.name = "xlnx-uartlite",
 | 
			
		||||
	.console_putc = xlnx_uartlite_putc,
 | 
			
		||||
	.console_getc = xlnx_uartlite_getc
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int xlnx_uartlite_init(unsigned long base)
 | 
			
		||||
{
 | 
			
		||||
	xlnx_uartlite_base = (volatile char *)base;
 | 
			
		||||
 | 
			
		||||
	sbi_console_set_device(&xlnx_uartlite_console);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user