1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2003, Axis Communications AB.
6 #include <linux/console.h>
7 #include <linux/kernel.h>
8 #include <linux/init.h>
9 #include <linux/string.h>
10 #include <hwregs/reg_rdwr.h>
11 #include <hwregs/reg_map.h>
12 #include <hwregs/ser_defs.h>
13 #include <hwregs/dma_defs.h>
14 #include <mach/pinmux.h>
19 unsigned long instance
;
21 unsigned long baudrate
;
26 struct dbg_port ports
[] =
60 #if CONFIG_ETRAX_SERIAL_PORTS == 5
72 static struct dbg_port
*port
=
73 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
75 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
77 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
79 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
85 #ifdef CONFIG_ETRAX_KGDB
86 static struct dbg_port
*kgdb_port
=
87 #if defined(CONFIG_ETRAX_KGDB_PORT0)
89 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
91 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
93 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
95 #elif defined(CONFIG_ETRAX_KGDB_PORT4)
102 static void start_port(struct dbg_port
*p
)
104 /* Set up serial port registers */
105 reg_ser_rw_tr_ctrl tr_ctrl
= {0};
106 reg_ser_rw_tr_dma_en tr_dma_en
= {0};
108 reg_ser_rw_rec_ctrl rec_ctrl
= {0};
109 reg_ser_rw_tr_baud_div tr_baud_div
= {0};
110 reg_ser_rw_rec_baud_div rec_baud_div
= {0};
112 if (!p
|| p
->started
)
118 crisv32_pinmux_alloc_fixed(pinmux_ser1
);
119 else if (p
->nbr
== 2)
120 crisv32_pinmux_alloc_fixed(pinmux_ser2
);
121 else if (p
->nbr
== 3)
122 crisv32_pinmux_alloc_fixed(pinmux_ser3
);
123 #if CONFIG_ETRAX_SERIAL_PORTS == 5
124 else if (p
->nbr
== 4)
125 crisv32_pinmux_alloc_fixed(pinmux_ser4
);
128 tr_ctrl
.base_freq
= rec_ctrl
.base_freq
= regk_ser_f29_493
;
129 tr_dma_en
.en
= rec_ctrl
.dma_mode
= regk_ser_no
;
130 tr_baud_div
.div
= rec_baud_div
.div
= 29493000 / p
->baudrate
/ 8;
131 tr_ctrl
.en
= rec_ctrl
.en
= 1;
133 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
;
138 } else if (p
->parity
== 'E') {
139 tr_ctrl
.par_en
= regk_ser_yes
;
140 tr_ctrl
.par
= regk_ser_even
;
141 rec_ctrl
.par_en
= regk_ser_yes
;
142 rec_ctrl
.par
= regk_ser_odd
;
146 tr_ctrl
.data_bits
= regk_ser_bits7
;
147 rec_ctrl
.data_bits
= regk_ser_bits7
;
150 REG_WR (ser
, p
->instance
, rw_tr_baud_div
, tr_baud_div
);
151 REG_WR (ser
, p
->instance
, rw_rec_baud_div
, rec_baud_div
);
152 REG_WR (ser
, p
->instance
, rw_tr_dma_en
, tr_dma_en
);
153 REG_WR (ser
, p
->instance
, rw_tr_ctrl
, tr_ctrl
);
154 REG_WR (ser
, p
->instance
, rw_rec_ctrl
, rec_ctrl
);
157 #ifdef CONFIG_ETRAX_KGDB
158 /* Use polling to get a single character from the kernel debug port */
159 int getDebugChar(void)
161 reg_ser_rs_stat_din stat
;
162 reg_ser_rw_ack_intr ack_intr
= { 0 };
165 stat
= REG_RD(ser
, kgdb_port
->instance
, rs_stat_din
);
168 /* Ack the data_avail interrupt. */
170 REG_WR(ser
, kgdb_port
->instance
, rw_ack_intr
, ack_intr
);
175 /* Use polling to put a single character to the kernel debug port */
176 void putDebugChar(int val
)
178 reg_ser_r_stat_din stat
;
180 stat
= REG_RD(ser
, kgdb_port
->instance
, r_stat_din
);
181 } while (!stat
.tr_rdy
);
182 REG_WR_INT(ser
, kgdb_port
->instance
, rw_dout
, val
);
184 #endif /* CONFIG_ETRAX_KGDB */
186 static void __init
early_putch(int c
)
188 reg_ser_r_stat_din stat
;
189 /* Wait until transmitter is ready and send. */
191 stat
= REG_RD(ser
, port
->instance
, r_stat_din
);
192 while (!stat
.tr_rdy
);
193 REG_WR_INT(ser
, port
->instance
, rw_dout
, c
);
197 early_console_write(struct console
*con
, const char *s
, unsigned n
)
199 extern void reset_watchdog(void);
203 for (i
= 0; i
< n
; i
++) {
204 /* TODO: the '\n' -> '\n\r' translation should be done at the
205 receiver. Remove it when the serial driver removes it. */
213 static struct console early_console_dev __initdata
= {
215 .write
= early_console_write
,
216 .flags
= CON_PRINTBUFFER
| CON_BOOT
,
220 /* Register console for printk's, etc. */
221 int __init
init_etrax_debug(void)
225 /* Register an early console if a debug port was chosen. */
226 register_console(&early_console_dev
);
228 #ifdef CONFIG_ETRAX_KGDB
229 start_port(kgdb_port
);
230 #endif /* CONFIG_ETRAX_KGDB */