]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - arch/cris/arch-v32/kernel/debugport.c
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[mirror_ubuntu-jammy-kernel.git] / arch / cris / arch-v32 / kernel / debugport.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
51533b61
MS
2/*
3 * Copyright (C) 2003, Axis Communications AB.
4 */
5
51533b61 6#include <linux/console.h>
4729d773 7#include <linux/kernel.h>
51533b61 8#include <linux/init.h>
4729d773 9#include <linux/string.h>
82264102
JN
10#include <hwregs/reg_rdwr.h>
11#include <hwregs/reg_map.h>
12#include <hwregs/ser_defs.h>
13#include <hwregs/dma_defs.h>
556dcee7 14#include <mach/pinmux.h>
51533b61
MS
15
16struct 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
26struct 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
82264102
JN
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
51533b61 70};
4729d773 71
51533b61
MS
72static struct dbg_port *port =
73#if defined(CONFIG_ETRAX_DEBUG_PORT0)
82264102 74 &ports[0];
51533b61 75#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
82264102 76 &ports[1];
51533b61 77#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
82264102 78 &ports[2];
51533b61 79#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
82264102 80 &ports[3];
51533b61 81#else
82264102 82 NULL;
51533b61
MS
83#endif
84
85#ifdef CONFIG_ETRAX_KGDB
86static struct dbg_port *kgdb_port =
87#if defined(CONFIG_ETRAX_KGDB_PORT0)
82264102 88 &ports[0];
51533b61 89#elif defined(CONFIG_ETRAX_KGDB_PORT1)
82264102 90 &ports[1];
51533b61 91#elif defined(CONFIG_ETRAX_KGDB_PORT2)
82264102 92 &ports[2];
51533b61 93#elif defined(CONFIG_ETRAX_KGDB_PORT3)
82264102
JN
94 &ports[3];
95#elif defined(CONFIG_ETRAX_KGDB_PORT4)
96 &ports[4];
51533b61 97#else
82264102 98 NULL;
51533b61
MS
99#endif
100#endif
101
4729d773 102static void start_port(struct dbg_port *p)
51533b61 103{
4729d773
JN
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};
51533b61 107
4729d773
JN
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)
51533b61 113 return;
4729d773 114
51533b61
MS
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);
82264102
JN
123#if CONFIG_ETRAX_SERIAL_PORTS == 5
124 else if (p->nbr == 4)
125 crisv32_pinmux_alloc_fixed(pinmux_ser4);
126#endif
51533b61 127
51533b61
MS
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
4729d773 133 if (p->parity == 'O') {
51533b61
MS
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;
4729d773 138 } else if (p->parity == 'E') {
51533b61
MS
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
4729d773 145 if (p->bits == 7) {
51533b61
MS
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
51533b61
MS
157#ifdef CONFIG_ETRAX_KGDB
158/* Use polling to get a single character from the kernel debug port */
4729d773 159int getDebugChar(void)
51533b61 160{
82264102 161 reg_ser_rs_stat_din stat;
51533b61
MS
162 reg_ser_rw_ack_intr ack_intr = { 0 };
163
164 do {
82264102
JN
165 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
166 } while (!stat.dav);
51533b61
MS
167
168 /* Ack the data_avail interrupt. */
82264102
JN
169 ack_intr.dav = 1;
170 REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
51533b61
MS
171
172 return stat.data;
173}
174
175/* Use polling to put a single character to the kernel debug port */
4729d773 176void putDebugChar(int val)
51533b61 177{
82264102 178 reg_ser_r_stat_din stat;
51533b61 179 do {
82264102
JN
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);
51533b61
MS
183}
184#endif /* CONFIG_ETRAX_KGDB */
185
4729d773
JN
186static 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
196static void __init
197early_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
213static 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
51533b61 220/* Register console for printk's, etc. */
4729d773 221int __init init_etrax_debug(void)
51533b61 222{
51533b61
MS
223 start_port(port);
224
4729d773
JN
225 /* Register an early console if a debug port was chosen. */
226 register_console(&early_console_dev);
227
51533b61
MS
228#ifdef CONFIG_ETRAX_KGDB
229 start_port(kgdb_port);
230#endif /* CONFIG_ETRAX_KGDB */
231 return 0;
232}