Linux-2.6.12-rc2
[safe/jmp/linux-2.6] / arch / cris / arch-v10 / kernel / debugport.c
1 /* Serialport functions for debugging
2  *
3  * Copyright (c) 2000 Axis Communications AB
4  *
5  * Authors:  Bjorn Wesen
6  *
7  * Exports:
8  *    console_print_etrax(char *buf)
9  *    int getDebugChar()
10  *    putDebugChar(int)
11  *    enableDebugIRQ()
12  *    init_etrax_debug()
13  *
14  * $Log: debugport.c,v $
15  * Revision 1.19  2004/10/21 07:26:16  starvik
16  * Made it possible to specify console settings on kernel command line.
17  *
18  * Revision 1.18  2004/10/19 13:07:37  starvik
19  * Merge of Linux 2.6.9
20  *
21  * Revision 1.17  2004/09/29 10:33:46  starvik
22  * Resolved a dealock when printing debug from kernel.
23  *
24  * Revision 1.16  2004/08/24 06:12:19  starvik
25  * Whitespace cleanup
26  *
27  * Revision 1.15  2004/08/16 12:37:19  starvik
28  * Merge of Linux 2.6.8
29  *
30  * Revision 1.14  2004/05/17 13:11:29  starvik
31  * Disable DMA until real serial driver is up
32  *
33  * Revision 1.13  2004/05/14 07:58:01  starvik
34  * Merge of changes from 2.4
35  *
36  * Revision 1.12  2003/09/11 07:29:49  starvik
37  * Merge of Linux 2.6.0-test5
38  *
39  * Revision 1.11  2003/07/07 09:53:36  starvik
40  * Revert all the 2.5.74 merge changes to make the console work again
41  *
42  * Revision 1.9  2003/02/17 17:07:23  starvik
43  * Solved the problem with corrupted debug output (from Linux 2.4)
44  *   * Wait until DMA, FIFO and pipe is empty before and after transmissions
45  *   * Buffer data until a FIFO flush can be triggered.
46  *
47  * Revision 1.8  2003/01/22 06:48:36  starvik
48  * Fixed warnings issued by GCC 3.2.1
49  *
50  * Revision 1.7  2002/12/12 08:26:32  starvik
51  * Don't use C-comments inside CVS comments
52  *
53  * Revision 1.6  2002/12/11 15:42:02  starvik
54  * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
55  *
56  * Revision 1.5  2002/11/20 06:58:03  starvik
57  * Compiles with kgdb
58  *
59  * Revision 1.4  2002/11/19 14:35:24  starvik
60  * Changes from linux 2.4
61  * Changed struct initializer syntax to the currently prefered notation
62  *
63  * Revision 1.3  2002/11/06 09:47:03  starvik
64  * Modified for new interrupt macros
65  *
66  * Revision 1.2  2002/01/21 15:21:50  bjornw
67  * Update for kdev_t changes
68  *
69  * Revision 1.6  2001/04/17 13:58:39  orjanf
70  * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
71  *
72  * Revision 1.5  2001/03/26 14:22:05  bjornw
73  * Namechange of some config options
74  *
75  * Revision 1.4  2000/10/06 12:37:26  bjornw
76  * Use physical addresses when talking to DMA
77  *
78  *
79  */
80
81 #include <linux/config.h>
82 #include <linux/console.h>
83 #include <linux/init.h>
84 #include <linux/major.h>
85 #include <linux/delay.h>
86 #include <linux/tty.h>
87 #include <asm/system.h>
88 #include <asm/arch/svinto.h>
89 #include <asm/io.h>             /* Get SIMCOUT. */
90
91 struct dbg_port
92 {
93   unsigned int index;
94   const volatile unsigned* read;
95   volatile char* write;
96   volatile unsigned* xoff;
97   volatile char* baud;
98   volatile char* tr_ctrl;
99   volatile char* rec_ctrl;
100   unsigned long irq;
101   unsigned int started;
102   unsigned long baudrate;
103   unsigned char parity;
104   unsigned int bits;
105 };
106
107 struct dbg_port ports[]=
108 {
109   {
110     0,
111     R_SERIAL0_READ,
112     R_SERIAL0_TR_DATA,
113     R_SERIAL0_XOFF,
114     R_SERIAL0_BAUD,
115     R_SERIAL0_TR_CTRL,
116     R_SERIAL0_REC_CTRL,
117     IO_STATE(R_IRQ_MASK1_SET, ser0_data, set)
118   },
119   {
120     1,
121     R_SERIAL1_READ,
122     R_SERIAL1_TR_DATA,
123     R_SERIAL1_XOFF,
124     R_SERIAL1_BAUD,
125     R_SERIAL1_TR_CTRL,
126     R_SERIAL1_REC_CTRL,
127     IO_STATE(R_IRQ_MASK1_SET, ser1_data, set)
128   },
129   {
130     2,
131     R_SERIAL2_READ,
132     R_SERIAL2_TR_DATA,
133     R_SERIAL2_XOFF,
134     R_SERIAL2_BAUD,
135     R_SERIAL2_TR_CTRL,
136     R_SERIAL2_REC_CTRL,
137     IO_STATE(R_IRQ_MASK1_SET, ser2_data, set)
138   },
139   {
140     3,
141     R_SERIAL3_READ,
142     R_SERIAL3_TR_DATA,
143     R_SERIAL3_XOFF,
144     R_SERIAL3_BAUD,
145     R_SERIAL3_TR_CTRL,
146     R_SERIAL3_REC_CTRL,
147     IO_STATE(R_IRQ_MASK1_SET, ser3_data, set)
148   }
149 };
150
151 static struct tty_driver *serial_driver;
152
153 struct dbg_port* port =
154 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
155   &ports[0];
156 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
157   &ports[1];
158 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
159   &ports[2];
160 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
161   &ports[3];
162 #else
163   NULL;
164 #endif
165 /* Used by serial.c to register a debug_write_function so that the normal
166  * serial driver is used for kernel debug output
167  */
168 typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len);
169
170 debugport_write_function debug_write_function = NULL;
171
172 static void
173 start_port(void)
174 {
175         unsigned long rec_ctrl = 0;
176         unsigned long tr_ctrl = 0;
177
178         if (!port)
179                 return;
180
181         if (port->started)
182                 return;
183         port->started = 1;
184
185         if (port->index == 0)
186         {
187                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6);
188                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
189         }
190         else if (port->index == 1)
191         {
192                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8);
193                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
194         }
195         else if (port->index == 2)
196         {
197                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2);
198                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
199                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3);
200                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0);
201                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser2, select);
202         }
203         else
204         {
205                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4);
206                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
207                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5);
208                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1);
209                 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser3, select);
210         }
211
212         *R_GEN_CONFIG = genconfig_shadow;
213
214         *port->xoff =
215                 IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) |
216                 IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) |
217                 IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0);
218
219         switch (port->baudrate)
220         {
221         case 0:
222         case 115200:
223                 *port->baud =
224                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
225                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
226                 break;
227         case 1200:
228                 *port->baud =
229                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) |
230                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz);
231                 break;
232         case 2400:
233                 *port->baud =
234                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) |
235                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz);
236                 break;
237         case 4800:
238                 *port->baud =
239                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) |
240                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz);
241                 break;
242         case 9600:
243                 *port->baud =
244                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) |
245                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz);
246                   break;
247         case 19200:
248                 *port->baud =
249                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) |
250                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz);
251                  break;
252         case 38400:
253                 *port->baud =
254                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) |
255                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz);
256                 break;
257         case 57600:
258                 *port->baud =
259                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) |
260                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz);
261                 break;
262         default:
263                 *port->baud =
264                   IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
265                   IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
266                   break;
267         }
268
269         if (port->parity == 'E') {
270                 rec_ctrl =
271                   IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
272                   IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
273                 tr_ctrl =
274                   IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
275                   IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
276         } else if (port->parity == 'O') {
277                 rec_ctrl =
278                   IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) |
279                   IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
280                 tr_ctrl =
281                   IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd) |
282                   IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
283         } else {
284                 rec_ctrl =
285                   IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
286                   IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, disable);
287                 tr_ctrl =
288                   IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
289                   IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable);
290         }
291
292         if (port->bits == 7)
293         {
294                 rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit);
295                 tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit);
296         }
297         else
298         {
299                 rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit);
300                 tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit);
301         }
302
303         *port->rec_ctrl =
304                 IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) |
305                 IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) |
306                 IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) |
307                 IO_STATE(R_SERIAL0_REC_CTRL, sampling, middle) |
308                 IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) |
309                 rec_ctrl;
310
311         *port->tr_ctrl =
312                 IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) |
313                 IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) |
314                 IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) |
315                 IO_STATE(R_SERIAL0_TR_CTRL, stop_bits, one_bit) |
316                 IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, normal) |
317                 tr_ctrl;
318 }
319
320 static void
321 console_write_direct(struct console *co, const char *buf, unsigned int len)
322 {
323         int i;
324         unsigned long flags;
325         local_irq_save(flags);
326         /* Send data */
327         for (i = 0; i < len; i++) {
328                 /* Wait until transmitter is ready and send.*/
329                 while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
330                         ;
331                 *port->write = buf[i];
332         }
333         local_irq_restore(flags);
334 }
335
336 static void
337 console_write(struct console *co, const char *buf, unsigned int len)
338 {
339         if (!port)
340                 return;
341
342 #ifdef CONFIG_SVINTO_SIM
343         /* no use to simulate the serial debug output */
344         SIMCOUT(buf, len);
345         return;
346 #endif
347
348         start_port();
349
350 #ifdef CONFIG_ETRAX_KGDB
351         /* kgdb needs to output debug info using the gdb protocol */
352         putDebugString(buf, len);
353         return;
354 #endif
355
356         if (debug_write_function)
357                 debug_write_function(co->index, buf, len);
358         else
359                 console_write_direct(co, buf, len);
360 }
361
362 /* legacy function */
363
364 void
365 console_print_etrax(const char *buf)
366 {
367         console_write(NULL, buf, strlen(buf));
368 }
369
370 /* Use polling to get a single character FROM the debug port */
371
372 int
373 getDebugChar(void)
374 {
375         unsigned long readval;
376
377         do {
378                 readval = *port->read;
379         } while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail)));
380
381         return (readval & IO_MASK(R_SERIAL0_READ, data_in));
382 }
383
384 /* Use polling to put a single character to the debug port */
385
386 void
387 putDebugChar(int val)
388 {
389         while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
390                 ;
391         *port->write = val;
392 }
393
394 /* Enable irq for receiving chars on the debug port, used by kgdb */
395
396 void
397 enableDebugIRQ(void)
398 {
399         *R_IRQ_MASK1_SET = port->irq;
400         /* use R_VECT_MASK directly, since we really bypass Linux normal
401          * IRQ handling in kgdb anyway, we don't need to use enable_irq
402          */
403         *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
404
405         *port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
406 }
407
408 static struct tty_driver*
409 etrax_console_device(struct console* co, int *index)
410 {
411         return serial_driver;
412 }
413
414 static int __init
415 console_setup(struct console *co, char *options)
416 {
417         char* s;
418
419         if (options) {
420                 port = &ports[co->index];
421                 port->baudrate = 115200;
422                 port->parity = 'N';
423                 port->bits = 8;
424                 port->baudrate = simple_strtoul(options, NULL, 10);
425                 s = options;
426                 while(*s >= '0' && *s <= '9')
427                         s++;
428                 if (*s) port->parity = *s++;
429                 if (*s) port->bits   = *s++ - '0';
430                 port->started = 0;
431                 start_port();
432         }
433         return 0;
434 }
435
436 static struct console sercons = {
437         name : "ttyS",
438         write: console_write,
439         read : NULL,
440         device : etrax_console_device,
441         unblank : NULL,
442         setup : console_setup,
443         flags : CON_PRINTBUFFER,
444         index : -1,
445         cflag : 0,
446         next : NULL
447 };
448 static struct console sercons0 = {
449         name : "ttyS",
450         write: console_write,
451         read : NULL,
452         device : etrax_console_device,
453         unblank : NULL,
454         setup : console_setup,
455         flags : CON_PRINTBUFFER,
456         index : 0,
457         cflag : 0,
458         next : NULL
459 };
460
461 static struct console sercons1 = {
462         name : "ttyS",
463         write: console_write,
464         read : NULL,
465         device : etrax_console_device,
466         unblank : NULL,
467         setup : console_setup,
468         flags : CON_PRINTBUFFER,
469         index : 1,
470         cflag : 0,
471         next : NULL
472 };
473 static struct console sercons2 = {
474         name : "ttyS",
475         write: console_write,
476         read : NULL,
477         device : etrax_console_device,
478         unblank : NULL,
479         setup : console_setup,
480         flags : CON_PRINTBUFFER,
481         index : 2,
482         cflag : 0,
483         next : NULL
484 };
485 static struct console sercons3 = {
486         name : "ttyS",
487         write: console_write,
488         read : NULL,
489         device : etrax_console_device,
490         unblank : NULL,
491         setup : console_setup,
492         flags : CON_PRINTBUFFER,
493         index : 3,
494         cflag : 0,
495         next : NULL
496 };
497 /*
498  *      Register console (for printk's etc)
499  */
500
501 int __init
502 init_etrax_debug(void)
503 {
504         static int first = 1;
505
506         if (!first) {
507                 if (!port) {
508                         register_console(&sercons0);
509                         register_console(&sercons1);
510                         register_console(&sercons2);
511                         register_console(&sercons3);
512                         unregister_console(&sercons);
513                 }
514                 return 0;
515         }
516         first = 0;
517         if (port)
518                 register_console(&sercons);
519         return 0;
520 }
521
522 int __init
523 init_console(void)
524 {
525         serial_driver = alloc_tty_driver(1);
526         if (!serial_driver)
527                 return -ENOMEM;
528         return 0;
529 }
530
531 __initcall(init_etrax_debug);