aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/imx.c
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2015-09-04 17:52:40 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-04 18:43:06 +0100
commit184bd70bbc81ff0aa561eb51914c952225e42aab (patch)
tree068cd5ab4af05f2933e2c92815141c74012aa411 /drivers/tty/serial/imx.c
parentserial: imx: always restart DMA if more data is available (diff)
downloadlinux-dev-184bd70bbc81ff0aa561eb51914c952225e42aab.tar.xz
linux-dev-184bd70bbc81ff0aa561eb51914c952225e42aab.zip
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>
Diffstat (limited to 'drivers/tty/serial/imx.c')
-rw-r--r--drivers/tty/serial/imx.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index dbee7ff2f8fd..cfda31a7edd6 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -975,6 +975,8 @@ static int start_rx_dma(struct imx_port *sport)
#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 @@ static int imx_uart_dma_init(struct imx_port *sport)
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 @@ static int imx_uart_dma_init(struct imx_port *sport)
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 @@ static void imx_enable_dma(struct imx_port *sport)
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 @@ static void imx_disable_dma(struct imx_port *sport)
temp &= ~UCR4_IDDMAEN;
writel(temp, sport->port.membase + UCR4);
+ imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
+
sport->dma_is_enabled = 0;
}