drivers/wifi: Remove unnecessary data structure copy
[coreboot2.git] / src / soc / samsung / exynos5250 / uart.c
blob7cd1d4671ab249b754b9a02045277fef3b85fe1c
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 // TODO initialize with correct peripheral id by base_port.
35 exynos_pinmux_uart3();
37 /* enable FIFOs */
38 write32(&uart->ufcon, 0x1);
39 write32(&uart->umcon, 0);
40 /* 8N1 */
41 write32(&uart->ulcon, 0x3);
42 /* No interrupts, no DMA, pure polling */
43 write32(&uart->ucon, 0x245);
45 serial_setbrg_dev(uart);
48 static int exynos5_uart_err_check(struct s5p_uart *uart, int op)
50 unsigned int mask;
53 * UERSTAT
54 * Break Detect [3]
55 * Frame Err [2] : receive operation
56 * Parity Err [1] : receive operation
57 * Overrun Err [0] : receive operation
59 if (op)
60 mask = 0x8;
61 else
62 mask = 0xf;
64 return read32(&uart->uerstat) & mask;
68 * Read a single byte from the serial port. Returns 1 on success, 0
69 * otherwise. When the function is successful, the character read is
70 * written into its argument c.
72 static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart)
74 /* wait for character to arrive */
75 while (!(read32(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
76 RX_FIFO_FULL_MASK))) {
77 if (exynos5_uart_err_check(uart, 0))
78 return 0;
81 return read8(&uart->urxh) & 0xff;
85 * Output a single byte to the serial port.
87 static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data)
89 /* wait for room in the tx FIFO */
90 while ((read32(&uart->ufstat) & TX_FIFO_FULL_MASK)) {
91 if (exynos5_uart_err_check(uart, 1))
92 return;
95 write8(&uart->utxh, data);
98 static void exynos5_uart_tx_flush(struct s5p_uart *uart)
100 while (read32(&uart->ufstat) & 0x1ff0000);
103 uintptr_t uart_platform_base(unsigned int idx)
105 if (idx < 4)
106 return 0x12c00000 + idx * 0x10000;
107 else
108 return 0;
111 void uart_init(unsigned int idx)
113 struct s5p_uart *uart = uart_platform_baseptr(idx);
114 exynos5_init_dev(uart);
117 unsigned char uart_rx_byte(unsigned int idx)
119 struct s5p_uart *uart = uart_platform_baseptr(idx);
120 return exynos5_uart_rx_byte(uart);
123 void uart_tx_byte(unsigned int idx, unsigned char data)
125 struct s5p_uart *uart = uart_platform_baseptr(idx);
126 exynos5_uart_tx_byte(uart, data);
129 void uart_tx_flush(unsigned int idx)
131 struct s5p_uart *uart = uart_platform_baseptr(idx);
132 exynos5_uart_tx_flush(uart);
135 enum cb_err fill_lb_serial(struct lb_serial *serial)
137 serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
138 serial->baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
139 serial->baud = get_uart_baudrate();
140 serial->regwidth = 4;
141 serial->input_hertz = uart_platform_refclk();
143 return CB_SUCCESS;