]>
Commit | Line | Data |
---|---|---|
e85390dc WD |
1 | /* |
2 | * COM1 NS16550 support | |
a47a12be | 3 | * originally from linux source (arch/powerpc/boot/ns16550.c) |
6d0f6bcf | 4 | * modified to use CONFIG_SYS_ISA_MEM and new defines |
e85390dc WD |
5 | */ |
6 | ||
7 | #include <config.h> | |
e85390dc | 8 | #include <ns16550.h> |
a1b322a9 | 9 | #include <watchdog.h> |
167cdad1 GR |
10 | #include <linux/types.h> |
11 | #include <asm/io.h> | |
e85390dc | 12 | |
200779e3 DZ |
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 */ | |
167cdad1 | 19 | #ifdef CONFIG_SYS_NS16550_PORT_MAPPED |
f8df9d0d SG |
20 | #define serial_out(x, y) outb(x, (ulong)y) |
21 | #define serial_in(y) inb((ulong)y) | |
79df1208 | 22 | #elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE > 0) |
f8df9d0d SG |
23 | #define serial_out(x, y) out_be32(y, x) |
24 | #define serial_in(y) in_be32(y) | |
79df1208 | 25 | #elif defined(CONFIG_SYS_NS16550_MEM32) && (CONFIG_SYS_NS16550_REG_SIZE < 0) |
f8df9d0d SG |
26 | #define serial_out(x, y) out_le32(y, x) |
27 | #define serial_in(y) in_le32(y) | |
167cdad1 | 28 | #else |
f8df9d0d SG |
29 | #define serial_out(x, y) writeb(x, y) |
30 | #define serial_in(y) readb(y) | |
167cdad1 | 31 | #endif |
e85390dc | 32 | |
ef509b90 VA |
33 | #if defined(CONFIG_K2HK_EVM) |
34 | #define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE 0 | |
35 | #define UART_REG_VAL_PWREMU_MGMT_UART_ENABLE ((1 << 14) | (1 << 13) | (1 << 0)) | |
36 | #endif | |
37 | ||
a160ea0b PW |
38 | #ifndef CONFIG_SYS_NS16550_IER |
39 | #define CONFIG_SYS_NS16550_IER 0x00 | |
40 | #endif /* CONFIG_SYS_NS16550_IER */ | |
41 | ||
f8df9d0d | 42 | void NS16550_init(NS16550_t com_port, int baud_divisor) |
e85390dc | 43 | { |
fd2aeac5 MH |
44 | #if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_OMAP34XX)) |
45 | /* | |
46 | * On some OMAP3 devices when UART3 is configured for boot mode before | |
47 | * SPL starts only THRE bit is set. We have to empty the transmitter | |
48 | * before initialization starts. | |
49 | */ | |
50 | if ((serial_in(&com_port->lsr) & (UART_LSR_TEMT | UART_LSR_THRE)) | |
51 | == UART_LSR_THRE) { | |
52 | serial_out(UART_LCR_DLAB, &com_port->lcr); | |
53 | serial_out(baud_divisor & 0xff, &com_port->dll); | |
54 | serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm); | |
55 | serial_out(UART_LCRVAL, &com_port->lcr); | |
56 | serial_out(0, &com_port->mdr1); | |
57 | } | |
58 | #endif | |
59 | ||
cb55b332 SW |
60 | while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT)) |
61 | ; | |
62 | ||
a160ea0b | 63 | serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); |
456ccfdf TR |
64 | #if defined(CONFIG_OMAP) || defined(CONFIG_AM33XX) || \ |
65 | defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX) | |
167cdad1 | 66 | serial_out(0x7, &com_port->mdr1); /* mode select reset TL16C750*/ |
945af8d7 | 67 | #endif |
69e06832 | 68 | serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr); |
167cdad1 GR |
69 | serial_out(0, &com_port->dll); |
70 | serial_out(0, &com_port->dlm); | |
71 | serial_out(UART_LCRVAL, &com_port->lcr); | |
72 | serial_out(UART_MCRVAL, &com_port->mcr); | |
73 | serial_out(UART_FCRVAL, &com_port->fcr); | |
74 | serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr); | |
75 | serial_out(baud_divisor & 0xff, &com_port->dll); | |
76 | serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm); | |
77 | serial_out(UART_LCRVAL, &com_port->lcr); | |
5289e83a | 78 | #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \ |
6213a68f | 79 | defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX) || \ |
9ed6e412 | 80 | defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX) |
5289e83a | 81 | |
f8df9d0d SG |
82 | /* /16 is proper to hit 115200 with 48MHz */ |
83 | serial_out(0, &com_port->mdr1); | |
b4746d8b | 84 | #endif /* CONFIG_OMAP */ |
ef509b90 VA |
85 | #if defined(CONFIG_K2HK_EVM) |
86 | serial_out(UART_REG_VAL_PWREMU_MGMT_UART_ENABLE, &com_port->regC); | |
87 | #endif | |
e85390dc WD |
88 | } |
89 | ||
f5675aa5 | 90 | #ifndef CONFIG_NS16550_MIN_FUNCTIONS |
f8df9d0d | 91 | void NS16550_reinit(NS16550_t com_port, int baud_divisor) |
e85390dc | 92 | { |
a160ea0b | 93 | serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); |
167cdad1 GR |
94 | serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr); |
95 | serial_out(0, &com_port->dll); | |
96 | serial_out(0, &com_port->dlm); | |
97 | serial_out(UART_LCRVAL, &com_port->lcr); | |
98 | serial_out(UART_MCRVAL, &com_port->mcr); | |
99 | serial_out(UART_FCRVAL, &com_port->fcr); | |
100 | serial_out(UART_LCR_BKSE, &com_port->lcr); | |
101 | serial_out(baud_divisor & 0xff, &com_port->dll); | |
102 | serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm); | |
103 | serial_out(UART_LCRVAL, &com_port->lcr); | |
e85390dc | 104 | } |
f5675aa5 | 105 | #endif /* CONFIG_NS16550_MIN_FUNCTIONS */ |
e85390dc | 106 | |
f8df9d0d | 107 | void NS16550_putc(NS16550_t com_port, char c) |
e85390dc | 108 | { |
f8df9d0d SG |
109 | while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0) |
110 | ; | |
167cdad1 | 111 | serial_out(c, &com_port->thr); |
1a2d9b30 SR |
112 | |
113 | /* | |
114 | * Call watchdog_reset() upon newline. This is done here in putc | |
115 | * since the environment code uses a single puts() to print the complete | |
116 | * environment upon "printenv". So we can't put this watchdog call | |
117 | * in puts(). | |
118 | */ | |
119 | if (c == '\n') | |
120 | WATCHDOG_RESET(); | |
e85390dc WD |
121 | } |
122 | ||
f5675aa5 | 123 | #ifndef CONFIG_NS16550_MIN_FUNCTIONS |
f8df9d0d | 124 | char NS16550_getc(NS16550_t com_port) |
e85390dc | 125 | { |
167cdad1 | 126 | while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) { |
f2041388 | 127 | #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_TTY) |
232c150a WD |
128 | extern void usbtty_poll(void); |
129 | usbtty_poll(); | |
130 | #endif | |
a1b322a9 | 131 | WATCHDOG_RESET(); |
232c150a | 132 | } |
167cdad1 | 133 | return serial_in(&com_port->rbr); |
e85390dc WD |
134 | } |
135 | ||
f8df9d0d | 136 | int NS16550_tstc(NS16550_t com_port) |
e85390dc | 137 | { |
f8df9d0d | 138 | return (serial_in(&com_port->lsr) & UART_LSR_DR) != 0; |
e85390dc WD |
139 | } |
140 | ||
f5675aa5 | 141 | #endif /* CONFIG_NS16550_MIN_FUNCTIONS */ |