coreboot/src/include/console/uart.h
Julius Werner 1732dcb90c drivers/uart: Add helper function to allow bit-banging
In some cases it may be useful to be able to bitbang a UART, such as
during early bring-up when a driver for the actual controller isn't
available yet. On some platforms we may even want to use this
permanently, such as on the SDM845 where the hardware UART controller
needs to have firmware loaded and is thus unavailable for most of the
bootblock.

This patch adds some helper code that makes it easy to implement this on
a platform, you just have to pass it a function to control the Tx pin
state and it will do the rest. It relies on the mono_time API and is
thus bound to microsecond timing granularity, but that seems to be
barely good enough for 115200 baud if the bit times are calculated
carefully.

Change-Id: If7dcecc7b8a95ec15f456efd2ec1f1e0dde239b4
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/25812
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2018-04-26 01:19:13 +00:00

106 lines
3 KiB
C

/*
* This file is part of the coreboot project.
*
* Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CONSOLE_UART_H
#define CONSOLE_UART_H
#include <rules.h>
#include <stdint.h>
/* Return the clock frequency UART uses as reference clock for
* baudrate generator. */
unsigned int uart_platform_refclk(void);
#if IS_ENABLED(CONFIG_UART_OVERRIDE_BAUDRATE)
/* Return the baudrate, define this in your platform when using the above
configuration. */
unsigned int get_uart_baudrate(void);
#else
static inline unsigned int get_uart_baudrate(void)
{
return CONFIG_TTYS0_BAUD;
}
#endif
/* Returns the divisor value for a given baudrate.
* The formula to satisfy is:
* refclk / divisor = baudrate * oversample
*/
unsigned int uart_baudrate_divisor(unsigned int baudrate,
unsigned int refclk, unsigned int oversample);
/* Returns the oversample divisor multiplied by any other divisors that act
* on the input clock
*/
unsigned int uart_input_clock_divider(void);
/* Bitbang out one byte on an 8n1 UART through the output function set_tx(). */
void uart_bitbang_tx_byte(unsigned char data, void (*set_tx)(int line_state));
void uart_init(int idx);
void uart_tx_byte(int idx, unsigned char data);
void uart_tx_flush(int idx);
unsigned char uart_rx_byte(int idx);
uintptr_t uart_platform_base(int idx);
#if !defined(__ROMCC__)
static inline void *uart_platform_baseptr(int idx)
{
return (void *)uart_platform_base(idx);
}
void oxford_remap(unsigned int new_base);
#define __CONSOLE_SERIAL_ENABLE__ (IS_ENABLED(CONFIG_CONSOLE_SERIAL) && \
(ENV_BOOTBLOCK || ENV_ROMSTAGE || ENV_RAMSTAGE || ENV_VERSTAGE || \
ENV_POSTCAR || (ENV_SMM && IS_ENABLED(CONFIG_DEBUG_SMI))))
#if __CONSOLE_SERIAL_ENABLE__
static inline void __uart_init(void)
{
uart_init(CONFIG_UART_FOR_CONSOLE);
}
static inline void __uart_tx_byte(u8 data)
{
uart_tx_byte(CONFIG_UART_FOR_CONSOLE, data);
}
static inline void __uart_tx_flush(void)
{
uart_tx_flush(CONFIG_UART_FOR_CONSOLE);
}
#else
static inline void __uart_init(void) {}
static inline void __uart_tx_byte(u8 data) {}
static inline void __uart_tx_flush(void) {}
#endif
#if IS_ENABLED(CONFIG_GDB_STUB) && (ENV_ROMSTAGE || ENV_RAMSTAGE)
#define CONFIG_UART_FOR_GDB CONFIG_UART_FOR_CONSOLE
static inline void __gdb_hw_init(void) { uart_init(CONFIG_UART_FOR_GDB); }
static inline void __gdb_tx_byte(u8 data)
{
uart_tx_byte(CONFIG_UART_FOR_GDB, data);
}
static inline void __gdb_tx_flush(void) { uart_tx_flush(CONFIG_UART_FOR_GDB); }
static inline u8 __gdb_rx_byte(void)
{
return uart_rx_byte(CONFIG_UART_FOR_GDB);
}
#endif
#endif /* __ROMCC__ */
#endif /* CONSOLE_UART_H */