mirror of
				https://github.com/riscv-software-src/opensbi
				synced 2025-11-04 14:00:31 +00:00 
			
		
		
		
	RISC-V doesn't generate exceptions on divide-by-zero, but the result, all bits set, is not likely what people expect either. In all cases where we divide by baudrate there's a chance it's zero (when the DT it came from is "bad"). To avoid difficult to debug situations, leave baudrate dependent registers alone when baudrate is zero, as, also in all cases, it appears we can skip initialization of those registers and still [hopefully] have a functioning UART. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Anup Patel <anup@brainfault.org>
		
			
				
	
	
		
			61 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			61 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * SPDX-License-Identifier: BSD-2-Clause
 | 
						|
 *
 | 
						|
 * Copyright (c) 2020 Vijai Kumar K <vijai@behindbytes.com>
 | 
						|
 */
 | 
						|
 | 
						|
#include <sbi/riscv_io.h>
 | 
						|
#include <sbi/sbi_console.h>
 | 
						|
#include <sbi_utils/serial/shakti-uart.h>
 | 
						|
 | 
						|
#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
 | 
						|
 | 
						|
#define UART_TX_FULL  0x2
 | 
						|
#define UART_RX_NOT_EMPTY 0x4
 | 
						|
#define UART_RX_FULL  0x8
 | 
						|
 | 
						|
static volatile char *uart_base;
 | 
						|
 | 
						|
static void shakti_uart_putc(char ch)
 | 
						|
{
 | 
						|
	while ((readb(uart_base + REG_STATUS) & UART_TX_FULL))
 | 
						|
		;
 | 
						|
	writeb(ch, uart_base + REG_TX);
 | 
						|
}
 | 
						|
 | 
						|
static int shakti_uart_getc(void)
 | 
						|
{
 | 
						|
	if (readb(uart_base + REG_STATUS) & UART_RX_NOT_EMPTY)
 | 
						|
		return readb(uart_base + REG_RX);
 | 
						|
	return -1;
 | 
						|
}
 | 
						|
 | 
						|
static struct sbi_console_device shakti_console = {
 | 
						|
	.name = "shakti_uart",
 | 
						|
	.console_putc = shakti_uart_putc,
 | 
						|
	.console_getc = shakti_uart_getc
 | 
						|
};
 | 
						|
 | 
						|
int shakti_uart_init(unsigned long base, u32 in_freq, u32 baudrate)
 | 
						|
{
 | 
						|
	uart_base = (volatile char *)base;
 | 
						|
	u16 baud;
 | 
						|
 | 
						|
	if (baudrate) {
 | 
						|
		baud = (u16)(in_freq / (16 * baudrate));
 | 
						|
		writew(baud, uart_base + REG_BAUD);
 | 
						|
	}
 | 
						|
 | 
						|
	sbi_console_set_device(&shakti_console);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 |