Linux iMX6 UART Driver Issues

Dear all,
I am facing various issues with iMX6 Linux UART driver.

I have some code that is known working that is talking to a remote device. Protocol is binary, baud rate is changed during init (9600 startup, 115200 normally), no flow control pins available (only tx/rx/ground).

For what I have seen so far:

  • kernel 3.14.28: a lot of garbage received. sometimes “imx-uart 21f4000.serial: overwrite!”. not working.
  • Kernel 3.14.52. same problem with continuous “imx-uart 21f4000.serial: Rx FIFO overrun”. not working.
  • Kernel 3.14.52 modified to not use DMA, working!
  • Uart driver from kernel 4.1 imx from FSL backported to 3.14.52. not working.
  • Uart driver from kernel 4.6 kernel.org. working!.

A different uart running at 3Mbit/s with RTS/CTS seems to work correctly after a short test.

Any suggestion? I have seens some reports on official FSL but I was not able to find any definitive/useful answer.

Using mainline driver is not my first choice since my backport will require additional work to be usable (I have completly disabled CTS/RTS to compile it), and disabling DMA seems just the wrong decision to me.

Thanks,
Francesco

If I understand correctly uart imx driver with RTS/CTS flow control disabled and DMA enabled is broken till commit
7e11577ef6f31faf4a505e7823bf78b679906aca

Hm interesting, that seems to be a whole patchset (several parent commits are actually also related to UART/DMA).

Back porting is a bit of a pain usually, especially across many version. If you know which were the relevant patches, you could try using git cherry-pick to pick the relevant fixes only.

Just for people having strange blocking issues with continuous UART data reception:
The implemented UART DMA requires a blank time of at least 8 byte times to initiate a transfer. In my case even a RX idle time of 6.8msec between consecutive data packets (at 19200Baud) was not sufficient to trigger the DMA transfer.
If this is the case received data is not accessible until the whole DMA buffer is full (after roughly 1000 bytes are received) and this results in receiving the data in large blocks with long delay even if they are available on the RX line in a continuous manner.

To prevent this issue you can disable the RX-DMA of the desired UART by changing the uart block of your DTS file (this example works for ttymxc4):

&uart5 {
	status = "okay";
	dma-names = "","tx";
};

It took a whole day for me to figure that out so i hope anyone stumbling over this problem will find this thread and the solution quicker :slight_smile:

Thanks for the solution,
But what is the corresponding android and kernel version?

What exactly does this have to do with Android? Concerning the kernel version @f.d. actually nicely listed those affected ones in his initial post.

This solution is for the Linux BSP (V2.6beta2 Kernel 3.14.52 in my case). But I’m very confident it will work with all versions having the UART DMAs enabled.

It is true for i.MX7 as same imx-uart driver is used.

This is exactly our problem. We have bytes arriving continuously every 10mS and the i.MX6dl OpenEmbedded build refuses to deliver any data until 4096 bytes have arrived, whereupon they all arrive at once, with some dropped. It’s very bad. Thanks for this fix.
However: I am very lost as to how to implement this fix, owing to the fact that I’m a total novice when it comes to building Linux.
I’ve installed OE and Qt following the directions here
I have created the SDK and I can build Linux images using bitbake. I can even make my own Qt apps and run them on the target.
Where do I find the DTS file mentioned above? Is it this one: “build/tmp-glibc/…/arm/boot/dts/imx6dl-colibri-eval-v3.dts” ?
OK, assuming that is the file to modify, how do I use bitbake to turn it into a .dtb file?
Any help greatly appreciated. Step-by-step instructions required, please. Sorry for being such a dunce.

Please have a look here and here. It is recommended to do the kernel build outside of OE for development and testing. Later on you may integrate it in project with OE.

Done. Using this method to turn off uart DMA and reverting to PIO, the serial-port data is delivered as expected; no dropped bytes, very low latency. @m0w1337 this is a good fix - thnx.
Thanks for your help.

Hi,

I have also experimented a lot with this UART issue. In addittion to your tests, I would like to add that I have found a solution to “Rx FIFO overrun” and “overwrite” errors backporting imx.c driver from linux kernel 3.18.31 (Rx FIFO overrun post). But still having timing problems with this backport.

Hi, thanks for the recomendation. I will test this solution using 3.18.31 kernel’s imx driver in order to check if the delays I have experimented dissapear.

Ditto - we just hit this same issue - fixed our issue - thanks for the great work!
If it helps we’re using 4.9.88_ga release on an imx6sx platform. The device we were trying to receive serial data from was a gps u-blox chip.

@nautilus: Thanks for you answer. Does this mean, the issue is still present in the kernel 4.9.88. Which driver version did you use?

Thanks a lot. This also fix my problem.

Thanks for you Input.

@nautilus , Hey same issue I am facing in kernel 4.9.87-640138-g18741 with imx6dq, connected gps u-blox on serial(ttymxc3). how you fixed it, is above change is enough?
not working for me.