I am currently working on making a new Kernel build for our boards that use a Colibri iMX6ULL module, upgrading from 4.9.166 to 6.1.76. I have a very strange issue with the new build where multiple uart ports will transmit data fine, but will always drop bytes when a large number come in at a time. This has been confirmed on UART6 which talks to a modem, and also UART1 which is used for the normal serial terminal (I haven’t tested any other UARTs). I can replicate it on the serial terminal easily by pasting some text into vi and always some bytes are dropped randomly:
Note on the above image the left section is from the new kernel build, and the right section is from the same test on the same Colibri module and same carrier board after re-flashing with the old kernel image.
Is there any setting in the device tree or kernel that could explain this issue?
Try if echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state2/disable helps.
I had some issues with timing critical latency on serial port on imx6ull, disabling sleep helped.
I believe it just masked the problem for a while. Make sure you have DMA enabled for your UART. To verify cat /proc/interrupts and check that interrupt events count is 0 for UART in question. It is not 0 when DMA is disabled
How is DMA enabled / disabled for uart? Looking at the kernel config file and comparing to my old kernel there are not any obvious DMA setting differences.
My serial port list in /sys/firmware is the same but none of the folders have the subfolders “dma” and “dma-names”.
In the device tree itself the only relevant section seems to be
&sdma {
status = "okay";
}
I used the provided device tree files from the latest BSP and only edited to change pin muxing as required and a few other minor things that shouldn’t relate to serial or DMA. Is there anything else that controls if the uarts want to use DMA?
– but only if I compile the kernel with CONFIG_IMX_SDMA=m . If I compile with CONFIG_IMX_SDMA=y the firmware won’t load with error “imx-sdma 20ec000.dma-controller: Direct firmware load for imx/sdma/sdma-imx6q.bin failed with error -2”, even though the bin file listed is present in the correct location. Presumably it should work fine as a module though because this is the default config for the BSP I believe.
Don’t confuse with 6ul instead of 6ull. imx6ul.dtsi is included by some 6ull file. Settings for uart8, which is different on 6ull, are specified in imx6ull.dtsi. You may miss dmas settings for uart1, which someone at NXP thinks doesn’t deserve DMA because it is console port by default, but you still can find settings for it in imx6ull reference manual.
– but only if I compile the kernel with CONFIG_IMX_SDMA=m . If I compile with CONFIG_IMX_SDMA=y the firmware won’t load with error “imx-sdma 20ec000.dma-controller: Direct firmware load for imx/sdma/sdma-imx6q.bin failed with error -2”, even though the bin file listed is present in the correct
To use =y you need to incorporate FW in kernel with CONFIG_EXTRA_FIRMWARE.
CONFIG_EXTRA_FIRMWARE=“imx/sdma/sdma-imx6q.bin”
,where imx/sdma/ is sub-path from /lib/firmware/ on target to FW binary. Other FWs may be specified separating them with space.
Thanks for the detailed explanation and info. I used the downstream example to update the device tree to add the dmas to uart6 (which is the main one I am concerned about), and now the dma files under that serial@… are present, and the port works properly without having to disable the cpuidle/state2 . Thanks for the help.