I am using a Jetson Orin Nano Developer Kit (JetPack 6.x) and I would like to use one of the UART ports for high-speed communication with an external real-time controller.
However, I found inconsistent information regarding the maximum supported UART baud rate.
The latest Jetson Orin Nano Series Data Sheet (DS-11105-001 v1.7) states in the document history:
“UART block frequency from 200 MHz to 68 MHz and baud rate from 12.5 Mbps to 4.25 Mbps.”
So it seems that the official maximum UART baud rate for Orin Nano is 4.25 Mbps.
However, I also found:
older Orin datasheets mentioning 12.5 Mbps
forum discussions mentioning that the UART controller supports 12.5 Mbaud
discussions about using custom baud rates with termios2 (BOTHER).
My questions are:
For the Jetson Orin Nano Developer Kit, what is the actual hardware maximum UART baud rate?
Is 4.25 Mbps a hardware limitation or only the officially validated value?
Is it possible to configure 10 Mbps UART using termios2/BOTHER, or is that beyond the capability of the UART hardware?
Has anyone successfully used UART above 4.25 Mbps on Orin Nano?
Long ago there was a discovery that the clock used with the UART was slightly out of tolerance. The design was inherited from long ago when people did not normally use the higher rates. As a result, some of the higher end rates only worked if there were settings which allowed for better tolerance of those higher rates. This included use of CTS/RTS and two stop bits. With those I think the baud rate approached the higher numbers to around 10 Mbps, but not 12. All of this is from memory though so I couldn’t tell you specifics.
People have often used a separate USB UART for this reason, especially if the device they were communicating with could not enable CTS/RTS or two stop bits.
On Jetson Orin Nano Developer Kit with standard JetPack/L4T configuration, the practical supported UART maximum should be treated as 4.25 Mbps.
The earlier 12.5/12.75 Mbaud references reflect T234 UART IP capability or special internal validation/override cases, not the default product configuration on general UARTs.
Therefore, using termios2/BOTHER does not make 10 Mbps supported if the underlying UART clock remains limited to 68 MHz.
The kernel identifies serial@3100000 and serial@3140000 as TEGRA_UART, while serial@31d0000 is identified as an SBSA UART.
I also noticed that in the default device tree, only serial@3100000 has a pinctrl configuration, while I could not find a pinctrl entry for serial@3140000 or serial@31d0000.
Therefore, I understand that the two TEGRA UART interfaces are limited to 4.25 Mbps because:
68 MHz / 16 = 4.25 Mbps
However, UART-I at serial@31d0000 appears to support a maximum clock of 204 MHz, which would theoretically correspond to:
204 MHz / 16 = 12.75 Mbps
Could you please confirm:
Can UART-I (serial@31d0000, /dev/ttyAMA0) be used for 10 Mbps communication on the Jetson Orin Nano Developer Kit?
Is UART-I physically routed to any accessible pins on the standard developer kit carrier board?
Is a pinmux/device-tree modification required to use UART-I externally?
Under my current standard JetPack/L4T configuration and without modifying the device tree or pinmux, does this mean that I can only use serial@3100000 as an externally accessible UART, with a maximum supported baud rate of 4.25 Mbps?
From the current Jetson Orin Nano Developer Kit documentation, the externally documented UART interfaces are the J14 debug UART and the 40-pin header UART. At this time, I do not see documentation confirming that UART-I (serial@31d0000, /dev/ttyAMA0) is routed to an external connector on the standard developer kit carrier board.
So under the default JetPack/L4T configuration, /dev/ttyAMA0 should not be assumed to be a supported external 10 Mbps UART. Using UART-I externally would require board-routing and pinmux/device-tree confirmation.
So, for the externally available UART on the Jetson Orin Nano Developer Kit, should I assume that the practical maximum supported baud rate is about 4.25 Mbps?
Also, do you agree with the suggestion below to use an external PCIe UART through an M.2 slot for higher baud rates? I noticed that the M.2 slots on the Developer Kit are mainly intended for NVMe SSDs. Is this approach actually practical and officially supported?
May I ask if you have actually implemented this solution on the Jetson Orin Nano Developer Kit?
Specifically:
Which PCIe UART board did you use?
Which M.2 slot did you connect it to (Key-M or Key-E)?
Was it plug-and-play under JetPack/Linux, or did you need to modify the device tree or compile a custom driver?
Were you able to achieve a stable 10 Mbps UART communication?
I would really appreciate any practical experience or hardware recommendations.
I’ve developed several PCIe addons for NVidia systems, but not this specific chip. I’ve used some MaxLinear chip on an M.2 Type E card, but these ports didn’t need to be fast. That card was used in a ConnectTech board for Xavier NX. So no, I can’t send you a ready-to-use solution, but based on my experience that solution should work.
What I can say:
The Diodes/Pericom PCIe UARTs should be detected by the Linux 8250_PCI kernel module out of the box. You may need to tweak module command line parameters in order to match the clock frequency to the hardware.
NVidia does not include all kernel modules that are present for example on a Debian or Ubuntu Linux on PC hardware. You might need to compile the module on the Jetson hardware.
There is absolutely nothing NVidia specific in this solution. If you are going to design a board it might be easier to test on PC hardware first since the kernel modules are there out of the box.
Since this is a PCIe solution you don’t need to mess with device trees. PCIe is auto-config. The bus driver scans the bus, firnds the chip and loads the module that matches vendor/device id.
The chip needs a baud rate crystal. The default value is good for the standard baud rate (300,1200, 38400,115200), but you need a faster one for higher speeds. The datasheet says you can go up to 60 MHz. You need to calculate a suitable value in order to get 10 MHz bit rate. Instead of a crystal you also can (and i recommend this) use a crystal oscillator.
The UART chip only uses a single lane. If the Type E slot is available it makes sense to design for this. otherwise you can also use a Type M slot and leave the other lanes unused.
Hope that helps.
Linux should have a suitable kernel driver. You don’t need to
Yes, for the externally available UART on the standard Jetson Orin Nano Developer Kit, you should assume the practical maximum baud rate is about 4.25 Mbps.
As for using an external PCIe UART through the M.2 slot, the current Developer Guide describes the two PCIe slots on the developer kit as slots for NVMe storage devices. So I would not describe a PCIe UART card over M.2 as an officially supported standard developer-kit solution.
If higher UART bandwidth is required, that would be more of a custom hardware approach rather than the documented default path on the standard developer kit.
Is there any technical reason? PCIe is PCIe, and the device class I plug in should’t matter except for driver reasons. I’ve used PCIe high-speed cameras (Ximea), CamLink frame grabbers (Epix), Magewell SDI framegrabbers, Intel/Realtek Ethernet cards, Hailo AI accelerators and many more on Jetson Devkits for the last 9 years, and I didn’t have any issues except for incompatible firmware on Intel i210 with TX1/TX2 boards.
Yes, I agree it is technically possible.
PCIe itself is not limited by device type, so a PCIe UART device may work if the hardware and Linux driver support are in place.
My earlier point was only that, in the current Jetson Orin Nano Developer Kit documentation, the M.2 PCIe slots are described as NVMe slots, so this would be considered a custom solution rather than a standard documented UART path on the devkit.
I implemented a UART loopback test on the Jetson Orin Nano Developer Kit using /dev/ttyTHS1 (TX connected directly to RX). The UART is configured with termios2 + BOTHER, and TCGETS2 confirms that the driver accepts the requested baud rate.
The test procedure is:
Configure the UART with the requested baud rate.
Start a receiver thread before transmission.
Transmit a fixed-size buffer (65536 bytes).
Call tcdrain() after write().
Measure:
TX time = from before write() until tcdrain() returns.
RX time = from the first received byte until the last received byte.
Estimate the baud rate from:
baud ≈ transmitted_bits / measured_time
The measured results are:
Requested baud
Measured result
150000
approximately 150 kbaud
1250000
approximately 1.23–1.24 Mbaud
2000000
approximately 1.91–1.96 Mbaud
2300000
approximately 2.25–2.30 Mbaud
At lower baud rates, the measured rate closely matches the requested value. However, once the requested baud exceeds about 2.5–2.7 Mbaud, the measured throughput seems to saturate around 2.6 Mbaud, even though:
TCGETS2 reports 4250000 baud,
all transmitted bytes are received correctly,
no data corruption occurs.
The result shown above was obtained with a C implementation. I repeated the test using Python and pySerial, and the measured throughput again saturated at approximately 2.5–2.6 Mbps.
From the Jetson documentation and your previous reply, I understand that the theoretical maximum UART baud rate should be around 4.25 Mbps.
My questions are:
Is there any known hardware or driver limitation that would explain why the measured throughput saturates around 2.6 Mbps?
Is there a recommended way from NVIDIA to verify the actual physical UART baud rate on Jetson (for example using specific registers or only an oscilloscope)?
Is it possible to achieve 4–4.25 Mbps on /dev/ttyTHS1 in loopback mode? If so, are there additional UART, DMA, FIFO, clock, or driver settings that need to be configured? Or what should I check?
Do you have an oscilloscope which can view the actual data TX and RX? It should be that period is about equal to 1/baud.
Possibility one is that the data rate is correct, but the system is not sending or receiving fast enough, and possibility two is that actual data rate slowed (or perhaps a mix, but it should be more obvious if the baud and period are approximately matching). The programmed clock rate won’t be a good test unless you know what divider is being used, although baud versus period might tell you if something is significantly “off” from what it should be.
I do not think this points to a hard UART limit at 2.6 Mbaud.
We have seen /dev/ttyTHS1 loopback run at 3.6864 Mbaud with 0 errors, and we have also verified 4 Mbaud in loopback on Jetson. So if your result always saturates around 2.5–2.6 Mbaud, it is more likely related to the test method or software timing than to an actual UART baud ceiling.
In particular, measuring from write() to tcdrain(), or from first RX byte to last RX byte, does not directly measure the physical UART line rate because it also includes software scheduling and buffering effects.
If you want to verify the real baud on the wire, please check the TX signal directly with an oscilloscope or logic analyzer. You can also try a simpler loopback test with RTS/CTS connected if hardware flow control is enabled.