| 442 | #endif |
| 443 | |
| 444 | static void uart_set_baudrate(uart_port_t uart_port, uint32_t baudrate) |
| 445 | { |
| 446 | size_t uart_base; |
| 447 | uint32_t quot, uart_clk; |
| 448 | uint8_t lcr; |
| 449 | |
| 450 | uart_base = SUNXI_UART0_BASE + uart_port * 0x400; |
| 451 | uart_clk = 24000000; /* FIXME: fixed to 24MHz */ |
| 452 | |
| 453 | quot = (uart_clk + 8 * baudrate) / (16 * baudrate); |
| 454 | |
| 455 | lcr = hal_readb(uart_base + UART_LCR); |
| 456 | |
| 457 | /* hold tx so that uart will update lcr and baud in the gap of tx */ |
| 458 | hal_writeb(UART_HALT_HTX | UART_HALT_FORCECFG, uart_base + UART_HALT); |
| 459 | hal_writeb(lcr | UART_LCR_DLAB, uart_base + UART_LCR); |
| 460 | hal_writeb(quot >> 8, uart_base + UART_DLH); |
| 461 | hal_writeb(quot & 0xFFu, uart_base + UART_DLL); |
| 462 | hal_writeb(UART_HALT_HTX | UART_HALT_FORCECFG | UART_HALT_LCRUP, uart_base + UART_HALT); |
| 463 | /* FIXME: implement timeout */ |
| 464 | while (hal_readb(uart_base + UART_HALT) & UART_HALT_LCRUP) |
| 465 | ; |
| 466 | |
| 467 | /* In fact there are two DLABs(DLAB and DLAB_BAK) in the hardware implementation. |
| 468 | * The DLAB_BAK is sellected only when SW_UART_HALT_FORCECFG is set to 1, |
| 469 | * and this bit can be access no matter uart is busy or not. |
| 470 | * So we select the DLAB_BAK always by leaving SW_UART_HALT_FORCECFG to be 1. */ |
| 471 | hal_writeb(lcr, uart_base + UART_LCR); |
| 472 | hal_writeb(UART_HALT_FORCECFG, uart_base + UART_HALT); |
| 473 | } |
| 474 | |
| 475 | static void uart_set_format(uart_port_t uart_port, uint8_t data_bits, uint8_t stop_bits, uint8_t parity) |
| 476 | { |