uboot/drivers/serial/ns16550.c
<<
>>
Prefs
   1/*
   2 * COM1 NS16550 support
   3 * originally from linux source (arch/powerpc/boot/ns16550.c)
   4 * modified to use CONFIG_SYS_ISA_MEM and new defines
   5 */
   6
   7#include <config.h>
   8#include <ns16550.h>
   9#include <watchdog.h>
  10#include <linux/types.h>
  11#include <asm/io.h>
  12
  13#define UART_LCRVAL UART_LCR_8N1                /* 8 data, 1 stop, no parity */
  14#define UART_MCRVAL (UART_MCR_DTR | \
  15                     UART_MCR_RTS)              /* RTS/DTR */
  16#define UART_FCRVAL (UART_FCR_FIFO_EN | \
  17                     UART_FCR_RXSR |    \
  18                     UART_FCR_TXSR)             /* Clear & enable FIFOs */
  19#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
  20#define serial_out(x, y)        outb(x, (ulong)y)
  21#define serial_in(y)            inb((ulong)y)
  22#elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE > 0)
  23#define serial_out(x, y)        out_be32(y, x)
  24#define serial_in(y)            in_be32(y)
  25#elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE < 0)
  26#define serial_out(x, y)        out_le32(y, x)
  27#define serial_in(y)            in_le32(y)
  28#else
  29#define serial_out(x, y)        writeb(x, y)
  30#define serial_in(y)            readb(y)
  31#endif
  32
  33#ifndef CONFIG_SYS_NS16550_IER
  34#define CONFIG_SYS_NS16550_IER  0x00
  35#endif /* CONFIG_SYS_NS16550_IER */
  36
  37void NS16550_init(NS16550_t com_port, int baud_divisor)
  38{
  39#if (!defined(CONFIG_SYS_NS16550_BROKEN_TEMT))
  40        while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT))
  41                ;
  42#endif
  43
  44        serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
  45#if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
  46                                        defined(CONFIG_AM33XX)
  47        serial_out(0x7, &com_port->mdr1);       /* mode select reset TL16C750*/
  48#endif
  49        serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr);
  50        serial_out(0, &com_port->dll);
  51        serial_out(0, &com_port->dlm);
  52        serial_out(UART_LCRVAL, &com_port->lcr);
  53        serial_out(UART_MCRVAL, &com_port->mcr);
  54        serial_out(UART_FCRVAL, &com_port->fcr);
  55        serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
  56        serial_out(baud_divisor & 0xff, &com_port->dll);
  57        serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
  58        serial_out(UART_LCRVAL, &com_port->lcr);
  59#if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
  60        defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX)
  61
  62#if defined(CONFIG_APTIX)
  63        /* /13 mode so Aptix 6MHz can hit 115200 */
  64        serial_out(3, &com_port->mdr1);
  65#else
  66        /* /16 is proper to hit 115200 with 48MHz */
  67        serial_out(0, &com_port->mdr1);
  68#endif
  69#endif /* CONFIG_OMAP */
  70}
  71
  72#ifndef CONFIG_NS16550_MIN_FUNCTIONS
  73void NS16550_reinit(NS16550_t com_port, int baud_divisor)
  74{
  75        serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
  76        serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
  77        serial_out(0, &com_port->dll);
  78        serial_out(0, &com_port->dlm);
  79        serial_out(UART_LCRVAL, &com_port->lcr);
  80        serial_out(UART_MCRVAL, &com_port->mcr);
  81        serial_out(UART_FCRVAL, &com_port->fcr);
  82        serial_out(UART_LCR_BKSE, &com_port->lcr);
  83        serial_out(baud_divisor & 0xff, &com_port->dll);
  84        serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
  85        serial_out(UART_LCRVAL, &com_port->lcr);
  86}
  87#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
  88
  89void NS16550_putc(NS16550_t com_port, char c)
  90{
  91        while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0)
  92                ;
  93        serial_out(c, &com_port->thr);
  94
  95        /*
  96         * Call watchdog_reset() upon newline. This is done here in putc
  97         * since the environment code uses a single puts() to print the complete
  98         * environment upon "printenv". So we can't put this watchdog call
  99         * in puts().
 100         */
 101        if (c == '\n')
 102                WATCHDOG_RESET();
 103}
 104
 105#ifndef CONFIG_NS16550_MIN_FUNCTIONS
 106char NS16550_getc(NS16550_t com_port)
 107{
 108        while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
 109#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_TTY)
 110                extern void usbtty_poll(void);
 111                usbtty_poll();
 112#endif
 113                WATCHDOG_RESET();
 114        }
 115        return serial_in(&com_port->rbr);
 116}
 117
 118int NS16550_tstc(NS16550_t com_port)
 119{
 120        return (serial_in(&com_port->lsr) & UART_LSR_DR) != 0;
 121}
 122
 123#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
 124