summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/omap-serial.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 6f3dbf740f0..9915e4d1418 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -232,24 +232,42 @@ static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
}
/*
+ * serial_omap_baud_is_mode16 - check if baud rate is MODE16X
+ * @port: uart port info
+ * @baud: baudrate for which mode needs to be determined
+ *
+ * Returns true if baud rate is MODE16X and false if MODE13X
+ * Original table in OMAP TRM named "UART Mode Baud Rates, Divisor Values,
+ * and Error Rates" determines modes not for all common baud rates.
+ * E.g. for 1000000 baud rate mode must be 16x, but according to that
+ * table it's determined as 13x.
+ */
+static bool
+serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud)
+{
+ unsigned int n13 = port->uartclk / (13 * baud);
+ unsigned int n16 = port->uartclk / (16 * baud);
+ int baudAbsDiff13 = baud - (port->uartclk / (13 * n13));
+ int baudAbsDiff16 = baud - (port->uartclk / (16 * n16));
+ if(baudAbsDiff13 < 0)
+ baudAbsDiff13 = -baudAbsDiff13;
+ if(baudAbsDiff16 < 0)
+ baudAbsDiff16 = -baudAbsDiff16;
+
+ return (baudAbsDiff13 > baudAbsDiff16);
+}
+
+/*
* serial_omap_get_divisor - calculate divisor value
* @port: uart port info
* @baud: baudrate for which divisor needs to be calculated.
- *
- * We have written our own function to get the divisor so as to support
- * 13x mode. 3Mbps Baudrate as an different divisor.
- * Reference OMAP TRM Chapter 17:
- * Table 17-1. UART Mode Baud Rates, Divisor Values, and Error Rates
- * referring to oversampling - divisor value
- * baudrate 460,800 to 3,686,400 all have divisor 13
- * except 3,000,000 which has divisor value 16
*/
static unsigned int
serial_omap_get_divisor(struct uart_port *port, unsigned int baud)
{
unsigned int divisor;
- if (baud > OMAP_MODE13X_SPEED && baud != 3000000)
+ if (!serial_omap_baud_is_mode16(port, baud))
divisor = 13;
else
divisor = 16;
@@ -916,7 +934,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
serial_out(up, UART_EFR, up->efr);
serial_out(up, UART_LCR, cval);
- if (baud > 230400 && baud != 3000000)
+ if (!serial_omap_baud_is_mode16(port, baud))
up->mdr1 = UART_OMAP_MDR1_13X_MODE;
else
up->mdr1 = UART_OMAP_MDR1_16X_MODE;