|
@@ -47,6 +47,10 @@
|
|
|
#define UART_EXAR_SLEEP 0x8b /* Sleep mode */
|
|
|
#define UART_EXAR_DVID 0x8d /* Device identification */
|
|
|
|
|
|
+/* Nuvoton NPCM timeout register */
|
|
|
+#define UART_NPCM_TOR 7
|
|
|
+#define UART_NPCM_TOIE BIT(7) /* Timeout Interrupt Enable */
|
|
|
+
|
|
|
/*
|
|
|
* Debugging.
|
|
|
*/
|
|
@@ -293,6 +297,15 @@ static const struct serial8250_config uart_config[] = {
|
|
|
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
|
|
|
.flags = UART_CAP_FIFO,
|
|
|
},
|
|
|
+ [PORT_NPCM] = {
|
|
|
+ .name = "Nuvoton 16550",
|
|
|
+ .fifo_size = 16,
|
|
|
+ .tx_loadsz = 16,
|
|
|
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
|
|
|
+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
|
|
|
+ .rxtrig_bytes = {1, 4, 8, 14},
|
|
|
+ .flags = UART_CAP_FIFO,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
/* Uart divisor latch read */
|
|
@@ -2141,6 +2154,15 @@ int serial8250_do_startup(struct uart_port *port)
|
|
|
UART_DA830_PWREMU_MGMT_FREE);
|
|
|
}
|
|
|
|
|
|
+ if (port->type == PORT_NPCM) {
|
|
|
+ /*
|
|
|
+ * Nuvoton calls the scratch register 'UART_TOR' (timeout
|
|
|
+ * register). Enable it, and set TIOC (timeout interrupt
|
|
|
+ * comparator) to be 0x20 for correct operation.
|
|
|
+ */
|
|
|
+ serial_port_out(port, UART_NPCM_TOR, UART_NPCM_TOIE | 0x20);
|
|
|
+ }
|
|
|
+
|
|
|
#ifdef CONFIG_SERIAL_8250_RSA
|
|
|
/*
|
|
|
* If this is an RSA port, see if we can kick it up to the
|
|
@@ -2463,6 +2485,15 @@ static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up,
|
|
|
return quot_16 >> 4;
|
|
|
}
|
|
|
|
|
|
+/* Nuvoton NPCM UARTs have a custom divisor calculation */
|
|
|
+static unsigned int npcm_get_divisor(struct uart_8250_port *up,
|
|
|
+ unsigned int baud)
|
|
|
+{
|
|
|
+ struct uart_port *port = &up->port;
|
|
|
+
|
|
|
+ return DIV_ROUND_CLOSEST(port->uartclk, 16 * baud + 2) - 2;
|
|
|
+}
|
|
|
+
|
|
|
static unsigned int serial8250_get_divisor(struct uart_8250_port *up,
|
|
|
unsigned int baud,
|
|
|
unsigned int *frac)
|
|
@@ -2483,6 +2514,8 @@ static unsigned int serial8250_get_divisor(struct uart_8250_port *up,
|
|
|
quot = 0x8002;
|
|
|
else if (up->port.type == PORT_XR17V35X)
|
|
|
quot = xr17v35x_get_divisor(up, baud, frac);
|
|
|
+ else if (up->port.type == PORT_NPCM)
|
|
|
+ quot = npcm_get_divisor(up, baud);
|
|
|
else
|
|
|
quot = uart_get_divisor(port, baud);
|
|
|
|