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.
Hi Cheng,
My customer is encountering this error, while communicating to a bluetooth module.
Is it supporting the UART SDMA issue in L3.14.28_1.0.0?
Best Regards,
Keita
Hi Cheng,
We use Freescale i.MX6Q with Linux 3.0.35_4.0.0
We use ttymxc2 @ 115k2 without RTS/CTS
We use ttymxc0 for @ 115k2 without RTS/CTS for communication with our machine.
When i do put a linux console on ttymxc2 sometimes suddenly it stops working and then i get:
"We cannot prepare for the RX slave dma!"
So it looks that the issue you described is not fixed in 3.0.35_4.0.0 yet?
Is it fixed in 3.0.35_4.1.0?
Looking forward to your reply.
Sake
I am also interested in fix for this issue, and I can tell that this is not fixed in the latest BSP releases.
I have a board that has bluetooth connected to UART with RTS/CTS which works okay *only if SDMA is disabled*. More info here Google Groups (last part of the post).
Hope to see answer from Freescale guys.
Best Regards,
Dmitriy Beykun