Commit 194846f398ef38d5e24c239d264a3f637c685e53

Authored by Michal Simek
Committed by Albert ARIBAUD
1 parent 76abfa5781

serial: Add Zynq serial driver

The driver is used on Xilinx Zynq platform.

Signed-off-by: Michal Simek <monstr@monstr.eu>
CC: Joe Hershberger <joe.hershberger@gmail.com>
CC: Marek Vasut <marex@denx.de>
Acked-by: Marek Vasut <marex@denx.de>

Showing 4 changed files with 261 additions and 0 deletions Inline Diff

1 /* 1 /*
2 * (C) Copyright 2004 2 * (C) Copyright 2004
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 * 4 *
5 * See file CREDITS for list of people who contributed to this 5 * See file CREDITS for list of people who contributed to this
6 * project. 6 * project.
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of 10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version. 11 * the License, or (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA 21 * MA 02111-1307 USA
22 */ 22 */
23 23
24 #include <common.h> 24 #include <common.h>
25 #include <serial.h> 25 #include <serial.h>
26 #include <stdio_dev.h> 26 #include <stdio_dev.h>
27 #include <post.h> 27 #include <post.h>
28 #include <linux/compiler.h> 28 #include <linux/compiler.h>
29 29
30 DECLARE_GLOBAL_DATA_PTR; 30 DECLARE_GLOBAL_DATA_PTR;
31 31
32 static struct serial_device *serial_devices; 32 static struct serial_device *serial_devices;
33 static struct serial_device *serial_current; 33 static struct serial_device *serial_current;
34 34
35 void serial_register(struct serial_device *dev) 35 void serial_register(struct serial_device *dev)
36 { 36 {
37 #ifdef CONFIG_NEEDS_MANUAL_RELOC 37 #ifdef CONFIG_NEEDS_MANUAL_RELOC
38 dev->init += gd->reloc_off; 38 dev->init += gd->reloc_off;
39 dev->setbrg += gd->reloc_off; 39 dev->setbrg += gd->reloc_off;
40 dev->getc += gd->reloc_off; 40 dev->getc += gd->reloc_off;
41 dev->tstc += gd->reloc_off; 41 dev->tstc += gd->reloc_off;
42 dev->putc += gd->reloc_off; 42 dev->putc += gd->reloc_off;
43 dev->puts += gd->reloc_off; 43 dev->puts += gd->reloc_off;
44 #endif 44 #endif
45 45
46 dev->next = serial_devices; 46 dev->next = serial_devices;
47 serial_devices = dev; 47 serial_devices = dev;
48 } 48 }
49 49
50 void serial_initialize(void) 50 void serial_initialize(void)
51 { 51 {
52 #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) 52 #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2)
53 serial_register(&serial_smc_device); 53 serial_register(&serial_smc_device);
54 #endif 54 #endif
55 #if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) || \ 55 #if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) || \
56 defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) 56 defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
57 serial_register(&serial_scc_device); 57 serial_register(&serial_scc_device);
58 #endif 58 #endif
59 59
60 #if defined(CONFIG_SYS_NS16550_SERIAL) 60 #if defined(CONFIG_SYS_NS16550_SERIAL)
61 #if defined(CONFIG_SYS_NS16550_COM1) 61 #if defined(CONFIG_SYS_NS16550_COM1)
62 serial_register(&eserial1_device); 62 serial_register(&eserial1_device);
63 #endif 63 #endif
64 #if defined(CONFIG_SYS_NS16550_COM2) 64 #if defined(CONFIG_SYS_NS16550_COM2)
65 serial_register(&eserial2_device); 65 serial_register(&eserial2_device);
66 #endif 66 #endif
67 #if defined(CONFIG_SYS_NS16550_COM3) 67 #if defined(CONFIG_SYS_NS16550_COM3)
68 serial_register(&eserial3_device); 68 serial_register(&eserial3_device);
69 #endif 69 #endif
70 #if defined(CONFIG_SYS_NS16550_COM4) 70 #if defined(CONFIG_SYS_NS16550_COM4)
71 serial_register(&eserial4_device); 71 serial_register(&eserial4_device);
72 #endif 72 #endif
73 #endif /* CONFIG_SYS_NS16550_SERIAL */ 73 #endif /* CONFIG_SYS_NS16550_SERIAL */
74 #if defined(CONFIG_FFUART) 74 #if defined(CONFIG_FFUART)
75 serial_register(&serial_ffuart_device); 75 serial_register(&serial_ffuart_device);
76 #endif 76 #endif
77 #if defined(CONFIG_BTUART) 77 #if defined(CONFIG_BTUART)
78 serial_register(&serial_btuart_device); 78 serial_register(&serial_btuart_device);
79 #endif 79 #endif
80 #if defined(CONFIG_STUART) 80 #if defined(CONFIG_STUART)
81 serial_register(&serial_stuart_device); 81 serial_register(&serial_stuart_device);
82 #endif 82 #endif
83 #if defined(CONFIG_S3C2410) 83 #if defined(CONFIG_S3C2410)
84 serial_register(&s3c24xx_serial0_device); 84 serial_register(&s3c24xx_serial0_device);
85 serial_register(&s3c24xx_serial1_device); 85 serial_register(&s3c24xx_serial1_device);
86 serial_register(&s3c24xx_serial2_device); 86 serial_register(&s3c24xx_serial2_device);
87 #endif 87 #endif
88 #if defined(CONFIG_S5P) 88 #if defined(CONFIG_S5P)
89 serial_register(&s5p_serial0_device); 89 serial_register(&s5p_serial0_device);
90 serial_register(&s5p_serial1_device); 90 serial_register(&s5p_serial1_device);
91 serial_register(&s5p_serial2_device); 91 serial_register(&s5p_serial2_device);
92 serial_register(&s5p_serial3_device); 92 serial_register(&s5p_serial3_device);
93 #endif 93 #endif
94 #if defined(CONFIG_MPC512X) 94 #if defined(CONFIG_MPC512X)
95 #if defined(CONFIG_SYS_PSC1) 95 #if defined(CONFIG_SYS_PSC1)
96 serial_register(&serial1_device); 96 serial_register(&serial1_device);
97 #endif 97 #endif
98 #if defined(CONFIG_SYS_PSC3) 98 #if defined(CONFIG_SYS_PSC3)
99 serial_register(&serial3_device); 99 serial_register(&serial3_device);
100 #endif 100 #endif
101 #if defined(CONFIG_SYS_PSC4) 101 #if defined(CONFIG_SYS_PSC4)
102 serial_register(&serial4_device); 102 serial_register(&serial4_device);
103 #endif 103 #endif
104 #if defined(CONFIG_SYS_PSC6) 104 #if defined(CONFIG_SYS_PSC6)
105 serial_register(&serial6_device); 105 serial_register(&serial6_device);
106 #endif 106 #endif
107 #endif 107 #endif
108 #if defined(CONFIG_SYS_BFIN_UART) 108 #if defined(CONFIG_SYS_BFIN_UART)
109 serial_register_bfin_uart(); 109 serial_register_bfin_uart();
110 #endif 110 #endif
111 #if defined(CONFIG_XILINX_UARTLITE) 111 #if defined(CONFIG_XILINX_UARTLITE)
112 # ifdef XILINX_UARTLITE_BASEADDR 112 # ifdef XILINX_UARTLITE_BASEADDR
113 serial_register(&uartlite_serial0_device); 113 serial_register(&uartlite_serial0_device);
114 # endif /* XILINX_UARTLITE_BASEADDR */ 114 # endif /* XILINX_UARTLITE_BASEADDR */
115 # ifdef XILINX_UARTLITE_BASEADDR1 115 # ifdef XILINX_UARTLITE_BASEADDR1
116 serial_register(&uartlite_serial1_device); 116 serial_register(&uartlite_serial1_device);
117 # endif /* XILINX_UARTLITE_BASEADDR1 */ 117 # endif /* XILINX_UARTLITE_BASEADDR1 */
118 # ifdef XILINX_UARTLITE_BASEADDR2 118 # ifdef XILINX_UARTLITE_BASEADDR2
119 serial_register(&uartlite_serial2_device); 119 serial_register(&uartlite_serial2_device);
120 # endif /* XILINX_UARTLITE_BASEADDR2 */ 120 # endif /* XILINX_UARTLITE_BASEADDR2 */
121 # ifdef XILINX_UARTLITE_BASEADDR3 121 # ifdef XILINX_UARTLITE_BASEADDR3
122 serial_register(&uartlite_serial3_device); 122 serial_register(&uartlite_serial3_device);
123 # endif /* XILINX_UARTLITE_BASEADDR3 */ 123 # endif /* XILINX_UARTLITE_BASEADDR3 */
124 #endif /* CONFIG_XILINX_UARTLITE */ 124 #endif /* CONFIG_XILINX_UARTLITE */
125 #if defined(CONFIG_ZYNQ_SERIAL)
126 # ifdef CONFIG_ZYNQ_SERIAL_BASEADDR0
127 serial_register(&uart_zynq_serial0_device);
128 # endif
129 # ifdef CONFIG_ZYNQ_SERIAL_BASEADDR1
130 serial_register(&uart_zynq_serial1_device);
131 # endif
132 #endif
125 serial_assign(default_serial_console()->name); 133 serial_assign(default_serial_console()->name);
126 } 134 }
127 135
128 void serial_stdio_init(void) 136 void serial_stdio_init(void)
129 { 137 {
130 struct stdio_dev dev; 138 struct stdio_dev dev;
131 struct serial_device *s = serial_devices; 139 struct serial_device *s = serial_devices;
132 140
133 while (s) { 141 while (s) {
134 memset(&dev, 0, sizeof(dev)); 142 memset(&dev, 0, sizeof(dev));
135 143
136 strcpy(dev.name, s->name); 144 strcpy(dev.name, s->name);
137 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 145 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
138 146
139 dev.start = s->init; 147 dev.start = s->init;
140 dev.stop = s->uninit; 148 dev.stop = s->uninit;
141 dev.putc = s->putc; 149 dev.putc = s->putc;
142 dev.puts = s->puts; 150 dev.puts = s->puts;
143 dev.getc = s->getc; 151 dev.getc = s->getc;
144 dev.tstc = s->tstc; 152 dev.tstc = s->tstc;
145 153
146 stdio_register(&dev); 154 stdio_register(&dev);
147 155
148 s = s->next; 156 s = s->next;
149 } 157 }
150 } 158 }
151 159
152 int serial_assign(const char *name) 160 int serial_assign(const char *name)
153 { 161 {
154 struct serial_device *s; 162 struct serial_device *s;
155 163
156 for (s = serial_devices; s; s = s->next) { 164 for (s = serial_devices; s; s = s->next) {
157 if (strcmp(s->name, name) == 0) { 165 if (strcmp(s->name, name) == 0) {
158 serial_current = s; 166 serial_current = s;
159 return 0; 167 return 0;
160 } 168 }
161 } 169 }
162 170
163 return 1; 171 return 1;
164 } 172 }
165 173
166 void serial_reinit_all(void) 174 void serial_reinit_all(void)
167 { 175 {
168 struct serial_device *s; 176 struct serial_device *s;
169 177
170 for (s = serial_devices; s; s = s->next) 178 for (s = serial_devices; s; s = s->next)
171 s->init(); 179 s->init();
172 } 180 }
173 181
174 static struct serial_device *get_current(void) 182 static struct serial_device *get_current(void)
175 { 183 {
176 struct serial_device *dev; 184 struct serial_device *dev;
177 185
178 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { 186 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
179 dev = default_serial_console(); 187 dev = default_serial_console();
180 188
181 /* We must have a console device */ 189 /* We must have a console device */
182 if (!dev) 190 if (!dev)
183 panic("Cannot find console"); 191 panic("Cannot find console");
184 } else 192 } else
185 dev = serial_current; 193 dev = serial_current;
186 return dev; 194 return dev;
187 } 195 }
188 196
189 int serial_init(void) 197 int serial_init(void)
190 { 198 {
191 return get_current()->init(); 199 return get_current()->init();
192 } 200 }
193 201
194 void serial_setbrg(void) 202 void serial_setbrg(void)
195 { 203 {
196 get_current()->setbrg(); 204 get_current()->setbrg();
197 } 205 }
198 206
199 int serial_getc(void) 207 int serial_getc(void)
200 { 208 {
201 return get_current()->getc(); 209 return get_current()->getc();
202 } 210 }
203 211
204 int serial_tstc(void) 212 int serial_tstc(void)
205 { 213 {
206 return get_current()->tstc(); 214 return get_current()->tstc();
207 } 215 }
208 216
209 void serial_putc(const char c) 217 void serial_putc(const char c)
210 { 218 {
211 get_current()->putc(c); 219 get_current()->putc(c);
212 } 220 }
213 221
214 void serial_puts(const char *s) 222 void serial_puts(const char *s)
215 { 223 {
216 get_current()->puts(s); 224 get_current()->puts(s);
217 } 225 }
218 226
219 #if CONFIG_POST & CONFIG_SYS_POST_UART 227 #if CONFIG_POST & CONFIG_SYS_POST_UART
220 static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE; 228 static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE;
221 229
222 /* Mark weak until post/cpu/.../uart.c migrate over */ 230 /* Mark weak until post/cpu/.../uart.c migrate over */
223 __weak 231 __weak
224 int uart_post_test(int flags) 232 int uart_post_test(int flags)
225 { 233 {
226 unsigned char c; 234 unsigned char c;
227 int ret, saved_baud, b; 235 int ret, saved_baud, b;
228 struct serial_device *saved_dev, *s; 236 struct serial_device *saved_dev, *s;
229 bd_t *bd = gd->bd; 237 bd_t *bd = gd->bd;
230 238
231 /* Save current serial state */ 239 /* Save current serial state */
232 ret = 0; 240 ret = 0;
233 saved_dev = serial_current; 241 saved_dev = serial_current;
234 saved_baud = bd->bi_baudrate; 242 saved_baud = bd->bi_baudrate;
235 243
236 for (s = serial_devices; s; s = s->next) { 244 for (s = serial_devices; s; s = s->next) {
237 /* If this driver doesn't support loop back, skip it */ 245 /* If this driver doesn't support loop back, skip it */
238 if (!s->loop) 246 if (!s->loop)
239 continue; 247 continue;
240 248
241 /* Test the next device */ 249 /* Test the next device */
242 serial_current = s; 250 serial_current = s;
243 251
244 ret = serial_init(); 252 ret = serial_init();
245 if (ret) 253 if (ret)
246 goto done; 254 goto done;
247 255
248 /* Consume anything that happens to be queued */ 256 /* Consume anything that happens to be queued */
249 while (serial_tstc()) 257 while (serial_tstc())
250 serial_getc(); 258 serial_getc();
251 259
252 /* Enable loop back */ 260 /* Enable loop back */
253 s->loop(1); 261 s->loop(1);
254 262
255 /* Test every available baud rate */ 263 /* Test every available baud rate */
256 for (b = 0; b < ARRAY_SIZE(bauds); ++b) { 264 for (b = 0; b < ARRAY_SIZE(bauds); ++b) {
257 bd->bi_baudrate = bauds[b]; 265 bd->bi_baudrate = bauds[b];
258 serial_setbrg(); 266 serial_setbrg();
259 267
260 /* 268 /*
261 * Stick to printable chars to avoid issues: 269 * Stick to printable chars to avoid issues:
262 * - terminal corruption 270 * - terminal corruption
263 * - serial program reacting to sequences and sending 271 * - serial program reacting to sequences and sending
264 * back random extra data 272 * back random extra data
265 * - most serial drivers add in extra chars (like \r\n) 273 * - most serial drivers add in extra chars (like \r\n)
266 */ 274 */
267 for (c = 0x20; c < 0x7f; ++c) { 275 for (c = 0x20; c < 0x7f; ++c) {
268 /* Send it out */ 276 /* Send it out */
269 serial_putc(c); 277 serial_putc(c);
270 278
271 /* Make sure it's the same one */ 279 /* Make sure it's the same one */
272 ret = (c != serial_getc()); 280 ret = (c != serial_getc());
273 if (ret) { 281 if (ret) {
274 s->loop(0); 282 s->loop(0);
275 goto done; 283 goto done;
276 } 284 }
277 285
278 /* Clean up the output in case it was sent */ 286 /* Clean up the output in case it was sent */
279 serial_putc('\b'); 287 serial_putc('\b');
280 ret = ('\b' != serial_getc()); 288 ret = ('\b' != serial_getc());
281 if (ret) { 289 if (ret) {
282 s->loop(0); 290 s->loop(0);
283 goto done; 291 goto done;
284 } 292 }
285 } 293 }
286 } 294 }
287 295
288 /* Disable loop back */ 296 /* Disable loop back */
289 s->loop(0); 297 s->loop(0);
290 298
291 /* XXX: There is no serial_uninit() !? */ 299 /* XXX: There is no serial_uninit() !? */
292 if (s->uninit) 300 if (s->uninit)
293 s->uninit(); 301 s->uninit();
294 } 302 }
295 303
296 done: 304 done:
297 /* Restore previous serial state */ 305 /* Restore previous serial state */
298 serial_current = saved_dev; 306 serial_current = saved_dev;
299 bd->bi_baudrate = saved_baud; 307 bd->bi_baudrate = saved_baud;
300 serial_reinit_all(); 308 serial_reinit_all();
301 serial_setbrg(); 309 serial_setbrg();
302 310
303 return ret; 311 return ret;
304 } 312 }
305 #endif 313 #endif
306 314
drivers/serial/Makefile
1 # 1 #
2 # (C) Copyright 2006-2009 2 # (C) Copyright 2006-2009
3 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 # 4 #
5 # See file CREDITS for list of people who contributed to this 5 # See file CREDITS for list of people who contributed to this
6 # project. 6 # project.
7 # 7 #
8 # This program is free software; you can redistribute it and/or 8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License as 9 # modify it under the terms of the GNU General Public License as
10 # published by the Free Software Foundation; either version 2 of 10 # published by the Free Software Foundation; either version 2 of
11 # the License, or (at your option) any later version. 11 # the License, or (at your option) any later version.
12 # 12 #
13 # This program is distributed in the hope that it will be useful, 13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details. 16 # GNU General Public License for more details.
17 # 17 #
18 # You should have received a copy of the GNU General Public License 18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software 19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 # MA 02111-1307 USA 21 # MA 02111-1307 USA
22 # 22 #
23 23
24 include $(TOPDIR)/config.mk 24 include $(TOPDIR)/config.mk
25 25
26 LIB := $(obj)libserial.o 26 LIB := $(obj)libserial.o
27 27
28 COBJS-$(CONFIG_ALTERA_UART) += altera_uart.o 28 COBJS-$(CONFIG_ALTERA_UART) += altera_uart.o
29 COBJS-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o 29 COBJS-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
30 COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o 30 COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o
31 COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o 31 COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o
32 COBJS-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o 32 COBJS-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
33 COBJS-$(CONFIG_MCFUART) += mcfuart.o 33 COBJS-$(CONFIG_MCFUART) += mcfuart.o
34 COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o 34 COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o
35 COBJS-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o 35 COBJS-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o
36 COBJS-$(CONFIG_SYS_NS16550) += ns16550.o 36 COBJS-$(CONFIG_SYS_NS16550) += ns16550.o
37 COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o 37 COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o
38 COBJS-$(CONFIG_S3C64XX) += s3c64xx.o 38 COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
39 COBJS-$(CONFIG_S5P) += serial_s5p.o 39 COBJS-$(CONFIG_S5P) += serial_s5p.o
40 COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial.o 40 COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial.o
41 COBJS-$(CONFIG_CLPS7111_SERIAL) += serial_clps7111.o 41 COBJS-$(CONFIG_CLPS7111_SERIAL) += serial_clps7111.o
42 COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o 42 COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
43 COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o 43 COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
44 COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o 44 COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
45 COBJS-$(CONFIG_LPC2292_SERIAL) += serial_lpc2292.o 45 COBJS-$(CONFIG_LPC2292_SERIAL) += serial_lpc2292.o
46 COBJS-$(CONFIG_LH7A40X_SERIAL) += serial_lh7a40x.o 46 COBJS-$(CONFIG_LH7A40X_SERIAL) += serial_lh7a40x.o
47 COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o 47 COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
48 COBJS-$(CONFIG_MXC_UART) += serial_mxc.o 48 COBJS-$(CONFIG_MXC_UART) += serial_mxc.o
49 COBJS-$(CONFIG_NETARM_SERIAL) += serial_netarm.o 49 COBJS-$(CONFIG_NETARM_SERIAL) += serial_netarm.o
50 COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o 50 COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
51 COBJS-$(CONFIG_PL011_SERIAL) += serial_pl01x.o 51 COBJS-$(CONFIG_PL011_SERIAL) += serial_pl01x.o
52 COBJS-$(CONFIG_PXA_SERIAL) += serial_pxa.o 52 COBJS-$(CONFIG_PXA_SERIAL) += serial_pxa.o
53 COBJS-$(CONFIG_SA1100_SERIAL) += serial_sa1100.o 53 COBJS-$(CONFIG_SA1100_SERIAL) += serial_sa1100.o
54 COBJS-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o 54 COBJS-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o
55 COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o 55 COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
56 COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o 56 COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
57 COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o 57 COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
58 COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o 58 COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
59 COBJS-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o
59 60
60 ifndef CONFIG_SPL_BUILD 61 ifndef CONFIG_SPL_BUILD
61 COBJS-$(CONFIG_USB_TTY) += usbtty.o 62 COBJS-$(CONFIG_USB_TTY) += usbtty.o
62 endif 63 endif
63 64
64 COBJS := $(sort $(COBJS-y)) 65 COBJS := $(sort $(COBJS-y))
65 SRCS := $(COBJS:.o=.c) 66 SRCS := $(COBJS:.o=.c)
66 OBJS := $(addprefix $(obj),$(COBJS)) 67 OBJS := $(addprefix $(obj),$(COBJS))
67 68
68 all: $(LIB) 69 all: $(LIB)
69 70
70 $(LIB): $(obj).depend $(OBJS) 71 $(LIB): $(obj).depend $(OBJS)
71 $(call cmd_link_o_target, $(OBJS)) 72 $(call cmd_link_o_target, $(OBJS))
72 73
73 ######################################################################### 74 #########################################################################
74 75
75 # defines $(obj).depend target 76 # defines $(obj).depend target
76 include $(SRCTREE)/rules.mk 77 include $(SRCTREE)/rules.mk
77 78
78 sinclude $(obj).depend 79 sinclude $(obj).depend
79 80
80 ######################################################################### 81 #########################################################################
81 82
drivers/serial/serial_zynq.c
File was created 1 /*
2 * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
3 * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24 #include <common.h>
25 #include <watchdog.h>
26 #include <asm/io.h>
27 #include <linux/compiler.h>
28 #include <serial.h>
29
30 #define ZYNQ_UART_SR_TXFULL 0x00000010 /* TX FIFO full */
31 #define ZYNQ_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */
32
33 #define ZYNQ_UART_CR_TX_EN 0x00000010 /* TX enabled */
34 #define ZYNQ_UART_CR_RX_EN 0x00000004 /* RX enabled */
35 #define ZYNQ_UART_CR_TXRST 0x00000002 /* TX logic reset */
36 #define ZYNQ_UART_CR_RXRST 0x00000001 /* RX logic reset */
37
38 #define ZYNQ_UART_MR_PARITY_NONE 0x00000020 /* No parity mode */
39
40 /* Some clock/baud constants */
41 #define ZYNQ_UART_BDIV 15 /* Default/reset BDIV value */
42 #define ZYNQ_UART_BASECLK 3125000L /* master / (bdiv + 1) */
43
44 struct uart_zynq {
45 u32 control; /* Control Register [8:0] */
46 u32 mode; /* Mode Register [10:0] */
47 u32 reserved1[4];
48 u32 baud_rate_gen; /* Baud Rate Generator [15:0] */
49 u32 reserved2[4];
50 u32 channel_sts; /* Channel Status [11:0] */
51 u32 tx_rx_fifo; /* FIFO [15:0] or [7:0] */
52 u32 baud_rate_divider; /* Baud Rate Divider [7:0] */
53 };
54
55 static struct uart_zynq *uart_zynq_ports[2] = {
56 #ifdef CONFIG_ZYNQ_SERIAL_BASEADDR0
57 [0] = (struct uart_zynq *)CONFIG_ZYNQ_SERIAL_BASEADDR0,
58 #endif
59 #ifdef CONFIG_ZYNQ_SERIAL_BASEADDR1
60 [1] = (struct uart_zynq *)CONFIG_ZYNQ_SERIAL_BASEADDR1,
61 #endif
62 };
63
64 struct uart_zynq_params {
65 u32 baudrate;
66 u32 clock;
67 };
68
69 static struct uart_zynq_params uart_zynq_ports_param[2] = {
70 #if defined(CONFIG_ZYNQ_SERIAL_BAUDRATE0) && defined(CONFIG_ZYNQ_SERIAL_CLOCK0)
71 [0].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE0,
72 [0].clock = CONFIG_ZYNQ_SERIAL_CLOCK0,
73 #endif
74 #if defined(CONFIG_ZYNQ_SERIAL_BAUDRATE1) && defined(CONFIG_ZYNQ_SERIAL_CLOCK1)
75 [1].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE1,
76 [1].clock = CONFIG_ZYNQ_SERIAL_CLOCK1,
77 #endif
78 };
79
80 /* Set up the baud rate in gd struct */
81 static void uart_zynq_serial_setbrg(const int port)
82 {
83 /* Calculation results. */
84 unsigned int calc_bauderror, bdiv, bgen;
85 unsigned long calc_baud = 0;
86 unsigned long baud = uart_zynq_ports_param[port].baudrate;
87 unsigned long clock = uart_zynq_ports_param[port].clock;
88 struct uart_zynq *regs = uart_zynq_ports[port];
89
90 /* master clock
91 * Baud rate = ------------------
92 * bgen * (bdiv + 1)
93 *
94 * Find acceptable values for baud generation.
95 */
96 for (bdiv = 4; bdiv < 255; bdiv++) {
97 bgen = clock / (baud * (bdiv + 1));
98 if (bgen < 2 || bgen > 65535)
99 continue;
100
101 calc_baud = clock / (bgen * (bdiv + 1));
102
103 /*
104 * Use first calculated baudrate with
105 * an acceptable (<3%) error
106 */
107 if (baud > calc_baud)
108 calc_bauderror = baud - calc_baud;
109 else
110 calc_bauderror = calc_baud - baud;
111 if (((calc_bauderror * 100) / baud) < 3)
112 break;
113 }
114
115 writel(bdiv, &regs->baud_rate_divider);
116 writel(bgen, &regs->baud_rate_gen);
117 }
118
119 /* Initialize the UART, with...some settings. */
120 static int uart_zynq_serial_init(const int port)
121 {
122 struct uart_zynq *regs = uart_zynq_ports[port];
123
124 if (!regs)
125 return -1;
126
127 /* RX/TX enabled & reset */
128 writel(ZYNQ_UART_CR_TX_EN | ZYNQ_UART_CR_RX_EN | ZYNQ_UART_CR_TXRST | \
129 ZYNQ_UART_CR_RXRST, &regs->control);
130 writel(ZYNQ_UART_MR_PARITY_NONE, &regs->mode); /* 8 bit, no parity */
131 uart_zynq_serial_setbrg(port);
132
133 return 0;
134 }
135
136 static void uart_zynq_serial_putc(const char c, const int port)
137 {
138 struct uart_zynq *regs = uart_zynq_ports[port];
139
140 while ((readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0)
141 WATCHDOG_RESET();
142
143 if (c == '\n') {
144 writel('\r', &regs->tx_rx_fifo);
145 while ((readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0)
146 WATCHDOG_RESET();
147 }
148 writel(c, &regs->tx_rx_fifo);
149 }
150
151 static void uart_zynq_serial_puts(const char *s, const int port)
152 {
153 while (*s)
154 uart_zynq_serial_putc(*s++, port);
155 }
156
157 static int uart_zynq_serial_tstc(const int port)
158 {
159 struct uart_zynq *regs = uart_zynq_ports[port];
160
161 return (readl(&regs->channel_sts) & ZYNQ_UART_SR_RXEMPTY) == 0;
162 }
163
164 static int uart_zynq_serial_getc(const int port)
165 {
166 struct uart_zynq *regs = uart_zynq_ports[port];
167
168 while (!uart_zynq_serial_tstc(port))
169 WATCHDOG_RESET();
170 return readl(&regs->tx_rx_fifo);
171 }
172
173 #if !defined(CONFIG_SERIAL_MULTI)
174 int serial_init(void)
175 {
176 return uart_zynq_serial_init(0);
177 }
178
179 void serial_setbrg(void)
180 {
181 uart_zynq_serial_setbrg(0);
182 }
183
184 void serial_putc(const char c)
185 {
186 uart_zynq_serial_putc(c, 0);
187 }
188
189 void serial_puts(const char *s)
190 {
191 uart_zynq_serial_puts(s, 0);
192 }
193
194 int serial_getc(void)
195 {
196 return uart_zynq_serial_getc(0);
197 }
198
199 int serial_tstc(void)
200 {
201 return uart_zynq_serial_tstc(0);
202 }
203 #else
204 /* Multi serial device functions */
205 #define DECLARE_PSSERIAL_FUNCTIONS(port) \
206 int uart_zynq##port##_init(void) \
207 { return uart_zynq_serial_init(port); } \
208 void uart_zynq##port##_setbrg(void) \
209 { return uart_zynq_serial_setbrg(port); } \
210 int uart_zynq##port##_getc(void) \
211 { return uart_zynq_serial_getc(port); } \
212 int uart_zynq##port##_tstc(void) \
213 { return uart_zynq_serial_tstc(port); } \
214 void uart_zynq##port##_putc(const char c) \
215 { uart_zynq_serial_putc(c, port); } \
216 void uart_zynq##port##_puts(const char *s) \
217 { uart_zynq_serial_puts(s, port); }
218
219 /* Serial device descriptor */
220 #define INIT_PSSERIAL_STRUCTURE(port, __name) { \
221 .name = __name, \
222 .init = uart_zynq##port##_init, \
223 .uninit = NULL, \
224 .setbrg = uart_zynq##port##_setbrg, \
225 .getc = uart_zynq##port##_getc, \
226 .tstc = uart_zynq##port##_tstc, \
227 .putc = uart_zynq##port##_putc, \
228 .puts = uart_zynq##port##_puts, \
229 }
230
231 DECLARE_PSSERIAL_FUNCTIONS(0);
232 struct serial_device uart_zynq_serial0_device =
233 INIT_PSSERIAL_STRUCTURE(0, "ttyPS0");
234 DECLARE_PSSERIAL_FUNCTIONS(1);
235 struct serial_device uart_zynq_serial1_device =
236 INIT_PSSERIAL_STRUCTURE(1, "ttyPS1");
237
238 __weak struct serial_device *default_serial_console(void)
239 {
240 if (uart_zynq_ports[0])
241 return &uart_zynq_serial0_device;
242 if (uart_zynq_ports[1])
243 return &uart_zynq_serial1_device;
244
245 return NULL;
246 }
247 #endif
248
1 #ifndef __SERIAL_H__ 1 #ifndef __SERIAL_H__
2 #define __SERIAL_H__ 2 #define __SERIAL_H__
3 3
4 #include <post.h> 4 #include <post.h>
5 5
6 struct serial_device { 6 struct serial_device {
7 /* enough bytes to match alignment of following func pointer */ 7 /* enough bytes to match alignment of following func pointer */
8 char name[16]; 8 char name[16];
9 9
10 int (*init) (void); 10 int (*init) (void);
11 int (*uninit) (void); 11 int (*uninit) (void);
12 void (*setbrg) (void); 12 void (*setbrg) (void);
13 int (*getc) (void); 13 int (*getc) (void);
14 int (*tstc) (void); 14 int (*tstc) (void);
15 void (*putc) (const char c); 15 void (*putc) (const char c);
16 void (*puts) (const char *s); 16 void (*puts) (const char *s);
17 #if CONFIG_POST & CONFIG_SYS_POST_UART 17 #if CONFIG_POST & CONFIG_SYS_POST_UART
18 void (*loop) (int); 18 void (*loop) (int);
19 #endif 19 #endif
20 20
21 struct serial_device *next; 21 struct serial_device *next;
22 }; 22 };
23 23
24 extern struct serial_device serial_smc_device; 24 extern struct serial_device serial_smc_device;
25 extern struct serial_device serial_scc_device; 25 extern struct serial_device serial_scc_device;
26 extern struct serial_device *default_serial_console(void); 26 extern struct serial_device *default_serial_console(void);
27 27
28 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \ 28 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
29 defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \ 29 defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
30 defined(CONFIG_405EX) || defined(CONFIG_440) || \ 30 defined(CONFIG_405EX) || defined(CONFIG_440) || \
31 defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) || \ 31 defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) || \
32 defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \ 32 defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \
33 defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) || \ 33 defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) || \
34 defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \ 34 defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \
35 defined(CONFIG_MICROBLAZE) 35 defined(CONFIG_MICROBLAZE)
36 extern struct serial_device serial0_device; 36 extern struct serial_device serial0_device;
37 extern struct serial_device serial1_device; 37 extern struct serial_device serial1_device;
38 #if defined(CONFIG_SYS_NS16550_SERIAL) 38 #if defined(CONFIG_SYS_NS16550_SERIAL)
39 extern struct serial_device eserial1_device; 39 extern struct serial_device eserial1_device;
40 extern struct serial_device eserial2_device; 40 extern struct serial_device eserial2_device;
41 extern struct serial_device eserial3_device; 41 extern struct serial_device eserial3_device;
42 extern struct serial_device eserial4_device; 42 extern struct serial_device eserial4_device;
43 #endif /* CONFIG_SYS_NS16550_SERIAL */ 43 #endif /* CONFIG_SYS_NS16550_SERIAL */
44 44
45 #endif 45 #endif
46 46
47 #if defined(CONFIG_MPC512X) 47 #if defined(CONFIG_MPC512X)
48 extern struct serial_device serial1_device; 48 extern struct serial_device serial1_device;
49 extern struct serial_device serial3_device; 49 extern struct serial_device serial3_device;
50 extern struct serial_device serial4_device; 50 extern struct serial_device serial4_device;
51 extern struct serial_device serial6_device; 51 extern struct serial_device serial6_device;
52 #endif 52 #endif
53 53
54 #if defined(CONFIG_XILINX_UARTLITE) 54 #if defined(CONFIG_XILINX_UARTLITE)
55 extern struct serial_device uartlite_serial0_device; 55 extern struct serial_device uartlite_serial0_device;
56 extern struct serial_device uartlite_serial1_device; 56 extern struct serial_device uartlite_serial1_device;
57 extern struct serial_device uartlite_serial2_device; 57 extern struct serial_device uartlite_serial2_device;
58 extern struct serial_device uartlite_serial3_device; 58 extern struct serial_device uartlite_serial3_device;
59 #endif 59 #endif
60 60
61 #if defined(CONFIG_S3C2410) 61 #if defined(CONFIG_S3C2410)
62 extern struct serial_device s3c24xx_serial0_device; 62 extern struct serial_device s3c24xx_serial0_device;
63 extern struct serial_device s3c24xx_serial1_device; 63 extern struct serial_device s3c24xx_serial1_device;
64 extern struct serial_device s3c24xx_serial2_device; 64 extern struct serial_device s3c24xx_serial2_device;
65 #endif 65 #endif
66 66
67 #if defined(CONFIG_S5P) 67 #if defined(CONFIG_S5P)
68 extern struct serial_device s5p_serial0_device; 68 extern struct serial_device s5p_serial0_device;
69 extern struct serial_device s5p_serial1_device; 69 extern struct serial_device s5p_serial1_device;
70 extern struct serial_device s5p_serial2_device; 70 extern struct serial_device s5p_serial2_device;
71 extern struct serial_device s5p_serial3_device; 71 extern struct serial_device s5p_serial3_device;
72 #endif 72 #endif
73 73
74 #if defined(CONFIG_OMAP3_ZOOM2) 74 #if defined(CONFIG_OMAP3_ZOOM2)
75 extern struct serial_device zoom2_serial_device0; 75 extern struct serial_device zoom2_serial_device0;
76 extern struct serial_device zoom2_serial_device1; 76 extern struct serial_device zoom2_serial_device1;
77 extern struct serial_device zoom2_serial_device2; 77 extern struct serial_device zoom2_serial_device2;
78 extern struct serial_device zoom2_serial_device3; 78 extern struct serial_device zoom2_serial_device3;
79 #endif 79 #endif
80 80
81 extern struct serial_device serial_ffuart_device; 81 extern struct serial_device serial_ffuart_device;
82 extern struct serial_device serial_btuart_device; 82 extern struct serial_device serial_btuart_device;
83 extern struct serial_device serial_stuart_device; 83 extern struct serial_device serial_stuart_device;
84 84
85 #if defined(CONFIG_SYS_BFIN_UART) 85 #if defined(CONFIG_SYS_BFIN_UART)
86 extern void serial_register_bfin_uart(void); 86 extern void serial_register_bfin_uart(void);
87 extern struct serial_device bfin_serial0_device; 87 extern struct serial_device bfin_serial0_device;
88 extern struct serial_device bfin_serial1_device; 88 extern struct serial_device bfin_serial1_device;
89 extern struct serial_device bfin_serial2_device; 89 extern struct serial_device bfin_serial2_device;
90 extern struct serial_device bfin_serial3_device; 90 extern struct serial_device bfin_serial3_device;
91 #endif 91 #endif
92 92
93 #if defined(CONFIG_ZYNQ_SERIAL)
94 extern struct serial_device uart_zynq_serial0_device;
95 extern struct serial_device uart_zynq_serial1_device;
96 #endif
97
93 extern void serial_register(struct serial_device *); 98 extern void serial_register(struct serial_device *);
94 extern void serial_initialize(void); 99 extern void serial_initialize(void);
95 extern void serial_stdio_init(void); 100 extern void serial_stdio_init(void);
96 extern int serial_assign(const char *name); 101 extern int serial_assign(const char *name);
97 extern void serial_reinit_all(void); 102 extern void serial_reinit_all(void);
98 103
99 /* For usbtty */ 104 /* For usbtty */
100 #ifdef CONFIG_USB_TTY 105 #ifdef CONFIG_USB_TTY
101 106
102 extern int usbtty_getc(void); 107 extern int usbtty_getc(void);
103 extern void usbtty_putc(const char c); 108 extern void usbtty_putc(const char c);
104 extern void usbtty_puts(const char *str); 109 extern void usbtty_puts(const char *str);
105 extern int usbtty_tstc(void); 110 extern int usbtty_tstc(void);
106 111
107 #else 112 #else
108 113
109 /* stubs */ 114 /* stubs */
110 #define usbtty_getc() 0 115 #define usbtty_getc() 0
111 #define usbtty_putc(a) 116 #define usbtty_putc(a)
112 #define usbtty_puts(a) 117 #define usbtty_puts(a)
113 #define usbtty_tstc() 0 118 #define usbtty_tstc() 0
114 119
115 #endif /* CONFIG_USB_TTY */ 120 #endif /* CONFIG_USB_TTY */
116 121
117 #if defined(CONFIG_MPC512X) && defined(CONFIG_SERIAL_MULTI) 122 #if defined(CONFIG_MPC512X) && defined(CONFIG_SERIAL_MULTI)
118 extern struct stdio_dev *open_port(int num, int baudrate); 123 extern struct stdio_dev *open_port(int num, int baudrate);
119 extern int close_port(int num); 124 extern int close_port(int num);
120 extern int write_port(struct stdio_dev *port, char *buf); 125 extern int write_port(struct stdio_dev *port, char *buf);
121 extern int read_port(struct stdio_dev *port, char *buf, int size); 126 extern int read_port(struct stdio_dev *port, char *buf, int size);
122 #endif 127 #endif
123 128
124 #endif 129 #endif
125 130