#define ISA_UART( NAME, BASE ) \
static struct ns16550_uart ns16550_ ## NAME = { \
.base = ( ( void * ) (BASE) ), \
+ .clock = NS16550_CLK_DEFAULT, \
}; \
struct uart NAME = { \
.refcnt = REF_INIT ( ref_no_free ), \
struct ns16550_uart *ns16550;
struct uart *uart;
uint32_t shift;
+ uint32_t clock;
int rc;
/* Allocate and initialise UART */
shift = 0;
ns16550->shift = shift;
+ /* Get clock rate */
+ if ( ( rc = fdt_u32 ( &sysfdt, offset, "clock-frequency",
+ &clock ) ) != 0 ) {
+ clock = NS16550_CLK_DEFAULT;
+ }
+ ns16550->clock = clock;
+
/* Register UART */
if ( ( rc = uart_register ( uart ) ) != 0 )
goto err_register;
ns16550_write ( ns16550, NS16550_LCR,
( NS16550_LCR_8N1 | NS16550_LCR_DLAB ) );
if ( baud ) {
- ns16550->divisor = ( NS16550_MAX_BAUD / baud );
+ ns16550->divisor = ( ( ns16550->clock / baud ) /
+ NS16550_CLK_BIT );
dlm = ( ( ns16550->divisor >> 8 ) & 0xff );
dll = ( ( ns16550->divisor >> 0 ) & 0xff );
ns16550_write ( ns16550, NS16550_DLM, dlm );
/** Divisor latch (most significant byte) */
#define NS16550_DLM 0x01
-/** Maximum baud rate */
-#define NS16550_MAX_BAUD 115200
-
/** A 16550-compatible UART */
struct ns16550_uart {
/** Register base address */
void *base;
/** Register shift */
unsigned int shift;
+ /** Input clock frequency */
+ unsigned int clock;
/** Baud rate divisor */
uint16_t divisor;
};
+/** Post-division clock cycles per data bit */
+#define NS16550_CLK_BIT 16
+
+/** Default input clock rate (1.8432 MHz) */
+#define NS16550_CLK_DEFAULT 1843200
+
#include <bits/ns16550.h>
/** Dummy COM1 UART for non-x86 platforms