UART's not receiving data, driver issue?

I’m trying to get 8 serialports on a imx7d+Iris, to do that, i activated uart5,uart 6 and added a max14830 to the spi bus. For this i altered the kernel config to include max310x and the default iris-v2 dts to this.

// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
 * Copyright 2017-2020 Toradex
 */

/dts-v1/;
#include "imx7d-colibri-emmc.dtsi"
#include "imx7-colibri-iris-v2.dtsi"

/ {
	model = "Toradex Colibri iMX7D 1GB on Colibri Iris V2 Board";
	compatible = "toradex,colibri-imx7d-emmc-iris-v2",
		     "toradex,colibri-imx7d-emmc",
		     "toradex,colibri-imx7d",
		     "fsl,imx7d";
};

&usbotg2 {
	vbus-supply = <&reg_usbh_vbus>;
	status = "okay";
};
&pwm1 {
	status = "disabled";
	/delete-property/pinctrl-0;
};
&pwm4 {
	status = "disabled";
	/delete-property/pinctrl-0;
};

&uart6 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart6>;
	assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
	assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
	fsl,dte-mode;
};
&uart7 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart7>;
	assigned-clocks = <&clks IMX7D_UART7_ROOT_SRC>;
	assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
	fsl,dte-mode;
};

&ecspi3 {

	/delete-node/spidev@0;

	max14830: max14830@3 {
		compatible = "maxim,max14830";
		spi-max-frequency = <15000000>;
		reg = <0>; // SPI chip select number
		clocks = <&clk16m0>;
		clock-names = "osc";
		interrupt-parent = <&gpio5 11>;
		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
		gpio-controller; // Marks the device node as a GPIO controller
		#gpio-cells = <2>;
		clk16m0: clk16m0 {
			compatible = "fixed-clock";
			#clock-cells = <0>;
			clock-frequency = <3686400>;
			clock-accuracy = <100>;
		};
	 };
};

&iomuxc {
 pinctrl_gpio2: gpio2-grp { /* On X22 Camera interface */
		fsl,pins = <
			MX7D_PAD_SD1_CD_B__GPIO5_IO0		0x74 /* SODIMM 69 */
			MX7D_PAD_I2C4_SDA__GPIO4_IO15		0x14 /* SODIMM 75 */
			MX7D_PAD_ECSPI1_MISO__GPIO4_IO18	0x14 /* SODIMM 79 */
			MX7D_PAD_I2C3_SCL__GPIO4_IO12		0x14 /* SODIMM 81 */
			MX7D_PAD_ECSPI2_MISO__GPIO4_IO22	0x14 /* SODIMM 85 */
			MX7D_PAD_ECSPI1_SS0__GPIO4_IO19		0x14 /* SODIMM 97 */
			MX7D_PAD_I2C3_SDA__GPIO4_IO13		0x14 /* SODIMM 94 */
			MX7D_PAD_I2C4_SCL__GPIO4_IO14		0x14 /* SODIMM 96 */
			MX7D_PAD_SD2_RESET_B__GPIO5_IO11	0x14 /* SODIMM 98 */
		>;
	};

  pinctrl_uart6: uart6grp {
     fsl,pins = <
         MX7D_PAD_ECSPI1_SCLK__UART6_DTE_TX        0x79 /* SODIMM 101 */
         MX7D_PAD_ECSPI1_MOSI__UART6_DTE_RX        0x79 /* SODIMM 103 */

     >;
  };
  pinctrl_uart7: uart7-grp {
     fsl,pins = <
         MX7D_PAD_ECSPI2_MOSI__UART7_DTE_RX        0x79 /* SODIMM 59 */
         MX7D_PAD_ECSPI2_SCLK__UART7_DTE_TX        0x79 /* SODIMM 67 */

     >;
  };
};

And in dmesg:

