Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak to support 1Mbaud and similar baudrates that require Mode16 instea... #26

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions drivers/tty/serial/omap-serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,25 +181,43 @@ static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
pdata->enable_wakeup(up->dev, 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;
Expand Down Expand Up @@ -893,7 +911,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;
Expand Down