11378df79SJean-Christophe PLAGNIOL-VILLARD /* 21378df79SJean-Christophe PLAGNIOL-VILLARD * COM1 NS16550 support 3a47a12beSStefan Roese * originally from linux source (arch/powerpc/boot/ns16550.c) 46d0f6bcfSJean-Christophe PLAGNIOL-VILLARD * modified to use CONFIG_SYS_ISA_MEM and new defines 51378df79SJean-Christophe PLAGNIOL-VILLARD */ 61378df79SJean-Christophe PLAGNIOL-VILLARD 71378df79SJean-Christophe PLAGNIOL-VILLARD #include <config.h> 81378df79SJean-Christophe PLAGNIOL-VILLARD #include <ns16550.h> 9a1b322a9SLadislav Michl #include <watchdog.h> 10167cdad1SGraeme Russ #include <linux/types.h> 11167cdad1SGraeme Russ #include <asm/io.h> 121378df79SJean-Christophe PLAGNIOL-VILLARD 13200779e3SDetlev Zundel #define UART_LCRVAL UART_LCR_8N1 /* 8 data, 1 stop, no parity */ 14200779e3SDetlev Zundel #define UART_MCRVAL (UART_MCR_DTR | \ 15200779e3SDetlev Zundel UART_MCR_RTS) /* RTS/DTR */ 16200779e3SDetlev Zundel #define UART_FCRVAL (UART_FCR_FIFO_EN | \ 17200779e3SDetlev Zundel UART_FCR_RXSR | \ 18200779e3SDetlev Zundel UART_FCR_TXSR) /* Clear & enable FIFOs */ 19167cdad1SGraeme Russ #ifdef CONFIG_SYS_NS16550_PORT_MAPPED 20167cdad1SGraeme Russ #define serial_out(x, y) outb(x, (ulong)y) 21167cdad1SGraeme Russ #define serial_in(y) inb((ulong)y) 2279df1208SDave Aldridge #elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE > 0) 2379df1208SDave Aldridge #define serial_out(x, y) out_be32(y, x) 2479df1208SDave Aldridge #define serial_in(y) in_be32(y) 2579df1208SDave Aldridge #elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE < 0) 2679df1208SDave Aldridge #define serial_out(x, y) out_le32(y, x) 2779df1208SDave Aldridge #define serial_in(y) in_le32(y) 28167cdad1SGraeme Russ #else 29167cdad1SGraeme Russ #define serial_out(x, y) writeb(x, y) 30167cdad1SGraeme Russ #define serial_in(y) readb(y) 31167cdad1SGraeme Russ #endif 321378df79SJean-Christophe PLAGNIOL-VILLARD 33a160ea0bSPrafulla Wadaskar #ifndef CONFIG_SYS_NS16550_IER 34a160ea0bSPrafulla Wadaskar #define CONFIG_SYS_NS16550_IER 0x00 35a160ea0bSPrafulla Wadaskar #endif /* CONFIG_SYS_NS16550_IER */ 36a160ea0bSPrafulla Wadaskar 371378df79SJean-Christophe PLAGNIOL-VILLARD void NS16550_init(NS16550_t com_port, int baud_divisor) 381378df79SJean-Christophe PLAGNIOL-VILLARD { 39a160ea0bSPrafulla Wadaskar serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); 40660888b7STom Rix #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2) 41167cdad1SGraeme Russ serial_out(0x7, &com_port->mdr1); /* mode select reset TL16C750*/ 421378df79SJean-Christophe PLAGNIOL-VILLARD #endif 43167cdad1SGraeme Russ serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr); 44167cdad1SGraeme Russ serial_out(0, &com_port->dll); 45167cdad1SGraeme Russ serial_out(0, &com_port->dlm); 46167cdad1SGraeme Russ serial_out(UART_LCRVAL, &com_port->lcr); 47167cdad1SGraeme Russ serial_out(UART_MCRVAL, &com_port->mcr); 48167cdad1SGraeme Russ serial_out(UART_FCRVAL, &com_port->fcr); 49167cdad1SGraeme Russ serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr); 50167cdad1SGraeme Russ serial_out(baud_divisor & 0xff, &com_port->dll); 51167cdad1SGraeme Russ serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm); 52167cdad1SGraeme Russ serial_out(UART_LCRVAL, &com_port->lcr); 53660888b7STom Rix #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2) 541378df79SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_APTIX) 55*f8df9d0dSSimon Glass /* /13 mode so Aptix 6MHz can hit 115200 */ 56*f8df9d0dSSimon Glass serial_out(3, &com_port->mdr1); 571378df79SJean-Christophe PLAGNIOL-VILLARD #else 58*f8df9d0dSSimon Glass /* /16 is proper to hit 115200 with 48MHz */ 59*f8df9d0dSSimon Glass serial_out(0, &com_port->mdr1); 601378df79SJean-Christophe PLAGNIOL-VILLARD #endif 61b4746d8bSMike Frysinger #endif /* CONFIG_OMAP */ 621378df79SJean-Christophe PLAGNIOL-VILLARD } 631378df79SJean-Christophe PLAGNIOL-VILLARD 64f5675aa5SRon Madrid #ifndef CONFIG_NS16550_MIN_FUNCTIONS 651378df79SJean-Christophe PLAGNIOL-VILLARD void NS16550_reinit(NS16550_t com_port, int baud_divisor) 661378df79SJean-Christophe PLAGNIOL-VILLARD { 67a160ea0bSPrafulla Wadaskar serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); 68167cdad1SGraeme Russ serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr); 69167cdad1SGraeme Russ serial_out(0, &com_port->dll); 70167cdad1SGraeme Russ serial_out(0, &com_port->dlm); 71167cdad1SGraeme Russ serial_out(UART_LCRVAL, &com_port->lcr); 72167cdad1SGraeme Russ serial_out(UART_MCRVAL, &com_port->mcr); 73167cdad1SGraeme Russ serial_out(UART_FCRVAL, &com_port->fcr); 74167cdad1SGraeme Russ serial_out(UART_LCR_BKSE, &com_port->lcr); 75167cdad1SGraeme Russ serial_out(baud_divisor & 0xff, &com_port->dll); 76167cdad1SGraeme Russ serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm); 77167cdad1SGraeme Russ serial_out(UART_LCRVAL, &com_port->lcr); 781378df79SJean-Christophe PLAGNIOL-VILLARD } 79f5675aa5SRon Madrid #endif /* CONFIG_NS16550_MIN_FUNCTIONS */ 801378df79SJean-Christophe PLAGNIOL-VILLARD 811378df79SJean-Christophe PLAGNIOL-VILLARD void NS16550_putc(NS16550_t com_port, char c) 821378df79SJean-Christophe PLAGNIOL-VILLARD { 83*f8df9d0dSSimon Glass while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0) 84*f8df9d0dSSimon Glass ; 85167cdad1SGraeme Russ serial_out(c, &com_port->thr); 861a2d9b30SStefan Roese 871a2d9b30SStefan Roese /* 881a2d9b30SStefan Roese * Call watchdog_reset() upon newline. This is done here in putc 891a2d9b30SStefan Roese * since the environment code uses a single puts() to print the complete 901a2d9b30SStefan Roese * environment upon "printenv". So we can't put this watchdog call 911a2d9b30SStefan Roese * in puts(). 921a2d9b30SStefan Roese */ 931a2d9b30SStefan Roese if (c == '\n') 941a2d9b30SStefan Roese WATCHDOG_RESET(); 951378df79SJean-Christophe PLAGNIOL-VILLARD } 961378df79SJean-Christophe PLAGNIOL-VILLARD 97f5675aa5SRon Madrid #ifndef CONFIG_NS16550_MIN_FUNCTIONS 981378df79SJean-Christophe PLAGNIOL-VILLARD char NS16550_getc(NS16550_t com_port) 991378df79SJean-Christophe PLAGNIOL-VILLARD { 100167cdad1SGraeme Russ while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) { 1011378df79SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_USB_TTY 1021378df79SJean-Christophe PLAGNIOL-VILLARD extern void usbtty_poll(void); 1031378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll(); 1041378df79SJean-Christophe PLAGNIOL-VILLARD #endif 105a1b322a9SLadislav Michl WATCHDOG_RESET(); 1061378df79SJean-Christophe PLAGNIOL-VILLARD } 107167cdad1SGraeme Russ return serial_in(&com_port->rbr); 1081378df79SJean-Christophe PLAGNIOL-VILLARD } 1091378df79SJean-Christophe PLAGNIOL-VILLARD 1101378df79SJean-Christophe PLAGNIOL-VILLARD int NS16550_tstc(NS16550_t com_port) 1111378df79SJean-Christophe PLAGNIOL-VILLARD { 112*f8df9d0dSSimon Glass return (serial_in(&com_port->lsr) & UART_LSR_DR) != 0; 1131378df79SJean-Christophe PLAGNIOL-VILLARD } 1141378df79SJean-Christophe PLAGNIOL-VILLARD 115f5675aa5SRon Madrid #endif /* CONFIG_NS16550_MIN_FUNCTIONS */ 116