UART support for 9 Mbaud rate

From the HiKey960_SoC_Reference_Manual.pdf :
“UART6 supports up to 1.2 Mbaud rate, and the other UARTs support up to 9 Mbaud rate.”

I am planning to drive UART3 to baudrate of 9000000 and have couple questions:

  1. UART3 on low expansion connector supports upto 9 MBauds. Is this correct ?
  2. Does the AMBA PL011 Serial driver support 9M baudrate ?

According to the spec yes.

I’ve never tried, but 9M is a non standard baudrate so you will have to specify BOTHER cflag ( termios-> c_cflag).

Thanks for the quick pointers Loic.

For experiment, I added baudrate support for 8M to termbits.h and tty_baudrate.c and found below observations:

  1. 8M baud gets clipped to 115200.
  2. max baudrate allowed at pl011_set_termios() is 6250000

[ 13.128483] serial serial0: ttyport_set_baudrate speed:8000000
[ 13.134393] tty_termios_encode_baud_rate: speed: i=8000000 0=8000000
[ 13.141150] tty_termios_baud_rate rate: 115200
[ 13.156407] pl011_set_termios: baud:115200 max:6250000

Is there a reason to lock max baud at 6.25M ? BTW does 8M need BOTHER flag as well ?

Thanks again for your support.

The baudrate is also limited by the UART controller clock which is internally divided by 16 to generate the transmit clock (cf pl011 spec). With your result, that would mean the UART controller is fed with a 100MHz clock (6.25 * 16).

On the other side, looking deeper in hisilicon clock driver [1] we can see that:
UART3_CLK = CLK_PPLL0 / 16
CLK_PLL0 is defined at a fixed at 1600000000 (HZ) which gives 100MHz for UART3_CLK, matching the prediction.

So this explains the limitation. Now if you really want to reach 9Mb/s I assume this is a request for hisilicon (I suppose ‘fixed’ clock can be configured from bootloader).

[1] https://elixir.bootlin.com/linux/v4.20.17/source/drivers/clk/hisilicon/clk-hi3660.c#L21

If the baudrate is not in the following list, you need to use BOTHER (baudrate other).

B57600
B115200
B230400
B460800
B500000
B576000
B921600
B1000000
B1152000
B1500000
B2000000
B2500000
B3000000
B3500000
B4000000

Thanks for your help Loic.

I am not too familiar with this but this check-in reduced UART3 clock to half the speed. If the h/w specs is to be true, clock divisor should be 8 ?

Do you mean CLK_PPLL0 can be bumped up only from the bootloader ?

Thanks for the pointer. I could run my UART device upto 6M with this flag on. The goal however stays at 8M :slight_smile:

Is the hikey960 bootloader code this one ?
https://android.googlesource.com/device/linaro/bootloader/arm-trusted-firmware/+/refs/heads/master

Would you be able to guide how do I go about changing the fixed clock ?

From the PL011 UART Technical Reference Manual, it appears baud rate is controlled by Integer Baud Rate Register (UARTIBRD) and Fractional Baud Rate Register (UARTFBRD) which are set as below from the bootloader. I am not sure if I should go down playing with these to achieve 8Mbaud. Any pointers will be very helpful.

./include/drivers/arm/pl011.h:22:#define UARTIBRD                  0x024
./include/drivers/arm/pl011.h:23:#define UARTFBRD                  0x028

Thank you.