1 /*
2 * Copyright (C) 2003, Axis Communications AB.
3 */
4
5 #include <linux/console.h>
6 #include <linux/init.h>
7 #include <hwregs/reg_rdwr.h>
8 #include <hwregs/reg_map.h>
9 #include <hwregs/ser_defs.h>
10 #include <hwregs/dma_defs.h>
11 #include <mach/pinmux.h>
12
13 struct dbg_port
14 {
15 unsigned char nbr;
16 unsigned long instance;
17 unsigned int started;
18 unsigned long baudrate;
19 unsigned char parity;
20 unsigned int bits;
21 };
22
23 struct dbg_port ports[] =
24 {
25 {
26 0,
27 regi_ser0,
28 0,
29 115200,
30 'N',
31 8
32 },
33 {
34 1,
35 regi_ser1,
36 0,
37 115200,
38 'N',
39 8
40 },
41 {
42 2,
43 regi_ser2,
44 0,
45 115200,
46 'N',
47 8
48 },
49 {
50 3,
51 regi_ser3,
52 0,
53 115200,
54 'N',
55 8
56 },
57 #if CONFIG_ETRAX_SERIAL_PORTS == 5
58 {
59 4,
60 regi_ser4,
61 0,
62 115200,
63 'N',
64 8
65 },
66 #endif
67 };
68 static struct dbg_port *port =
69 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
70 &ports[0];
71 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
72 &ports[1];
73 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
74 &ports[2];
75 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
76 &ports[3];
77 #elif defined(CONFIG_ETRAX_DEBUG_PORT4)
78 &ports[4];
79 #else
80 NULL;
81 #endif
82
83 #ifdef CONFIG_ETRAX_KGDB
84 static struct dbg_port *kgdb_port =
85 #if defined(CONFIG_ETRAX_KGDB_PORT0)
86 &ports[0];
87 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
88 &ports[1];
89 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
90 &ports[2];
91 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
92 &ports[3];
93 #elif defined(CONFIG_ETRAX_KGDB_PORT4)
94 &ports[4];
95 #else
96 NULL;
97 #endif
98 #endif
99
100 static void
start_port(struct dbg_port * p)101 start_port(struct dbg_port* p)
102 {
103 if (!p)
104 return;
105
106 if (p->started)
107 return;
108 p->started = 1;
109
110 if (p->nbr == 1)
111 crisv32_pinmux_alloc_fixed(pinmux_ser1);
112 else if (p->nbr == 2)
113 crisv32_pinmux_alloc_fixed(pinmux_ser2);
114 else if (p->nbr == 3)
115 crisv32_pinmux_alloc_fixed(pinmux_ser3);
116 #if CONFIG_ETRAX_SERIAL_PORTS == 5
117 else if (p->nbr == 4)
118 crisv32_pinmux_alloc_fixed(pinmux_ser4);
119 #endif
120
121 /* Set up serial port registers */
122 reg_ser_rw_tr_ctrl tr_ctrl = {0};
123 reg_ser_rw_tr_dma_en tr_dma_en = {0};
124
125 reg_ser_rw_rec_ctrl rec_ctrl = {0};
126 reg_ser_rw_tr_baud_div tr_baud_div = {0};
127 reg_ser_rw_rec_baud_div rec_baud_div = {0};
128
129 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
130 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
131 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
132 tr_ctrl.en = rec_ctrl.en = 1;
133
134 if (p->parity == 'O')
135 {
136 tr_ctrl.par_en = regk_ser_yes;
137 tr_ctrl.par = regk_ser_odd;
138 rec_ctrl.par_en = regk_ser_yes;
139 rec_ctrl.par = regk_ser_odd;
140 }
141 else if (p->parity == 'E')
142 {
143 tr_ctrl.par_en = regk_ser_yes;
144 tr_ctrl.par = regk_ser_even;
145 rec_ctrl.par_en = regk_ser_yes;
146 rec_ctrl.par = regk_ser_odd;
147 }
148
149 if (p->bits == 7)
150 {
151 tr_ctrl.data_bits = regk_ser_bits7;
152 rec_ctrl.data_bits = regk_ser_bits7;
153 }
154
155 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
156 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
157 REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);
158 REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);
159 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
160 }
161
162 #ifdef CONFIG_ETRAX_KGDB
163 /* Use polling to get a single character from the kernel debug port */
164 int
getDebugChar(void)165 getDebugChar(void)
166 {
167 reg_ser_rs_stat_din stat;
168 reg_ser_rw_ack_intr ack_intr = { 0 };
169
170 do {
171 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
172 } while (!stat.dav);
173
174 /* Ack the data_avail interrupt. */
175 ack_intr.dav = 1;
176 REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
177
178 return stat.data;
179 }
180
181 /* Use polling to put a single character to the kernel debug port */
182 void
putDebugChar(int val)183 putDebugChar(int val)
184 {
185 reg_ser_r_stat_din stat;
186 do {
187 stat = REG_RD(ser, kgdb_port->instance, r_stat_din);
188 } while (!stat.tr_rdy);
189 REG_WR_INT(ser, kgdb_port->instance, rw_dout, val);
190 }
191 #endif /* CONFIG_ETRAX_KGDB */
192
193 /* Register console for printk's, etc. */
194 int __init
init_etrax_debug(void)195 init_etrax_debug(void)
196 {
197 start_port(port);
198
199 #ifdef CONFIG_ETRAX_KGDB
200 start_port(kgdb_port);
201 #endif /* CONFIG_ETRAX_KGDB */
202 return 0;
203 }
204