Blame view

arch/m68k/atari/debug.c 8.78 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
  /*
   * linux/arch/m68k/atari/debug.c
   *
   * Atari debugging and serial console stuff
   *
   * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file COPYING in the main directory of this archive
   * for more details.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
  #include <linux/types.h>
  #include <linux/tty.h>
  #include <linux/console.h>
  #include <linux/init.h>
  #include <linux/delay.h>
a3b2004a2   Adrian Bunk   m68k: kill arch/m...
17
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
  
  #include <asm/atarihw.h>
  #include <asm/atariints.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
  /* Can be set somewhere, if a SCC master reset has already be done and should
   * not be repeated; used by kgdb */
  int atari_SCC_reset_done;
a3b2004a2   Adrian Bunk   m68k: kill arch/m...
24
  EXPORT_SYMBOL(atari_SCC_reset_done);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
  
  static struct console atari_console_driver = {
6ff5801ac   Roman Zippel   m68k: reformat va...
27
28
29
  	.name	= "debug",
  	.flags	= CON_PRINTBUFFER,
  	.index	= -1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  };
6ff5801ac   Roman Zippel   m68k: reformat va...
31
  static inline void ata_mfp_out(char c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  {
3d92e8f3a   Geert Uytterhoeven   m68k: atari - Ren...
33
  	while (!(st_mfp.trn_stat & 0x80))	/* wait for tx buf empty */
6ff5801ac   Roman Zippel   m68k: reformat va...
34
  		barrier();
3d92e8f3a   Geert Uytterhoeven   m68k: atari - Ren...
35
  	st_mfp.usart_dta = c;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  }
5575d0a3c   Adrian Bunk   m68k/atari/debug....
37
38
  static void atari_mfp_console_write(struct console *co, const char *str,
  				    unsigned int count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
40
41
42
43
44
45
  	while (count--) {
  		if (*str == '
  ')
  			ata_mfp_out('\r');
  		ata_mfp_out(*str++);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  }
6ff5801ac   Roman Zippel   m68k: reformat va...
47
  static inline void ata_scc_out(char c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
49
50
  	do {
  		MFPDELAY();
de339e4b7   Geert Uytterhoeven   m68k/atari: Renam...
51
  	} while (!(atari_scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
  	MFPDELAY();
de339e4b7   Geert Uytterhoeven   m68k/atari: Renam...
53
  	atari_scc.cha_b_data = c;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  }
5575d0a3c   Adrian Bunk   m68k/atari/debug....
55
56
  static void atari_scc_console_write(struct console *co, const char *str,
  				    unsigned int count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
58
59
60
61
62
63
  	while (count--) {
  		if (*str == '
  ')
  			ata_scc_out('\r');
  		ata_scc_out(*str++);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  }
6ff5801ac   Roman Zippel   m68k: reformat va...
65
  static inline void ata_midi_out(char c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
67
68
69
  	while (!(acia.mid_ctrl & ACIA_TDRE))	/* wait for tx buf empty */
  		barrier();
  	acia.mid_data = c;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  }
5575d0a3c   Adrian Bunk   m68k/atari/debug....
71
72
  static void atari_midi_console_write(struct console *co, const char *str,
  				     unsigned int count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
74
75
76
77
78
79
  	while (count--) {
  		if (*str == '
  ')
  			ata_midi_out('\r');
  		ata_midi_out(*str++);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
  }
6ff5801ac   Roman Zippel   m68k: reformat va...
81
  static int ata_par_out(char c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
83
84
85
  	unsigned char tmp;
  	/* This a some-seconds timeout in case no printer is connected */
  	unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ;
3d92e8f3a   Geert Uytterhoeven   m68k: atari - Ren...
86
  	while ((st_mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */
6ff5801ac   Roman Zippel   m68k: reformat va...
87
88
89
90
91
92
93
94
95
96
97
98
  		;
  	if (!i)
  		return 0;
  
  	sound_ym.rd_data_reg_sel = 15;	/* select port B */
  	sound_ym.wd_data = c;		/* put char onto port */
  	sound_ym.rd_data_reg_sel = 14;	/* select port A */
  	tmp = sound_ym.rd_data_reg_sel;
  	sound_ym.wd_data = tmp & ~0x20;	/* set strobe L */
  	MFPDELAY();			/* wait a bit */
  	sound_ym.wd_data = tmp | 0x20;	/* set strobe H */
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
  }
6ff5801ac   Roman Zippel   m68k: reformat va...
100
101
  static void atari_par_console_write(struct console *co, const char *str,
  				    unsigned int count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
103
  	static int printer_present = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104

6ff5801ac   Roman Zippel   m68k: reformat va...
105
  	if (!printer_present)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  		return;
6ff5801ac   Roman Zippel   m68k: reformat va...
107
108
109
110
111
112
113
114
115
116
117
118
119
  
  	while (count--) {
  		if (*str == '
  ') {
  			if (!ata_par_out('\r')) {
  				printer_present = 0;
  				return;
  			}
  		}
  		if (!ata_par_out(*str++)) {
  			printer_present = 0;
  			return;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
  }
5575d0a3c   Adrian Bunk   m68k/atari/debug....
122
  #if 0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
  int atari_mfp_console_wait_key(struct console *co)
  {
3d92e8f3a   Geert Uytterhoeven   m68k: atari - Ren...
125
  	while (!(st_mfp.rcv_stat & 0x80))	/* wait for rx buf filled */
6ff5801ac   Roman Zippel   m68k: reformat va...
126
  		barrier();
3d92e8f3a   Geert Uytterhoeven   m68k: atari - Ren...
127
  	return st_mfp.usart_dta;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
  }
  
  int atari_scc_console_wait_key(struct console *co)
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
132
133
  	do {
  		MFPDELAY();
de339e4b7   Geert Uytterhoeven   m68k/atari: Renam...
134
  	} while (!(atari_scc.cha_b_ctrl & 0x01)); /* wait for rx buf filled */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  	MFPDELAY();
de339e4b7   Geert Uytterhoeven   m68k/atari: Renam...
136
  	return atari_scc.cha_b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
  }
  
  int atari_midi_console_wait_key(struct console *co)
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
141
142
143
  	while (!(acia.mid_ctrl & ACIA_RDRF)) /* wait for rx buf filled */
  		barrier();
  	return acia.mid_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
  }
  #endif
6ff5801ac   Roman Zippel   m68k: reformat va...
146
147
  /*
   * The following two functions do a quick'n'dirty initialization of the MFP or
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
   * SCC serial ports. They're used by the debugging interface, kgdb, and the
6ff5801ac   Roman Zippel   m68k: reformat va...
149
150
   * serial console code.
   */
6ff5801ac   Roman Zippel   m68k: reformat va...
151
  static void __init atari_init_mfp_port(int cflag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
  	/*
  	 * timer values for 1200...115200 bps; > 38400 select 110, 134, or 150
  	 * bps, resp., and work only correct if there's a RSVE or RSSPEED
  	 */
  	static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 };
  	int baud = cflag & CBAUD;
  	int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0;
  	int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00;
  
  	if (cflag & CBAUDEX)
  		baud += B38400;
  	if (baud < B1200 || baud > B38400+2)
  		baud = B9600;		/* use default 9600bps for non-implemented rates */
  	baud -= B1200;			/* baud_table[] starts at 1200bps */
3d92e8f3a   Geert Uytterhoeven   m68k: atari - Ren...
167
168
169
170
171
172
  	st_mfp.trn_stat &= ~0x01;	/* disable TX */
  	st_mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */
  	st_mfp.tim_ct_cd &= 0x70;	/* stop timer D */
  	st_mfp.tim_dt_d = baud_table[baud];
  	st_mfp.tim_ct_cd |= 0x01;	/* start timer D, 1:4 */
  	st_mfp.trn_stat |= 0x01;	/* enable TX */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  }
6ff5801ac   Roman Zippel   m68k: reformat va...
174
175
  #define SCC_WRITE(reg, val)				\
  	do {						\
de339e4b7   Geert Uytterhoeven   m68k/atari: Renam...
176
  		atari_scc.cha_b_ctrl = (reg);		\
6ff5801ac   Roman Zippel   m68k: reformat va...
177
  		MFPDELAY();				\
de339e4b7   Geert Uytterhoeven   m68k/atari: Renam...
178
  		atari_scc.cha_b_ctrl = (val);		\
6ff5801ac   Roman Zippel   m68k: reformat va...
179
180
  		MFPDELAY();				\
  	} while (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
  
  /* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
   * delay of ~ 60us. */
6ff5801ac   Roman Zippel   m68k: reformat va...
184
185
186
187
188
189
  #define LONG_DELAY()					\
  	do {						\
  		int i;					\
  		for (i = 100; i > 0; --i)		\
  			MFPDELAY();			\
  	} while (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190

6ff5801ac   Roman Zippel   m68k: reformat va...
191
  static void __init atari_init_scc_port(int cflag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  	static int clksrc_table[9] =
  		/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
  		{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
  	static int brgsrc_table[9] =
  		/* reg 14: 0 = RTxC, 2 = PCLK */
  		{ 2, 2, 2, 2, 2, 2, 0, 2, 2 };
  	static int clkmode_table[9] =
  		/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
  		{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
  	static int div_table[9] =
  		/* reg12 (BRG low) */
  		{ 208, 138, 103, 50, 24, 11, 1, 0, 0 };
  
  	int baud = cflag & CBAUD;
  	int clksrc, clkmode, div, reg3, reg5;
  
  	if (cflag & CBAUDEX)
  		baud += B38400;
  	if (baud < B1200 || baud > B38400+2)
  		baud = B9600;		/* use default 9600bps for non-implemented rates */
  	baud -= B1200;			/* tables starts at 1200bps */
  
  	clksrc  = clksrc_table[baud];
  	clkmode = clkmode_table[baud];
  	div     = div_table[baud];
  	if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) {
  		/* special treatment for TT, where rates >= 38400 are done via TRxC */
  		clksrc = 0x28;		/* TRxC */
  		clkmode = baud == 6 ? 0xc0 :
  			  baud == 7 ? 0x80 : /* really 76800bps */
  				      0x40;  /* really 153600bps */
  		div = 0;
  	}
  
  	reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
  	reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
de339e4b7   Geert Uytterhoeven   m68k/atari: Renam...
229
  	(void)atari_scc.cha_b_ctrl;	/* reset reg pointer */
6ff5801ac   Roman Zippel   m68k: reformat va...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
  	SCC_WRITE(9, 0xc0);		/* reset */
  	LONG_DELAY();			/* extra delay after WR9 access */
  	SCC_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03)
  				      : 0 | 0x04 /* 1 stopbit */ | clkmode);
  	SCC_WRITE(3, reg3);
  	SCC_WRITE(5, reg5);
  	SCC_WRITE(9, 0);		/* no interrupts */
  	LONG_DELAY();			/* extra delay after WR9 access */
  	SCC_WRITE(10, 0);		/* NRZ mode */
  	SCC_WRITE(11, clksrc);		/* main clock source */
  	SCC_WRITE(12, div);		/* BRG value */
  	SCC_WRITE(13, 0);		/* BRG high byte */
  	SCC_WRITE(14, brgsrc_table[baud]);
  	SCC_WRITE(14, brgsrc_table[baud] | (div ? 1 : 0));
  	SCC_WRITE(3, reg3 | 1);
  	SCC_WRITE(5, reg5 | 8);
  
  	atari_SCC_reset_done = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
  }
6ff5801ac   Roman Zippel   m68k: reformat va...
249
  static void __init atari_init_midi_port(int cflag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
  {
6ff5801ac   Roman Zippel   m68k: reformat va...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  	int baud = cflag & CBAUD;
  	int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00;
  	/* warning 7N1 isn't possible! (instead 7O2 is used...) */
  	int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04;
  	int div;
  
  	/* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as
  	 * default) the standard MIDI speed 31250. */
  	if (cflag & CBAUDEX)
  		baud += B38400;
  	if (baud == B4800)
  		div = ACIA_DIV64;	/* really 7812.5 bps */
  	else if (baud == B38400+2 /* 115200 */)
  		div = ACIA_DIV1;	/* really 500 kbps (does that work??) */
  	else
  		div = ACIA_DIV16;	/* 31250 bps, standard for MIDI */
  
  	/* RTS low, ints disabled */
  	acia.mid_ctrl = div | csize | parity |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
271
272
  		    ((atari_switches & ATARI_SWITCH_MIDI) ?
  		     ACIA_RHTID : ACIA_RLTID);
  }
d6713b409   Roman Zippel   m68k: early param...
273
  static int __init atari_debug_setup(char *arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
  {
d6713b409   Roman Zippel   m68k: early param...
275
276
277
278
  	if (!MACH_IS_ATARI)
  		return 0;
  
  	if (!strcmp(arg, "ser"))
6ff5801ac   Roman Zippel   m68k: reformat va...
279
  		/* defaults to ser2 for a Falcon and ser1 otherwise */
d6713b409   Roman Zippel   m68k: early param...
280
  		arg = MACH_IS_FALCON ? "ser2" : "ser1";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281

d6713b409   Roman Zippel   m68k: early param...
282
  	if (!strcmp(arg, "ser1")) {
6ff5801ac   Roman Zippel   m68k: reformat va...
283
284
285
  		/* ST-MFP Modem1 serial port */
  		atari_init_mfp_port(B9600|CS8);
  		atari_console_driver.write = atari_mfp_console_write;
d6713b409   Roman Zippel   m68k: early param...
286
  	} else if (!strcmp(arg, "ser2")) {
6ff5801ac   Roman Zippel   m68k: reformat va...
287
288
289
  		/* SCC Modem2 serial port */
  		atari_init_scc_port(B9600|CS8);
  		atari_console_driver.write = atari_scc_console_write;
d6713b409   Roman Zippel   m68k: early param...
290
  	} else if (!strcmp(arg, "midi")) {
6ff5801ac   Roman Zippel   m68k: reformat va...
291
292
293
  		/* MIDI port */
  		atari_init_midi_port(B9600|CS8);
  		atari_console_driver.write = atari_midi_console_write;
d6713b409   Roman Zippel   m68k: early param...
294
  	} else if (!strcmp(arg, "par")) {
6ff5801ac   Roman Zippel   m68k: reformat va...
295
296
297
298
299
300
301
302
303
304
305
306
  		/* parallel printer */
  		atari_turnoff_irq(IRQ_MFP_BUSY); /* avoid ints */
  		sound_ym.rd_data_reg_sel = 7;	/* select mixer control */
  		sound_ym.wd_data = 0xff;	/* sound off, ports are output */
  		sound_ym.rd_data_reg_sel = 15;	/* select port B */
  		sound_ym.wd_data = 0;		/* no char */
  		sound_ym.rd_data_reg_sel = 14;	/* select port A */
  		sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */
  		atari_console_driver.write = atari_par_console_write;
  	}
  	if (atari_console_driver.write)
  		register_console(&atari_console_driver);
d6713b409   Roman Zippel   m68k: early param...
307
308
  
  	return 0;
6ff5801ac   Roman Zippel   m68k: reformat va...
309
  }
d6713b409   Roman Zippel   m68k: early param...
310
311
  
  early_param("debug", atari_debug_setup);