coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
uart.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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>
11 
12 #define RX_FIFO_COUNT_MASK 0xff
13 #define RX_FIFO_FULL_MASK (1 << 8)
14 #define TX_FIFO_FULL_MASK (1 << 24)
15 
16 static void serial_setbrg_dev(struct s5p_uart *uart)
17 {
18  u32 uclk;
19  u32 val;
20 
21  // All UARTs share the same clock.
23  val = uclk / get_uart_baudrate();
24 
25  write32(&uart->ubrdiv, val / 16 - 1);
26 }
27 
28 /*
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.
31  */
32 static void exynos5_init_dev(struct s5p_uart *uart)
33 {
34  // TODO initialize with correct peripheral id by base_port.
36 
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);
44 
45  serial_setbrg_dev(uart);
46 }
47 
48 static int exynos5_uart_err_check(struct s5p_uart *uart, int op)
49 {
50  unsigned int mask;
51 
52  /*
53  * UERSTAT
54  * Break Detect [3]
55  * Frame Err [2] : receive operation
56  * Parity Err [1] : receive operation
57  * Overrun Err [0] : receive operation
58  */
59  if (op)
60  mask = 0x8;
61  else
62  mask = 0xf;
63 
64  return read32(&uart->uerstat) & mask;
65 }
66 
67 /*
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.
71  */
72 static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart)
73 {
74  /* wait for character to arrive */
75  while (!(read32(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
77  if (exynos5_uart_err_check(uart, 0))
78  return 0;
79  }
80 
81  return read8(&uart->urxh) & 0xff;
82 }
83 
84 /*
85  * Output a single byte to the serial port.
86  */
87 static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data)
88 {
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;
93  }
94 
95  write8(&uart->utxh, data);
96 }
97 
98 static void exynos5_uart_tx_flush(struct s5p_uart *uart)
99 {
100  while (read32(&uart->ufstat) & 0x1ff0000);
101 }
102 
103 uintptr_t uart_platform_base(unsigned int idx)
104 {
105  if (idx < 4)
106  return 0x12c00000 + idx * 0x10000;
107  else
108  return 0;
109 }
110 
111 void uart_init(unsigned int idx)
112 {
113  struct s5p_uart *uart = uart_platform_baseptr(idx);
114  exynos5_init_dev(uart);
115 }
116 
117 unsigned char uart_rx_byte(unsigned int idx)
118 {
119  struct s5p_uart *uart = uart_platform_baseptr(idx);
120  return exynos5_uart_rx_byte(uart);
121 }
122 
123 void uart_tx_byte(unsigned int idx, unsigned char data)
124 {
125  struct s5p_uart *uart = uart_platform_baseptr(idx);
126  exynos5_uart_tx_byte(uart, data);
127 }
128 
129 void uart_tx_flush(unsigned int idx)
130 {
131  struct s5p_uart *uart = uart_platform_baseptr(idx);
132  exynos5_uart_tx_flush(uart);
133 }
134 
135 void uart_fill_lb(void *data)
136 {
137  struct lb_serial serial;
139  serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
140  serial.baud = get_uart_baudrate();
141  serial.regwidth = 4;
142  serial.input_hertz = uart_platform_refclk();
143  serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
144  lb_add_serial(&serial, data);
145 
147 }
static void write8(void *addr, uint8_t val)
Definition: mmio.h:30
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
static uint8_t read8(const void *addr)
Definition: mmio.h:12
unsigned int get_uart_baudrate(void)
Definition: bmcinfo.c:167
#define LB_TAG_CONSOLE_SERIAL8250MEM
#define LB_SERIAL_TYPE_MEMORY_MAPPED
@ PERIPH_ID_UART3
Definition: periph.h:17
void lb_add_console(uint16_t consoletype, void *data)
void lb_add_serial(struct lb_serial *serial, void *data)
static void * uart_platform_baseptr(unsigned int idx)
Definition: uart.h:57
unsigned int serial
Definition: edid.c:52
void uart_init(unsigned int idx)
Definition: uart.c:13
void uart_tx_flush(unsigned int idx)
Definition: uart.c:27
uintptr_t uart_platform_base(unsigned int idx)
Definition: uart.c:8
unsigned char uart_rx_byte(unsigned int idx)
Definition: uart.c:17
void uart_fill_lb(void *data)
Definition: uart.c:31
void uart_tx_byte(unsigned int idx, unsigned char data)
Definition: uart.c:22
void exynos_pinmux_uart3(void)
Definition: pinmux.c:32
unsigned int uart_platform_refclk(void)
Definition: uart.c:85
static const int mask[4]
Definition: gpio.c:308
unsigned long clock_get_periph_rate(enum periph_id peripheral)
get the clk frequency of the required peripheral
Definition: clock.c:220
static void exynos5_init_dev(struct s5p_uart *uart)
Definition: uart.c:32
static int exynos5_uart_err_check(struct s5p_uart *uart, int op)
Definition: uart.c:48
static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart)
Definition: uart.c:72
static void serial_setbrg_dev(struct s5p_uart *uart)
Definition: uart.c:16
#define TX_FIFO_FULL_MASK
Definition: uart.c:14
static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data)
Definition: uart.c:87
#define RX_FIFO_FULL_MASK
Definition: uart.c:13
static void exynos5_uart_tx_flush(struct s5p_uart *uart)
Definition: uart.c:98
#define RX_FIFO_COUNT_MASK
Definition: uart.c:12
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
Definition: uart.h:6
unsigned int uerstat
Definition: uart.h:12
unsigned int ubrdiv
Definition: uart.h:19
unsigned int ufstat
Definition: uart.h:13
unsigned char urxh
Definition: uart.h:17
unsigned int ulcon
Definition: uart.h:7
unsigned char utxh
Definition: uart.h:15
unsigned int ucon
Definition: uart.h:8
unsigned int ufcon
Definition: uart.h:9
unsigned int umcon
Definition: uart.h:10
u8 val
Definition: sys.c:300