提交 905c0dec 编写于 作者: L Lucas Stach 提交者: Greg Kroah-Hartman

serial: imx: don't use idle condition detect for DMA transfers

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: NLucas Stach <l.stach@pengutronix.de>
Acked-by: NJiada Wang <jiada_wang@mentor.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 184bd70b
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册