UART TX Interrupt not triggered in Jetpack 3.1

I’ve recently upgraded my TX1 connected to a custom carrier board to JetPack-L4T-3.1. I have connected a device to ttyTHS2 and was able to communicate reliably with CTS/RTS enabled in previous Jetpack versions (2.3). Sending over ttyTHS2 seems to be impossible with the new L4T.

Some diagnostics:

sudo cat /proc/tty/driver/tegra_hsuart
serinfo:1.0 driver revision:
1: uart:TEGRA_UART mmio:0x70006040 irq:321 tx:0 rx:0 CTS
2: uart:TEGRA_UART mmio:0x70006200 irq:322 tx:24 rx:146854 RTS|CTS|DTR
3: uart:TEGRA_UART mmio:0x70006300 irq:323 tx:0 rx:0 CTS

Rx is continuously increasing and I’m correctly receiving data from the attached device.
Tx is stuck. After a few unsuccessful sends it remains at 24.

TIOCGICOUNT (serial_icounter_struct counters) returns:

brk=0,buf_overrun=0,cts=0,dcd=0,dsr=0,frame=0,overrun=0,parity=0,rng=0,rx=366743,tx=24

TIOCINQ = 0 → so the receiving buffer is correctly cleared
TIOCOUTQ = 510 → and growing with the amount of data I write(…)

Seems that somehow the Tx interrupt is not triggered.

Any ideas?

Can someone verify that “serial@c280000” device tree block corresponds to “/dev/ttyTHS2” on both the TX1 and TX2?

There was a patch required in R27.1 for “/dev/ttyTHS2” to function correctly on a TX2, and it looks like a TX2 has this set correctly under R28.1. However, I extracted a device tree from R28.1 on a TX1, and I do not see the controller listed (it should be the same controller, but I can’t guarantee it). This part of the device tree on R28.1 of a TX1 does not show up:

serial@c280000

For the original discussion on a TX2/R27.1 see:
https://devtalk.nvidia.com/default/topic/1001264/jetson-tx2/tx2-uarts/post/5125115/#5125115

You might try this as a workaround (I have not tested…be sure to keep a working alternate boot entry via serial console in case this fails)…

# Reverse the existing device tree:
sudo apt-get install device-tree-compiler
dtc -I fs -O dts -o extracted_tx1-`uname -r`.dts /proc/device-tree
# You should now have <b>"extracted_tx1-4.4.38-tegra.dts"</b>
# Edit the extracted dts, insert this block which is a copy of the TX2 R28.1 "/dev/ttyTHS2" block:
        serial@c280000 {
                reg = <0x0 0xc280000 0x0 0x40>;
                dmas = <0x19 0x3 0x19 0x3>;
                interrupts = <0x0 0x72 0x4>;
                reg-shift = <0x2>;
                compatible = "nvidia,tegra186-hsuart";
                clock-names = "serial", "parent";
                reset-names = "serial";
                nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>;
                clocks = <0xd 0xd7 0xd 0x10d>;
                resets = <0xd 0x31>;
                nvidia,memory-clients = <0xe>;
                status = "okay";
                phandle = <0x85>;
                #stream-id-cells = <0x1>;
                dma-names = "rx", "tx";
                linux,phandle = <0x85>;
        };

# Now compile to dtb:
dtc -I dts -O dtb -o extracted_tx1-4.4.38-tegra.dtb

On the extracted R28.1 TX2 dts file this block is inserted immediately after “memory@80000000”. Copy the dtb file to “/boot”.

In extlinux.conf, add this FDT key/value pair before the APPEND line in an alternate boot entry:

FDT /boot/extracted_tx1-4.4.38-tegra.dtb

If this is correct, then “/dev/ttyTHS2” will work for connector J17 (which is also wired to the camera module, you might remove that for testing).

On the TX1 I believe the address you’re looking for is serial@70006200.

martingpu what release did you come from? Ever since upgrading to jetpack 3.0 on the TX1 I have found ttyTHS2 to be unreliable at high speeds (even when using flow control).

JetPack 3.0 worked fine for me. I’ve found these changes on serial@70006200 between 3.0 and 3.1.

JetPack 3.0 (24.2.1):

serial@70006200 {
		compatible = "nvidia,tegra114-hsuart";
		reg = <0x0 0x70006200 0x0 0x40>;
		reg-shift = <0x2>;
		interrupts = <0x0 0x2e 0x4>;
		nvidia,dma-request-selector = <0x5d 0xa>;
		iommus = <0x46 0xe>;
		dmas = <0x5d 0xa 0x5d 0xa>;
		dma-names = "rx", "tx";
		status = "okay";
	};

JetPack 3.1 (28.1.0):

serial@70006200 {
		compatible = "nvidia,tegra114-hsuart";
		reg = <0x0 0x70006200 0x0 0x40>;
		reg-shift = <0x2>;
		interrupts = <0x0 0x2e 0x4>;
		iommus = <0x52 0xe>;
		dmas = <0x6e 0xa 0x6e 0xa>;
		dma-names = "rx", "tx";
		clocks = <0x41 0x37 0x41 0xf3>;
		clock-names = "serial", "parent";
		resets = <0x41 0x37>;
		reset-names = "serial";
		nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>;
		status = "okay";
	};

Does anyone know what nvidia,adjust-baud-rates does?

I don’t know what “nvidia,adjust-baud-rates” is for, I am also curious.

The adjust-baud-rates field is used in the driver here:
[url]nv-tegra.nvidia Code Review - linux-4.4.git/blob - drivers/tty/serial/serial-tegra.c

I saw where the device tree parameters are stored, I just don’t know the significance of how it is used (which is somewhere else in the code…I’m interested in the behavior caused by the parameters).

Oh sorry I thought that was self evident from the driver. When a new baud rate is set the driver calls tegra_get_tolerance_rate if the clksrc is configurable. It just adjusts the baud rate slightly when it falls in a certain threshold.

I am still unable to write anything to ttyTHS2. any ideas?

Test both with and without CTS/RTS hardware flow control (unless of course you don’t have CTS/RTS wires…then you can’t test with hardware flow control).

Also, try wiring the connector’s TX to RX, and the connector’s CTS to RTS…then test if the connector can talk to itself (it’s loopback). If the terminal you type into echos, then you know your port is correctly set up with its current settings. After that test with an actual remote device on the connector (you could do a similar test on the remote end before connecting Jetson to remote end…then you’d know both serial UARTs are set the same).

Loopback is not working. The exact same connections an software running on Jetpack 3.0 is working perfectly. I think somehow something in the kernel is corrupted.

Are there any debug messages in “dmesg --follow” as you try to use the port? Also, what is the output from:

dmesg | egrep 'ttyTHS'

Also, what do you see from (mostly I’m interested in knowing if the port driver responds):

stty -a -F /dev/ttyTHS2