Increase serial port baudrate

Hello.

I need to load u-boot and u-boot spl via uart, for some reason i can’t use sd or spi flash. But it takes too much time, because default uart baudrate is 115200.
What have I tried:

  1. change baudrate in u-boot menuconfig;
  2. change budrate u-boot envronment variable “baudrate”;
  3. stty -F /dev/ttyS0 921600 in linux.

And its works for raspberry pi 4, but not for visionfive2. Baudrate changed, but in terminal i see unprintable characters. I can only reduce baudrate below 115200, but not increase. I have tried some usb-to-serial devices and the problem is definitely not with them.

The JH7110Datasheet says: “Programmable baud rate generator supports up to 3 Mbps”.

Is it possible configure visionfive2’s uart to 1Mb baudrate?

1 Like

Hi, I too recently found the booting time to be way too long and wanted to increase the baudrate. With the default UART0 console, I managed to increase the SPL and U-Boot baud rate to 500000 baud.

There are two seperate UART transfer during recovery boot:

  1. The BootROM receives SPL using XMODEM.

  2. SPL receives u-boot.itb using YMODEM.

As far as i know, the BootROM UART downloader uses UART0 at 115200 baud, and there is no way around that. See JH-7110’s Boot Sources page and VisionFive2’s Recovering the Bootloader page

After the BootROM starts SPL; The baud rate can be specifed at build time using:

CONFIG_BAUDRATE

The default console for u-boot SPL and proper is also UART0 also at 115200 baud. See jh7110-common.dtsi

UART 0 to 5 are specified to be compatible with snps,dw-apb-uart which matches with U-Boot’s NS16550 driver (See ns16550.c)

Which calcualtes the integer UART divisor using ns16550_calc_divisor()

Giving this formula:

N = round( F_UART / (16 * B_requested))

The actual baud produced by UART becomes:

B_actual = F_uart / 16N

If the divisor (N) before rounding is not an integer, the UART produces the rate corresponding to that divisor rounded to nearest integer. Hence, It does not necessarily produce the requested rate.

UART0, UART1 and UART2 receive their core clock directly from the 24 MHz system oscillator. See StarFive’s JH7110 clock diagram

Therefore, for UART0–2:

B_actual = 24000000 / 16N = 1500000/N

where (N) is the UART’s integer divisor, gives:

Divisor (N) UART0 physical rate
1 1500000 baud
2 750000 baud
3 500000 baud
4 375000 baud
5 300000 baud
6 250000 baud
8 187500 baud
⁞ ⁞

The 2nd variable in actually being able to use UART0 at a higher baudrate is The host adapter must support the physical rate generated by the VF2.

In my case, the adapter is a CP2102. Its datasheet, Section 7 and Table 12, lists standard rates including:

500000
576000
921600

but not 750000 or 1500000. Hence, the highest directly matching documented rate is 500000

If an adapter can genuinely generate 750000, UART0 should also work at 750000. An adapter supporting 1500000 could theoretically use UART0’s highest exact rate.

When it comes to the 3 Mbps capability; StarFive’s UART documentation includes a note:

3 Mbps is supported by UART3, UART4 and UART5. Use the fraction in SYSTOP_CRG.

UART3–5 have a different input-clock path involving a fractional divider. Their internal UART still uses the same 16x integer-divisor formula, but the clock supplied to the UART can theoretically be adjusted so that a desired baud rate becomes possible.

Rates such as 921600 or 1 Mbaud may be possible by:

  1. Switching SPL and U-Boot’s console from UART0 to UART3, UART4 or UART5.
  2. Remultiplexing that UART onto exposed GPIO pins, potentially the same pins used by UART0.
  3. Configuring the UART3–5 core clock and fractional divider.
  4. Setting CONFIG_BAUDRATE to the intended rate.
  5. Configuring the host adapter to the same rate.

I havent attempted this tough, and the 500000 i achieved works well.

A bit late, but I hope this clarified things :slight_smile: