2 * Copyright (C) 2003, Axis Communications AB.
5 #include <linux/console.h>
6 #include <linux/init.h>
7 #include <linux/major.h>
8 #include <linux/delay.h>
10 #include <asm/system.h>
12 #include <asm/arch/hwregs/ser_defs.h>
13 #include <asm/arch/hwregs/dma_defs.h>
14 #include <asm/arch/pinmux.h>
17 #include <asm/arch/hwregs/intr_vect_defs.h>
22 unsigned long instance
;
24 unsigned long baudrate
;
29 struct dbg_port ports
[] =
64 static struct dbg_port
*port
=
65 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
67 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
69 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
71 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
77 #ifdef CONFIG_ETRAX_KGDB
78 static struct dbg_port
*kgdb_port
=
79 #if defined(CONFIG_ETRAX_KGDB_PORT0)
81 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
83 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
85 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
92 #ifdef CONFIG_ETRAXFS_SIM
93 extern void print_str( const char *str
);
94 static char buffer
[1024];
95 static char msg
[] = "Debug: ";
96 static int buffer_pos
= sizeof(msg
) - 1;
99 extern struct tty_driver
*serial_driver
;
102 start_port(struct dbg_port
* p
)
112 crisv32_pinmux_alloc_fixed(pinmux_ser1
);
113 else if (p
->nbr
== 2)
114 crisv32_pinmux_alloc_fixed(pinmux_ser2
);
115 else if (p
->nbr
== 3)
116 crisv32_pinmux_alloc_fixed(pinmux_ser3
);
118 /* Set up serial port registers */
119 reg_ser_rw_tr_ctrl tr_ctrl
= {0};
120 reg_ser_rw_tr_dma_en tr_dma_en
= {0};
122 reg_ser_rw_rec_ctrl rec_ctrl
= {0};
123 reg_ser_rw_tr_baud_div tr_baud_div
= {0};
124 reg_ser_rw_rec_baud_div rec_baud_div
= {0};
126 tr_ctrl
.base_freq
= rec_ctrl
.base_freq
= regk_ser_f29_493
;
127 tr_dma_en
.en
= rec_ctrl
.dma_mode
= regk_ser_no
;
128 tr_baud_div
.div
= rec_baud_div
.div
= 29493000 / p
->baudrate
/ 8;
129 tr_ctrl
.en
= rec_ctrl
.en
= 1;
131 if (p
->parity
== 'O')
133 tr_ctrl
.par_en
= regk_ser_yes
;
134 tr_ctrl
.par
= regk_ser_odd
;
135 rec_ctrl
.par_en
= regk_ser_yes
;
136 rec_ctrl
.par
= regk_ser_odd
;
138 else if (p
->parity
== 'E')
140 tr_ctrl
.par_en
= regk_ser_yes
;
141 tr_ctrl
.par
= regk_ser_even
;
142 rec_ctrl
.par_en
= regk_ser_yes
;
143 rec_ctrl
.par
= regk_ser_odd
;
148 tr_ctrl
.data_bits
= regk_ser_bits7
;
149 rec_ctrl
.data_bits
= regk_ser_bits7
;
152 REG_WR (ser
, p
->instance
, rw_tr_baud_div
, tr_baud_div
);
153 REG_WR (ser
, p
->instance
, rw_rec_baud_div
, rec_baud_div
);
154 REG_WR (ser
, p
->instance
, rw_tr_dma_en
, tr_dma_en
);
155 REG_WR (ser
, p
->instance
, rw_tr_ctrl
, tr_ctrl
);
156 REG_WR (ser
, p
->instance
, rw_rec_ctrl
, rec_ctrl
);
160 #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
163 console_write(struct console
*co
, const char *buf
, unsigned int len
)
169 #elif !defined(CONFIG_ETRAXFS_SIM)
172 console_write_direct(struct console
*co
, const char *buf
, unsigned int len
)
175 reg_ser_r_stat_din stat
;
176 reg_ser_rw_tr_dma_en tr_dma_en
, old
;
178 /* Switch to manual mode */
179 tr_dma_en
= old
= REG_RD (ser
, port
->instance
, rw_tr_dma_en
);
180 if (tr_dma_en
.en
== regk_ser_yes
) {
181 tr_dma_en
.en
= regk_ser_no
;
182 REG_WR(ser
, port
->instance
, rw_tr_dma_en
, tr_dma_en
);
186 for (i
= 0; i
< len
; i
++) {
188 if (buf
[i
] == '\n') {
190 stat
= REG_RD (ser
, port
->instance
, r_stat_din
);
191 } while (!stat
.tr_rdy
);
192 REG_WR_INT (ser
, port
->instance
, rw_dout
, '\r');
194 /* Wait until transmitter is ready and send.*/
196 stat
= REG_RD (ser
, port
->instance
, r_stat_din
);
197 } while (!stat
.tr_rdy
);
198 REG_WR_INT (ser
, port
->instance
, rw_dout
, buf
[i
]);
202 if (tr_dma_en
.en
!= old
.en
)
203 REG_WR(ser
, port
->instance
, rw_tr_dma_en
, old
);
207 console_write(struct console
*co
, const char *buf
, unsigned int len
)
211 console_write_direct(co
, buf
, len
);
221 console_write(struct console
*co
, const char *buf
, unsigned int len
)
224 pos
= memchr(buf
, '\n', len
);
227 memcpy(buffer
+ buffer_pos
, buf
, l
);
228 memcpy(buffer
, msg
, sizeof(msg
) - 1);
229 buffer
[buffer_pos
+ l
] = '\0';
231 buffer_pos
= sizeof(msg
) - 1;
232 if (pos
- buf
!= len
) {
233 memcpy(buffer
+ buffer_pos
, pos
, len
- l
);
234 buffer_pos
+= len
- l
;
237 memcpy(buffer
+ buffer_pos
, buf
, len
);
244 int raw_printk(const char *fmt
, ...)
246 static char buf
[1024];
250 printed_len
= vsnprintf(buf
, sizeof(buf
), fmt
, args
);
252 console_write(NULL
, buf
, strlen(buf
));
257 stupid_debug(char* buf
)
259 console_write(NULL
, buf
, strlen(buf
));
262 #ifdef CONFIG_ETRAX_KGDB
263 /* Use polling to get a single character from the kernel debug port */
267 reg_ser_rs_status_data stat
;
268 reg_ser_rw_ack_intr ack_intr
= { 0 };
271 stat
= REG_RD(ser
, kgdb_instance
, rs_status_data
);
272 } while (!stat
.data_avail
);
274 /* Ack the data_avail interrupt. */
275 ack_intr
.data_avail
= 1;
276 REG_WR(ser
, kgdb_instance
, rw_ack_intr
, ack_intr
);
281 /* Use polling to put a single character to the kernel debug port */
283 putDebugChar(int val
)
285 reg_ser_r_status_data stat
;
287 stat
= REG_RD (ser
, kgdb_instance
, r_status_data
);
288 } while (!stat
.tr_ready
);
289 REG_WR (ser
, kgdb_instance
, rw_data_out
, REG_TYPE_CONV(reg_ser_rw_data_out
, int, val
));
291 #endif /* CONFIG_ETRAX_KGDB */
294 console_setup(struct console
*co
, char *options
)
299 port
= &ports
[co
->index
];
300 port
->baudrate
= 115200;
303 port
->baudrate
= simple_strtoul(options
, NULL
, 10);
305 while(*s
>= '0' && *s
<= '9')
307 if (*s
) port
->parity
= *s
++;
308 if (*s
) port
->bits
= *s
++ - '0';
315 /* This is a dummy serial device that throws away anything written to it.
316 * This is used when no debug output is wanted.
318 static struct tty_driver dummy_driver
;
320 static int dummy_open(struct tty_struct
*tty
, struct file
* filp
)
325 static void dummy_close(struct tty_struct
*tty
, struct file
* filp
)
329 static int dummy_write(struct tty_struct
* tty
,
330 const unsigned char *buf
, int count
)
336 dummy_write_room(struct tty_struct
*tty
)
342 init_dummy_console(void)
344 memset(&dummy_driver
, 0, sizeof(struct tty_driver
));
345 dummy_driver
.driver_name
= "serial";
346 dummy_driver
.name
= "ttyS";
347 dummy_driver
.major
= TTY_MAJOR
;
348 dummy_driver
.minor_start
= 68;
349 dummy_driver
.num
= 1; /* etrax100 has 4 serial ports */
350 dummy_driver
.type
= TTY_DRIVER_TYPE_SERIAL
;
351 dummy_driver
.subtype
= SERIAL_TYPE_NORMAL
;
352 dummy_driver
.init_termios
= tty_std_termios
;
353 dummy_driver
.init_termios
.c_cflag
=
354 B115200
| CS8
| CREAD
| HUPCL
| CLOCAL
; /* is normally B9600 default... */
355 dummy_driver
.flags
= TTY_DRIVER_REAL_RAW
| TTY_DRIVER_DYNAMIC_DEV
;
357 dummy_driver
.open
= dummy_open
;
358 dummy_driver
.close
= dummy_close
;
359 dummy_driver
.write
= dummy_write
;
360 dummy_driver
.write_room
= dummy_write_room
;
361 if (tty_register_driver(&dummy_driver
))
362 panic("Couldn't register dummy serial driver\n");
365 static struct tty_driver
*
366 crisv32_console_device(struct console
* co
, int *index
)
370 return port
? serial_driver
: &dummy_driver
;
373 static struct console sercons
= {
375 write
: console_write
,
377 device
: crisv32_console_device
,
379 setup
: console_setup
,
380 flags
: CON_PRINTBUFFER
,
385 static struct console sercons0
= {
387 write
: console_write
,
389 device
: crisv32_console_device
,
391 setup
: console_setup
,
392 flags
: CON_PRINTBUFFER
,
398 static struct console sercons1
= {
400 write
: console_write
,
402 device
: crisv32_console_device
,
404 setup
: console_setup
,
405 flags
: CON_PRINTBUFFER
,
410 static struct console sercons2
= {
412 write
: console_write
,
414 device
: crisv32_console_device
,
416 setup
: console_setup
,
417 flags
: CON_PRINTBUFFER
,
422 static struct console sercons3
= {
424 write
: console_write
,
426 device
: crisv32_console_device
,
428 setup
: console_setup
,
429 flags
: CON_PRINTBUFFER
,
435 /* Register console for printk's, etc. */
437 init_etrax_debug(void)
439 static int first
= 1;
442 unregister_console(&sercons
);
443 register_console(&sercons0
);
444 register_console(&sercons1
);
445 register_console(&sercons2
);
446 register_console(&sercons3
);
447 init_dummy_console();
451 register_console(&sercons
);
454 #ifdef CONFIG_ETRAX_KGDB
455 start_port(kgdb_port
);
456 #endif /* CONFIG_ETRAX_KGDB */
460 __initcall(init_etrax_debug
);