docs: Add 24.12 release notes
[coreboot2.git] / src / soc / samsung / exynos5420 / uart.c
blobeb1d3f9fcac4d9f99175d9694662996cab00ff55
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <boot/coreboot_tables.h>
5 #include <console/uart.h>
6 #include <soc/clk.h>
7 #include <soc/cpu.h>
8 #include <soc/periph.h>
9 #include <soc/uart.h>
10 #include <types.h>
12 #define RX_FIFO_COUNT_MASK 0xff
13 #define RX_FIFO_FULL_MASK (1 << 8)
14 #define TX_FIFO_FULL_MASK (1 << 24)
16 static void serial_setbrg_dev(struct s5p_uart *uart)
18 u32 uclk;
19 u32 val;
21 // All UARTs share the same clock.
22 uclk = clock_get_periph_rate(PERIPH_ID_UART3);
23 val = uclk / get_uart_baudrate();
25 write32(&uart->ubrdiv, val / 16 - 1);
29 * Initialise the serial port with the given baudrate. The settings
30 * are always 8 data bits, no parity, 1 stop bit, no start bits.
32 static void exynos5_init_dev(struct s5p_uart *uart)
34 /* enable FIFOs */
35 write32(&uart->ufcon, 0x1);
36 write32(&uart->umcon, 0);
37 /* 8N1 */
38 write32(&uart->ulcon, 0x3);
39 /* No interrupts, no DMA, pure polling */
40 write32(&uart->ucon, 0x245);
42 serial_setbrg_dev(uart);
45 static int exynos5_uart_err_check(struct s5p_uart *uart, int op)
47 unsigned int mask;
50 * UERSTAT
51 * Break Detect [3]
52 * Frame Err [2] : receive operation
53 * Parity Err [1] : receive operation
54 * Overrun Err [0] : receive operation
56 if (op)
57 mask = 0x8;
58 else
59 mask = 0xf;
61 return read32(&uart->uerstat) & mask;
65 * Read a single byte from the serial port. Returns 1 on success, 0
66 * otherwise. When the function is successful, the character read is
67 * written into its argument c.
69 static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart)
71 /* wait for character to arrive */
72 while (!(read32(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
73 RX_FIFO_FULL_MASK))) {
74 if (exynos5_uart_err_check(uart, 0))
75 return 0;
78 return read8(&uart->urxh) & 0xff;
82 * Output a single byte to the serial port.
84 static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data)
86 /* wait for room in the tx FIFO */
87 while ((read32(&uart->ufstat) & TX_FIFO_FULL_MASK)) {
88 if (exynos5_uart_err_check(uart, 1))
89 return;
92 write8(&uart->utxh, data);
95 uintptr_t uart_platform_base(unsigned int idx)
97 if (idx < 4)
98 return 0x12c00000 + idx * 0x10000;
99 else
100 return 0;
103 void uart_init(unsigned int idx)
105 struct s5p_uart *uart = uart_platform_baseptr(idx);
106 exynos5_init_dev(uart);
109 unsigned char uart_rx_byte(unsigned int idx)
111 struct s5p_uart *uart = uart_platform_baseptr(idx);
112 return exynos5_uart_rx_byte(uart);
115 void uart_tx_byte(unsigned int idx, unsigned char data)
117 struct s5p_uart *uart = uart_platform_baseptr(idx);
118 exynos5_uart_tx_byte(uart, data);
121 void uart_tx_flush(unsigned int idx)
123 /* Exynos5250 implements this too. */
126 enum cb_err fill_lb_serial(struct lb_serial *serial)
128 serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
129 serial->baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
130 serial->baud = get_uart_baudrate();
131 serial->regwidth = 4;
132 serial->input_hertz = uart_platform_refclk();
134 return CB_SUCCESS;