iMX6 Linux serial port buffer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX6 Linux serial port buffer

Jump to solution
4,688 Views
Maddis
Contributor IV

Hi,

I have custom iMX6 based hw that previously ran Yocto 1.7 and Linux 3.10.17. I have touchscreen connected to Uart4. With 3.10.17 it worked just fine. Then I updated to latest BSP version with Yocto 2.0 and Linux 4.1.15 and that touchscreen doesn't work properly anymore.

I use inputattach to connect the serial port to input system and I thought that the problem was in touchscreen serial port driver, but I think the problem is in either in imx serial driver or most likely driver configuration.

The problem is that when using single finger to touchscreen the touch is really laggy. I can actually move the finger across the screen and when I lift the finger it'll do the moves then. With two fingers the touch works just fine.

I did some more digging opened serial port with minicom and it seems that if I keep single finger pressed on screen the data is outputted maybe once/twice a second.  With two fingers the data is coming in with faster rate so that's why it works better.

I'm suspecting that there is some buffer flushing that takes too long with newer kernel since lifting the finger triggers the data output so timeout  waiting for new data has elapsed.  I went through the serial-driver code, but couldn't find any configurable buffers especially that could be done via device tree.

I changed the CTSTL to 1 from driver trying to lower the trigger threshold, but that did absolutely nothing. I also checked with scope that when pressing with just one finger the touch screen keeps sending constantly new data so the problem is in Linux end.

Any idea what else to try?

Labels (2)
0 Kudos
1 Solution
3,131 Views
Maddis
Contributor IV

This is now fixed. Turns out that newer kernel has modified DMA handling that causes DMA to be used always. Older kernel used it only if set_termios - function was called.

Quick'n'Dirty fix was to disable DMA for the serial port where the touch was connected to.

DMA and lack of flow control caused that the constant flow of data kept DMA from outputting data forward before the buffer got full (4kB) or timeout happened (finger was lifted from screen).

View solution in original post

5 Replies
3,132 Views
Maddis
Contributor IV

This is now fixed. Turns out that newer kernel has modified DMA handling that causes DMA to be used always. Older kernel used it only if set_termios - function was called.

Quick'n'Dirty fix was to disable DMA for the serial port where the touch was connected to.

DMA and lack of flow control caused that the constant flow of data kept DMA from outputting data forward before the buffer got full (4kB) or timeout happened (finger was lifted from screen).

1,989 Views
YJS
Contributor I

Thank you very much for coming back to record, this problem has been bothering me for two weeks.

0 Kudos
3,131 Views
Maddis
Contributor IV

I did test program that reads the serial port and noticed that when using single finger the data is outputted in 4kB blocks (4096 bytes). So clearly some buffer gets filled before data is outputted. Also if I remove finger before the buffer is filled the data is outputted as well so it either gets some character or most likely the delay that trigs the outputting the data forward.

One interesting thing I noticed. I put couple prints to drivers/tty/serial/imx.c interrupt handlers. Only interrupts I got was when I wrote something to serial console. Nothing when I used touchscreen or even when I read directly the /dev/ttymxc4 - device. I thought the /dev/ttymxc4 is handled by that driver?

0 Kudos
3,131 Views
jamesbone
NXP TechSupport
NXP TechSupport

Do you think you can post the DTS file to see how the Touch it is configured?  something like :

&tsc {

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_tsc>;

xnur-gpio = <&gpio1 3 0>;

measure_delay_time = <0xffff>;

pre_charge_time = <0xfff>;

status = "disabled";

};

0 Kudos
3,131 Views
Maddis
Contributor IV

Well, since the touch is connected to serial port there is no separate device tree config for it. You only configure serial port in Device Tree and then use inputattach to attach serial port to Linux's input system. There is a driver in kernel that reads the serial port and parses the data and outputs input system events.

I checked the serial port driver and didn't see any config you can do in Device Tree except the RTS/CTS and DTE.