serial: imx: don't use idle condition detect for DMA transfers
authorLucas Stach <l.stach@pengutronix.de>
Fri, 4 Sep 2015 15:52:41 +0000 (17:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 4 Oct 2015 17:43:06 +0000 (18:43 +0100)
The reference manual states that idle condition detect should not be used
with DMA transfers, as the ROM SDMA scripts don't check those conditions.

The RAM SDMA scripts worked around this, but the change broke compatibility
with the ROM scripts.

The previous commits fixed the DMA burst sizes, so that the aging timer is
now working as described in the reference manual. With this fixed we can
remove the hack of using the idle condition detect to stop the DMA transfer
if there are no new characters incoming.

This should work with both the ROM and RAM SDMA scripts.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Acked-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/imx.c

index cfda31a7edd62638ae674bddce802122fddf1ec7..f1366cf4e6a9304e4c78798c5405452a5ed0901c 100644 (file)
@@ -884,14 +884,12 @@ static void imx_rx_dma_done(struct imx_port *sport)
 }
 
 /*
- * There are three kinds of RX DMA interrupts(such as in the MX6Q):
+ * There are two kinds of RX DMA interrupts(such as in the MX6Q):
  *   [1] the RX DMA buffer is full.
- *   [2] the Aging timer expires(wait for 8 bytes long)
- *   [3] the Idle Condition Detect(enabled the UCR4_IDDMAEN).
+ *   [2] the aging timer expires
  *
- * The [2] is trigger when a character was been sitting in the FIFO
- * meanwhile [3] can wait for 32 bytes long when the RX line is
- * on IDLE state and RxFIFO is empty.
+ * Condition [2] is triggered when a character has been sitting in the FIFO
+ * for at least 8 byte durations.
  */
 static void dma_rx_callback(void *data)
 {
@@ -909,13 +907,6 @@ static void dma_rx_callback(void *data)
        status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state);
        count = RX_BUF_SIZE - state.residue;
 
-       if (readl(sport->port.membase + USR2) & USR2_IDLE) {
-               /* In condition [3] the SDMA counted up too early */
-               count--;
-
-               writel(USR2_IDLE, sport->port.membase + USR2);
-       }
-
        dev_dbg(sport->port.dev, "We get %d bytes.\n", count);
 
        if (count) {
@@ -1072,20 +1063,13 @@ static void imx_enable_dma(struct imx_port *sport)
 
        /* set UCR1 */
        temp = readl(sport->port.membase + UCR1);
-       temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN |
-               /* wait for 32 idle frames for IDDMA interrupt */
-               UCR1_ICD_REG(3);
+       temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN;
        writel(temp, sport->port.membase + UCR1);
 
        temp = readl(sport->port.membase + UCR2);
        temp |= UCR2_ATEN;
        writel(temp, sport->port.membase + UCR2);
 
-       /* set UCR4 */
-       temp = readl(sport->port.membase + UCR4);
-       temp |= UCR4_IDDMAEN;
-       writel(temp, sport->port.membase + UCR4);
-
        imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
 
        sport->dma_is_enabled = 1;
@@ -1105,11 +1089,6 @@ static void imx_disable_dma(struct imx_port *sport)
        temp &= ~(UCR2_CTSC | UCR2_CTS | UCR2_ATEN);
        writel(temp, sport->port.membase + UCR2);
 
-       /* clear UCR4 */
-       temp = readl(sport->port.membase + UCR4);
-       temp &= ~UCR4_IDDMAEN;
-       writel(temp, sport->port.membase + UCR4);
-
        imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
 
        sport->dma_is_enabled = 0;