Ethan Cheng

i.MX6Q UART SDMA issue on ARM2 -blog archive

Discussion created by Ethan Cheng Employee on Sep 3, 2012
Latest reply on Nov 11, 2015 by Keita Nagashima

There are two uart which are ttymxc1 and ttymxc3 on ARM2, and usually ttymcx3 is used for console.
If we use ttymxc1 to transmit data from PC to ARM2, it will get an error message "We cannot prepare for the RX slave dma!" and the transmission will be stopped randomly.
The root cause of this issue is software process of SDMA could be mistaken when an unexpected hardware interrupt was happened.
Let have a look about SDMA source code.

static int sdma_run_channel(struct sdma_channel *sdmac)
{
 struct sdma_engine *sdma = sdmac->sdma;
 int channel = sdmac->channel;
 int ret;

 init_completion(&sdmac->done);

 wmb();
 __raw_writel(1 << channel, sdma->regs + SDMA_H_START);  // (1) Start SDMA channel to load script.

 ret = wait_for_completion_timeout(&sdmac->done, HZ);  // (2) Wait for SDMA interrupt to indicate script loading is completed.

 return ret ? 0 : -ETIMEDOUT;
}

static void mxc_sdma_handle_channel(struct sdma_channel *sdmac)
{
 complete(&sdmac->done);  // (3) Inform script loading is completed.

 /* not interested in channel 0 interrupts */
 if (sdmac->channel == 0)
  return;

 if (sdmac->flags & IMX_DMA_SG_LOOP)
  sdma_handle_channel_loop(sdmac);
 else
  mxc_sdma_handle_channel_normal(sdmac);
}

The correct process we expected is (1) -> (2) -> (3).
But, a bug exists in this software design when an unexcepted hardware interrupt was happened between (1) and (2).

Please think about the below scenario.
 __raw_writel(1 << channel, sdma->regs + SDMA_H_START);  // (1) Start SDMA channel to load script
 other hardware interrupt ISR;
 SDMA hardware interrupt ISR;  // (3) will be executed.
 ret = wait_for_completion_timeout(&sdmac->done, HZ);  // (2) Wait for SDMA interrupt to indicate script loading is completed.

The process flow will be (1) -> (3) -> (2) and it causes (2) to get timeout and return an error code.
Solution A:
Use a work queque to execute "complete" function in SDMA interrupt handler.
The drawback is the performance of SDMA will be affected.

Solution B:
Re-load the script/context when receiving (2) timeout error code.
Because this bug as the above described is happened seldom, this solution should be acceptable.

Outcomes