1
2
3
4
5#include <linux/console.h>
6#include <linux/kernel.h>
7#include <linux/init.h>
8#include <linux/string.h>
9#include <hwregs/reg_rdwr.h>
10#include <hwregs/reg_map.h>
11#include <hwregs/ser_defs.h>
12#include <hwregs/dma_defs.h>
13#include <mach/pinmux.h>
14
15struct dbg_port
16{
17 unsigned char nbr;
18 unsigned long instance;
19 unsigned int started;
20 unsigned long baudrate;
21 unsigned char parity;
22 unsigned int bits;
23};
24
25struct dbg_port ports[] =
26{
27 {
28 0,
29 regi_ser0,
30 0,
31 115200,
32 'N',
33 8
34 },
35 {
36 1,
37 regi_ser1,
38 0,
39 115200,
40 'N',
41 8
42 },
43 {
44 2,
45 regi_ser2,
46 0,
47 115200,
48 'N',
49 8
50 },
51 {
52 3,
53 regi_ser3,
54 0,
55 115200,
56 'N',
57 8
58 },
59#if CONFIG_ETRAX_SERIAL_PORTS == 5
60 {
61 4,
62 regi_ser4,
63 0,
64 115200,
65 'N',
66 8
67 },
68#endif
69};
70
71static struct dbg_port *port =
72#if defined(CONFIG_ETRAX_DEBUG_PORT0)
73 &ports[0];
74#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
75 &ports[1];
76#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
77 &ports[2];
78#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
79 &ports[3];
80#else
81 NULL;
82#endif
83
84#ifdef CONFIG_ETRAX_KGDB
85static struct dbg_port *kgdb_port =
86#if defined(CONFIG_ETRAX_KGDB_PORT0)
87 &ports[0];
88#elif defined(CONFIG_ETRAX_KGDB_PORT1)
89 &ports[1];
90#elif defined(CONFIG_ETRAX_KGDB_PORT2)
91 &ports[2];
92#elif defined(CONFIG_ETRAX_KGDB_PORT3)
93 &ports[3];
94#elif defined(CONFIG_ETRAX_KGDB_PORT4)
95 &ports[4];
96#else
97 NULL;
98#endif
99#endif
100
101static void start_port(struct dbg_port *p)
102{
103
104 reg_ser_rw_tr_ctrl tr_ctrl = {0};
105 reg_ser_rw_tr_dma_en tr_dma_en = {0};
106
107 reg_ser_rw_rec_ctrl rec_ctrl = {0};
108 reg_ser_rw_tr_baud_div tr_baud_div = {0};
109 reg_ser_rw_rec_baud_div rec_baud_div = {0};
110
111 if (!p || p->started)
112 return;
113
114 p->started = 1;
115
116 if (p->nbr == 1)
117 crisv32_pinmux_alloc_fixed(pinmux_ser1);
118 else if (p->nbr == 2)
119 crisv32_pinmux_alloc_fixed(pinmux_ser2);
120 else if (p->nbr == 3)
121 crisv32_pinmux_alloc_fixed(pinmux_ser3);
122#if CONFIG_ETRAX_SERIAL_PORTS == 5
123 else if (p->nbr == 4)
124 crisv32_pinmux_alloc_fixed(pinmux_ser4);
125#endif
126
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;
131
132 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;
137 } else if (p->parity == 'E') {
138 tr_ctrl.par_en = regk_ser_yes;
139 tr_ctrl.par = regk_ser_even;
140 rec_ctrl.par_en = regk_ser_yes;
141 rec_ctrl.par = regk_ser_odd;
142 }
143
144 if (p->bits == 7) {
145 tr_ctrl.data_bits = regk_ser_bits7;
146 rec_ctrl.data_bits = regk_ser_bits7;
147 }
148
149 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
150 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
151 REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);
152 REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);
153 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
154}
155
156#ifdef CONFIG_ETRAX_KGDB
157
158int getDebugChar(void)
159{
160 reg_ser_rs_stat_din stat;
161 reg_ser_rw_ack_intr ack_intr = { 0 };
162
163 do {
164 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
165 } while (!stat.dav);
166
167
168 ack_intr.dav = 1;
169 REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
170
171 return stat.data;
172}
173
174
175void putDebugChar(int val)
176{
177 reg_ser_r_stat_din stat;
178 do {
179 stat = REG_RD(ser, kgdb_port->instance, r_stat_din);
180 } while (!stat.tr_rdy);
181 REG_WR_INT(ser, kgdb_port->instance, rw_dout, val);
182}
183#endif
184
185static void __init early_putch(int c)
186{
187 reg_ser_r_stat_din stat;
188
189 do
190 stat = REG_RD(ser, port->instance, r_stat_din);
191 while (!stat.tr_rdy);
192 REG_WR_INT(ser, port->instance, rw_dout, c);
193}
194
195static void __init
196early_console_write(struct console *con, const char *s, unsigned n)
197{
198 extern void reset_watchdog(void);
199 int i;
200
201
202 for (i = 0; i < n; i++) {
203
204
205 if (s[i] == '\n')
206 early_putch('\r');
207 early_putch(s[i]);
208 reset_watchdog();
209 }
210}
211
212static struct console early_console_dev __initdata = {
213 .name = "early",
214 .write = early_console_write,
215 .flags = CON_PRINTBUFFER | CON_BOOT,
216 .index = -1
217};
218
219
220int __init init_etrax_debug(void)
221{
222 start_port(port);
223
224
225 register_console(&early_console_dev);
226
227#ifdef CONFIG_ETRAX_KGDB
228 start_port(kgdb_port);
229#endif
230 return 0;
231}
232