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: Lucas Stach <l.stach@pengutronix.de> Acked-by: Jiada Wang <jiada_wang@mentor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
184bd70bbc
commit
905c0decad
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue