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  /* 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);
41 
42  serial_setbrg_dev(uart);
43 }
44 
45 static int exynos5_uart_err_check(struct s5p_uart *uart, int op)
46 {
47  unsigned int mask;
48 
49  /*
50  * UERSTAT
51  * Break Detect [3]
52  * Frame Err [2] : receive operation
53  * Parity Err [1] : receive operation
54  * Overrun Err [0] : receive operation
55  */
56  if (op)
57  mask = 0x8;
58  else
59  mask = 0xf;
60 
61  return read32(&uart->uerstat) & mask;
62 }
63 
64 /*
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.
68  */
69 static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart)
70 {
71  /* wait for character to arrive */
72  while (!(read32(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
74  if (exynos5_uart_err_check(uart, 0))
75  return 0;
76  }
77 
78  return read8(&uart->urxh) & 0xff;
79 }
80 
81 /*
82  * Output a single byte to the serial port.
83  */
84 static void exynos5_uart_tx_byte(struct s5p_uart *uart, unsigned char data)
85 {
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;
90  }
91 
92  write8(&uart->utxh, data);
93 }
94 
95 uintptr_t uart_platform_base(unsigned int idx)
96 {
97  if (idx < 4)
98  return 0x12c00000 + idx * 0x10000;
99  else
100  return 0;
101 }
102 
103 void uart_init(unsigned int idx)
104 {
105  struct s5p_uart *uart = uart_platform_baseptr(idx);
106  exynos5_init_dev(uart);
107 }
108 
109 unsigned char uart_rx_byte(unsigned int idx)
110 {
111  struct s5p_uart *uart = uart_platform_baseptr(idx);
112  return exynos5_uart_rx_byte(uart);
113 }
114 
115 void uart_tx_byte(unsigned int idx, unsigned char data)
116 {
117  struct s5p_uart *uart = uart_platform_baseptr(idx);
118  exynos5_uart_tx_byte(uart, data);
119 }
120 
121 void uart_tx_flush(unsigned int idx)
122 {
123  /* Exynos5250 implements this too. */
124 }
125 
126 void uart_fill_lb(void *data)
127 {
128  struct lb_serial serial;
130  serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
131  serial.baud = get_uart_baudrate();
132  serial.regwidth = 4;
133  serial.input_hertz = uart_platform_refclk();
134  serial.uart_pci_addr = 0;
135  lb_add_serial(&serial, data);
136 
138 }
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
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:45
static unsigned char exynos5_uart_rx_byte(struct s5p_uart *uart)
Definition: uart.c:69
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:84
#define RX_FIFO_FULL_MASK
Definition: uart.c:13
#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