*
* High-speed serial driver for NVIDIA Tegra SoCs
*
- * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
*
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*
#define TEGRA_TX_PIO 1
#define TEGRA_TX_DMA 2
+#define TEGRA_UART_FCR_IIR_FIFO_EN 0x40
+
/**
* tegra_uart_chip_data: SOC specific data.
*
bool tx_fifo_full_status;
bool allow_txfifo_reset_fifo_mode;
bool support_clk_src_div;
+ bool fifo_mode_enable_status;
};
struct tegra_uart_port {
tup->current_baud));
}
+static int tegra_uart_is_fifo_mode_enabled(struct tegra_uart_port *tup)
+{
+ unsigned long iir;
+ unsigned int tmout = 100;
+ int ret = -EIO;
+
+ do {
+ iir = tegra_uart_read(tup, UART_IIR);
+ if (iir & TEGRA_UART_FCR_IIR_FIFO_EN) {
+ ret = 0;
+ break;
+ }
+ if (--tmout == 0)
+ break;
+ udelay(1);
+ } while (1);
+
+ return ret;
+}
+
static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits)
{
unsigned long fcr = tup->fcr_shadow;
+ int ret;
if (tup->cdata->allow_txfifo_reset_fifo_mode) {
fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
tegra_uart_write(tup, fcr, UART_FCR);
fcr |= UART_FCR_ENABLE_FIFO;
tegra_uart_write(tup, fcr, UART_FCR);
+ if (tup->cdata->fifo_mode_enable_status) {
+ ret = tegra_uart_is_fifo_mode_enabled(tup);
+ if (ret < 0)
+ dev_err(tup->uport.dev, "FIFO mode not enabled\n");
+ }
}
/* Dummy read to ensure the write is posted */
tup->fcr_shadow |= TEGRA_UART_TX_TRIG_16B;
tegra_uart_write(tup, tup->fcr_shadow, UART_FCR);
- mdelay(3);
+ if (tup->cdata->fifo_mode_enable_status) {
+ ret = tegra_uart_is_fifo_mode_enabled(tup);
+ if (ret < 0) {
+ dev_err(tup->uport.dev, "FIFO mode not enabled\n");
+ return ret;
+ }
+ } else
+ udelay(20);
+
/*
* Initialize the UART with default configuration
* (115200, N, 8, 1) so that the receive DMA buffer may be
.tx_fifo_full_status = false,
.allow_txfifo_reset_fifo_mode = true,
.support_clk_src_div = false,
+ .fifo_mode_enable_status = false,
};
static struct tegra_uart_chip_data tegra30_uart_chip_data = {
.tx_fifo_full_status = true,
.allow_txfifo_reset_fifo_mode = false,
.support_clk_src_div = true,
+ .fifo_mode_enable_status = false,
};
static struct tegra_uart_chip_data tegra114_uart_chip_data = {
.tx_fifo_full_status = true,
.allow_txfifo_reset_fifo_mode = false,
.support_clk_src_div = true,
+ .fifo_mode_enable_status = false,
};
static struct tegra_uart_chip_data tegra186_uart_chip_data = {
.tx_fifo_full_status = true,
.allow_txfifo_reset_fifo_mode = false,
.support_clk_src_div = true,
+ .fifo_mode_enable_status = true,
};
static struct of_device_id tegra_uart_of_match[] = {