]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/serial/serial_s3c44b0.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[people/ms/u-boot.git] / drivers / serial / serial_s3c44b0.c
1 pyright 2002
2 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
3 * Marius Groeger <mgroeger@sysgo.de>
4 *
5 * (C) Copyright 2002
6 * ght 2002-2004
7 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
8 *
9 * (C) Copyright 2002
10 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
11 * Marius Groeger <mgroeger@sysgo.de>
12 *
13 * (C) Copyright 2002
14 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
15 * Alex Zuepke <azu@sysgo.de>
16 *
17 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
18 *
19 * SPDX-License-Identifier: GPL-2.0+
20 */
21
22 #include <common.h>
23 #include <asm/hardware.h>
24
25 DECLARE_GLOBAL_DATA_PTR;
26
27 /* flush serial input queue. returns 0 on success or negative error
28 * number otherwise
29 */
30 static int serial_flush_input(void)
31 {
32 volatile u32 tmp;
33
34 /* keep on reading as long as the receiver is not empty */
35 while(UTRSTAT0&0x01) {
36 tmp = REGB(URXH0);
37 }
38
39 return 0;
40 }
41
42
43 /* flush output queue. returns 0 on success or negative error number
44 * otherwise
45 */
46 static int serial_flush_output(void)
47 {
48 /* wait until the transmitter is no longer busy */
49 while(!(UTRSTAT0 & 0x02)) {
50 }
51
52 return 0;
53 }
54
55
56 static void s3c44b0_serial_setbrg(void)
57 {
58 u32 divisor = 0;
59
60 /* get correct divisor */
61 switch(gd->baudrate) {
62
63 case 1200:
64 #if CONFIG_S3C44B0_CLOCK_SPEED==66
65 divisor = 3124;
66 #elif CONFIG_S3C44B0_CLOCK_SPEED==75
67 divisor = 3905;
68 #else
69 # error CONFIG_S3C44B0_CLOCK_SPEED undefined
70 #endif
71 break;
72
73 case 9600:
74 #if CONFIG_S3C44B0_CLOCK_SPEED==66
75 divisor = 390;
76 #elif CONFIG_S3C44B0_CLOCK_SPEED==75
77 divisor = 487;
78 #else
79 # error CONFIG_S3C44B0_CLOCK_SPEED undefined
80 #endif
81 break;
82
83 case 19200:
84 #if CONFIG_S3C44B0_CLOCK_SPEED==66
85 divisor = 194;
86 #elif CONFIG_S3C44B0_CLOCK_SPEED==75
87 divisor = 243;
88 #else
89 # error CONFIG_S3C44B0_CLOCK_SPEED undefined
90 #endif
91 break;
92
93 case 38400:
94 #if CONFIG_S3C44B0_CLOCK_SPEED==66
95 divisor = 97;
96 #elif CONFIG_S3C44B0_CLOCK_SPEED==75
97 divisor = 121;
98 #else
99 # error CONFIG_S3C44B0_CLOCK_SPEED undefined
100 #endif /* break; */
101
102 case 57600:
103 #if CONFIG_S3C44B0_CLOCK_SPEED==66
104 divisor = 64;
105 #elif CONFIG_S3C44B0_CLOCK_SPEED==75
106 divisor = 80;
107 #else
108 # error CONFIG_S3C44B0_CLOCK_SPEED undefined
109 #endif /* break; */
110
111 case 115200:
112 #if CONFIG_S3C44B0_CLOCK_SPEED==66
113 divisor = 32;
114 #elif CONFIG_S3C44B0_CLOCK_SPEED==75
115 divisor = 40;
116 #else
117 # error CONFIG_S3C44B0_CLOCK_SPEED undefined
118 #endif /* break; */
119 }
120
121 serial_flush_output();
122 serial_flush_input();
123 UFCON0 = 0x0;
124 ULCON0 = 0x03;
125 UCON0 = 0x05;
126 UBRDIV0 = divisor;
127
128 UFCON1 = 0x0;
129 ULCON1 = 0x03;
130 UCON1 = 0x05;
131 UBRDIV1 = divisor;
132
133 for(divisor=0; divisor<100; divisor++) {
134 /* NOP */
135 }
136 }
137
138
139 /*
140 * Initialise the serial port with the given baudrate. The settings
141 * are always 8 data bits, no parity, 1 stop bit, no start bits.
142 *
143 */
144 static int s3c44b0_serial_init(void)
145 {
146 serial_setbrg ();
147
148 return (0);
149 }
150
151
152 /*
153 * Output a single byte to the serial port.
154 */
155 static void s3c44b0_serial_putc(const char c)
156 {
157 /* wait for room in the transmit FIFO */
158 while(!(UTRSTAT0 & 0x02));
159
160 UTXH0 = (unsigned char)c;
161
162 /*
163 to be polite with serial console add a line feed
164 to the carriage return character
165 */
166 if (c=='\n')
167 serial_putc('\r');
168 }
169
170 /*
171 * Read a single byte from the serial port. Returns 1 on success, 0
172 * otherwise. When the function is succesfull, the character read is
173 * written into its argument c.
174 */
175 static int s3c44b0_serial_tstc(void)
176 {
177 return (UTRSTAT0 & 0x01);
178 }
179
180 /*
181 * Read a single byte from the serial port. Returns 1 on success, 0
182 * otherwise. When the function is succesfull, the character read is
183 * written into its argument c.
184 */
185 static int s3c44b0_serial_getc(void)
186 {
187 int rv;
188
189 for(;;) {
190 rv = s3c44b0_serial_tstc();
191
192 if(rv > 0)
193 return URXH0;
194 }
195 }
196
197 static struct serial_device s3c44b0_serial_drv = {
198 .name = "s3c44b0_serial",
199 .start = s3c44b0_serial_init,
200 .stop = NULL,
201 .setbrg = s3c44b0_serial_setbrg,
202 .putc = s3c44b0_serial_putc,
203 .puts = default_serial_puts,
204 .getc = s3c44b0_serial_getc,
205 .tstc = s3c44b0_serial_tstc,
206 };
207
208 void s3c44b0_serial_initialize(void)
209 {
210 serial_register(&s3c44b0_serial_drv);
211 }
212
213 __weak struct serial_device *default_serial_console(void)
214 {
215 return &s3c44b0_serial_drv;
216 }