Patrick Georgi | ac95903 | 2020-05-05 22:49:26 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Hung-Te Lin | 7635a60 | 2013-02-12 00:07:38 +0800 | [diff] [blame] | 2 | |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 3 | #include <device/mmio.h> |
Kyösti Mälkki | bbf6f3d | 2014-03-15 01:32:55 +0200 | [diff] [blame] | 4 | #include <boot/coreboot_tables.h> |
Kyösti Mälkki | 1d7541f | 2014-02-17 21:34:42 +0200 | [diff] [blame] | 5 | #include <console/uart.h> |
David Hendricks | ff0d869 | 2017-12-28 20:18:10 -0800 | [diff] [blame] | 6 | #include <drivers/uart/pl011.h> |
Hung-Te Lin | 7635a60 | 2013-02-12 00:07:38 +0800 | [diff] [blame] | 7 | |
Felix Held | e3a1247 | 2020-09-11 15:47:09 +0200 | [diff] [blame] | 8 | void uart_init(unsigned int idx) |
Hung-Te Lin | 7635a60 | 2013-02-12 00:07:38 +0800 | [diff] [blame] | 9 | { |
Naresh Solanki | 5466261 | 2023-08-10 13:21:44 +0200 | [diff] [blame^] | 10 | struct pl011_uart *regs = uart_platform_baseptr(idx); |
| 11 | uint32_t tmp; |
| 12 | |
| 13 | if (!regs) |
| 14 | return; |
| 15 | |
| 16 | /* Disable UART */ |
| 17 | tmp = read32(®s->cr); |
| 18 | tmp &= ~PL011_UARTCR_UARTEN; |
| 19 | write32(®s->cr, tmp); |
| 20 | |
| 21 | /* |
| 22 | * Program Divisor |
| 23 | * As per: PL011 Technical reference manual: |
| 24 | * BAUDDIV = (Fuartclk / (16 * baud_rate)) |
| 25 | * Considering 6 bits(64) for UARTFBRD |
| 26 | * BAUDDIV = (Fuartclk * 4 / baud_rate) |
| 27 | */ |
| 28 | tmp = uart_platform_refclk() * 4 / get_uart_baudrate(); |
| 29 | |
| 30 | write32(®s->ibrd, tmp >> 6); |
| 31 | write32(®s->fbrd, tmp & 0x3f); |
| 32 | |
| 33 | /* Program LINE Control 8n1, FIFO enable */ |
| 34 | tmp = read32(®s->lcr_h); |
| 35 | tmp |= PL011_LINE_CONTROL; |
| 36 | write32(®s->lcr_h, tmp); |
| 37 | |
| 38 | /* Enable UART */ |
| 39 | tmp = read32(®s->cr); |
| 40 | tmp |= PL011_UARTCR_UARTEN | PL011_UARTCR_RXE | PL011_UARTCR_TXE; |
| 41 | write32(®s->cr, tmp); |
Hung-Te Lin | 7635a60 | 2013-02-12 00:07:38 +0800 | [diff] [blame] | 42 | } |
| 43 | |
Felix Held | e3a1247 | 2020-09-11 15:47:09 +0200 | [diff] [blame] | 44 | void uart_tx_byte(unsigned int idx, unsigned char data) |
Hung-Te Lin | 7635a60 | 2013-02-12 00:07:38 +0800 | [diff] [blame] | 45 | { |
David Hendricks | ff0d869 | 2017-12-28 20:18:10 -0800 | [diff] [blame] | 46 | struct pl011_uart *regs = uart_platform_baseptr(idx); |
| 47 | |
| 48 | write8(®s->dr, data); |
| 49 | uart_tx_flush(idx); |
Hung-Te Lin | 7635a60 | 2013-02-12 00:07:38 +0800 | [diff] [blame] | 50 | } |
| 51 | |
Felix Held | e3a1247 | 2020-09-11 15:47:09 +0200 | [diff] [blame] | 52 | void uart_tx_flush(unsigned int idx) |
Kyösti Mälkki | 7e75f20 | 2014-02-10 23:21:14 +0200 | [diff] [blame] | 53 | { |
David Hendricks | ff0d869 | 2017-12-28 20:18:10 -0800 | [diff] [blame] | 54 | struct pl011_uart *regs = uart_platform_baseptr(idx); |
| 55 | |
| 56 | /* FIXME: add a timeout */ |
| 57 | while (!(read32(®s->fr) & PL011_UARTFR_TXFE)) |
| 58 | ; |
Hung-Te Lin | 7635a60 | 2013-02-12 00:07:38 +0800 | [diff] [blame] | 59 | } |
Kyösti Mälkki | 0567c91 | 2014-02-14 10:31:38 +0200 | [diff] [blame] | 60 | |
Felix Held | e3a1247 | 2020-09-11 15:47:09 +0200 | [diff] [blame] | 61 | unsigned char uart_rx_byte(unsigned int idx) |
Kyösti Mälkki | 0567c91 | 2014-02-14 10:31:38 +0200 | [diff] [blame] | 62 | { |
Marcello Sylvester Bauer | 2423189 | 2018-04-11 15:55:02 +0200 | [diff] [blame] | 63 | struct pl011_uart *regs = uart_platform_baseptr(idx); |
| 64 | |
| 65 | while (read32(®s->fr) & PL011_UARTFR_RXFE) |
| 66 | ; |
| 67 | return read8(®s->dr); |
Kyösti Mälkki | 0567c91 | 2014-02-14 10:31:38 +0200 | [diff] [blame] | 68 | } |
Kyösti Mälkki | bbf6f3d | 2014-03-15 01:32:55 +0200 | [diff] [blame] | 69 | |
Arthur Heymans | 9948c52 | 2022-10-24 14:37:40 +0200 | [diff] [blame] | 70 | enum cb_err fill_lb_serial(struct lb_serial *serial) |
Kyösti Mälkki | bbf6f3d | 2014-03-15 01:32:55 +0200 | [diff] [blame] | 71 | { |
Arthur Heymans | 9948c52 | 2022-10-24 14:37:40 +0200 | [diff] [blame] | 72 | serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED; |
| 73 | serial->baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE); |
| 74 | serial->baud = get_uart_baudrate(); |
Arthur Heymans | e67513e | 2023-08-02 19:52:45 +0200 | [diff] [blame] | 75 | serial->regwidth = 4; |
Arthur Heymans | 9948c52 | 2022-10-24 14:37:40 +0200 | [diff] [blame] | 76 | serial->input_hertz = uart_platform_refclk(); |
Kyösti Mälkki | bbf6f3d | 2014-03-15 01:32:55 +0200 | [diff] [blame] | 77 | |
Arthur Heymans | 9948c52 | 2022-10-24 14:37:40 +0200 | [diff] [blame] | 78 | return CB_SUCCESS; |
Kyösti Mälkki | bbf6f3d | 2014-03-15 01:32:55 +0200 | [diff] [blame] | 79 | } |