License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[sfrench/cifs-2.6.git] / arch / cris / arch-v32 / kernel / debugport.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2003, Axis Communications AB.
4  */
5
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>
15
16 struct dbg_port
17 {
18         unsigned char nbr;
19         unsigned long instance;
20         unsigned int started;
21         unsigned long baudrate;
22         unsigned char parity;
23         unsigned int bits;
24 };
25
26 struct dbg_port ports[] =
27 {
28   {
29     0,
30     regi_ser0,
31     0,
32     115200,
33     'N',
34     8
35   },
36   {
37     1,
38     regi_ser1,
39     0,
40     115200,
41     'N',
42     8
43   },
44   {
45     2,
46     regi_ser2,
47     0,
48     115200,
49     'N',
50     8
51   },
52   {
53     3,
54     regi_ser3,
55     0,
56     115200,
57     'N',
58     8
59   },
60 #if CONFIG_ETRAX_SERIAL_PORTS == 5
61   {
62     4,
63     regi_ser4,
64     0,
65     115200,
66     'N',
67     8
68   },
69 #endif
70 };
71
72 static struct dbg_port *port =
73 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
74         &ports[0];
75 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
76         &ports[1];
77 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
78         &ports[2];
79 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
80         &ports[3];
81 #else
82         NULL;
83 #endif
84
85 #ifdef CONFIG_ETRAX_KGDB
86 static struct dbg_port *kgdb_port =
87 #if defined(CONFIG_ETRAX_KGDB_PORT0)
88         &ports[0];
89 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
90         &ports[1];
91 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
92         &ports[2];
93 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
94         &ports[3];
95 #elif defined(CONFIG_ETRAX_KGDB_PORT4)
96         &ports[4];
97 #else
98         NULL;
99 #endif
100 #endif
101
102 static void start_port(struct dbg_port *p)
103 {
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};
107
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};
111
112         if (!p || p->started)
113                 return;
114
115         p->started = 1;
116
117         if (p->nbr == 1)
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);
126 #endif
127
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;
132
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;
143         }
144
145         if (p->bits == 7) {
146                 tr_ctrl.data_bits = regk_ser_bits7;
147                 rec_ctrl.data_bits = regk_ser_bits7;
148         }
149
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);
155 }
156
157 #ifdef CONFIG_ETRAX_KGDB
158 /* Use polling to get a single character from the kernel debug port */
159 int getDebugChar(void)
160 {
161         reg_ser_rs_stat_din stat;
162         reg_ser_rw_ack_intr ack_intr = { 0 };
163
164         do {
165                 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
166         } while (!stat.dav);
167
168         /* Ack the data_avail interrupt. */
169         ack_intr.dav = 1;
170         REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
171
172         return stat.data;
173 }
174
175 /* Use polling to put a single character to the kernel debug port */
176 void putDebugChar(int val)
177 {
178         reg_ser_r_stat_din stat;
179         do {
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);
183 }
184 #endif /* CONFIG_ETRAX_KGDB */
185
186 static void __init early_putch(int c)
187 {
188         reg_ser_r_stat_din stat;
189         /* Wait until transmitter is ready and send. */
190         do
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);
194 }
195
196 static void __init
197 early_console_write(struct console *con, const char *s, unsigned n)
198 {
199         extern void reset_watchdog(void);
200         int i;
201
202         /* Send data. */
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.   */
206                 if (s[i] == '\n')
207                         early_putch('\r');
208                 early_putch(s[i]);
209                 reset_watchdog();
210         }
211 }
212
213 static struct console early_console_dev __initdata = {
214         .name   = "early",
215         .write  = early_console_write,
216         .flags  = CON_PRINTBUFFER | CON_BOOT,
217         .index  = -1
218 };
219
220 /* Register console for printk's, etc. */
221 int __init init_etrax_debug(void)
222 {
223         start_port(port);
224
225         /* Register an early console if a debug port was chosen.  */
226         register_console(&early_console_dev);
227
228 #ifdef CONFIG_ETRAX_KGDB
229         start_port(kgdb_port);
230 #endif /* CONFIG_ETRAX_KGDB */
231         return 0;
232 }