ns16550.c 3.72 KB
Newer Older
wdenk's avatar
wdenk committed
1
2
/*
 * COM1 NS16550 support
Stefan Roese's avatar
Stefan Roese committed
3
 * originally from linux source (arch/powerpc/boot/ns16550.c)
4
 * modified to use CONFIG_SYS_ISA_MEM and new defines
wdenk's avatar
wdenk committed
5
6
7
8
 */

#include <config.h>
#include <ns16550.h>
9
#include <watchdog.h>
10
11
#include <linux/types.h>
#include <asm/io.h>
wdenk's avatar
wdenk committed
12

13
14
15
16
17
18
#define UART_LCRVAL UART_LCR_8N1		/* 8 data, 1 stop, no parity */
#define UART_MCRVAL (UART_MCR_DTR | \
		     UART_MCR_RTS)		/* RTS/DTR */
#define UART_FCRVAL (UART_FCR_FIFO_EN |	\
		     UART_FCR_RXSR |	\
		     UART_FCR_TXSR)		/* Clear & enable FIFOs */
19
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
20
21
#define serial_out(x, y)	outb(x, (ulong)y)
#define serial_in(y)		inb((ulong)y)
22
#elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE > 0)
23
24
#define serial_out(x, y)	out_be32(y, x)
#define serial_in(y)		in_be32(y)
25
#elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE < 0)
26
27
#define serial_out(x, y)	out_le32(y, x)
#define serial_in(y)		in_le32(y)
28
#else
29
30
#define serial_out(x, y)	writeb(x, y)
#define serial_in(y)		readb(y)
31
#endif
wdenk's avatar
wdenk committed
32

33
34
35
36
#ifndef CONFIG_SYS_NS16550_IER
#define CONFIG_SYS_NS16550_IER  0x00
#endif /* CONFIG_SYS_NS16550_IER */

37
void NS16550_init(NS16550_t com_port, int baud_divisor)
wdenk's avatar
wdenk committed
38
{
39
#if (!defined(CONFIG_SYS_NS16550_BROKEN_TEMT))
40
41
	while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT))
		;
42
#endif
43

44
	serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
45
46
#if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
					defined(CONFIG_AM33XX)
47
	serial_out(0x7, &com_port->mdr1);	/* mode select reset TL16C750*/
48
#endif
49
50
51
52
53
54
55
56
57
58
	serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr);
	serial_out(0, &com_port->dll);
	serial_out(0, &com_port->dlm);
	serial_out(UART_LCRVAL, &com_port->lcr);
	serial_out(UART_MCRVAL, &com_port->mcr);
	serial_out(UART_FCRVAL, &com_port->fcr);
	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
	serial_out(baud_divisor & 0xff, &com_port->dll);
	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
	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
64
	/* /13 mode so Aptix 6MHz can hit 115200 */
	serial_out(3, &com_port->mdr1);
65
#else
66
67
	/* /16 is proper to hit 115200 with 48MHz */
	serial_out(0, &com_port->mdr1);
68
#endif
69
#endif /* CONFIG_OMAP */
wdenk's avatar
wdenk committed
70
71
}

72
#ifndef CONFIG_NS16550_MIN_FUNCTIONS
73
void NS16550_reinit(NS16550_t com_port, int baud_divisor)
wdenk's avatar
wdenk committed
74
{
75
	serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
76
77
78
79
80
81
82
83
84
85
	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
	serial_out(0, &com_port->dll);
	serial_out(0, &com_port->dlm);
	serial_out(UART_LCRVAL, &com_port->lcr);
	serial_out(UART_MCRVAL, &com_port->mcr);
	serial_out(UART_FCRVAL, &com_port->fcr);
	serial_out(UART_LCR_BKSE, &com_port->lcr);
	serial_out(baud_divisor & 0xff, &com_port->dll);
	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
	serial_out(UART_LCRVAL, &com_port->lcr);
wdenk's avatar
wdenk committed
86
}
87
#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
wdenk's avatar
wdenk committed
88

89
void NS16550_putc(NS16550_t com_port, char c)
wdenk's avatar
wdenk committed
90
{
91
92
	while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0)
		;
93
	serial_out(c, &com_port->thr);
94
95
96
97
98
99
100
101
102

	/*
	 * Call watchdog_reset() upon newline. This is done here in putc
	 * since the environment code uses a single puts() to print the complete
	 * environment upon "printenv". So we can't put this watchdog call
	 * in puts().
	 */
	if (c == '\n')
		WATCHDOG_RESET();
wdenk's avatar
wdenk committed
103
104
}

105
#ifndef CONFIG_NS16550_MIN_FUNCTIONS
106
char NS16550_getc(NS16550_t com_port)
wdenk's avatar
wdenk committed
107
{
108
	while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
109
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_TTY)
110
111
112
		extern void usbtty_poll(void);
		usbtty_poll();
#endif
113
		WATCHDOG_RESET();
114
	}
115
	return serial_in(&com_port->rbr);
wdenk's avatar
wdenk committed
116
117
}

118
int NS16550_tstc(NS16550_t com_port)
wdenk's avatar
wdenk committed
119
{
120
	return (serial_in(&com_port->lsr) & UART_LSR_DR) != 0;
wdenk's avatar
wdenk committed
121
122
}

123
#endif /* CONFIG_NS16550_MIN_FUNCTIONS */