1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <boot/coreboot_tables.h>
5 #include <console/uart.h>
8 #include <soc/periph.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
)
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();
38 write32(&uart
->ufcon
, 0x1);
39 write32(&uart
->umcon
, 0);
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
)
55 * Frame Err [2] : receive operation
56 * Parity Err [1] : receive operation
57 * Overrun Err [0] : receive operation
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))
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))
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
)
106 return 0x12c00000 + idx
* 0x10000;
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();