Platform: Jetson AGX Orin (T234, p3737+p3701), L4T R36.4.3, Kernel 5.15.148-tegra
- BACKGROUND - Original PIO Mode Issue (Before Any Modifications)
In stock L4T R36.4.3 with PIO mode (default configuration, no DMA enabled in device tree for serial@3110000):
Observed behavior:
- Transmit 18 bytes, expect 46-byte response
- Kernel logs show icount.rx=46 (kernel received 46 bytes)
- User space only receives 44 bytes (2 bytes lost in tty_flip_buffer_push timing)
- Success rate: ~99.5%, but 0.5% frame loss is unacceptable for industrial communication
Root cause identified: serial-tegra.c calls tty_insert_flip_string() but only calls tty_flip_buffer_push() at end of RX ISR. The 2-byte loss occurs when push() flushes partial data while more data is still being processed.
- ATTEMPTED FIX - Device Tree DMA Configuration
To solve PIO timing issues, we attempted to enable DMA mode by modifying device tree:
Changes made:
File 1: tegra234-p3737-0000+p3701-xxxx-nv-common.dtsi - board-level enable
serial@3110000 {
compatible = "nvidia,tegra194-hsuart";
reset-names = "serial";
status = "okay";
-
dmas = <&gpcdma 26>, <&gpcdma 27>; -
dma-names = "rx", "tx"; };
File 2: tegra234-soc-overlay.dtsi - serial@3110000 base definition
serial@3110000 {
compatible = "nvidia,tegra234-uart", "nvidia,tegra20-uart";
reg = <0x0 0x03110000 0x0 0x10000>;
...
-
iommus = <&smmu_niso0 TEGRA234_SID_GPCDMA>; -
dma-coherent; status = "disabled"; };
- CURRENT FAILURE - Both DMA and PIO Paths Broken
After above DT changes and kernel rebuild:
Issue A: RX DMA - No Data Transfer
DMA DEBUG: channel rx allocated successfully
DMA DEBUG: RX slave config: src=0x3110000, dst=0xffffffd0, width=1
// No “RX COMPLETE” callbacks - DMA never fires
- DMA channels allocate without error
- But no actual data transfer occurs
- kernel_rx_delta=0 during tests
Issue B: TX Data Corruption (Critical)
When DMA partially works, TX shows systematic 4-byte data shift:
Test sequence:
- Write 18 bytes: DB 10 04 00 BB 14 35 02 00 00 01 01 00 00 00 00 24 00
- First TX: 16 bytes sent correctly (db 10 04 00 bb 14 35 02…)
- Complete, tail=16, remaining 2 bytes in buffer
- Second write 18 bytes to buffer at tail=18
- Bug: Driver sees tail=18 (not 4-byte aligned) → triggers “alignment PIO”
- PIO sends 2 “alignment” bytes (which are actually valid frame data)
- tail advances to 20 (consumed 2 valid data bytes as “padding”)
- Subsequent DMA sends from offset 20: 04 00 bb 14 35 02… (shifted garbage)
Log evidence:
[ 290.065433] start_next_tx: tail_idx=0, count=18, align=0 → choosing DMA
[ 290.065438] TX: sending 16 bytes: db 10 04 00 bb 14 35 02… (OK)
[ 290.065469] TX COMPLETE: tail_after=16, head=18, pending=2
[ 290.566163] start_next_tx: tail_idx=18, align_needed=2 → choosing PIO for alignment
[ 290.566181] start_next_tx: tail_idx=20, count=16, align=0 → choosing DMA
[ 290.566187] TX: sending 16 bytes: 04 00 bb 14 35 02 00 00… (WRONG! Shifted by 4)
The 4-byte shift: tail jumps 18→20 (consumed 2 valid bytes) + next frame starts 4 bytes later than expected, causing the “04 00 bb 14” garbage data.