]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
serial: tegra: check for FIFO mode enabled status
authorShardar Shariff Md <smohammed@nvidia.com>
Tue, 2 Jun 2015 10:20:00 +0000 (15:50 +0530)
committerLaxman Dewangan <ldewangan@nvidia.com>
Wed, 3 Jun 2015 05:24:10 +0000 (22:24 -0700)
- Check if FIFO mode is enabled or not after enabling
the FIFO mode before filling FIFO.
- Correct the delay 20 micro sec after enabling FIFO mode
as per the HW Bug for previous Tegra SOCs (earlier to T186)

Bug 200075959

Change-Id: I93e615afd9c43fc604cec262e811a9e561654e02
Signed-off-by: Shardar Shariff Md <smohammed@nvidia.com>
Reviewed-on: http://git-master/r/751327
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
drivers/tty/serial/serial-tegra.c

index d5ffd056b3c052c569eeaa799b6ac8f014868bad..36cd1bea612b2a8037d1a0b55c4506d35dee1ff7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * 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>
  *
@@ -85,6 +85,8 @@
 #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.
  *
@@ -97,6 +99,7 @@ struct tegra_uart_chip_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 {
@@ -249,9 +252,30 @@ static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup,
                        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);
@@ -264,6 +288,11 @@ static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits)
                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 */
@@ -946,7 +975,15 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup)
        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
@@ -1360,24 +1397,28 @@ static struct tegra_uart_chip_data tegra20_uart_chip_data = {
        .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[] = {