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
)
35 write32(&uart
->ufcon
, 0x1);
36 write32(&uart
->umcon
, 0);
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
)
52 * Frame Err [2] : receive operation
53 * Parity Err [1] : receive operation
54 * Overrun Err [0] : receive operation
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))
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))
92 write8(&uart
->utxh
, data
);
95 uintptr_t uart_platform_base(unsigned int idx
)
98 return 0x12c00000 + idx
* 0x10000;
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();