serial: imx: configure proper DMA burst sizes
Triggering the DMA engine for every byte is horribly inefficient.
Also it doesn't allow to use the aging timer for the RX FIFO as this
requires the DMA engine to leave one byte remaining in the FIFO when
doing a normal burst transfer.
Adjust watermark levels so that the DMA engine can do at least 8 byte
burst transfers. This is a conservative value, as the both TX and RX
FIFOs are able to contain 32 bytes.
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>
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index dbee7ff..cfda31a 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -975,6 +975,8 @@
#define TXTL_DEFAULT 2 /* reset default */
#define RXTL_DEFAULT 1 /* reset default */
+#define TXTL_DMA 8 /* DMA burst setting */
+#define RXTL_DMA 9 /* DMA burst setting */
static void imx_setup_ufcr(struct imx_port *sport,
unsigned char txwl, unsigned char rxwl)
@@ -1022,7 +1024,8 @@
slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = sport->port.mapbase + URXD0;
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- slave_config.src_maxburst = RXTL_DEFAULT;
+ /* one byte less than the watermark level to enable the aging timer */
+ slave_config.src_maxburst = RXTL_DMA - 1;
ret = dmaengine_slave_config(sport->dma_chan_rx, &slave_config);
if (ret) {
dev_err(dev, "error in RX dma configuration.\n");
@@ -1046,7 +1049,7 @@
slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = sport->port.mapbase + URTX0;
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- slave_config.dst_maxburst = TXTL_DEFAULT;
+ slave_config.dst_maxburst = TXTL_DMA;
ret = dmaengine_slave_config(sport->dma_chan_tx, &slave_config);
if (ret) {
dev_err(dev, "error in TX dma configuration.");
@@ -1083,6 +1086,8 @@
temp |= UCR4_IDDMAEN;
writel(temp, sport->port.membase + UCR4);
+ imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
+
sport->dma_is_enabled = 1;
}
@@ -1105,6 +1110,8 @@
temp &= ~UCR4_IDDMAEN;
writel(temp, sport->port.membase + UCR4);
+ imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
+
sport->dma_is_enabled = 0;
}