2 * Copyright (C) 2003, Axis Communications AB.
5 #include <linux/config.h>
6 #include <linux/console.h>
7 #include <linux/init.h>
8 #include <linux/major.h>
9 #include <linux/delay.h>
10 #include <linux/tty.h>
11 #include <asm/system.h>
13 #include <asm/arch/hwregs/ser_defs.h>
14 #include <asm/arch/hwregs/dma_defs.h>
15 #include <asm/arch/pinmux.h>
18 #include <asm/arch/hwregs/intr_vect_defs.h>
23 unsigned long instance;
25 unsigned long baudrate;
30 struct dbg_port ports[] =
65 static struct dbg_port *port =
66 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
68 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
70 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
72 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
78 #ifdef CONFIG_ETRAX_KGDB
79 static struct dbg_port *kgdb_port =
80 #if defined(CONFIG_ETRAX_KGDB_PORT0)
82 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
84 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
86 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
93 #ifdef CONFIG_ETRAXFS_SIM
94 extern void print_str( const char *str );
95 static char buffer[1024];
96 static char msg[] = "Debug: ";
97 static int buffer_pos = sizeof(msg) - 1;
100 extern struct tty_driver *serial_driver;
103 start_port(struct dbg_port* p)
113 crisv32_pinmux_alloc_fixed(pinmux_ser1);
114 else if (p->nbr == 2)
115 crisv32_pinmux_alloc_fixed(pinmux_ser2);
116 else if (p->nbr == 3)
117 crisv32_pinmux_alloc_fixed(pinmux_ser3);
119 /* Set up serial port registers */
120 reg_ser_rw_tr_ctrl tr_ctrl = {0};
121 reg_ser_rw_tr_dma_en tr_dma_en = {0};
123 reg_ser_rw_rec_ctrl rec_ctrl = {0};
124 reg_ser_rw_tr_baud_div tr_baud_div = {0};
125 reg_ser_rw_rec_baud_div rec_baud_div = {0};
127 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
128 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
129 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
130 tr_ctrl.en = rec_ctrl.en = 1;
132 if (p->parity == 'O')
134 tr_ctrl.par_en = regk_ser_yes;
135 tr_ctrl.par = regk_ser_odd;
136 rec_ctrl.par_en = regk_ser_yes;
137 rec_ctrl.par = regk_ser_odd;
139 else if (p->parity == 'E')
141 tr_ctrl.par_en = regk_ser_yes;
142 tr_ctrl.par = regk_ser_even;
143 rec_ctrl.par_en = regk_ser_yes;
144 rec_ctrl.par = regk_ser_odd;
149 tr_ctrl.data_bits = regk_ser_bits7;
150 rec_ctrl.data_bits = regk_ser_bits7;
153 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
154 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
155 REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);
156 REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);
157 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
161 #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
164 console_write(struct console *co, const char *buf, unsigned int len)
170 #elif !defined(CONFIG_ETRAXFS_SIM)
173 console_write_direct(struct console *co, const char *buf, unsigned int len)
176 reg_ser_r_stat_din stat;
177 reg_ser_rw_tr_dma_en tr_dma_en, old;
179 /* Switch to manual mode */
180 tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
181 if (tr_dma_en.en == regk_ser_yes) {
182 tr_dma_en.en = regk_ser_no;
183 REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
187 for (i = 0; i < len; i++) {
189 if (buf[i] == '\n') {
191 stat = REG_RD (ser, port->instance, r_stat_din);
192 } while (!stat.tr_rdy);
193 REG_WR_INT (ser, port->instance, rw_dout, '\r');
195 /* Wait until transmitter is ready and send.*/
197 stat = REG_RD (ser, port->instance, r_stat_din);
198 } while (!stat.tr_rdy);
199 REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
203 if (tr_dma_en.en != old.en)
204 REG_WR(ser, port->instance, rw_tr_dma_en, old);
208 console_write(struct console *co, const char *buf, unsigned int len)
212 console_write_direct(co, buf, len);
222 console_write(struct console *co, const char *buf, unsigned int len)
225 pos = memchr(buf, '\n', len);
228 memcpy(buffer + buffer_pos, buf, l);
229 memcpy(buffer, msg, sizeof(msg) - 1);
230 buffer[buffer_pos + l] = '\0';
232 buffer_pos = sizeof(msg) - 1;
233 if (pos - buf != len) {
234 memcpy(buffer + buffer_pos, pos, len - l);
235 buffer_pos += len - l;
238 memcpy(buffer + buffer_pos, buf, len);
245 int raw_printk(const char *fmt, ...)
247 static char buf[1024];
251 printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
253 console_write(NULL, buf, strlen(buf));
258 stupid_debug(char* buf)
260 console_write(NULL, buf, strlen(buf));
263 #ifdef CONFIG_ETRAX_KGDB
264 /* Use polling to get a single character from the kernel debug port */
268 reg_ser_rs_status_data stat;
269 reg_ser_rw_ack_intr ack_intr = { 0 };
272 stat = REG_RD(ser, kgdb_instance, rs_status_data);
273 } while (!stat.data_avail);
275 /* Ack the data_avail interrupt. */
276 ack_intr.data_avail = 1;
277 REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);
282 /* Use polling to put a single character to the kernel debug port */
284 putDebugChar(int val)
286 reg_ser_r_status_data stat;
288 stat = REG_RD (ser, kgdb_instance, r_status_data);
289 } while (!stat.tr_ready);
290 REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));
292 #endif /* CONFIG_ETRAX_KGDB */
295 console_setup(struct console *co, char *options)
300 port = &ports[co->index];
301 port->baudrate = 115200;
304 port->baudrate = simple_strtoul(options, NULL, 10);
306 while(*s >= '0' && *s <= '9')
308 if (*s) port->parity = *s++;
309 if (*s) port->bits = *s++ - '0';
316 /* This is a dummy serial device that throws away anything written to it.
317 * This is used when no debug output is wanted.
319 static struct tty_driver dummy_driver;
321 static int dummy_open(struct tty_struct *tty, struct file * filp)
326 static void dummy_close(struct tty_struct *tty, struct file * filp)
330 static int dummy_write(struct tty_struct * tty,
331 const unsigned char *buf, int count)
337 dummy_write_room(struct tty_struct *tty)
343 init_dummy_console(void)
345 memset(&dummy_driver, 0, sizeof(struct tty_driver));
346 dummy_driver.driver_name = "serial";
347 dummy_driver.name = "ttyS";
348 dummy_driver.major = TTY_MAJOR;
349 dummy_driver.minor_start = 68;
350 dummy_driver.num = 1; /* etrax100 has 4 serial ports */
351 dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
352 dummy_driver.subtype = SERIAL_TYPE_NORMAL;
353 dummy_driver.init_termios = tty_std_termios;
354 dummy_driver.init_termios.c_cflag =
355 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
356 dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
358 dummy_driver.open = dummy_open;
359 dummy_driver.close = dummy_close;
360 dummy_driver.write = dummy_write;
361 dummy_driver.write_room = dummy_write_room;
362 if (tty_register_driver(&dummy_driver))
363 panic("Couldn't register dummy serial driver\n");
366 static struct tty_driver*
367 crisv32_console_device(struct console* co, int *index)
371 return port ? serial_driver : &dummy_driver;
374 static struct console sercons = {
376 write: console_write,
378 device : crisv32_console_device,
380 setup : console_setup,
381 flags : CON_PRINTBUFFER,
386 static struct console sercons0 = {
388 write: console_write,
390 device : crisv32_console_device,
392 setup : console_setup,
393 flags : CON_PRINTBUFFER,
399 static struct console sercons1 = {
401 write: console_write,
403 device : crisv32_console_device,
405 setup : console_setup,
406 flags : CON_PRINTBUFFER,
411 static struct console sercons2 = {
413 write: console_write,
415 device : crisv32_console_device,
417 setup : console_setup,
418 flags : CON_PRINTBUFFER,
423 static struct console sercons3 = {
425 write: console_write,
427 device : crisv32_console_device,
429 setup : console_setup,
430 flags : CON_PRINTBUFFER,
436 /* Register console for printk's, etc. */
438 init_etrax_debug(void)
440 static int first = 1;
443 unregister_console(&sercons);
444 register_console(&sercons0);
445 register_console(&sercons1);
446 register_console(&sercons2);
447 register_console(&sercons3);
448 init_dummy_console();
452 register_console(&sercons);
455 #ifdef CONFIG_ETRAX_KGDB
456 start_port(kgdb_port);
457 #endif /* CONFIG_ETRAX_KGDB */
461 __initcall(init_etrax_debug);