Setup UART clock to get maximum baud rate

Hello everyone,

I’d like to test UARTs at maximum possible baud rate.
Default device tree (imx7-colibri.dtsi) provides this configuration for UART1:

&uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1 &pinctrl_uart1_ctrl2>;
        assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
        assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
        uart-has-rtscts;
        fsl,dte-mode;
};

With IMX7D_OSC_24M_CLK I can run the UART at maximum 1.5Mbps. (24MHz/16 = 1.5Mbps)
I would like to setup the reference clock at SYS_PLL (480MHz) with a div x6 to reach 80MHz (maximum accepted for UART).

In my custom device tree I tried this without success:

&uart1 {
        assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
        assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_CLK>;
        assigned-clock-rates = <80000000>;
};

I got this error

~# dmesg | grep uart                                                                                                          
[    1.271156] imx-uart 30860000.serial: clk_set_rate() failed
[    1.278506] imx-uart: probe of 30860000.serial failed with error -16

How can I set CCM (source clock, pre_div, post_div, ecc) in the correct way?

Thank you in advance,

Luca

Dear @lupo

I think 80MHz is not supported by the controller at all. In the datasheet (https://www.nxp.com/docs/en/data-sheet/IMX7DCEC.pdf page 14) they say “Programmable baud rates up to 4 Mbps”.

Would 4Mbps be enough for your usecase? Do you really want to use RS232 for such high speeds? If so why?

Regards,
Stefan

Dear @stefan_e.tx ,

I spoke about 80 MHz since in the IMX7DRM document at chapter 5.2 Clock Control Module the UART1_CLK_ROOT must have a maximum clock frequency of 80 MHz.
1825-clock.jpg

However, 4 Mbps is good for my tests.
I would like to test the maximum baud rate and understand if eventually evaluate an external SPI/I2C - UART chip for our custom carrier board.

How can I setup a baud rate of 4Mbps?

Regards,

Luca

Dear @lupo

It looks like the driver is not ready for the other clock roots. Maybe the following patch will work:
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index ee90d117df571…1335286821b74 100644
— a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -188,7 +188,7 @@

 #define UART_NR 8
 #define IMX_RXBD_NUM 20
-#define IMX_MODULE_MAX_CLK_RATE        80000000
+#define IMX_MODULE_MAX_CLK_RATE        240000000

 /* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */
 enum imx_uart_type {
@@ -2179,6 +2179,7 @@ static int serial_imx_probe(struct platform_device *pdev)
        }

        sport->port.uartclk = clk_get_rate(sport->clk_per);

It will then accept “assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;”. However, I couldn’t test higher baud rates because of lacking setup. At least 115200 still seem to work.

Please also note that you have to use the flag CBAUDEX to set such high baud rates:

Regards,
Stefan

Dear @stefan_e.tx ,

I tried to apply your change but the problem is still present

~# dmesg | grep uart
[    1.273747] imx-uart 30890000.serial: clk_set_rate() failed
[    1.281100] imx-uart: probe of 30890000.serial failed with error -16

Maybe I’m missing something.
Have you also modified line 2179?

Luca

Hi @lupo

I think the SYS_PLL is at 480 MHz, did you change the devicetree to “assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;” as well?
This was basically the only change. And it should only appear when uart clock ist > IMX_MODULE_MAX_CLK_RATE MHz…

Regards,
Stefan

Dear @stefan_e.tx,

Sorry, my fault! I had a compilation error.
Now it works, and on startup I can see this

  [0.557122] 30860000.serial: ttymxc0 at MMIO 0x30860000 (irq = 54, base_baud = 1500000) is a IMX
  [1.266989] console [ttymxc0] enabled
  [1.273535] 30890000.serial: ttymxc1 at MMIO 0x30890000 (irq = 55, base_baud = 15000000) is a IMX
  [1.286914] 30880000.serial: ttymxc2 at MMIO 0x30880000 (irq = 56, base_baud = 15000000) is a IMX

UART2 and UART3 now have a base baud of 15000000 = (240MHz/16)

I tested the UART1 in loopback (connecting TX with RX) with baud rate at 4Mbps:

~# ./i.MX7-Test -b 4000000 -p /dev/ttymxc1 -s
Linux serial test app
/dev/ttymxc1: count for this session: rx=2187754, tx=2190825, rx err=0
/dev/ttymxc1: TIOCGICOUNT: ret=0, rx=11539677, tx=115710370, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 0
/dev/ttymxc1: count for this session: rx=4435909, tx=4438980, rx err=0
/dev/ttymxc1: TIOCGICOUNT: ret=0, rx=13787832, tx=117958525, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 0
/dev/ttymxc1: count for this session: rx=6701468, tx=6707610, rx err=0
/dev/ttymxc1: TIOCGICOUNT: ret=0, rx=16055438, tx=120226131, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 0

Every 5 sec ~2.2/2.3 MByte of data has been trasmitted, so the UART can reach a speed of ~3.6Mbps.

Thank you for your support.

Luca

Great, thanks for the feedback!

Hi @stefan_e.tx @lupo ,
We are trying to check throughput getting below logs (error setting 232, no data received). Is this correct how to calculate throughput? for Loopback test do I need to cross cross RX-TX TTL signals?

Linux serial test app
Error setting RS-232 mode: Not a typewriter
/dev/ttyLP1: count for this session: rx=2039296, tx=2041849, rx err=0
/dev/ttyLP1: TIOCGICOUNT: ret=0, rx=6062334, tx=28786829, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 0
/dev/ttyLP1: count for this session: rx=4439168, tx=4442853, rx err=0
/dev/ttyLP1: TIOCGICOUNT: ret=0, rx=10862078, tx=31186716, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 0
/dev/ttyLP1: No data received for 5.0s.

Thanks
AMR

Hi @abdulmohamed

Could you ask a new question with providing all the information needed to reproduce the error?

Thanks and best regards,
Jaski

sure @jaski.tx

Thanks very much.

https://www.toradex.com/community/questions/63632/uart-throughput.html?childToView=63685#answer-63685

Created as we discussed. Please help

Thanks. Yeah we will continue the discussion there.