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>
7 #include <stdint.h>
8 
9 #include <soc/addressmap.h>
10 #include <soc/pll.h>
11 
12 struct mtk_uart {
13  union {
14  uint32_t thr; /* Transmit holding register. */
15  uint32_t rbr; /* Receive buffer register. */
16  uint32_t dll; /* Divisor latch lsb. */
17  };
18  union {
19  uint32_t ier; /* Interrupt enable register. */
20  uint32_t dlm; /* Divisor latch msb. */
21  };
22  union {
23  uint32_t iir; /* Interrupt identification register. */
24  uint32_t fcr; /* FIFO control register. */
25  uint32_t efr; /* Enhanced feature register. */
26  };
27  uint32_t lcr; /* Line control register. */
28  union {
29  uint32_t mcr; /* Modem control register. */
30  uint32_t xn1; /* XON1 */
31  };
32  union {
33  uint32_t lsr; /* Line status register. */
34  uint32_t xn2; /* XON2 */
35  };
36  union {
37  uint32_t msr; /* Modem status register. */
38  uint32_t xf1; /* XOFF1 */
39  };
40  union {
41  uint32_t scr; /* Scratch register. */
42  uint32_t xf2; /* XOFF2 */
43  };
44  uint32_t autobaud_en; /* Enable auto baudrate. */
45  uint32_t highspeed; /* High speed UART. */
47 
48 /* Peripheral Reset and Power Down registers */
65 } __packed;
66 
67 static struct mtk_uart *const uart_ptr = (void *)UART0_BASE;
68 
69 static void mtk_uart_tx_flush(void);
70 static int mtk_uart_tst_byte(void);
71 
72 static void mtk_uart_init(void)
73 {
74  /* Use a hardcoded divisor for now. */
75  const unsigned int uartclk = UART_HZ;
76  const unsigned int baudrate = get_uart_baudrate();
77  const uint8_t line_config = UART8250_LCR_WLS_8; /* 8n1 */
78  unsigned int highspeed, quot, divisor, remainder;
79 
80  if (baudrate <= 115200) {
81  highspeed = 0;
82  quot = 16;
83  } else {
84  highspeed = 2;
85  quot = 4;
86  }
87 
88  /* Set divisor DLL and DLH */
89  divisor = uartclk / (quot * baudrate);
90  remainder = uartclk % (quot * baudrate);
91 
92  if (remainder >= (quot / 2) * baudrate)
93  divisor += 1;
94 
96 
97  /* Disable interrupts. */
98  write8(&uart_ptr->ier, 0);
99  /* Force DTR and RTS to high. */
101  /* Set High speed UART register. */
103  /* Set line configuration, access divisor latches. */
104  write8(&uart_ptr->lcr, UART8250_LCR_DLAB | line_config);
105  /* Set the divisor. */
106  write8(&uart_ptr->dll, divisor & 0xff);
107  write8(&uart_ptr->dlm, (divisor >> 8) & 0xff);
108  /* Hide the divisor latches. */
109  write8(&uart_ptr->lcr, line_config);
110  /* Enable FIFOs, and clear receive and transmit. */
111  write8(&uart_ptr->fcr,
114 
115 }
116 
117 static void mtk_uart_tx_byte(unsigned char data)
118 {
119  while (!(read8(&uart_ptr->lsr) & UART8250_LSR_THRE))
120  ;
121  write8(&uart_ptr->thr, data);
122 }
123 
124 static void mtk_uart_tx_flush(void)
125 {
126  while (!(read8(&uart_ptr->lsr) & UART8250_LSR_TEMT))
127  ;
128 }
129 
130 static unsigned char mtk_uart_rx_byte(void)
131 {
132  if (!mtk_uart_tst_byte())
133  return 0;
134  return read8(&uart_ptr->rbr);
135 }
136 
137 static int mtk_uart_tst_byte(void)
138 {
140 }
141 
142 void uart_init(unsigned int idx)
143 {
144  mtk_uart_init();
145 }
146 
147 unsigned char uart_rx_byte(unsigned int idx)
148 {
149  return mtk_uart_rx_byte();
150 }
151 
152 void uart_tx_byte(unsigned int idx, unsigned char data)
153 {
154  mtk_uart_tx_byte(data);
155 }
156 
157 void uart_tx_flush(unsigned int idx)
158 {
160 }
161 
162 void uart_fill_lb(void *data)
163 {
164  struct lb_serial serial;
166  serial.baseaddr = UART0_BASE;
167  serial.baud = get_uart_baudrate();
168  serial.regwidth = 4;
169  serial.input_hertz = UART_HZ;
170  serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
171  lb_add_serial(&serial, data);
172 
174 }
static void write8(void *addr, uint8_t val)
Definition: mmio.h:30
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
void lb_add_console(uint16_t consoletype, void *data)
void lb_add_serial(struct lb_serial *serial, void *data)
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
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
@ UART_HZ
Definition: pll.h:247
static void mtk_uart_tx_flush(void)
Definition: uart.c:124
static void mtk_uart_tx_byte(unsigned char data)
Definition: uart.c:117
static void mtk_uart_init(void)
Definition: uart.c:72
struct mtk_uart __packed
static int mtk_uart_tst_byte(void)
Definition: uart.c:137
static unsigned char mtk_uart_rx_byte(void)
Definition: uart.c:130
static struct mtk_uart *const uart_ptr
Definition: uart.c:67
#define UART0_BASE
Definition: addressmap.h:21
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
uint32_t pdn1_set
Definition: uart.c:53
uint32_t pdn0_set
Definition: uart.c:52
uint32_t pdn_md2_sta
Definition: uart.c:63
uint32_t pdn1_sta
Definition: uart.c:57
uint32_t pdn_md2_set
Definition: uart.c:59
uint32_t pdn1_clr
Definition: uart.c:55
uint32_t rst1
Definition: uart.c:51
uint32_t pdn_md2_clr
Definition: uart.c:61
uint32_t pdn_md1_sta
Definition: uart.c:62
uint32_t pdn_md1_set
Definition: uart.c:58
uint32_t pdn0_clr
Definition: uart.c:54
uint32_t pdn_md_mask
Definition: uart.c:64
uint32_t pdn0_sta
Definition: uart.c:56
uint32_t pdn_md1_clr
Definition: uart.c:60
uint32_t rst0
Definition: uart.c:50
Definition: uart.c:12
uint32_t iir
Definition: uart.c:23
uint32_t efr
Definition: uart.c:25
uint32_t mcr
Definition: uart.c:29
uint32_t thr
Definition: uart.c:14
uint32_t ier
Definition: uart.c:19
uint32_t dlm
Definition: uart.c:20
uint32_t xn2
Definition: uart.c:34
uint32_t xf2
Definition: uart.c:42
uint32_t scr
Definition: uart.c:41
uint32_t xn1
Definition: uart.c:30
uint32_t xf1
Definition: uart.c:38
uint32_t autobaud_en
Definition: uart.c:44
uint32_t lsr
Definition: uart.c:33
uint32_t msr
Definition: uart.c:37
uint32_t rbr
Definition: uart.c:15
uint32_t dll
Definition: uart.c:16
uint32_t highspeed
Definition: uart.c:45
uint32_t lcr
Definition: uart.c:27
uint32_t fcr
Definition: uart.c:24
#define UART8250_LCR_WLS_8
Definition: uart8250reg.h:44
#define UART8250_LCR_DLAB
Definition: uart8250reg.h:50
#define UART8250_LSR_DR
Definition: uart8250reg.h:67
#define UART8250_FCR_CLEAR_RCVR
Definition: uart8250reg.h:30
#define UART8250_FCR_CLEAR_XMIT
Definition: uart8250reg.h:31
#define UART8250_LSR_TEMT
Definition: uart8250reg.h:73
#define UART8250_MCR_DTR
Definition: uart8250reg.h:53
#define UART8250_FCR_FIFO_EN
Definition: uart8250reg.h:29
#define UART8250_MCR_RTS
Definition: uart8250reg.h:54
#define UART8250_LSR_THRE
Definition: uart8250reg.h:72