[    0.170378] 30860000.serial: ttymxc0 at MMIO 0x30860000 (irq = 53, base_baud = 1500000) is a IMX
[    0.903400] printk: console [ttymxc0] enabled
[    0.908490] 30890000.serial: ttymxc1 at MMIO 0x30890000 (irq = 54, base_baud = 1500000) is a IMX
[    0.917888] 30880000.serial: ttymxc2 at MMIO 0x30880000 (irq = 55, base_baud = 1500000) is a IMX
[    0.927278] 30a80000.serial: ttymxc5 at MMIO 0x30a80000 (irq = 60, base_baud = 1500000) is a IMX
[    0.936632] 30a90000.serial: ttymxc6 at MMIO 0x30a90000 (irq = 61, base_baud = 1500000) is a IMX
...
[    5.676200] spi2.0: ttyMAX0 at I/O 0x0 (irq = 213, base_baud = 2764800) is a MAX14830
[    5.714256] spi2.0: ttyMAX1 at I/O 0x20 (irq = 213, base_baud = 2764800) is a MAX14830
[    5.754157] spi2.0: ttyMAX2 at I/O 0x40 (irq = 213, base_baud = 2764800) is a MAX14830
[    5.776362] spi2.0: ttyMAX3 at I/O 0x60 (irq = 213, base_baud = 2764800) is a MAX14830
[    5.801429] spi_imx 30840000.spi: probed

But what i thought wasn’t related but maybe is:

[    5.592088] imx-sdma 30bd0000.sdma: Direct firmware load for imx/sdma/sdma-imx7d.bin failed with error -2
[    5.624679] imx-sdma 30bd0000.sdma: Direct firmware load for imx/sdma/sdma-imx7d.bin failed with error -2
[    5.649985] imx-sdma 30bd0000.sdma: external firmware not found, using ROM firmware

When i try the ttymxc5 and 6 with a loop, the result cat /proc/tty/driver/IMX-uart

serinfo:1.0 driver revision:
0: uart:IMX mmio:0x30860000 irq:53 tx:48755 rx:518 RTS|DTR|DSR
1: uart:IMX mmio:0x30890000 irq:54 tx:0 rx:0 RTS|DTR|DSR
2: uart:IMX mmio:0x30880000 irq:55 tx:0 rx:4096 RTS|DTR|DSR
5: uart:IMX mmio:0x30A80000 irq:60 tx:11 rx:4096 DSR
6: uart:IMX mmio:0x30A90000 irq:61 tx:16 rx:4096 DSR

The 4096 is the size of the buffer, and this number only goes up with steps of 4096…

Any ideas?

Maybe try without dma turned on for the uarts?

Do you get the same kind of results looping the other ports together?

Maybe turn the baud rate down a bit?

Baudrate doesn’t make a difference, the only thing that works if i start from scratch again (use downloader to install 5.4 minimal reference, overwrite dtb,kernel and modules), then it looks like this in dmesg

[    4.776947] imx-sdma 30bd0000.sdma: loaded firmware 4.5
[    4.791704] spi2.0: ttyMAX0 at I/O 0x0 (irq = 213, base_baud = 2764800) is a MAX14830
[    4.853067] spi2.0: ttyMAX1 at I/O 0x20 (irq = 213, base_baud = 2764800) is a MAX14830
[    4.947981] spi2.0: ttyMAX2 at I/O 0x40 (irq = 213, base_baud = 2764800) is a MAX14830
[    5.017229] spi2.0: ttyMAX3 at I/O 0x60 (irq = 213, base_baud = 2764800) is a MAX14830
[    5.049155] spi_imx 30840000.spi: probed

So at some point something breaks dma support.

There were some references about loading the dma firmware as a module? You try that?

Well, i did read somewhere about a lib/firmware folder and noticed that one was missing… So i copied the one from the reference minimal and then the error is no longer displayed but the issue isn’t gone with it…
So then it gets loaded but maybe something else is also missing but not reported…

Hi @Michielt,
I think we should divide this to try to see what’s going on:
Are the IMX UART ports working? From what you showed it seems that they are at least detected. Did you try to use any or all of them to see if they work?

As a separate issue, do the UART’s connected to the max14830 work? They seem also to at least be properly detected.

If any of the cases doesn’t work, what’s the outcome of the tests?
Could you describe how are you trying them?
Are there any errors, or maybe freezes while trying to open the devices?

Regards,
Rafael Beims

Hi @rafael.tx

  • When i echo something on the ttyMAX it’s seems to take longer than the regular one’s to complete.
  • The mxc1,2,5 and 6 allow data to be send but don’t receive anything and rx buffer goes up by 4096 every x bytes.
  • For some reason mxc0 works fine…

I know the TX side of the max works because i can see spi traffic with a logic analyzer. But no data is send out of the chip and seem to be stuck in the max 14830 fifo(separate issue i think outside of the scope of this board maybe).

