coreboot-v2/src/lib/uart8250.c
<<
>>
Prefs
   1/* Should support 8250, 16450, 16550, 16550A type uarts */
   2#include <arch/io.h>
   3#include <uart8250.h>
   4
   5/* Data */
   6#define UART_RBR 0x00
   7#define UART_TBR 0x00
   8
   9/* Control */
  10#define UART_IER 0x01
  11#define UART_IIR 0x02
  12#define UART_FCR 0x02
  13#define UART_LCR 0x03
  14#define UART_MCR 0x04
  15#define UART_DLL 0x00
  16#define UART_DLM 0x01
  17
  18/* Status */
  19#define UART_LSR 0x05
  20#define UART_MSR 0x06
  21#define UART_SCR 0x07
  22
  23static inline int uart8250_can_tx_byte(unsigned base_port)
  24{
  25        return inb(base_port + UART_LSR) & 0x20;
  26}
  27
  28static inline void uart8250_wait_to_tx_byte(unsigned base_port)
  29{
  30        while(!uart8250_can_tx_byte(base_port))
  31                ;
  32}
  33
  34static inline void uart8250_wait_until_sent(unsigned base_port)
  35{
  36        while(!(inb(base_port + UART_LSR) & 0x40)) 
  37                ;
  38}
  39
  40void uart8250_tx_byte(unsigned base_port, unsigned char data)
  41{
  42        uart8250_wait_to_tx_byte(base_port);
  43        outb(data, base_port + UART_TBR);
  44        /* Make certain the data clears the fifos */
  45        uart8250_wait_until_sent(base_port);
  46}
  47
  48int uart8250_can_rx_byte(unsigned base_port)
  49{
  50        return inb(base_port + UART_LSR) & 0x01;
  51}
  52
  53unsigned char uart8250_rx_byte(unsigned base_port)
  54{
  55        while(!uart8250_can_rx_byte(base_port))
  56                ;
  57        return inb(base_port + UART_RBR);
  58}
  59
  60void uart8250_init(unsigned base_port, unsigned divisor, unsigned lcs)
  61{
  62        lcs &= 0x7f;
  63        /* disable interrupts */
  64        outb(0x0, base_port + UART_IER);
  65        /* enable fifo's */
  66        outb(0x01, base_port + UART_FCR);
  67        /* assert DTR and RTS so the other end is happy */
  68        outb(0x03, base_port + UART_MCR);
  69        /* Set Baud Rate Divisor to 12 ==> 115200 Baud */
  70        outb(0x80 | lcs, base_port + UART_LCR);
  71        outb(divisor & 0xFF,   base_port + UART_DLL);
  72        outb((divisor >> 8) & 0xFF,    base_port + UART_DLM);
  73        outb(lcs, base_port + UART_LCR);
  74}
  75
  76/* Initialize a generic uart */
  77void init_uart8250(unsigned base_port, struct uart8250 *uart)
  78{
  79        int divisor;
  80        int lcs;
  81        divisor = 115200/(uart->baud ? uart->baud: 1);
  82        lcs = 3;
  83        if (base_port == CONFIG_TTYS0_BASE) {
  84                /* Don't reinitialize the console serial port,
  85                 * This is espeically nasty in SMP.
  86                 */
  87                return;
  88        }
  89        uart8250_init(base_port, divisor, lcs);
  90}
  91
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.