- Initial checkin of the freebios2 tree
[coreboot.git] / src / lib / uart8250.c
1 #ifndef lint
2 static char rcsid[] = "$Id$";
3 #endif
4
5 /* Should support 8250, 16450, 16550, 16550A type uarts */
6 #include <arch/io.h>
7 #include <uart8250.h>
8
9 /* Data */
10 #define UART_RBR 0x00
11 #define UART_TBR 0x00
12
13 /* Control */
14 #define UART_IER 0x01
15 #define UART_IIR 0x02
16 #define UART_FCR 0x02
17 #define UART_LCR 0x03
18 #define UART_MCR 0x04
19 #define UART_DLL 0x00
20 #define UART_DLM 0x01
21
22 /* Status */
23 #define UART_LSR 0x05
24 #define UART_MSR 0x06
25 #define UART_SCR 0x07
26
27 static inline int uart8250_can_tx_byte(unsigned base_port)
28 {
29         return inb(base_port + UART_LSR) & 0x20;
30 }
31
32 static inline void uart8250_wait_to_tx_byte(unsigned base_port)
33 {
34         while(!uart8250_can_tx_byte(base_port))
35                 ;
36 }
37
38 static inline void uart8250_wait_until_sent(unsigned base_port)
39 {
40         while(!(inb(base_port + UART_LSR) & 0x40)) 
41                 ;
42 }
43
44 void uart8250_tx_byte(unsigned base_port, unsigned char data)
45 {
46         uart8250_wait_to_tx_byte(base_port);
47         outb(data, base_port + UART_TBR);
48         /* Make certain the data clears the fifos */
49         uart8250_wait_until_sent(base_port);
50 }
51
52 void uart8250_init(unsigned base_port, unsigned divisor, unsigned lcs)
53 {
54         lcs &= 0x7f;
55         /* disable interrupts */
56         outb(0x0, base_port + UART_IER);
57         /* enable fifo's */
58         outb(0x01, base_port + UART_FCR);
59         /* Set Baud Rate Divisor to 12 ==> 115200 Baud */
60         outb(0x80 | lcs, base_port + UART_LCR);
61         outb(divisor & 0xFF,   base_port + UART_DLL);
62         outb((divisor >> 8) & 0xFF,    base_port + UART_DLM);
63         outb(lcs, base_port + UART_LCR);
64 }