Everything seems to work (well up to the max14830) if i use the ‘minimal reference image’ with the altered kernel and modules but when i install a debian rootfs instead (with the same modules) it no longer works and gives the ‘not found error’ (i probably should have clarified this in the opening post).

I assumed the modules tar created by yocto (with toradex git) created ‘all’ the drivers etc but it doesn’t build a ‘firmware’ folder. So i copied the one from the reference minimal. That took care of ‘not found’ issue but broke the tx… (sending one byte resulted in 4k or something added on the counter), copying other things from the lib resulted in kernel panic…

So i think all of this (except the max14830 fifo issue) boils down to: how to i get a properly set up /lib if i want to use a regular distro?

Hi @Michielt, just to confirm: If you use the downloaded minimal reference image and make the changes in the device tree, do you get the builtin UART’s working?

I just read your answer and saw that you want to build a debian image. In this case I would suggest to you that you take a look into Torizon, as it provides easy to use images where you can load your application using containers that are based on Debian images.
Then I saw that you already asked about that on this question:

If you cannot use Torizon because of the lack of modules but you would otherwise be interested in trying it out you could build your own Torizon Core image and include your customized kernel configuration.

If you don’t need anything debian specific for your application, then you can also build the kernel yourself by following this article and also customize your own image to load your application and libraries.

If you need help with customizing OS images for your application, we also have in our partner network a list of several companies that can help you.

Building a custom debian to run on a platform that’s not supported by them is not that simple. It should be doable if you are able to pick all the correct pieces (kernel image, binary firmwares, kernel modules) that are provided inside the yocto built image and load them on your image. As you already noticed by your tests, if something is missing or is from an incompatible version / build stuff stops working, you start to see kernel panics and can run into other stability problems.
Also it is worth to mention that setting up a builder system that can actually replicate your debian image for maintainability in the future can also be a pain.

Hi @rafael.tx
Yes all serial ports work fine if i use the minimal reference image or my debian version without the max310x module call.

I think where i went wrong is (kernel image, binary firmwares, kernel modules) not building any firmware outside of kernel modules.
So i decided (based on this and the other thread) to have another look at Torizon and see if i can get to where i want with it.

But first i want to get that max14830 working because that’s the whole reason i can’t keep using the Debian i made. But still stuck on the TX fifo not flushing.

So found a (rather obvious) mistake in that section…
clock-names = "osc"; should be clock-names = "xtal";
That solved not sending data, but receiving still not working.

interrupt-parent = <&gpio5>; // the gpio group
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
gpio-controller; // Marks the device node as a GPIO controller
#gpio-cells = <2>;

Is the most likely candidate but i’m fairly certain the pin is correct because when i try to use this pin in another application this fails if the driver is active.

Tried replacing it to

interrupt-parent = <&gpio5>; // the gpio group
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller; // Marks the device node as a interrupt controller
#interrupt-cells = <2>;

But didn’t seem to make any difference.

The odd thing is that when a physical loop is made cat /proc/tty/driver/max310x does show an increase in both rx and tx, but rx doesn’t go up when connected to a usb->serial or another one of the four ports (ttyMAX2<->ttyMAX3 doesn’t show an increase in rx either).

The reason for RX not working was frustratingly simple…
Because i used the reference minimal that hasn’t got minicom etc i just used cat /proc/tty/driver/max310x to see if data arrived…

Turns out the driver probably assumes that no port opened = no use gathering data so disables RX…
Direct loop probably works because it opens the port for a split second.
The moment i opened the ports in the data acquisition software everything worked…

So the solution to the max14830 issue:

  • clock-names = "osc"; should be clock-names = "xtal";
  • RX only works if the port is opened by a process

So resulting correct/working node:

&ecspi3 {

	/delete-node/spidev@0;

	max14830: max14830@3 {
		compatible = "maxim,max14830";
		spi-max-frequency = <15000000>;
		reg = <0>; // SPI chip select number
		clocks = <&clk16m0>;
		clock-names = "xtal"; /* because using external xtal */
		interrupt-parent = <&gpio5>;
		interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
		gpio-controller;  /* Marks the device node as a GPIO controller */
		#gpio-cells = <2>;
		clk16m0: clk16m0 {
			compatible = "fixed-clock";
			#clock-cells = <0>;
			clock-frequency = <3686400>; /* external xtal frequency */
			clock-accuracy = <100>;
		};
	 };
};

Hi @Michielt, that’s very good to hear! Thank you very much for sharing the solution!