uart/sifive: make divisor configurable

The SiFive UART on the HiFive Unleashed uses the tlclk as input clock
which runs at coreclk / 2.

The input frequency is configured in the board code depending on the
current stage. (bootblock + romstage run at 33.33Mhz, ramstage at 1Ghz)

Change-Id: Iaf66723dba3d308f809fde5b05dfc3e43f43bd42
Signed-off-by: Philipp Hug <philipp@hug.cx>
Reviewed-on: https://review.coreboot.org/27440
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
This commit is contained in:
Philipp Hug 2018-07-07 21:34:31 +02:00 committed by Ronald G. Minnich
parent 3e51d53064
commit 7524400242
3 changed files with 20 additions and 5 deletions

View File

@ -46,11 +46,10 @@ struct sifive_uart_registers {
#define IP_TXWM BIT(0)
#define IP_RXWM BIT(1)
void uart_init(int idx)
static void sifive_uart_init(struct sifive_uart_registers *regs, int div)
{
struct sifive_uart_registers *regs = uart_platform_baseptr(idx);
/* TODO: Configure the divisor */
/* Configure the divisor */
write32(&regs->div, div);
/* Enable transmission, one stop bit, transmit watermark at 1 */
write32(&regs->txctrl, TXCTRL_TXEN|TXCTRL_NSTOP(1)|TXCTRL_TXCNT(1));
@ -59,6 +58,14 @@ void uart_init(int idx)
write32(&regs->rxctrl, RXCTRL_RXEN|RXCTRL_RXCNT(0));
}
void uart_init(int idx)
{
unsigned int div;
div = uart_baudrate_divisor(get_uart_baudrate(),
uart_platform_refclk(), uart_input_clock_divider());
sifive_uart_init(uart_platform_baseptr(idx), div);
}
static bool uart_can_tx(struct sifive_uart_registers *regs)
{
return !(read32(&regs->txdata) & TXDATA_FULL);

View File

@ -20,7 +20,7 @@ config SOC_SIFIVE_FU540
select ARCH_RAMSTAGE_RISCV
select BOOTBLOCK_CONSOLE
select DRIVERS_UART_SIFIVE
select UART_OVERRIDE_REFCLK
if SOC_SIFIVE_FU540
config RISCV_ARCH

View File

@ -23,3 +23,11 @@ uintptr_t uart_platform_base(int idx)
else
return 0;
}
unsigned int uart_platform_refclk(void)
{
/*
* The SiFive UART uses tlclk, which is coreclk/2 as input
*/
return 33330000 / 2;
}