]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - board/nuvoton/common/uart.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2023 Nuvoton Technology Corp.
10 #include <linux/delay.h>
15 #define LCR_DLAB BIT(7)
17 void board_set_console(void)
19 const unsigned long baudrate_table
[] = CFG_SYS_BAUDRATE_TABLE
;
20 struct udevice
*dev
= gd
->cur_serial_dev
;
21 unsigned int baudrate
, max_delta
;
22 void __iomem
*uart_reg
;
33 uart_reg
= dev_read_addr_ptr(dev
);
34 ret
= clk_get_by_index(dev
, 0, &clk
);
38 uart_clk
= clk_get_rate(&clk
);
39 setbits_8(uart_reg
+ UART_LCR
, LCR_DLAB
);
40 dll
= readb(uart_reg
+ UART_DLL
);
41 dlm
= readb(uart_reg
+ UART_DLM
);
42 clrbits_8(uart_reg
+ UART_LCR
, LCR_DLAB
);
43 divisor
= dll
| (dlm
<< 8);
44 baudrate
= uart_clk
/ ((16 * (divisor
+ 2)));
45 for (i
= 0; i
< ARRAY_SIZE(baudrate_table
); ++i
) {
46 max_delta
= baudrate_table
[i
] / 20;
47 if (abs(baudrate
- baudrate_table
[i
]) < max_delta
) {
48 /* The baudrate is supported */
49 gd
->baudrate
= baudrate_table
[i
];
54 if (i
== ARRAY_SIZE(baudrate_table
)) {
55 /* current baudrate is not suitable, set to default */
56 divisor
= DIV_ROUND_CLOSEST(uart_clk
, 16 * gd
->baudrate
) - 2;
57 setbits_8(uart_reg
+ UART_LCR
, LCR_DLAB
);
58 writeb(divisor
& 0xff, uart_reg
+ UART_DLL
);
59 writeb(divisor
>> 8, uart_reg
+ UART_DLM
);
60 clrbits_8(uart_reg
+ UART_LCR
, LCR_DLAB
);
62 printf("\r\nUART(source %u): change baudrate from %u to %u\n",
63 uart_clk
, baudrate
, uart_clk
/ ((16 * (divisor
+ 2))));
66 debug("Set env baudrate=%u\n", gd
->baudrate
);
67 snprintf(string
, sizeof(string
), "ttyS0,%un8", gd
->baudrate
);
68 env_set("console", string
);