patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / 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.14  2004/05/17 13:11:29  starvik
16  * Disable DMA until real serial driver is up
17  *
18  * Revision 1.13  2004/05/14 07:58:01  starvik
19  * Merge of changes from 2.4
20  *
21  * Revision 1.12  2003/09/11 07:29:49  starvik
22  * Merge of Linux 2.6.0-test5
23  *
24  * Revision 1.11  2003/07/07 09:53:36  starvik
25  * Revert all the 2.5.74 merge changes to make the console work again
26  *
27  * Revision 1.9  2003/02/17 17:07:23  starvik
28  * Solved the problem with corrupted debug output (from Linux 2.4)
29  *   * Wait until DMA, FIFO and pipe is empty before and after transmissions
30  *   * Buffer data until a FIFO flush can be triggered.
31  *
32  * Revision 1.8  2003/01/22 06:48:36  starvik
33  * Fixed warnings issued by GCC 3.2.1
34  *
35  * Revision 1.7  2002/12/12 08:26:32  starvik
36  * Don't use C-comments inside CVS comments
37  *
38  * Revision 1.6  2002/12/11 15:42:02  starvik
39  * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
40  *
41  * Revision 1.5  2002/11/20 06:58:03  starvik
42  * Compiles with kgdb
43  *
44  * Revision 1.4  2002/11/19 14:35:24  starvik
45  * Changes from linux 2.4
46  * Changed struct initializer syntax to the currently prefered notation
47  *
48  * Revision 1.3  2002/11/06 09:47:03  starvik
49  * Modified for new interrupt macros
50  *
51  * Revision 1.2  2002/01/21 15:21:50  bjornw
52  * Update for kdev_t changes
53  *
54  * Revision 1.6  2001/04/17 13:58:39  orjanf
55  * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
56  *
57  * Revision 1.5  2001/03/26 14:22:05  bjornw
58  * Namechange of some config options
59  *
60  * Revision 1.4  2000/10/06 12:37:26  bjornw
61  * Use physical addresses when talking to DMA
62  *
63  *
64  */
65
66 #include <linux/config.h>
67 #include <linux/console.h>
68 #include <linux/init.h>
69 #include <linux/major.h>
70 #include <linux/delay.h>
71 #include <linux/tty.h>
72 #include <asm/system.h>
73 #include <asm/arch/svinto.h>
74 #include <asm/io.h>             /* Get SIMCOUT. */
75
76 /* Which serial-port is our debug port ? */
77
78 #if defined(CONFIG_ETRAX_DEBUG_PORT0) || defined(CONFIG_ETRAX_DEBUG_PORT_NULL)
79 #define DEBUG_PORT_IDX 0
80 #define DEBUG_OCMD R_DMA_CH6_CMD
81 #define DEBUG_FIRST R_DMA_CH6_FIRST
82 #define DEBUG_OCLRINT R_DMA_CH6_CLR_INTR
83 #define DEBUG_STATUS R_DMA_CH6_STATUS
84 #define DEBUG_READ R_SERIAL0_READ
85 #define DEBUG_WRITE R_SERIAL0_TR_DATA
86 #define DEBUG_TR_CTRL R_SERIAL0_TR_CTRL
87 #define DEBUG_REC_CTRL R_SERIAL0_REC_CTRL
88 #define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser0_data, set)
89 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma6_descr, clr)
90 #endif
91
92 #ifdef CONFIG_ETRAX_DEBUG_PORT1
93 #define DEBUG_PORT_IDX 1
94 #define DEBUG_OCMD R_DMA_CH8_CMD
95 #define DEBUG_FIRST R_DMA_CH8_FIRST
96 #define DEBUG_OCLRINT R_DMA_CH8_CLR_INTR
97 #define DEBUG_STATUS R_DMA_CH8_STATUS
98 #define DEBUG_READ R_SERIAL1_READ
99 #define DEBUG_WRITE R_SERIAL1_TR_DATA
100 #define DEBUG_TR_CTRL R_SERIAL1_TR_CTRL
101 #define DEBUG_REC_CTRL R_SERIAL1_REC_CTRL
102 #define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser1_data, set)
103 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma8_descr, clr)
104 #endif
105
106 #ifdef CONFIG_ETRAX_DEBUG_PORT2
107 #define DEBUG_PORT_IDX 2
108 #define DEBUG_OCMD R_DMA_CH2_CMD
109 #define DEBUG_FIRST R_DMA_CH2_FIRST
110 #define DEBUG_OCLRINT R_DMA_CH2_CLR_INTR
111 #define DEBUG_STATUS R_DMA_CH2_STATUS
112 #define DEBUG_READ R_SERIAL2_READ
113 #define DEBUG_WRITE R_SERIAL2_TR_DATA
114 #define DEBUG_TR_CTRL R_SERIAL2_TR_CTRL
115 #define DEBUG_REC_CTRL R_SERIAL2_REC_CTRL
116 #define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser2_data, set)
117 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma2_descr, clr)
118 #endif
119
120 #ifdef CONFIG_ETRAX_DEBUG_PORT3
121 #define DEBUG_PORT_IDX 3
122 #define DEBUG_OCMD R_DMA_CH4_CMD
123 #define DEBUG_FIRST R_DMA_CH4_FIRST
124 #define DEBUG_OCLRINT R_DMA_CH4_CLR_INTR
125 #define DEBUG_STATUS R_DMA_CH4_STATUS
126 #define DEBUG_READ R_SERIAL3_READ
127 #define DEBUG_WRITE R_SERIAL3_TR_DATA
128 #define DEBUG_TR_CTRL R_SERIAL3_TR_CTRL
129 #define DEBUG_REC_CTRL R_SERIAL3_REC_CTRL
130 #define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser3_data, set)
131 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma4_descr, clr)
132 #endif
133
134 #define MIN_SIZE 32 /* Size that triggers the FIFO to flush characters to interface */
135
136 static struct tty_driver *serial_driver;
137
138 typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len);
139
140 debugport_write_function debug_write_function = NULL;
141
142 static void
143 console_write_direct(struct console *co, const char *buf, unsigned int len)
144 {
145         int i;
146         /* Send data */
147         for (i = 0; i < len; i++) {
148                 /* Wait until transmitter is ready and send.*/
149                 while(!(*DEBUG_READ & IO_MASK(R_SERIAL0_READ, tr_ready)));
150                 *DEBUG_WRITE = buf[i];
151         }
152 }
153
154 static void 
155 console_write(struct console *co, const char *buf, unsigned int len)
156 {
157         unsigned long flags;
158 #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
159         /* no debug printout at all */
160         return;
161 #endif
162
163 #ifdef CONFIG_SVINTO_SIM
164         /* no use to simulate the serial debug output */
165         SIMCOUT(buf,len);
166         return;
167 #endif
168
169 #ifdef CONFIG_ETRAX_KGDB
170         /* kgdb needs to output debug info using the gdb protocol */
171         putDebugString(buf, len);
172         return;
173 #endif
174
175         local_irq_save(flags);
176         if (debug_write_function)
177                 if (debug_write_function(co->index, buf, len))
178                         return;
179         console_write_direct(co, buf, len);
180         local_irq_restore(flags);
181 }
182
183 /* legacy function */
184
185 void
186 console_print_etrax(const char *buf)
187 {
188         console_write(NULL, buf, strlen(buf));
189 }
190
191 /* Use polling to get a single character FROM the debug port */
192
193 int
194 getDebugChar(void)
195 {
196         unsigned long readval;
197         
198         do {
199                 readval = *DEBUG_READ;
200         } while(!(readval & IO_MASK(R_SERIAL0_READ, data_avail)));
201
202         return (readval & IO_MASK(R_SERIAL0_READ, data_in));
203 }
204
205 /* Use polling to put a single character to the debug port */
206
207 void
208 putDebugChar(int val)
209 {
210         while(!(*DEBUG_READ & IO_MASK(R_SERIAL0_READ, tr_ready))) ;
211 ;
212         *DEBUG_WRITE = val;
213 }
214
215 /* Enable irq for receiving chars on the debug port, used by kgdb */
216
217 void
218 enableDebugIRQ(void)
219 {
220         *R_IRQ_MASK1_SET = DEBUG_IRQ;
221         /* use R_VECT_MASK directly, since we really bypass Linux normal
222          * IRQ handling in kgdb anyway, we don't need to use enable_irq
223          */
224         *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
225
226         *DEBUG_REC_CTRL = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
227 }
228
229 static struct tty_driver*
230 console_device(struct console *c, int *index)
231 {
232         *index = c->index;
233         return serial_driver;
234 }
235
236 static int __init 
237 console_setup(struct console *co, char *options)
238 {
239         return 0;
240 }
241
242 static struct console sercons = {
243         .name    = "ttyS",
244         .write   = console_write,
245         .read    = NULL,
246         .device  = console_device,
247         .unblank = NULL,
248         .setup   = console_setup,
249         .flags   = CON_PRINTBUFFER,
250         .index   = DEBUG_PORT_IDX,
251         .cflag   = 0,
252         .next    = NULL
253 };
254
255 /*
256  *      Register console (for printk's etc)
257  */
258
259 void __init 
260 init_etrax_debug(void)
261 {
262 #if CONFIG_ETRAX_DEBUG_PORT_NULL
263         return;
264 #endif
265
266 #if DEBUG_PORT_IDX == 0
267         genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma6);
268         genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
269 #elif DEBUG_PORT_IDX == 1
270         genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma8);
271         genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
272 #elif DEBUG_PORT_IDX == 2
273         genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma2);
274         genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
275 #elif DEBUG_PORT_IDX == 3
276         genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma4);
277         genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
278 #endif
279         *R_GEN_CONFIG = genconfig_shadow;
280
281         register_console(&sercons);
282 }
283
284 int __init
285 init_console(void)
286 {
287         serial_driver = alloc_tty_driver(1);
288         if (!serial_driver)
289                 return -ENOMEM;
290         return 0;
291 }