aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-09-26 11:21:36 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-26 16:41:05 -0400
commitc5dd553b9fd069892c9e2de734f4f604e280fa7a (patch)
tree1e6f3dfaff8d1fd8d43ae2c534adc098a7add115 /drivers/tty
parent91f61ce24f95f6d5f96efb56e0a8633e19184289 (diff)
serial: pl011: handle corruption at high clock speeds
This works around a few glitches in the ST version of the PL011 serial driver when using very high baud rates, as we do in the Ux500: 3, 3.25, 4 and 4.05 Mbps. Problem Observed/rootcause: When using high baud-rates, and the baudrate*8 is getting close to the provided clock frequency (so a division factor close to 1), when using bursts of characters (so they are abutted), then it seems as if there is not enough time to detect the beginning of the start-bit which is a timing reference for the entire character, and thus the sampling moment of character bits is moving towards the end of each bit, instead of the middle. Fix: Increase slightly the RX baud rate of the UART above the theoretical baudrate by 5%. This will definitely give more margin time to the UART_RX to correctly sample the data at the middle of the bit period. Also fix the ages old copy-paste error in the very stressed comment, it's referencing the registers used in the PL010 driver rather than the PL011 ones. Signed-off-by: Guillaume Jaunet <guillaume.jaunet@stericsson.com> Signed-off-by: Christophe Arnal <christophe.arnal@stericsson.com> Signed-off-by: Matthias Locher <matthias.locher@stericsson.com> Signed-off-by: Rajanikanth HV <rajanikanth.hv@stericsson.com> Cc: stable <stable@vger.kernel.org> Cc: Bibek Basu <bibek.basu@stericsson.com> Cc: Par-Gunnar Hjalmdahl <par-gunnar.hjalmdahl@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/amba-pl011.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index cede93876649..925eb8813a45 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1595,13 +1595,26 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
1595 old_cr &= ~ST_UART011_CR_OVSFACT; 1595 old_cr &= ~ST_UART011_CR_OVSFACT;
1596 } 1596 }
1597 1597
1598 /*
1599 * Workaround for the ST Micro oversampling variants to
1600 * increase the bitrate slightly, by lowering the divisor,
1601 * to avoid delayed sampling of start bit at high speeds,
1602 * else we see data corruption.
1603 */
1604 if (uap->vendor->oversampling) {
1605 if ((baud >= 3000000) && (baud < 3250000) && (quot > 1))
1606 quot -= 1;
1607 else if ((baud > 3250000) && (quot > 2))
1608 quot -= 2;
1609 }
1598 /* Set baud rate */ 1610 /* Set baud rate */
1599 writew(quot & 0x3f, port->membase + UART011_FBRD); 1611 writew(quot & 0x3f, port->membase + UART011_FBRD);
1600 writew(quot >> 6, port->membase + UART011_IBRD); 1612 writew(quot >> 6, port->membase + UART011_IBRD);
1601 1613
1602 /* 1614 /*
1603 * ----------v----------v----------v----------v----- 1615 * ----------v----------v----------v----------v-----
1604 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L 1616 * NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER
1617 * UART011_FBRD & UART011_IBRD.
1605 * ----------^----------^----------^----------^----- 1618 * ----------^----------^----------^----------^-----
1606 */ 1619 */
1607 writew(lcr_h, port->membase + uap->lcrh_rx); 1620 writew(lcr_h, port->membase + uap->lcrh_rx);