blob: b6f57c7246bd652cc33ff66159261e1e1ea891cb [file] [log] [blame]
wdenkc7de8292002-11-19 11:04:11 +00001#include <common.h>
2#include <ns16550.h>
3#include "short_types.h"
4#include "memio.h"
5#include "articiaS.h"
6
Wolfgang Denkd87080b2006-03-31 18:32:53 +02007DECLARE_GLOBAL_DATA_PTR;
8
wdenkc7de8292002-11-19 11:04:11 +00009#ifndef CFG_NS16550
10static uint32 ComPort1;
11
12uint16 SerialEcho = 1;
13
14
15#define RECEIVER_HOLDING 0
16#define TRANSMITTER_HOLDING 0
17#define INTERRUPT_ENABLE 1
18#define INTERRUPT_STATUS 2
19#define FIFO_CONTROL 2
20#define LINE_CONTROL 3
21#define MODEM_CONTROL 4
22#define LINE_STATUS 5
23#define MODEM_STATUS 6
24#define SCRATCH_PAD 7
25
26#define DIVISOR_LATCH_LSB 0
27#define DIVISOR_LATCH_MSB 1
28#define PRESCALER_DIVISION 5
29
30#define COM_WRITE_BYTE(reg, byte) out_byte((ComPort1+reg), byte)
31#define COM_READ_BYTE(reg) in_byte((ComPort1+reg))
32
33static int serial_init_done = 0;
34
35void serial_init (void)
36{
37#if 0
38 uint32 clock_divisor = 115200 / baudrate;
39 uint8 cfg;
40 uint8 a;
41 uint16 devfn = 7 << 3;
42
43 if (serial_init_done)
44 return;
45
46 /* Enter configuration mode */
47 cfg = pci_read_cfg_byte (0, devfn, 0x85);
48 pci_write_cfg_byte (0, devfn, 0x85, cfg | 0x02);
49
50 /* Set serial port COM1 as 3F8 */
51 out_byte (0x3F0, 0xE7);
52 out_byte (0x3f1, 0xfe);
53
54 /* Set serial port COM2 as 2F8 */
55 out_byte (0x3f0, 0xe8);
56 out_byte (0x3f1, 0xeb);
57
58 /* Enable */
59 out_byte (0x3f0, 0xe2);
60 a = in_byte (0x3f1);
61 a |= 0xc;
62 out_byte (0x3f0, 0xe2);
63 out_byte (0x3f1, a);
64
65 /* Reset the configuration mode */
66 pci_write_cfg_byte (0, devfn, 0x85, cfg);
67#endif
68
69 ComPort1 = 0x3F8;
70
71 /* Disable interrupts */
72 COM_WRITE_BYTE (INTERRUPT_ENABLE, 0x00);
73
74 /* Set baud rate */
75 /* COM_WRITE_BYTE(LINE_CONTROL, 0x83); */
76 /* COM_WRITE_BYTE(DIVISOR_LATCH_LSB, (uint8)(clock_divisor & 0xFF)); */
77 /* COM_WRITE_BYTE(DIVISOR_LATCH_MSB, (uint8)(clock_divisor >> 8)); */
78 /* __asm("eieio"); */
79
80 /* Set 8-N-1 */
81 COM_WRITE_BYTE (LINE_CONTROL, 0x03);
82 __asm ("eieio");
83
84 /* Disable FIFO */
85 COM_WRITE_BYTE (MODEM_CONTROL, 0x03);
86 COM_WRITE_BYTE (FIFO_CONTROL, 0x07);
87
88 __asm ("eieio");
89 serial_init_done = 1;
90}
91
92extern int console_changed;
93
94void serial_putc (const char sendme)
95{
96 if (sendme == '\n') {
97 while ((in_byte (0x3FD) & 0x40) == 0);
98 out_byte (0x3f8, 0x0D);
99 }
100
101 while ((in_byte (0x3FD) & 0x40) == 0);
102 out_byte (0x3f8, sendme);
103}
104
105int serial_getc (void)
106{
107#if 0
108 uint8 c;
109
110 for (;;) {
111 uint8 x = in_byte (0x3FD);
112
113 if (x & 0x01)
114 break;
115
116 if (x & 0x0C)
117 out_byte (0x3fd, 0x0c);
118 }
119
120 c = in_byte (0x3F8);
121
122 return c;
123#else
124 while ((in_byte (0x3FD) & 0x01) == 0) {
125 if (console_changed != 0) {
126 printf ("Console changed\n");
127 console_changed = 0;
128 return 0;
129 }
130 }
131 return in_byte (0x3F8);
132#endif
133}
134
135int serial_tstc (void)
136{
137 return (in_byte (0x03FD) & 0x01) != 0;
138}
139
140void serial_debug_putc (int c)
141{
142 serial_puts ("DBG");
143 serial_putc (c);
144 serial_putc (0x0d);
145 serial_putc (0x0A);
146}
147
148#else
149
150const NS16550_t Com0 = (NS16550_t) CFG_NS16550_COM1;
151const NS16550_t Com1 = (NS16550_t) CFG_NS16550_COM2;
152
153int serial_init (void)
154{
wdenkc7de8292002-11-19 11:04:11 +0000155 uint32 clock_divisor = 115200 / gd->baudrate;
156
157 NS16550_init (Com0, clock_divisor);
158 /* NS16550_reinit(Com1, clock_divisor); */
159 /* serial_puts("COM1: 3F8h initalized"); */
160
161 return (0);
162}
163
164#if 0
165void serial_putc (const char c)
166{
167 NS16550_putc (Com0, c);
168 if (c == '\n')
169 NS16550_putc (Com0, 0x0D);
170}
171
172int serial_getc (void)
173{
174 return (int) NS16550_getc (Com0);
175}
176
177int serial_tstc (void)
178{
179 return NS16550_tstc (Com0);
180}
181#else
182void serial_putc (const char sendme)
183{
184 if (sendme == '\n') {
185 while ((in_byte (0x3FD) & 0x40) == 0);
186 out_byte (0x3f8, 0x0D);
187 }
188
189 while ((in_byte (0x3FD) & 0x40) == 0);
190 out_byte (0x3f8, sendme);
191}
192
193
194extern int console_changed;
195
196int serial_getc (void)
197{
198#if 0
199 uint8 c;
200
201 for (;;) {
202 uint8 x = in_byte (0x3FD);
203
204 if (x & 0x01)
205 break;
206
207 if (x & 0x0C)
208 out_byte (0x3fd, 0x0c);
209 }
210
211 c = in_byte (0x3F8);
212
213 return c;
214#else
215 while ((in_byte (0x3FD) & 0x01) == 0) {
216 if (console_changed != 0) {
217 console_changed = 0;
218 return 0;
219 }
220 }
221
222 return in_byte (0x3F8);
223#endif
224}
225
226int serial_tstc (void)
227{
228 return (in_byte (0x03FD) & 0x01) != 0;
229}
230#endif
231
232#endif
233
234void serial_puts (const char *string)
235{
236 while (*string)
237 serial_putc (*string++);
238}
239
240void serial_setbrg (void)
241{
wdenkc7de8292002-11-19 11:04:11 +0000242 uint32 clock_divisor = 115200 / gd->baudrate;
243
244 NS16550_init (Com0, clock_divisor);
245}