diff options
author | Jon Hunter <jonathanh@nvidia.com> | 2015-05-05 17:17:52 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-10 20:12:18 +0300 |
commit | 245c0278ab2a2e3d0360296710b4c285291469b5 (patch) | |
tree | 30fb45f2883375fc903d9f0500e5fff0c2c8d292 /drivers/tty/serial/serial-tegra.c | |
parent | 7a7a7e6d9b8f78e73b45bdc436c5fbdbb7220c74 (diff) | |
download | linux-245c0278ab2a2e3d0360296710b4c285291469b5.tar.xz |
serial: tegra: Correct delay after TX flush
For all tegra devices (up to t210), there is a hardware issue that
requires software to wait for 32 UART clock periods for the flush
to propagate otherwise TX data could be post. Add a helper function
to wait for N UART clock periods and update delay following FIFO
flush to be 32 UART clock cycles.
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/serial-tegra.c')
-rw-r--r-- | drivers/tty/serial/serial-tegra.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 1d5ea3964ee5..9e08d3f07509 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -234,6 +234,22 @@ static void tegra_uart_break_ctl(struct uart_port *u, int break_ctl) tup->lcr_shadow = lcr; } +/** + * tegra_uart_wait_cycle_time: Wait for N UART clock periods + * + * @tup: Tegra serial port data structure. + * @cycles: Number of clock periods to wait. + * + * Tegra UARTs are clocked at 16X the baud/bit rate and hence the UART + * clock speed is 16X the current baud rate. + */ +static void tegra_uart_wait_cycle_time(struct tegra_uart_port *tup, + unsigned int cycles) +{ + if (tup->current_baud) + udelay(DIV_ROUND_UP(cycles * 1000000, tup->current_baud * 16)); +} + /* Wait for a symbol-time. */ static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup, unsigned int syms) @@ -263,8 +279,12 @@ static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) /* Dummy read to ensure the write is posted */ tegra_uart_read(tup, UART_SCR); - /* Wait for the flush to propagate. */ - tegra_uart_wait_sym_time(tup, 1); + /* + * For all tegra devices (up to t210), there is a hardware issue that + * requires software to wait for 32 UART clock periods for the flush + * to propagate, otherwise data could be lost. + */ + tegra_uart_wait_cycle_time(tup, 32); } static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) |