1 /*
2  * Copyright (C) 2003, Axis Communications AB.
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 
15 struct 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 
25 struct 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 
71 static 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
85 static 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 
start_port(struct dbg_port * p)101 static void start_port(struct dbg_port *p)
102 {
103 	/* Set up serial port registers */
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 /* Use polling to get a single character from the kernel debug port */
getDebugChar(void)158 int 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 	/* Ack the data_avail interrupt. */
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 /* Use polling to put a single character to the kernel debug port */
putDebugChar(int val)175 void 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 /* CONFIG_ETRAX_KGDB */
184 
early_putch(int c)185 static void __init early_putch(int c)
186 {
187 	reg_ser_r_stat_din stat;
188 	/* Wait until transmitter is ready and send. */
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 
195 static void __init
early_console_write(struct console * con,const char * s,unsigned n)196 early_console_write(struct console *con, const char *s, unsigned n)
197 {
198 	extern void reset_watchdog(void);
199 	int i;
200 
201 	/* Send data. */
202 	for (i = 0; i < n; i++) {
203 		/* TODO: the '\n' -> '\n\r' translation should be done at the
204 		   receiver. Remove it when the serial driver removes it.   */
205 		if (s[i] == '\n')
206 			early_putch('\r');
207 		early_putch(s[i]);
208 		reset_watchdog();
209 	}
210 }
211 
212 static 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 /* Register console for printk's, etc. */
init_etrax_debug(void)220 int __init init_etrax_debug(void)
221 {
222         start_port(port);
223 
224 	/* Register an early console if a debug port was chosen.  */
225 	register_console(&early_console_dev);
226 
227 #ifdef CONFIG_ETRAX_KGDB
228 	start_port(kgdb_port);
229 #endif /* CONFIG_ETRAX_KGDB */
230 	return 0;
231 }
232