xref: /rk3399_rockchip-uboot/drivers/serial/ns16550.c (revision 1a2d9b30e31e2b7ed0acb64bfb2290911e3c9efb)
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)
22167cdad1SGraeme Russ #else
23167cdad1SGraeme Russ #define serial_out(x,y) writeb(x,y)
24167cdad1SGraeme Russ #define serial_in(y) 	readb(y)
25167cdad1SGraeme Russ #endif
261378df79SJean-Christophe PLAGNIOL-VILLARD 
271378df79SJean-Christophe PLAGNIOL-VILLARD void NS16550_init (NS16550_t com_port, int baud_divisor)
281378df79SJean-Christophe PLAGNIOL-VILLARD {
29167cdad1SGraeme Russ 	serial_out(0x00, &com_port->ier);
30660888b7STom Rix #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
31167cdad1SGraeme Russ 	serial_out(0x7, &com_port->mdr1);	/* mode select reset TL16C750*/
321378df79SJean-Christophe PLAGNIOL-VILLARD #endif
33167cdad1SGraeme Russ 	serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr);
34167cdad1SGraeme Russ 	serial_out(0, &com_port->dll);
35167cdad1SGraeme Russ 	serial_out(0, &com_port->dlm);
36167cdad1SGraeme Russ 	serial_out(UART_LCRVAL, &com_port->lcr);
37167cdad1SGraeme Russ 	serial_out(UART_MCRVAL, &com_port->mcr);
38167cdad1SGraeme Russ 	serial_out(UART_FCRVAL, &com_port->fcr);
39167cdad1SGraeme Russ 	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
40167cdad1SGraeme Russ 	serial_out(baud_divisor & 0xff, &com_port->dll);
41167cdad1SGraeme Russ 	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
42167cdad1SGraeme Russ 	serial_out(UART_LCRVAL, &com_port->lcr);
43660888b7STom Rix #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
441378df79SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_APTIX)
45167cdad1SGraeme Russ 	serial_out(3, &com_port->mdr1);	/* /13 mode so Aptix 6MHz can hit 115200 */
461378df79SJean-Christophe PLAGNIOL-VILLARD #else
47167cdad1SGraeme Russ 	serial_out(0, &com_port->mdr1);	/* /16 is proper to hit 115200 with 48MHz */
481378df79SJean-Christophe PLAGNIOL-VILLARD #endif
49b4746d8bSMike Frysinger #endif /* CONFIG_OMAP */
501378df79SJean-Christophe PLAGNIOL-VILLARD }
511378df79SJean-Christophe PLAGNIOL-VILLARD 
52f5675aa5SRon Madrid #ifndef CONFIG_NS16550_MIN_FUNCTIONS
531378df79SJean-Christophe PLAGNIOL-VILLARD void NS16550_reinit (NS16550_t com_port, int baud_divisor)
541378df79SJean-Christophe PLAGNIOL-VILLARD {
55167cdad1SGraeme Russ 	serial_out(0x00, &com_port->ier);
56167cdad1SGraeme Russ 	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
57167cdad1SGraeme Russ 	serial_out(0, &com_port->dll);
58167cdad1SGraeme Russ 	serial_out(0, &com_port->dlm);
59167cdad1SGraeme Russ 	serial_out(UART_LCRVAL, &com_port->lcr);
60167cdad1SGraeme Russ 	serial_out(UART_MCRVAL, &com_port->mcr);
61167cdad1SGraeme Russ 	serial_out(UART_FCRVAL, &com_port->fcr);
62167cdad1SGraeme Russ 	serial_out(UART_LCR_BKSE, &com_port->lcr);
63167cdad1SGraeme Russ 	serial_out(baud_divisor & 0xff, &com_port->dll);
64167cdad1SGraeme Russ 	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
65167cdad1SGraeme Russ 	serial_out(UART_LCRVAL, &com_port->lcr);
661378df79SJean-Christophe PLAGNIOL-VILLARD }
67f5675aa5SRon Madrid #endif /* CONFIG_NS16550_MIN_FUNCTIONS */
681378df79SJean-Christophe PLAGNIOL-VILLARD 
691378df79SJean-Christophe PLAGNIOL-VILLARD void NS16550_putc (NS16550_t com_port, char c)
701378df79SJean-Christophe PLAGNIOL-VILLARD {
71167cdad1SGraeme Russ 	while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0);
72167cdad1SGraeme Russ 	serial_out(c, &com_port->thr);
73*1a2d9b30SStefan Roese 
74*1a2d9b30SStefan Roese 	/*
75*1a2d9b30SStefan Roese 	 * Call watchdog_reset() upon newline. This is done here in putc
76*1a2d9b30SStefan Roese 	 * since the environment code uses a single puts() to print the complete
77*1a2d9b30SStefan Roese 	 * environment upon "printenv". So we can't put this watchdog call
78*1a2d9b30SStefan Roese 	 * in puts().
79*1a2d9b30SStefan Roese 	 */
80*1a2d9b30SStefan Roese 	if (c == '\n')
81*1a2d9b30SStefan Roese 		WATCHDOG_RESET();
821378df79SJean-Christophe PLAGNIOL-VILLARD }
831378df79SJean-Christophe PLAGNIOL-VILLARD 
84f5675aa5SRon Madrid #ifndef CONFIG_NS16550_MIN_FUNCTIONS
851378df79SJean-Christophe PLAGNIOL-VILLARD char NS16550_getc (NS16550_t com_port)
861378df79SJean-Christophe PLAGNIOL-VILLARD {
87167cdad1SGraeme Russ 	while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
881378df79SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_USB_TTY
891378df79SJean-Christophe PLAGNIOL-VILLARD 		extern void usbtty_poll(void);
901378df79SJean-Christophe PLAGNIOL-VILLARD 		usbtty_poll();
911378df79SJean-Christophe PLAGNIOL-VILLARD #endif
92a1b322a9SLadislav Michl 		WATCHDOG_RESET();
931378df79SJean-Christophe PLAGNIOL-VILLARD 	}
94167cdad1SGraeme Russ 	return serial_in(&com_port->rbr);
951378df79SJean-Christophe PLAGNIOL-VILLARD }
961378df79SJean-Christophe PLAGNIOL-VILLARD 
971378df79SJean-Christophe PLAGNIOL-VILLARD int NS16550_tstc (NS16550_t com_port)
981378df79SJean-Christophe PLAGNIOL-VILLARD {
99167cdad1SGraeme Russ 	return ((serial_in(&com_port->lsr) & UART_LSR_DR) != 0);
1001378df79SJean-Christophe PLAGNIOL-VILLARD }
1011378df79SJean-Christophe PLAGNIOL-VILLARD 
102f5675aa5SRon Madrid #endif /* CONFIG_NS16550_MIN_FUNCTIONS */
103